Separate out init code from the rest of the 32bit flat code.
[seabios.git] / src / smp.c
index 71b0da8ce39994759877ebdb2f206957f0f73538..38e117ebb74b389e61b8c42377a0c67d8f4e5bce 100644 (file)
--- a/src/smp.c
+++ b/src/smp.c
@@ -8,11 +8,12 @@
 #include "util.h" // dprintf
 #include "config.h" // CONFIG_*
 #include "cmos.h" // CMOS_BIOS_SMP_COUNT
-#include "farptr.h" // ASSERT32
 #include "paravirt.h"
 
 #define APIC_ICR_LOW ((u8*)BUILD_APIC_ADDR + 0x300)
 #define APIC_SVR     ((u8*)BUILD_APIC_ADDR + 0x0F0)
+#define APIC_LINT0   ((u8*)BUILD_APIC_ADDR + 0x350)
+#define APIC_LINT1   ((u8*)BUILD_APIC_ADDR + 0x360)
 
 #define APIC_ENABLED 0x0100
 
@@ -33,7 +34,7 @@ wrmsr_smp(u32 index, u64 val)
 
 u32 CountCPUs VAR16VISIBLE;
 u32 MaxCountCPUs VAR16VISIBLE;
-extern void smp_ap_boot_code();
+extern void smp_ap_boot_code(void);
 ASM16(
     "  .global smp_ap_boot_code\n"
     "smp_ap_boot_code:\n"
@@ -68,12 +69,14 @@ ASM16(
 void
 smp_probe(void)
 {
-    ASSERT32();
+    ASSERT32FLAT();
     u32 eax, ebx, ecx, cpuid_features;
     cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
-    if ((cpuid_features & CPUID_APIC)) {
+    if (eax < 1 || !(cpuid_features & CPUID_APIC)) {
         // No apic - only the main cpu is present.
+        dprintf(1, "No apic - only the main cpu is present.\n");
         CountCPUs= 1;
+        MaxCountCPUs = 1;
         return;
     }
 
@@ -91,7 +94,16 @@ smp_probe(void)
     u32 val = readl(APIC_SVR);
     writel(APIC_SVR, val | APIC_ENABLED);
 
+    if (! CONFIG_COREBOOT) {
+        /* Set LINT0 as Ext_INT, level triggered */
+        writel(APIC_LINT0, 0x8700);
+
+        /* Set LINT1 as NMI, level triggered */
+        writel(APIC_LINT1, 0x8400);
+    }
+
     // broadcast SIPI
+    barrier();
     writel(APIC_ICR_LOW, 0x000C4500);
     u32 sipi_vector = BUILD_AP_BOOT_ADDR >> 12;
     writel(APIC_ICR_LOW, 0x000C4600 | sipi_vector);
@@ -102,7 +114,7 @@ smp_probe(void)
     } else {
         u8 cmos_smp_count = inb_cmos(CMOS_BIOS_SMP_COUNT);
         while (cmos_smp_count + 1 != readl(&CountCPUs))
-             ;
+            yield();
     }
 
     // Restore memory.