mptable: Get pin count of I/O APIC and calculate GSI base accordingly
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 17 Mar 2011 05:37:43 +0000 (13:37 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 17 Mar 2011 08:14:17 +0000 (16:14 +0800)
sys/platform/pc32/apic/mpapic.c
sys/platform/pc32/i386/mp_machdep.c
sys/platform/pc64/apic/mpapic.c
sys/platform/pc64/x86_64/mp_machdep.c

index 57fce94..83906b4 100644 (file)
@@ -1069,6 +1069,9 @@ ioapic_config(void)
        }
 
        e->ioapic_enumerate(e);
+
+       if (!ioapic_use_old)
+               panic("ioapic_config: new ioapic not working yet\n");
 }
 
 void
index 9059692..aa22933 100644 (file)
@@ -199,6 +199,8 @@ struct mptable_ioapic {
        int             mio_idx;
        int             mio_apic_id;
        uint32_t        mio_addr;
+       int             mio_gsi_base;
+       int             mio_npin;
        TAILQ_ENTRY(mptable_ioapic) mio_link;
 };
 
@@ -3602,7 +3604,7 @@ static void
 mptable_ioapic_enumerate(struct ioapic_enumerator *e)
 {
        struct mptable_bus_info bus_info;
-       const struct mptable_ioapic *ioapic;
+       struct mptable_ioapic *ioapic;
        struct mptable_pos mpt;
        mpcth_t cth;
        int error;
@@ -3611,13 +3613,37 @@ mptable_ioapic_enumerate(struct ioapic_enumerator *e)
        KKASSERT(!TAILQ_EMPTY(&mptable_ioapic_list));
 
        TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
+               if (!ioapic_use_old) {
+                       const struct mptable_ioapic *prev_ioapic;
+                       uint32_t ver;
+                       void *addr;
+
+                       addr = ioapic_map(ioapic->mio_addr);
+
+                       ver = ioapic_read(addr, IOAPIC_VER);
+                       ioapic->mio_npin = ((ver & IOART_VER_MAXREDIR)
+                                           >> MAXREDIRSHIFT) + 1;
+
+                       prev_ioapic = TAILQ_PREV(ioapic,
+                                       mptable_ioapic_list, mio_link);
+                       if (prev_ioapic == NULL) {
+                               ioapic->mio_gsi_base = 0;
+                       } else {
+                               ioapic->mio_gsi_base =
+                                       prev_ioapic->mio_gsi_base +
+                                       prev_ioapic->mio_npin;
+                       }
+                       /* TODO */
+               }
                if (bootverbose) {
                        kprintf("MPTABLE: IOAPIC addr 0x%08x, "
-                               "apic id %d, idx %d\n",
+                               "apic id %d, idx %d, gsi base %d, npin %d\n",
                                ioapic->mio_addr,
-                               ioapic->mio_apic_id, ioapic->mio_idx);
+                               ioapic->mio_apic_id,
+                               ioapic->mio_idx,
+                               ioapic->mio_gsi_base,
+                               ioapic->mio_npin);
                }
-               /* TODO */
        }
 
        if (mptable_use_default) {
index a32b987..7ea6720 100644 (file)
@@ -1132,6 +1132,9 @@ ioapic_config(void)
        }
 
        e->ioapic_enumerate(e);
+
+       if (!ioapic_use_old)
+               panic("ioapic_config: new ioapic not working yet\n");
 }
 
 void
index 0fe0b0a..05ed6c2 100644 (file)
@@ -198,6 +198,8 @@ struct mptable_ioapic {
        int             mio_idx;
        int             mio_apic_id;
        uint32_t        mio_addr;
+       int             mio_gsi_base;
+       int             mio_npin;
        TAILQ_ENTRY(mptable_ioapic) mio_link;
 };
 
@@ -3597,7 +3599,7 @@ static void
 mptable_ioapic_enumerate(struct ioapic_enumerator *e)
 {
        struct mptable_bus_info bus_info;
-       const struct mptable_ioapic *ioapic;
+       struct mptable_ioapic *ioapic;
        struct mptable_pos mpt;
        mpcth_t cth;
        int error;
@@ -3606,13 +3608,37 @@ mptable_ioapic_enumerate(struct ioapic_enumerator *e)
        KKASSERT(!TAILQ_EMPTY(&mptable_ioapic_list));
 
        TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
+               if (!ioapic_use_old) {
+                       const struct mptable_ioapic *prev_ioapic;
+                       uint32_t ver;
+                       void *addr;
+
+                       addr = ioapic_map(ioapic->mio_addr);
+
+                       ver = ioapic_read(addr, IOAPIC_VER);
+                       ioapic->mio_npin = ((ver & IOART_VER_MAXREDIR)
+                                           >> MAXREDIRSHIFT) + 1;
+
+                       prev_ioapic = TAILQ_PREV(ioapic,
+                                       mptable_ioapic_list, mio_link);
+                       if (prev_ioapic == NULL) {
+                               ioapic->mio_gsi_base = 0;
+                       } else {
+                               ioapic->mio_gsi_base =
+                                       prev_ioapic->mio_gsi_base +
+                                       prev_ioapic->mio_npin;
+                       }
+                       /* TODO */
+               }
                if (bootverbose) {
                        kprintf("MPTABLE: IOAPIC addr 0x%08x, "
-                               "apic id %d, idx %d\n",
+                               "apic id %d, idx %d, gsi base %d, npin %d\n",
                                ioapic->mio_addr,
-                               ioapic->mio_apic_id, ioapic->mio_idx);
+                               ioapic->mio_apic_id,
+                               ioapic->mio_idx,
+                               ioapic->mio_gsi_base,
+                               ioapic->mio_npin);
                }
-               /* TODO */
        }
 
        if (mptable_use_default) {