[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [HVM] Route ISA IRQ 0 to IOAPIC GSI 2, just like 99% of native systems.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxxx
# Date 1167162551 0
# Node ID d752d8ccd282874f2a681d046fdafb36df2830f5
# Parent  ce4e548f42b89f0c716f2fbe812c9172b28e7469
[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@xxxxxxxxxxxxx>
---
 tools/firmware/hvmloader/acpi/build.c |   24 +++++++++++----
 tools/firmware/hvmloader/mp_tables.c  |    2 -
 xen/arch/x86/hvm/hpet.c               |   53 +++-------------------------------
 xen/arch/x86/hvm/irq.c                |   10 +++---
 4 files changed, 30 insertions(+), 59 deletions(-)

diff -r ce4e548f42b8 -r d752d8ccd282 tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c     Mon Dec 25 19:29:05 2006 +0000
+++ b/tools/firmware/hvmloader/acpi/build.c     Tue Dec 26 19:49:11 2006 +0000
@@ -69,16 +69,28 @@ int construct_madt(struct acpi_20_madt *
     intsrcovr = (struct acpi_20_madt_intsrcovr *)(madt + 1);
     for ( i = 0; i < 16; i++ )
     {
-        if ( !(PCI_ISA_IRQ_MASK & (1U << i)) )
-            continue;
-
-        /* PCI: active-low level-triggered */
         memset(intsrcovr, 0, sizeof(*intsrcovr));
         intsrcovr->type   = ACPI_INTERRUPT_SOURCE_OVERRIDE;
         intsrcovr->length = sizeof(*intsrcovr);
         intsrcovr->source = i;
-        intsrcovr->gsi    = i;
-        intsrcovr->flags  = 0xf;
+
+        if ( i == 0 )
+        {
+            /* ISA IRQ0 routed to IOAPIC GSI 2. */
+            intsrcovr->gsi    = 2;
+            intsrcovr->flags  = 0x0;
+        }
+        else if ( PCI_ISA_IRQ_MASK & (1U << i) )
+        {
+            /* PCI: active-low level-triggered. */
+            intsrcovr->gsi    = i;
+            intsrcovr->flags  = 0xf;
+        }
+        else
+        {
+            /* No need for a INT source override structure. */
+            continue;
+        }
 
         offset += sizeof(*intsrcovr);
         intsrcovr++;
diff -r ce4e548f42b8 -r d752d8ccd282 tools/firmware/hvmloader/mp_tables.c
--- a/tools/firmware/hvmloader/mp_tables.c      Mon Dec 25 19:29:05 2006 +0000
+++ b/tools/firmware/hvmloader/mp_tables.c      Tue Dec 26 19:49:11 2006 +0000
@@ -373,7 +373,7 @@ void create_mp_tables(void)
     {
         if ( i == 2 ) continue; /* skip the slave PIC connection */
         fill_mp_io_intr_entry((struct mp_io_intr_entry *)p, 
-                              BUS_ID_ISA, i, IOAPIC_ID, i);
+                              BUS_ID_ISA, i, IOAPIC_ID, (i == 0) ? 2 : i);
         p += sizeof(struct mp_io_intr_entry);
     }
 
diff -r ce4e548f42b8 -r d752d8ccd282 xen/arch/x86/hvm/hpet.c
--- a/xen/arch/x86/hvm/hpet.c   Mon Dec 25 19:29:05 2006 +0000
+++ b/xen/arch/x86/hvm/hpet.c   Tue Dec 26 19:49:11 2006 +0000
@@ -97,9 +97,6 @@
     ((timer_config(h, n) & HPET_TN_INT_ROUTE_CAP_MASK) \
         >> HPET_TN_INT_ROUTE_CAP_SHIFT)
 
-#define timer_int_route_valid(h, n)  \
-    (timer_int_route_cap(h, n) & (1 << timer_int_route(h, n)))    
- 
 #define hpet_time_after(a, b)   ((int32_t)(b) -(int32_t)(a) < 0)
 #define hpet_time_after64(a, b)   ((int64_t)(b) -(int64_t)(a) < 0)
 
@@ -409,54 +406,14 @@ struct hvm_mmio_handler hpet_mmio_handle
     .write_handler = hpet_write
 };
 
-static void hpet_irq_assert(struct domain *d, 
-                            unsigned int isa_irq, unsigned int intr)
-{
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
-
-    spin_lock(&hvm_irq->lock);
-
-    if ( !__test_and_set_bit(isa_irq, &hvm_irq->isa_irq) &&
-         (hvm_irq->gsi_assert_count[isa_irq]++ == 0) )
-    {
-        vioapic_irq_positive_edge(d, intr);
-        vpic_irq_positive_edge(d, isa_irq);
-    }
-
-    spin_unlock(&hvm_irq->lock);
-}
-
-static void hpet_irq_deassert(struct domain *d,
-                unsigned int isa_irq, unsigned int intr)
-{
-    hvm_isa_irq_deassert(d, isa_irq);
-}
-
 static void hpet_set_irq(struct domain *d, int hpet_tn)
 {
-    int irq, intr;
-
-    if ( (hpet_tn != 0) && (hpet_tn != 1) )
-        return;
-
     /* if LegacyReplacementRoute bit is set, HPET specification requires
        timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
-       timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC.
-       It's hard to distinguish NON-APIC and I/O APIC, so we set both PIC
-       and I/O APIC here. Guest OS shall make proper mask setting to ensure
-       only one interrupt is injected into it. */
-    if ( hpet_tn == 0 )
-    {
-        irq  = 0;
-        intr = 2;
-    }
-    else
-    {
-        irq = intr = 8;
-    }
-    
-    hpet_irq_deassert(d, irq, intr);
-    hpet_irq_assert(d, irq, intr);
+       timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC. */
+    int isa_irq = (hpet_tn == 0) ? 0 : 8;
+    hvm_isa_irq_deassert(d, isa_irq);
+    hvm_isa_irq_assert(d, isa_irq);
 }
 
 static void hpet_route_interrupt(HPETState *h, unsigned int tn)
@@ -465,7 +422,7 @@ static void hpet_route_interrupt(HPETSta
     struct domain *d = h->vcpu->domain;
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
 
-    if ( (tn_int_route >= VIOAPIC_NUM_PINS) || !timer_int_route_valid(h, tn) )
+    if ( !(timer_int_route_cap(h, tn) & (1U << tn_int_route)) )
     {
         gdprintk(XENLOG_ERR,
                  "HPET: timer%u: invalid interrupt route config\n", tn);
diff -r ce4e548f42b8 -r d752d8ccd282 xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c    Mon Dec 25 19:29:05 2006 +0000
+++ b/xen/arch/x86/hvm/irq.c    Tue Dec 26 19:49:11 2006 +0000
@@ -85,15 +85,16 @@ void hvm_isa_irq_assert(
     struct domain *d, unsigned int isa_irq)
 {
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq;
 
     ASSERT(isa_irq <= 15);
 
     spin_lock(&hvm_irq->lock);
 
     if ( !__test_and_set_bit(isa_irq, &hvm_irq->isa_irq) &&
-         (hvm_irq->gsi_assert_count[isa_irq]++ == 0) )
-    {
-        vioapic_irq_positive_edge(d, isa_irq);
+         (hvm_irq->gsi_assert_count[gsi]++ == 0) )
+    {
+        vioapic_irq_positive_edge(d, gsi);
         vpic_irq_positive_edge(d, isa_irq);
     }
 
@@ -104,13 +105,14 @@ void hvm_isa_irq_deassert(
     struct domain *d, unsigned int isa_irq)
 {
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    unsigned int gsi = (isa_irq == 0) ? 2 : isa_irq;
 
     ASSERT(isa_irq <= 15);
 
     spin_lock(&hvm_irq->lock);
 
     if ( __test_and_clear_bit(isa_irq, &hvm_irq->isa_irq) &&
-         (--hvm_irq->gsi_assert_count[isa_irq] == 0) )
+         (--hvm_irq->gsi_assert_count[gsi] == 0) )
         vpic_irq_negative_edge(d, isa_irq);
 
     spin_unlock(&hvm_irq->lock);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.