X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fsmp.c;h=8c077a1bab49e2a80b810ab1eb673a5291df5e23;hb=b93739776593eb470bd18ce8f8b028054cee0e3d;hp=a912857eab6e57f17ef2df5e0a673574786dfcbc;hpb=10ad799ff49508127e75f57c3927603441232ae3;p=seabios.git diff --git a/src/smp.c b/src/smp.c index a912857..8c077a1 100644 --- a/src/smp.c +++ b/src/smp.c @@ -8,23 +8,26 @@ #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 -struct { u32 ecx, eax, edx; } smp_mtrr[16] VAR16VISIBLE; +struct { u32 ecx, eax, edx; } smp_mtrr[32] VAR16VISIBLE; u32 smp_mtrr_count VAR16VISIBLE; void wrmsr_smp(u32 index, u64 val) { wrmsr(index, val); - if (smp_mtrr_count >= ARRAY_SIZE(smp_mtrr)) + if (smp_mtrr_count >= ARRAY_SIZE(smp_mtrr)) { + warn_noalloc(); return; + } smp_mtrr[smp_mtrr_count].ecx = index; smp_mtrr[smp_mtrr_count].eax = val; smp_mtrr[smp_mtrr_count].edx = val >> 32; @@ -33,7 +36,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 +71,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,17 +96,28 @@ 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); // Wait for other CPUs to process the SIPI. - if (CONFIG_COREBOOT) + if (CONFIG_COREBOOT) { msleep(10); - else - while (inb_cmos(CMOS_BIOS_SMP_COUNT) + 1 != readl(&CountCPUs)) - ; + } else { + u8 cmos_smp_count = inb_cmos(CMOS_BIOS_SMP_COUNT); + while (cmos_smp_count + 1 != readl(&CountCPUs)) + yield(); + } // Restore memory. *(u64*)BUILD_AP_BOOT_ADDR = old; @@ -113,11 +129,3 @@ smp_probe(void) dprintf(1, "Found %d cpu(s) max supported %d cpu(s)\n", readl(&CountCPUs), MaxCountCPUs); } - -// Reset variables to zero -void -smp_probe_setup(void) -{ - CountCPUs = 0; - smp_mtrr_count = 0; -}