ia64/xen-unstable

changeset 13195:d752d8ccd282

[HVM] Route ISA IRQ 0 to IOAPIC GSI 2, just like 99% of native systems.
This is a built-in assumption of HPET 'legacy' IRQ routing, which is
why we have changed to this routing strategy now.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@localhost.localdomain
date Tue Dec 26 19:49:11 2006 +0000 (2006-12-26)
parents ce4e548f42b8
children 6f8d650f3ab1
files tools/firmware/hvmloader/acpi/build.c tools/firmware/hvmloader/mp_tables.c xen/arch/x86/hvm/hpet.c xen/arch/x86/hvm/irq.c
line diff
     1.1 --- a/tools/firmware/hvmloader/acpi/build.c	Mon Dec 25 19:29:05 2006 +0000
     1.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Tue Dec 26 19:49:11 2006 +0000
     1.3 @@ -69,16 +69,28 @@ int construct_madt(struct acpi_20_madt *
     1.4      intsrcovr = (struct acpi_20_madt_intsrcovr *)(madt + 1);
     1.5      for ( i = 0; i < 16; i++ )
     1.6      {
     1.7 -        if ( !(PCI_ISA_IRQ_MASK & (1U << i)) )
     1.8 -            continue;
     1.9 -
    1.10 -        /* PCI: active-low level-triggered */
    1.11          memset(intsrcovr, 0, sizeof(*intsrcovr));
    1.12          intsrcovr->type   = ACPI_INTERRUPT_SOURCE_OVERRIDE;
    1.13          intsrcovr->length = sizeof(*intsrcovr);
    1.14          intsrcovr->source = i;
    1.15 -        intsrcovr->gsi    = i;
    1.16 -        intsrcovr->flags  = 0xf;
    1.17 +
    1.18 +        if ( i == 0 )
    1.19 +        {
    1.20 +            /* ISA IRQ0 routed to IOAPIC GSI 2. */
    1.21 +            intsrcovr->gsi    = 2;
    1.22 +            intsrcovr->flags  = 0x0;
    1.23 +        }
    1.24 +        else if ( PCI_ISA_IRQ_MASK & (1U << i) )
    1.25 +        {
    1.26 +            /* PCI: active-low level-triggered. */
    1.27 +            intsrcovr->gsi    = i;
    1.28 +            intsrcovr->flags  = 0xf;
    1.29 +        }
    1.30 +        else
    1.31 +        {
    1.32 +            /* No need for a INT source override structure. */
    1.33 +            continue;
    1.34 +        }
    1.35  
    1.36          offset += sizeof(*intsrcovr);
    1.37          intsrcovr++;
     2.1 --- a/tools/firmware/hvmloader/mp_tables.c	Mon Dec 25 19:29:05 2006 +0000
     2.2 +++ b/tools/firmware/hvmloader/mp_tables.c	Tue Dec 26 19:49:11 2006 +0000
     2.3 @@ -373,7 +373,7 @@ void create_mp_tables(void)
     2.4      {
     2.5          if ( i == 2 ) continue; /* skip the slave PIC connection */
     2.6          fill_mp_io_intr_entry((struct mp_io_intr_entry *)p, 
     2.7 -                              BUS_ID_ISA, i, IOAPIC_ID, i);
     2.8 +                              BUS_ID_ISA, i, IOAPIC_ID, (i == 0) ? 2 : i);
     2.9          p += sizeof(struct mp_io_intr_entry);
    2.10      }
    2.11  
     3.1 --- a/xen/arch/x86/hvm/hpet.c	Mon Dec 25 19:29:05 2006 +0000
     3.2 +++ b/xen/arch/x86/hvm/hpet.c	Tue Dec 26 19:49:11 2006 +0000
     3.3 @@ -97,9 +97,6 @@
     3.4      ((timer_config(h, n) & HPET_TN_INT_ROUTE_CAP_MASK) \
     3.5          >> HPET_TN_INT_ROUTE_CAP_SHIFT)
     3.6  
     3.7 -#define timer_int_route_valid(h, n)  \
     3.8 -    (timer_int_route_cap(h, n) & (1 << timer_int_route(h, n)))    
     3.9 - 
    3.10  #define hpet_time_after(a, b)   ((int32_t)(b) -(int32_t)(a) < 0)
    3.11  #define hpet_time_after64(a, b)   ((int64_t)(b) -(int64_t)(a) < 0)
    3.12  
    3.13 @@ -409,54 +406,14 @@ struct hvm_mmio_handler hpet_mmio_handle
    3.14      .write_handler = hpet_write
    3.15  };
    3.16  
    3.17 -static void hpet_irq_assert(struct domain *d, 
    3.18 -                            unsigned int isa_irq, unsigned int intr)
    3.19 -{
    3.20 -    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
    3.21 -
    3.22 -    spin_lock(&hvm_irq->lock);
    3.23 -
    3.24 -    if ( !__test_and_set_bit(isa_irq, &hvm_irq->isa_irq) &&
    3.25 -         (hvm_irq->gsi_assert_count[isa_irq]++ == 0) )
    3.26 -    {
    3.27 -        vioapic_irq_positive_edge(d, intr);
    3.28 -        vpic_irq_positive_edge(d, isa_irq);
    3.29 -    }
    3.30 -
    3.31 -    spin_unlock(&hvm_irq->lock);
    3.32 -}
    3.33 -
    3.34 -static void hpet_irq_deassert(struct domain *d,
    3.35 -                unsigned int isa_irq, unsigned int intr)
    3.36 -{
    3.37 -    hvm_isa_irq_deassert(d, isa_irq);
    3.38 -}
    3.39 -
    3.40  static void hpet_set_irq(struct domain *d, int hpet_tn)
    3.41  {
    3.42 -    int irq, intr;
    3.43 -
    3.44 -    if ( (hpet_tn != 0) && (hpet_tn != 1) )
    3.45 -        return;
    3.46 -
    3.47      /* if LegacyReplacementRoute bit is set, HPET specification requires
    3.48         timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
    3.49 -       timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC.
    3.50 -       It's hard to distinguish NON-APIC and I/O APIC, so we set both PIC
    3.51 -       and I/O APIC here. Guest OS shall make proper mask setting to ensure
    3.52 -       only one interrupt is injected into it. */
    3.53 -    if ( hpet_tn == 0 )
    3.54 -    {
    3.55 -        irq  = 0;
    3.56 -        intr = 2;
    3.57 -    }
    3.58 -    else
    3.59 -    {
    3.60 -        irq = intr = 8;
    3.61 -    }
    3.62 -    
    3.63 -    hpet_irq_deassert(d, irq, intr);
    3.64 -    hpet_irq_assert(d, irq, intr);
    3.65 +       timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC. */
    3.66 +    int isa_irq = (hpet_tn == 0) ? 0 : 8;
    3.67 +    hvm_isa_irq_deassert(d, isa_irq);
    3.68 +    hvm_isa_irq_assert(d, isa_irq);
    3.69  }
    3.70  
    3.71  static void hpet_route_interrupt(HPETState *h, unsigned int tn)
    3.72 @@ -465,7 +422,7 @@ static void hpet_route_interrupt(HPETSta
    3.73      struct domain *d = h->vcpu->domain;
    3.74      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
    3.75  
    3.76 -    if ( (tn_int_route >= VIOAPIC_NUM_PINS) || !timer_int_route_valid(h, tn) )
    3.77 +    if ( !(timer_int_route_cap(h, tn) & (1U << tn_int_route)) )
    3.78      {
    3.79          gdprintk(XENLOG_ERR,
    3.80                   "HPET: timer%u: invalid interrupt route config\n", tn);
     4.1 --- a/xen/arch/x86/hvm/irq.c	Mon Dec 25 19:29:05 2006 +0000
     4.2 +++ b/xen/arch/x86/hvm/irq.c	Tue Dec 26 19:49:11 2006 +0000
     4.3 @@ -85,15 +85,16 @@ void hvm_isa_irq_assert(
     4.4      struct domain *d, unsigned int isa_irq)
     4.5  {
     4.6      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
     4.7 +    unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq;
     4.8  
     4.9      ASSERT(isa_irq <= 15);
    4.10  
    4.11      spin_lock(&hvm_irq->lock);
    4.12  
    4.13      if ( !__test_and_set_bit(isa_irq, &hvm_irq->isa_irq) &&
    4.14 -         (hvm_irq->gsi_assert_count[isa_irq]++ == 0) )
    4.15 +         (hvm_irq->gsi_assert_count[gsi]++ == 0) )
    4.16      {
    4.17 -        vioapic_irq_positive_edge(d, isa_irq);
    4.18 +        vioapic_irq_positive_edge(d, gsi);
    4.19          vpic_irq_positive_edge(d, isa_irq);
    4.20      }
    4.21  
    4.22 @@ -104,13 +105,14 @@ void hvm_isa_irq_deassert(
    4.23      struct domain *d, unsigned int isa_irq)
    4.24  {
    4.25      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
    4.26 +    unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq;
    4.27  
    4.28      ASSERT(isa_irq <= 15);
    4.29  
    4.30      spin_lock(&hvm_irq->lock);
    4.31  
    4.32      if ( __test_and_clear_bit(isa_irq, &hvm_irq->isa_irq) &&
    4.33 -         (--hvm_irq->gsi_assert_count[isa_irq] == 0) )
    4.34 +         (--hvm_irq->gsi_assert_count[gsi] == 0) )
    4.35          vpic_irq_negative_edge(d, isa_irq);
    4.36  
    4.37      spin_unlock(&hvm_irq->lock);