diff options
author | Rudolf Marek <r.marek@assembler.cz> | 2012-02-25 23:51:12 +0100 |
---|---|---|
committer | Peter Stuge <peter@stuge.se> | 2012-03-20 15:13:09 +0100 |
commit | 06253cd9a5742078386f355a06c0f13bebbcc5ce (patch) | |
tree | 07228b3b106b9edcbe7083d4fbaef8530c05ccdc /src/arch/x86 | |
parent | 06c04299c1420fa94a1a53cc36c9d91a5e31a22a (diff) | |
download | coreboot-06253cd9a5742078386f355a06c0f13bebbcc5ce.tar.xz |
Avoid using CPUID in SMBIOS tables. Check for CPUID otherwise claim 486 class cpu.
Change-Id: Ic7c4452a1b55bae0cefee118003540ec39ef9fd4
Signed-off-by: Rudolf Marek <r.marek@assembler.cz>
Reviewed-on: http://review.coreboot.org/683
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-by: Peter Stuge <peter@stuge.se>
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/boot/smbios.c | 49 | ||||
-rw-r--r-- | src/arch/x86/include/arch/cpu.h | 1 | ||||
-rw-r--r-- | src/arch/x86/lib/cpu.c | 9 |
3 files changed, 36 insertions, 23 deletions
diff --git a/src/arch/x86/boot/smbios.c b/src/arch/x86/boot/smbios.c index e5156d9de7..2bd00c49d4 100644 --- a/src/arch/x86/boot/smbios.c +++ b/src/arch/x86/boot/smbios.c @@ -76,34 +76,41 @@ int smbios_string_table_len(char *start) static int smbios_cpu_vendor(char *start) { - char tmp[13]; + char tmp[13] = "Unknown"; u32 *_tmp = (u32 *)tmp; - struct cpuid_result res = cpuid(0); + struct cpuid_result res; - _tmp[0] = res.ebx; - _tmp[1] = res.edx; - _tmp[2] = res.ecx; - tmp[12] = '\0'; - return smbios_add_string(start, tmp); + if (cpu_have_cpuid()) { + res = cpuid(0); + _tmp[0] = res.ebx; + _tmp[1] = res.edx; + _tmp[2] = res.ecx; + tmp[12] = '\0'; + } + return smbios_add_string(start, tmp); } static int smbios_processor_name(char *start) { - char tmp[49]; + char tmp[49] = "Unknown Processor Name"; u32 *_tmp = (u32 *)tmp; struct cpuid_result res; int i; - for (i = 0; i < 3; i++) { - res = cpuid(0x80000002 + i); - _tmp[i * 4 + 0] = res.eax; - _tmp[i * 4 + 1] = res.ebx; - _tmp[i * 4 + 2] = res.ecx; - _tmp[i * 4 + 3] = res.edx; + if (cpu_have_cpuid()) { + res = cpuid(0x80000000); + if (res.eax >= 0x80000004) { + for (i = 0; i < 3; i++) { + res = cpuid(0x80000002 + i); + _tmp[i * 4 + 0] = res.eax; + _tmp[i * 4 + 1] = res.ebx; + _tmp[i * 4 + 2] = res.ecx; + _tmp[i * 4 + 3] = res.edx; + } + tmp[48] = 0; + } } - - tmp[48] = 0; return smbios_add_string(start, tmp); } @@ -184,7 +191,13 @@ static int smbios_write_type4(unsigned long *current, int handle) struct smbios_type4 *t = (struct smbios_type4 *)*current; int len = sizeof(struct smbios_type4); - res = cpuid(1); + /* Provide sane defaults even for CPU without CPUID */ + res.eax = res.edx = 0; + res.ebx = 0x10000; + + if (cpu_have_cpuid()) { + res = cpuid(1); + } memset(t, 0, sizeof(struct smbios_type4)); t->type = SMBIOS_PROCESSOR_INFORMATION; @@ -194,7 +207,7 @@ static int smbios_write_type4(unsigned long *current, int handle) t->processor_id[1] = res.edx; t->processor_manufacturer = smbios_cpu_vendor(t->eos); t->processor_version = smbios_processor_name(t->eos); - t->processor_family = 0x0c; + t->processor_family = (res.eax > 0) ? 0x0c : 0x6; t->processor_type = 3; /* System Processor */ t->processor_upgrade = 0x06; t->core_count = (res.ebx >> 16) & 0xff; diff --git a/src/arch/x86/include/arch/cpu.h b/src/arch/x86/include/arch/cpu.h index 85357d744e..2dfcd72e95 100644 --- a/src/arch/x86/include/arch/cpu.h +++ b/src/arch/x86/include/arch/cpu.h @@ -109,6 +109,7 @@ static inline unsigned int cpuid_edx(unsigned int op) #include <device/device.h> int cpu_phys_address_size(void); +int cpu_have_cpuid(void); struct cpu_device_id { unsigned vendor; diff --git a/src/arch/x86/lib/cpu.c b/src/arch/x86/lib/cpu.c index a7f7b322c0..fac523f902 100644 --- a/src/arch/x86/lib/cpu.c +++ b/src/arch/x86/lib/cpu.c @@ -31,9 +31,8 @@ static inline int flag_is_changeable_p(uint32_t flag) return ((f1^f2) & flag) != 0; } - /* Probe for the CPUID instruction */ -static int have_cpuid_p(void) +int cpu_have_cpuid(void) { return flag_is_changeable_p(X86_EFLAGS_ID); } @@ -141,7 +140,7 @@ static int cpu_cpuid_extended_level(void) int cpu_phys_address_size(void) { - if (!(have_cpuid_p())) + if (!(cpu_have_cpuid())) return 32; if (cpu_cpuid_extended_level() >= 0x80000008) @@ -159,7 +158,7 @@ static void identify_cpu(struct device *cpu) vendor_name[0] = '\0'; /* Unset */ /* Find the id and vendor_name */ - if (!have_cpuid_p()) { + if (!cpu_have_cpuid()) { /* Its a 486 if we can modify the AC flag */ if (flag_is_changeable_p(X86_EFLAGS_AC)) { cpu->device = 0x00000400; /* 486 */ @@ -175,7 +174,7 @@ static void identify_cpu(struct device *cpu) memcpy(vendor_name, "NexGenDriven", 13); } } - if (have_cpuid_p()) { + if (cpu_have_cpuid()) { int cpuid_level; struct cpuid_result result; result = cpuid(0x00000000); |