ioapic: Save interrupt source override information
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 17 Mar 2011 07:48:53 +0000 (15:48 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 17 Mar 2011 08:14:19 +0000 (16:14 +0800)
sys/platform/pc32/apic/mpapic.c
sys/platform/pc32/i386/mp_machdep.c
sys/platform/pc32/i386/mp_madt.c
sys/platform/pc32/include/smp.h
sys/platform/pc64/apic/mpapic.c
sys/platform/pc64/include/smp.h
sys/platform/pc64/x86_64/mp_machdep.c
sys/platform/pc64/x86_64/mp_madt.c

index a042c39..c81b36f 100644 (file)
@@ -1184,3 +1184,15 @@ ioapic_add(void *addr, int gsi_base, int npin)
        if (info == NULL)
                TAILQ_INSERT_HEAD(&ioapic_conf.ioc_list, ninfo, io_link);
 }
+
+void
+ioapic_intsrc(int irq, int gsi)
+{
+       KKASSERT(irq < 16);
+       if (ioapic_conf.ioc_intsrc[irq] != -1 &&
+           ioapic_conf.ioc_intsrc[irq] != gsi) {
+               kprintf("IOAPIC: warning intsrc irq %d, gsi %d -> gsi %d\n",
+                       irq, ioapic_conf.ioc_intsrc[irq], gsi);
+       }
+       ioapic_conf.ioc_intsrc[irq] = gsi;
+}
index cac2709..bd9811a 100644 (file)
@@ -3570,6 +3570,7 @@ static int
 mptable_ioapic_int_callback(void *xarg, const void *pos, int type)
 {
        struct mptable_ioapic_int_cbarg *arg = xarg;
+       const struct mptable_ioapic *ioapic;
        const struct mptable_bus *bus;
        const struct INTENTRY *ent;
 
@@ -3590,11 +3591,40 @@ mptable_ioapic_int_callback(void *xarg, const void *pos, int type)
        if (bus == NULL)
                return 0;
 
-       /* XXX rough estimation */
-       if (ent->src_bus_irq != ent->dst_apic_int) {
-               if (bootverbose) {
-                       kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
-                               ent->src_bus_irq, ent->dst_apic_int);
+       TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
+               if (ioapic->mio_apic_id == ent->dst_apic_id)
+                       break;
+       }
+       if (ioapic == NULL) {
+               kprintf("MPTABLE: warning ISA int dst apic id %d "
+                       "does not exist\n", ent->dst_apic_id);
+               return 0;
+       }
+
+       if (!ioapic_use_old) {
+               int gsi;
+
+               if (ent->dst_apic_int >= ioapic->mio_npin) {
+                       panic("mptable_ioapic_enumerate: invalid I/O APIC "
+                             "pin %d, should be < %d",
+                             ent->dst_apic_int, ioapic->mio_npin);
+               }
+               gsi = ioapic->mio_gsi_base + ent->dst_apic_int;
+
+               if (ent->src_bus_irq != gsi) {
+                       if (bootverbose) {
+                               kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
+                                       ent->src_bus_irq, gsi);
+                       }
+                       ioapic_intsrc(ent->src_bus_irq, gsi);
+               }
+       } else {
+               /* XXX rough estimation */
+               if (ent->src_bus_irq != ent->dst_apic_int) {
+                       if (bootverbose) {
+                               kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
+                                       ent->src_bus_irq, ent->dst_apic_int);
+                       }
                }
        }
        return 0;
@@ -3650,7 +3680,7 @@ mptable_ioapic_enumerate(struct ioapic_enumerator *e)
        if (mptable_use_default) {
                if (bootverbose)
                        kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (default)\n");
-               /* TODO default intsrc */
+               ioapic_intsrc(0, 2);
                return;
        }
 
@@ -3666,7 +3696,7 @@ mptable_ioapic_enumerate(struct ioapic_enumerator *e)
        if (TAILQ_EMPTY(&bus_info.mbi_list)) {
                if (bootverbose)
                        kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (no bus)\n");
-               /* TODO default intsrc */
+               ioapic_intsrc(0, 2);
        } else {
                struct mptable_ioapic_int_cbarg arg;
 
@@ -3683,7 +3713,7 @@ mptable_ioapic_enumerate(struct ioapic_enumerator *e)
                                kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 "
                                        "(no int)\n");
                        }
-                       /* TODO default intsrc */
+                       ioapic_intsrc(0, 2);
                }
        }
 
index 7154ab0..163f8a8 100644 (file)
@@ -840,11 +840,13 @@ madt_ioapic_enum_callback(void *xarg, const struct acpi_madt_ent *ent)
                const struct acpi_madt_intsrc *intsrc_ent;
 
                intsrc_ent = (const struct acpi_madt_intsrc *)ent;
-               if (intsrc_ent->mint_src == intsrc_ent->mint_gsi)
+               if (intsrc_ent->mint_src == intsrc_ent->mint_gsi ||
+                   intsrc_ent->mint_bus != MADT_INT_BUS_ISA)
                        return 0;
 
                MADT_VPRINTF("INTSRC irq %d -> gsi %u\n",
                             intsrc_ent->mint_src, intsrc_ent->mint_gsi);
