Rudolf Marek ([email protected]) just uploaded a new patch set to gerrit, 
which you can find at http://review.coreboot.org/683

-gerrit

commit 904a8089cf7017480da09c0c1b1754af404e08e3
Author: Rudolf Marek <[email protected]>
Date:   Sat Feb 25 23:51:12 2012 +0100

    Avoid using CPUID in SMBIOS tables. Check for CPUID otherwise claim 486 
class cpu.
    
    Change-Id: Ic7c4452a1b55bae0cefee118003540ec39ef9fd4
    Signed-off-by: Rudolf Marek <[email protected]>
---
 src/arch/x86/boot/smbios.c      |   49 ++++++++++++++++++++++++--------------
 src/arch/x86/include/arch/cpu.h |   29 +++++++++++++++++++++++
 src/arch/x86/lib/cpu.c          |   29 -----------------------
 3 files changed, 60 insertions(+), 47 deletions(-)

diff --git a/src/arch/x86/boot/smbios.c b/src/arch/x86/boot/smbios.c
index e5156d9..7e2729c 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 (have_cpuid_p()) {
+               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 (have_cpuid_p()) {
+               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 (have_cpuid_p()) {
+               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 85357d7..4f395ce 100644
--- a/src/arch/x86/include/arch/cpu.h
+++ b/src/arch/x86/include/arch/cpu.h
@@ -29,6 +29,35 @@ struct cpuid_result {
        uint32_t edx;
 };
 
+/* Standard macro to see if a specific flag is changeable */
+static inline int flag_is_changeable_p(uint32_t flag)
+{
+       uint32_t f1, f2;
+
+       asm(
+               "pushfl\n\t"
+               "pushfl\n\t"
+               "popl %0\n\t"
+               "movl %0,%1\n\t"
+               "xorl %2,%0\n\t"
+               "pushl %0\n\t"
+               "popfl\n\t"
+               "pushfl\n\t"
+               "popl %0\n\t"
+               "popfl\n\t"
+               : "=&r" (f1), "=&r" (f2)
+               : "ir" (flag));
+       return ((f1^f2) & flag) != 0;
+}
+
+
+/* Probe for the CPUID instruction */
+static int have_cpuid_p(void)
+{
+       return flag_is_changeable_p(X86_EFLAGS_ID);
+}
+
+
 /*
  * Generic CPUID function
  */
diff --git a/src/arch/x86/lib/cpu.c b/src/arch/x86/lib/cpu.c
index ada57e2..60296be 100644
--- a/src/arch/x86/lib/cpu.c
+++ b/src/arch/x86/lib/cpu.c
@@ -9,35 +9,6 @@
 #include <device/path.h>
 #include <device/device.h>
 #include <smp/spinlock.h>
-
-/* Standard macro to see if a specific flag is changeable */
-static inline int flag_is_changeable_p(uint32_t flag)
-{
-       uint32_t f1, f2;
-
-       asm(
-               "pushfl\n\t"
-               "pushfl\n\t"
-               "popl %0\n\t"
-               "movl %0,%1\n\t"
-               "xorl %2,%0\n\t"
-               "pushl %0\n\t"
-               "popfl\n\t"
-               "pushfl\n\t"
-               "popl %0\n\t"
-               "popfl\n\t"
-               : "=&r" (f1), "=&r" (f2)
-               : "ir" (flag));
-       return ((f1^f2) & flag) != 0;
-}
-
-
-/* Probe for the CPUID instruction */
-static int have_cpuid_p(void)
-{
-       return flag_is_changeable_p(X86_EFLAGS_ID);
-}
-
 /*
  * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected
  * by the fact that they preserve the flags across the division of 5/2.

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to