X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fsmp.c;h=8c077a1bab49e2a80b810ab1eb673a5291df5e23;hb=db301ef20c03657631790393ac36ec191dbf24e2;hp=687947293b38e953901dfe4bdf7da269c4292571;hpb=847058533fb1f1221e6741593d1543b37177c97a;p=seabios.git diff --git a/src/smp.c b/src/smp.c index 6879472..8c077a1 100644 --- a/src/smp.c +++ b/src/smp.c @@ -8,53 +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 -static inline void writel(void *addr, u32 val) -{ - *(volatile u32 *)addr = val; -} - -static inline void writew(void *addr, u16 val) -{ - *(volatile u16 *)addr = val; -} - -static inline void writeb(void *addr, u8 val) -{ - *(volatile u8 *)addr = val; -} - -static inline u32 readl(const void *addr) -{ - return *(volatile const u32 *)addr; -} - -static inline u16 readw(const void *addr) -{ - return *(volatile const u16 *)addr; -} - -static inline u8 readb(const void *addr) -{ - return *(volatile const u8 *)addr; -} - -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; @@ -63,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" @@ -98,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; } @@ -121,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) - mdelay(10); - else - while (inb_cmos(CMOS_BIOS_SMP_COUNT) + 1 != readl(&CountCPUs)) - ; + if (CONFIG_COREBOOT) { + msleep(10); + } 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; @@ -143,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; -}