aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2009-06-21 09:10:28 -0400
committerKevin O'Connor <kevin@koconnor.net>2009-06-21 09:10:28 -0400
commite97ca7bd12d1ad394620d606747e423ee7cfd9ce (patch)
treee9b3860d787c259cd19bba01770ce4b17a493966
parent09880dada98c075b98e68b08cb3ce8ffbf605faf (diff)
downloadseabios-e97ca7bd12d1ad394620d606747e423ee7cfd9ce.tar.gz
Forward port bochs smp changes; rename smpdetect.c to smp.c.
Rename smpdetect.c to smp.c - the code does more than just cpu detection. Don't probe cpu count on demand - schedule it during post. Add logic to run wrmsr on all cpus. Don't make mtrr setup specific to kvm - do it on all machines that have mtrr and msrs. Detect cpu signature/features automatically in mptable. Also, make sure acpi structures are packed.
-rw-r--r--Makefile2
-rw-r--r--src/acpi.c18
-rw-r--r--src/mptable.c13
-rw-r--r--src/mptable.h2
-rw-r--r--src/mtrr.c28
-rw-r--r--src/post.c2
-rw-r--r--src/smbios.c2
-rw-r--r--src/smp.c (renamed from src/smpdetect.c)65
-rw-r--r--src/util.h21
9 files changed, 97 insertions, 56 deletions
diff --git a/Makefile b/Makefile
index 356e72cf..71e3cb48 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ OUT=out/
# Source files
SRCBOTH=output.c util.c floppy.c ata.c misc.c mouse.c kbd.c pci.c \
- serial.c clock.c pic.c cdrom.c ps2port.c smpdetect.c resume.c \
+ serial.c clock.c pic.c cdrom.c ps2port.c smp.c resume.c \
pnpbios.c pirtable.c
SRC16=$(SRCBOTH) system.c disk.c apm.c pcibios.c vgahooks.c font.c
SRC32=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
diff --git a/src/acpi.c b/src/acpi.c
index 6a509718..f140f1ac 100644
--- a/src/acpi.c
+++ b/src/acpi.c
@@ -35,7 +35,7 @@
struct acpi_table_header /* ACPI common table header */
{
ACPI_TABLE_HEADER_DEF
-};
+} PACKED;
/*
* ACPI 1.0 Root System Description Table (RSDT)
@@ -46,7 +46,7 @@ struct rsdt_descriptor_rev1
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
u32 table_offset_entry [3]; /* Array of pointers to other */
/* ACPI tables */
-};
+} PACKED;
/*
* ACPI 1.0 Firmware ACPI Control Structure (FACS)
@@ -62,7 +62,7 @@ struct facs_descriptor_rev1
u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */
u32 reserved1 : 31; /* Must be 0 */
u8 resverved3 [40]; /* Reserved - must be zero */
-};
+} PACKED;
/*
@@ -124,7 +124,7 @@ struct fadt_descriptor_rev1
#else
u32 flags;
#endif
-};
+} PACKED;
/*
* MADT values and structures
@@ -149,7 +149,7 @@ struct multiple_apic_table
#else
u32 flags;
#endif
-};
+} PACKED;
/* Values for Type in APIC_HEADER_DEF */
@@ -185,7 +185,7 @@ struct madt_processor_apic
#else
u32 flags;
#endif
-};
+} PACKED;
struct madt_io_apic
{
@@ -195,7 +195,7 @@ struct madt_io_apic
u32 address; /* APIC physical address */
u32 interrupt; /* Global system interrupt where INTI
* lines start */
-};
+} PACKED;
#if CONFIG_KVM
/* IRQs 5,9,10,11 */
@@ -245,7 +245,7 @@ acpi_build_processor_ssdt(u8 *ssdt)
{
u8 *ssdt_ptr = ssdt;
int i, length;
- int smp_cpus = smp_probe();
+ int smp_cpus = CountCPUs;
int acpi_cpus = smp_cpus > 0xff ? 0xff : smp_cpus;
ssdt_ptr[9] = 0; // checksum;
@@ -348,7 +348,7 @@ void acpi_bios_init(void)
ssdt = (void *)(addr);
addr += acpi_build_processor_ssdt(ssdt);
- int smp_cpus = smp_probe();
+ int smp_cpus = CountCPUs;
addr = ALIGN(addr, 8);
madt_addr = addr;
madt_size = sizeof(*madt) +
diff --git a/src/mptable.c b/src/mptable.c
index 9e030fe8..47aee24b 100644
--- a/src/mptable.c
+++ b/src/mptable.c
@@ -18,7 +18,7 @@ mptable_init(void)
dprintf(3, "init MPTable\n");
- int smp_cpus = smp_probe();
+ int smp_cpus = CountCPUs;
if (smp_cpus <= 1)
// Building an mptable on uniprocessor machines confuses some OSes.
return;
@@ -57,6 +57,8 @@ mptable_init(void)
config->lapic = BUILD_APIC_ADDR;
// CPU definitions.
+ u32 cpuid_signature, ebx, ecx, cpuid_features;
+ cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features);
struct mpt_cpu *cpus = (void*)&config[1];
int i;
for (i = 0; i < smp_cpus; i++) {
@@ -67,8 +69,13 @@ mptable_init(void)
cpu->apicver = 0x11;
/* cpu flags: enabled, bootstrap cpu */
cpu->cpuflag = (i == 0 ? 3 : 1);
- cpu->cpufeature = 0x600;
- cpu->featureflag = 0x201;
+ if (cpuid_signature) {
+ cpu->cpusignature = cpuid_signature;
+ cpu->featureflag = cpuid_features;
+ } else {
+ cpu->cpusignature = 0x600;
+ cpu->featureflag = 0x201;
+ }
}
/* isa bus */
diff --git a/src/mptable.h b/src/mptable.h
index d8fecb31..4c4d52fb 100644
--- a/src/mptable.h
+++ b/src/mptable.h
@@ -44,7 +44,7 @@ struct mpt_cpu {
u8 apicid;
u8 apicver;
u8 cpuflag;
- u32 cpufeature;
+ u32 cpusignature;
u32 featureflag;
u32 reserved[2];
} PACKED;
diff --git a/src/mtrr.c b/src/mtrr.c
index 12837e00..a9cd5f78 100644
--- a/src/mtrr.c
+++ b/src/mtrr.c
@@ -24,28 +24,18 @@
#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
-static u64 rdmsr(u32 index)
-{
- u64 ret;
- asm ("rdmsr" : "=A"(ret) : "c"(index));
- return ret;
-}
-
-static void wrmsr(u32 index, u64 val)
-{
- asm volatile ("wrmsr" : : "c"(index), "A"(val));
-}
-
-static void wrmsr_smp(u32 index, u64 val)
-{
- // XXX - should run this on other CPUs also.
- wrmsr(index, val);
-}
-
void mtrr_setup(void)
{
- if (! CONFIG_KVM)
+ if (CONFIG_COREBOOT)
+ return;
+
+ u32 eax, ebx, ecx, cpuid_features;
+ cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
+ if (!(cpuid_features & CPUID_MTRR))
+ return;
+ if (!(cpuid_features & CPUID_MSR))
return;
+
dprintf(3, "init mtrr\n");
int i, vcnt, fix, wc;
diff --git a/src/post.c b/src/post.c
index 3c68990b..638f95a8 100644
--- a/src/post.c
+++ b/src/post.c
@@ -163,10 +163,10 @@ post()
mathcp_setup();
smp_probe_setup();
-
memmap_setup();
ram_probe();
mtrr_setup();
+ smp_probe();
pnp_setup();
vga_setup();
diff --git a/src/smbios.c b/src/smbios.c
index e2f21901..40812e3b 100644
--- a/src/smbios.c
+++ b/src/smbios.c
@@ -559,7 +559,7 @@ smbios_init(void)
add_struct(smbios_type_0_init(p));
add_struct(smbios_type_1_init(p));
add_struct(smbios_type_3_init(p));
- int smp_cpus = smp_probe();
+ int smp_cpus = CountCPUs;
for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
add_struct(smbios_type_4_init(p, cpu_num));
add_struct(smbios_type_16_init(p));
diff --git a/src/smpdetect.c b/src/smp.c
index a25e0424..49e5631e 100644
--- a/src/smpdetect.c
+++ b/src/smp.c
@@ -10,8 +10,6 @@
#include "cmos.h" // CMOS_BIOS_SMP_COUNT
#include "farptr.h" // ASSERT32
-#define CPUID_APIC (1 << 9)
-
#define APIC_ICR_LOW ((u8*)BUILD_APIC_ADDR + 0x300)
#define APIC_SVR ((u8*)BUILD_APIC_ADDR + 0x0F0)
@@ -47,38 +45,68 @@ static inline u8 readb(const void *addr)
return *(volatile const u8 *)addr;
}
-u32 smp_cpus VAR16_32;
+struct { u32 ecx, eax, edx; } smp_mtrr[16] VAR16_32;
+u32 smp_mtrr_count VAR16_32;
+
+void
+wrmsr_smp(u32 index, u64 val)
+{
+ wrmsr(index, val);
+ if (smp_mtrr_count >= ARRAY_SIZE(smp_mtrr))
+ return;
+ smp_mtrr[smp_mtrr_count].ecx = index;
+ smp_mtrr[smp_mtrr_count].eax = val;
+ smp_mtrr[smp_mtrr_count].edx = val >> 32;
+ smp_mtrr_count++;
+}
+
+u32 CountCPUs VAR16_32;
extern void smp_ap_boot_code();
ASM16(
" .global smp_ap_boot_code\n"
"smp_ap_boot_code:\n"
- // Increment the cpu counter
+
+ // Setup data segment
" movw $" __stringify(SEG_BIOS) ", %ax\n"
" movw %ax, %ds\n"
- " lock incl smp_cpus\n"
+
+ // MTRR setup
+ " movl $smp_mtrr, %esi\n"
+ " movl smp_mtrr_count, %ebx\n"
+ "1:testl %ebx, %ebx\n"
+ " jz 2f\n"
+ " movl 0(%esi), %ecx\n"
+ " movl 4(%esi), %eax\n"
+ " movl 8(%esi), %edx\n"
+ " wrmsr\n"
+ " addl $12, %esi\n"
+ " decl %ebx\n"
+ " jmp 1b\n"
+ "2:\n"
+
+ // Increment the cpu counter
+ " lock incl CountCPUs\n"
+
// Halt the processor.
"1:hlt\n"
" jmp 1b\n"
);
-/* find the number of CPUs by launching a SIPI to them */
-int
+// find and initialize the CPUs by launching a SIPI to them
+void
smp_probe(void)
{
ASSERT32();
- if (smp_cpus)
- return smp_cpus;
-
u32 eax, ebx, ecx, cpuid_features;
cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
if (! (cpuid_features & CPUID_APIC)) {
// No apic - only the main cpu is present.
- smp_cpus = 1;
- return 1;
+ CountCPUs= 1;
+ return;
}
// Init the counter.
- writel(&smp_cpus, 1);
+ writel(&CountCPUs, 1);
// Setup jump trampoline to counter code.
u64 old = *(u64*)BUILD_AP_BOOT_ADDR;
@@ -100,20 +128,19 @@ smp_probe(void)
if (CONFIG_COREBOOT)
mdelay(10);
else
- while (inb_cmos(CMOS_BIOS_SMP_COUNT) + 1 != readl(&smp_cpus))
+ while (inb_cmos(CMOS_BIOS_SMP_COUNT) + 1 != readl(&CountCPUs))
;
// Restore memory.
*(u64*)BUILD_AP_BOOT_ADDR = old;
- u32 count = readl(&smp_cpus);
- dprintf(1, "Found %d cpu(s)\n", count);
- return count;
+ dprintf(1, "Found %d cpu(s)\n", readl(&CountCPUs));
}
-// Reset smp_cpus to zero (forces a recheck on reboots).
+// Reset variables to zero
void
smp_probe_setup(void)
{
- smp_cpus = 0;
+ CountCPUs = 0;
+ smp_mtrr_count = 0;
}
diff --git a/src/util.h b/src/util.h
index 2ba80ddf..6ae7f192 100644
--- a/src/util.h
+++ b/src/util.h
@@ -51,6 +51,9 @@ static inline void wbinvd(void)
asm volatile("wbinvd");
}
+#define CPUID_MSR (1 << 5)
+#define CPUID_APIC (1 << 9)
+#define CPUID_MTRR (1 << 12)
static inline void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
{
asm("cpuid"
@@ -58,6 +61,18 @@ static inline void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
: "0" (index));
}
+static inline u64 rdmsr(u32 index)
+{
+ u64 ret;
+ asm ("rdmsr" : "=A"(ret) : "c"(index));
+ return ret;
+}
+
+static inline void wrmsr(u32 index, u64 val)
+{
+ asm volatile ("wrmsr" : : "c"(index), "A"(val));
+}
+
static inline u64 rdtscll(void)
{
u64 val;
@@ -177,8 +192,10 @@ void pci_bios_setup(void);
// smm.c
void smm_init();
-// smpdetect.c
-int smp_probe(void);
+// smp.c
+extern u32 CountCPUs VAR16_32;
+void wrmsr_smp(u32 index, u64 val);
+void smp_probe(void);
void smp_probe_setup(void);
// smbios.c