i386: Prepare mp_enable() for multi-stage procedure segmentation
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 4 Jun 2011 11:47:24 +0000 (19:47 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 4 Jun 2011 11:47:59 +0000 (19:47 +0800)
sys/platform/pc32/apic/lapic.c
sys/platform/pc32/apic/lapic.h
sys/platform/pc32/i386/machdep.c
sys/platform/pc32/i386/mp_machdep.c

index 7e63dd0..a0f3343 100644 (file)
@@ -90,6 +90,7 @@ static const uint32_t lapic_timer_divisors[] = {
  */
 int    cpu_id_to_apic_id[NAPICID];
 int    apic_id_to_cpu_id[NAPICID];
+int    lapic_enable = 1;
 
 /*
  * Enable LAPIC, configure interrupts.
@@ -641,18 +642,13 @@ int
 lapic_config(void)
 {
        struct lapic_enumerator *e;
-       int error, i, enable, ap_max;
+       int error, i, ap_max;
+
+       KKASSERT(lapic_enable);
 
        for (i = 0; i < NAPICID; ++i)
                APICID_TO_CPUID(i) = -1;
 
-       enable = 1;
-       TUNABLE_INT_FETCH("hw.lapic_enable", &enable);
-       if (!enable) {
-               kprintf("LAPIC: Warning LAPIC is disabled\n");
-               return ENXIO;
-       }
-
        TAILQ_FOREACH(e, &lapic_enumerators, lapic_link) {
                error = e->lapic_probe(e);
                if (!error)
index abe5ba0..759caa2 100644 (file)
@@ -56,6 +56,7 @@ struct lapic_enumerator {
 extern volatile lapic_t                *lapic;
 extern int                     cpu_id_to_apic_id[];
 extern int                     apic_id_to_cpu_id[];
+extern int                     lapic_enable;
 
 void   apic_dump(char*);
 void   lapic_init(boolean_t);
index e4c9596..f275249 100644 (file)
 #include <sys/machintr.h>
 #include <machine_base/icu/icu_abi.h>
 #include <machine_base/icu/elcr_var.h>
+#include <machine_base/apic/lapic.h>
 #include <machine_base/apic/ioapic.h>
 #include <machine_base/apic/ioapic_abi.h>
 
@@ -1946,6 +1947,7 @@ init386(int first)
 #ifdef SMP
        TUNABLE_INT_FETCH("hw.apic_io_enable", &ioapic_enable); /* for compat */
        TUNABLE_INT_FETCH("hw.ioapic_enable", &ioapic_enable);
+       TUNABLE_INT_FETCH("hw.lapic_enable", &lapic_enable);
 #endif
 
        /*
index 6bbf698..780205f 100644 (file)
@@ -310,23 +310,30 @@ mp_enable(u_int boot_addr)
 
        POSTCODE(MP_ENABLE_POST);
 
-       error = lapic_config();
-       if (error) {
-               if (ioapic_enable) {
-                       ioapic_enable = 0;
-                       icu_reinit_noioapic();
-               }
-               cpu_simple_setup();
-               return;
+       if (lapic_enable) {
+               error = lapic_config();
+               if (error)
+                       lapic_enable = 0;
        }
 
-       /* Initialize BSP's local APIC */
-       lapic_init(TRUE);
+       if (lapic_enable) {
+               /* Initialize BSP's local APIC */
+               lapic_init(TRUE);
+       } else if (ioapic_enable) {
+               ioapic_enable = 0;
+               icu_reinit_noioapic();
+       }
 
-       /* start each Application Processor */
-       start_all_aps(boot_addr);
+       if (lapic_enable) {
+               /* start each Application Processor */
+               start_all_aps(boot_addr);
+       } else {
+               cpu_simple_setup();
+       }
 
        if (ioapic_enable) {
+               KASSERT(lapic_enable,
+                   ("I/O APIC is enabled, but LAPIC is disabled\n"));
                error = ioapic_config();
                if (error) {
                        ioapic_enable = 0;