Avoid using CPUID in SMBIOS tables. Check for CPUID otherwise claim 486 class cpu.
authorRudolf Marek <r.marek@assembler.cz>
Sat, 25 Feb 2012 22:51:12 +0000 (23:51 +0100)
committerPeter Stuge <peter@stuge.se>
Tue, 20 Mar 2012 14:13:09 +0000 (15:13 +0100)
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>
src/arch/x86/boot/smbios.c
src/arch/x86/include/arch/cpu.h
src/arch/x86/lib/cpu.c

index e5156d9de786f0773305def08d73175304b8e275..2bd00c49d4aa778a1979d6c7f8786bb716247815 100644 (file)
@@ -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;
index 85357d744e6b563cc7ad640645a956b4c32a5529..2dfcd72e95f0cc6cca27a7cb397ac4d280530ceb 100644 (file)
@@ -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;
index a7f7b322c003f8b0fff26d1a417b67d7da6348fb..fac523f902311ca5d6df12ead56b68b33863b578 100644 (file)
@@ -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);