[coreboot] Patch set updated for coreboot: ad487c1 Avoid using CPUID in SMBIOS tables. Check for CPUID otherwise claim 486 class cpu.

Rudolf Marek (r.marek@assembler.cz) gerrit at coreboot.org
Tue Mar 20 14:36:14 CET 2012


Rudolf Marek (r.marek at assembler.cz) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/683

-gerrit

commit ad487c1984683a4626490d65642b8fcd9ba2a081
Author: Rudolf Marek <r.marek at assembler.cz>
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 <r.marek at assembler.cz>
---
 src/arch/x86/boot/smbios.c      |   49 ++++++++++++++++++++++++--------------
 src/arch/x86/include/arch/cpu.h |    1 +
 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 e5156d9..2bd00c4 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 85357d7..2dfcd72 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 a7f7b32..fac523f 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);




More information about the coreboot mailing list