Don't turn off apic after smp detect; use cmos for smp count on emulators.
Don't restor the APIC_SVR value - doing so confuses kvm.
When running on an emulator, get the smp count from cmos (timing on an
emulator - especially when simulating large cpu counts - is too
unreliable to do a count based on timers.)
diff --git a/src/cmos.h b/src/cmos.h
index f663163..5c7b39d 100644
--- a/src/cmos.h
+++ b/src/cmos.h
@@ -39,6 +39,7 @@
#define CMOS_MEM_HIGHMEM_LOW 0x5b
#define CMOS_MEM_HIGHMEM_MID 0x5c
#define CMOS_MEM_HIGHMEM_HIGH 0x5d
+#define CMOS_BIOS_SMP_COUNT 0x5f
// CMOS_FLOPPY_DRIVE_TYPE bitdefs
#define CFD_NO_DRIVE 0
diff --git a/src/smpdetect.c b/src/smpdetect.c
index 7f0c7aa..0274026 100644
--- a/src/smpdetect.c
+++ b/src/smpdetect.c
@@ -7,6 +7,7 @@
#include "util.h" // dprintf
#include "config.h" // CONFIG_*
+#include "cmos.h" // CMOS_BIOS_SMP_COUNT
#define CPUID_APIC (1 << 9)
@@ -96,10 +97,13 @@
writel(APIC_ICR_LOW, 0x000C4600 | sipi_vector);
// Wait for other CPUs to process the SIPI.
- mdelay(10);
+ if (CONFIG_COREBOOT)
+ mdelay(10);
+ else
+ while (inb_cmos(CMOS_BIOS_SMP_COUNT) + 1 != readl(&smp_cpus))
+ ;
// Restore memory.
- writel(APIC_SVR, val);
*(u64*)BUILD_AP_BOOT_ADDR = old;
u32 count = readl(&smp_cpus);