summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/boot/smbios.c49
-rw-r--r--src/arch/x86/include/arch/cpu.h1
-rw-r--r--src/arch/x86/lib/cpu.c9
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);