Avoid using CPUID in SMBIOS tables. Check for CPUID otherwise claim 486 class cpu.
[coreboot.git] / src / arch / x86 / lib / cpu.c
index 3732ae296e96d7f0573b572d497b0640d27c496c..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);
 }
@@ -131,6 +130,26 @@ static const char *cpu_vendor_name(int vendor)
        return name;
 }
 
+static int cpu_cpuid_extended_level(void)
+{
+       return cpuid_eax(0x80000000);
+}
+
+#define CPUID_FEATURE_PAE (1 << 6)
+#define CPUID_FEATURE_PSE36 (1 << 17)
+
+int cpu_phys_address_size(void)
+{
+       if (!(cpu_have_cpuid()))
+               return 32;
+
+       if (cpu_cpuid_extended_level() >= 0x80000008)
+               return cpuid_eax(0x80000008) & 0xff;
+
+       if (cpuid_edx(1) & (CPUID_FEATURE_PAE | CPUID_FEATURE_PSE36))
+               return 36;
+       return 32;
+}
 static void identify_cpu(struct device *cpu)
 {
        char vendor_name[16];
@@ -139,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 */
@@ -155,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);
@@ -207,7 +226,7 @@ static void set_cpu_ops(struct device *cpu)
                }
        }
        return;
- found:
+found:
        cpu->ops = driver->ops;
 }