+               ioapic_intsrc(intsrc_ent->mint_src, intsrc_ent->mint_gsi);
        } else if (ent->me_type == MADT_ENT_IOAPIC) {
                const struct acpi_madt_ioapic *ioapic_ent;
 
index 4da1f13..bf6503a 100644 (file)
@@ -160,6 +160,7 @@ void        lapic_enumerator_register(struct lapic_enumerator *);
 void   ioapic_config(void);
 void   ioapic_enumerator_register(struct ioapic_enumerator *);
 void   ioapic_add(void *, int, int);
+void   ioapic_intsrc(int, int);
 extern int apic_io_enable;
 extern int ioapic_use_old;
 
index 1e4d374..50ef94b 100644 (file)
@@ -1246,3 +1246,15 @@ ioapic_add(void *addr, int gsi_base, int npin)
        if (info == NULL)
                TAILQ_INSERT_HEAD(&ioapic_conf.ioc_list, ninfo, io_link);
 }
+
+void
+ioapic_intsrc(int irq, int gsi)
+{
+       KKASSERT(irq < 16);
+       if (ioapic_conf.ioc_intsrc[irq] != -1 &&
+           ioapic_conf.ioc_intsrc[irq] != gsi) {
+               kprintf("IOAPIC: warning intsrc irq %d, gsi %d -> gsi %d\n",
+                       irq, ioapic_conf.ioc_intsrc[irq], gsi);
+       }
+       ioapic_conf.ioc_intsrc[irq] = gsi;
+}
index c2136b5..5a4d3b2 100644 (file)
@@ -171,6 +171,7 @@ void        lapic_enumerator_register(struct lapic_enumerator *);
 void   ioapic_config(void);
 void   ioapic_enumerator_register(struct ioapic_enumerator *);
 void   ioapic_add(void *, int, int);
+void   ioapic_intsrc(int, int);
 
 #if defined(READY)
 void   clr_io_apic_mask24      (int, u_int32_t);
index 3f469de..e41ef75 100644 (file)
@@ -3565,6 +3565,7 @@ static int
 mptable_ioapic_int_callback(void *xarg, const void *pos, int type)
 {
        struct mptable_ioapic_int_cbarg *arg = xarg;
+       const struct mptable_ioapic *ioapic;
        const struct mptable_bus *bus;
        const struct INTENTRY *ent;
 
@@ -3585,11 +3586,40 @@ mptable_ioapic_int_callback(void *xarg, const void *pos, int type)
        if (bus == NULL)
                return 0;
 
-       /* XXX rough estimation */
-       if (ent->src_bus_irq != ent->dst_apic_int) {
-               if (bootverbose) {
-                       kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
-                               ent->src_bus_irq, ent->dst_apic_int);
+       TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
+               if (ioapic->mio_apic_id == ent->dst_apic_id)
+                       break;
+       }
+       if (ioapic == NULL) {
+               kprintf("MPTABLE: warning ISA int dst apic id %d "
+                       "does not exist\n", ent->dst_apic_id);
+               return 0;
+       }
+
+       if (!ioapic_use_old) {
+               int gsi;
+
+               if (ent->dst_apic_int >= ioapic->mio_npin) {
+                       panic("mptable_ioapic_enumerate: invalid I/O APIC "
+                             "pin %d, should be < %d",
+                             ent->dst_apic_int, ioapic->mio_npin);
+               }
+               gsi = ioapic->mio_gsi_base + ent->dst_apic_int;
+
+               if (ent->src_bus_irq != gsi) {
+                       if (bootverbose) {
+                               kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
+                                       ent->src_bus_irq, gsi);
+                       }
+                       ioapic_intsrc(ent->src_bus_irq, gsi);
+               }
+       } else {
+               /* XXX rough estimation */
+               if (ent->src_bus_irq != ent->dst_apic_int) {
+                       if (bootverbose) {
+                               kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
+                                       ent->src_bus_irq, ent->dst_apic_int);
+                       }
                }
        }
        return 0;
@@ -3645,7 +3675,7 @@ mptable_ioapic_enumerate(struct ioapic_enumerator *e)
        if (mptable_use_default) {
                if (bootverbose)
                        kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (default)\n");
-               /* TODO default intsrc */
+               ioapic_intsrc(0, 2);
                return;
        }
 
@@ -3661,7 +3691,7 @@ mptable_ioapic_enumerate(struct ioapic_enumerator *e)
        if (TAILQ_EMPTY(&bus_info.mbi_list)) {
                if (bootverbose)
                        kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (no bus)\n");
-               /* TODO default intsrc */
+               ioapic_intsrc(0, 2);
        } else {
                struct mptable_ioapic_int_cbarg arg;
 
@@ -3678,7 +3708,7 @@ mptable_ioapic_enumerate(struct ioapic_enumerator *e)
                                kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 "
                                        "(no int)\n");
                        }
-                       /* TODO default intsrc */
+                       ioapic_intsrc(0, 2);
                }
        }
 
index 2c8b8aa..c784a45 100644 (file)
@@ -839,11 +839,13 @@ madt_ioapic_enum_callback(void *xarg, const struct acpi_madt_ent *ent)
                const struct acpi_madt_intsrc *intsrc_ent;
 
                intsrc_ent = (const struct acpi_madt_intsrc *)ent;
-               if (intsrc_ent->mint_src == intsrc_ent->mint_gsi)
+               if (intsrc_ent->mint_src == intsrc_ent->mint_gsi ||
+                   intsrc_ent->mint_bus != MADT_INT_BUS_ISA)
                        return 0;
 
                MADT_VPRINTF("INTSRC irq %d -> gsi %u\n",
                             intsrc_ent->mint_src, intsrc_ent->mint_gsi);
+               ioapic_intsrc(intsrc_ent->mint_src, intsrc_ent->mint_gsi);
        } else if (ent->me_type == MADT_ENT_IOAPIC) {
                const struct acpi_madt_ioapic *ioapic_ent;