Fallback to ACPI MADT CPU enumeration, if BIOS does not provide MP table.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 13 Jun 2009 12:17:43 +0000 (20:17 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 13 Jun 2009 12:21:58 +0000 (20:21 +0800)
APIC_IO does not work with ACPI MADT CPU enumeration yet.

sys/platform/pc32/i386/mp_machdep.c
sys/platform/pc32/i386/mp_madt.c

index 106ae9f..86c7b57 100644 (file)
@@ -220,6 +220,9 @@ static int need_hyperthreading_fixup;
 static u_int logical_cpus;
 u_int  logical_cpus_mask;
 
+static int madt_probe_test;
+TUNABLE_INT("hw.madt_probe_test", &madt_probe_test);
+
 /** XXX FIXME: where does this really belong, isa.h/isa.c perhaps? */
 int    current_postcode;
 
@@ -502,40 +505,54 @@ mp_enable(u_int boot_addr)
 
        POSTCODE(MP_ENABLE_POST);
 
-#if 0
-       madt_probe();
-#endif
+       if (madt_probe_test)
+               mpfps_paddr = 0;
+       else
+               mpfps_paddr = mptable_probe();
 
-       mpfps_paddr = mptable_probe();
-       if (mpfps_paddr == 0)
-               panic("mp_enable: mptable_probe failed\n");
+       if (mpfps_paddr) {
+               mptable_map(&mpt, mpfps_paddr);
 
-       mptable_map(&mpt, mpfps_paddr);
+               /*
+                * We can safely map physical memory into SMPpt after
+                * mptable_pass1() completes.
+                */
+               mptable_pass1(&mpt);
 
-       /*
-        * We can safely map physical memory into SMPpt after
-        * mptable_pass1() completes.
-        */
-       mptable_pass1(&mpt);
+               if (cpu_apic_address == 0)
+                       panic("mp_enable: no local apic (mptable)!\n");
 
-       if (cpu_apic_address == 0)
-               panic("mp_enable: no local apic!\n");
+               /*
+                * Examine the MP table for needed info
+                */
+               x = mptable_pass2(&mpt);
 
-       /* examine the MP table for needed info, uses physical addresses */
-       x = mptable_pass2(&mpt);
+               mptable_unmap(&mpt);
 
-       mptable_unmap(&mpt);
+               /* Local apic is mapped on last page */
+               SMPpt[NPTEPG - 1] = (pt_entry_t)(PG_V | PG_RW | PG_N |
+                   pmap_get_pgeflag() | (cpu_apic_address & PG_FRAME));
 
-       /* local apic is mapped on last page */
-       SMPpt[NPTEPG - 1] = (pt_entry_t)(PG_V | PG_RW | PG_N |
-           pmap_get_pgeflag() | (cpu_apic_address & PG_FRAME));
+               /*
+                * Can't process default configs till the
+                * CPU APIC is pmapped
+                */
+               if (x)
+                       mptable_default(x);
 
-       /* can't process default configs till the CPU APIC is pmapped */
-       if (x)
-               mptable_default(x);
+               /* Post scan cleanup */
+               mptable_fix();
+       } else {
+               if (madt_probe())
+                       panic("mp_enable: madt_probe failed\n");
+
+               if (cpu_apic_address == 0)
+                       panic("mp_enable: no local apic (madt)!\n");
 
-       /* post scan cleanup */
-       mptable_fix();
+               /* Local apic is mapped on last page */
+               SMPpt[NPTEPG - 1] = (pt_entry_t)(PG_V | PG_RW | PG_N |
+                   pmap_get_pgeflag() | (cpu_apic_address & PG_FRAME));
+       }
 
 #if defined(APIC_IO)
 
index c164872..70fe17d 100644 (file)
@@ -342,7 +342,7 @@ static int
 madt_parse(vm_paddr_t madt_paddr)
 {
        struct acpi_madt *madt;
-       int size, cur, error;
+       int size, cur, error, cpu_count;
 
        KKASSERT(madt_paddr != 0);
 
@@ -366,11 +366,13 @@ madt_parse(vm_paddr_t madt_paddr)
 
        kprintf("madt: LAPIC address 0x%08x, flags %#x\n",
                madt->madt_lapic_addr, madt->madt_flags);
+       cpu_apic_address = madt->madt_lapic_addr;
 
        size = madt->madt_hdr.sdth_len -
               (sizeof(*madt) - sizeof(madt->madt_ents));
        cur = 0;
        error = 0;
+       cpu_count = 0;
 
        while (size - cur > sizeof(struct acpi_madt_ent)) {
                const struct acpi_madt_ent *ent;
@@ -405,9 +407,16 @@ madt_parse(vm_paddr_t madt_paddr)
                                kprintf("madt: cpu_id %d, apic_id %d\n",
                                        lapic_ent->ml_cpu_id,
                                        lapic_ent->ml_apic_id);
+                               mp_set_cpuids(lapic_ent->ml_cpu_id,
+                                             lapic_ent->ml_apic_id);
+                               ++cpu_count;
                        }
                }
        }
+       if (cpu_count == 0)
+               error = EINVAL;
+       if (!error)
+               mp_naps = cpu_count - 1;
 back:
        madt_sdth_unmap(&madt->madt_hdr);
        return error;