[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dmidecode] [PATCH 3/6] dmidecode: Split CPUID type detection from dmi_p
From: |
Jean Delvare |
Subject: |
[dmidecode] [PATCH 3/6] dmidecode: Split CPUID type detection from dmi_processor_id |
Date: |
Thu, 4 Mar 2021 17:47:21 +0100 |
Move the code which decides the CPUID type to a separate function, so
that it can be called from a different context.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
---
dmidecode.c | 210 ++++++++++++++++++++++++++++++++----------------------------
dmidecode.h | 12 +++
2 files changed, 127 insertions(+), 95 deletions(-)
--- dmidecode.orig/dmidecode.c 2021-03-04 15:41:02.176098460 +0100
+++ dmidecode/dmidecode.c 2021-03-04 15:45:57.860593149 +0100
@@ -85,6 +85,8 @@
#define out_of_spec "<OUT OF SPEC>"
static const char *bad_index = "<BAD INDEX>";
+enum cpuid_type cpuid_type = cpuid_none;
+
#define SUPPORTED_SMBIOS_VER 0x030300
#define FLAG_NO_FILE_OFFSET (1 << 0)
@@ -1037,73 +1039,20 @@ static const char *dmi_processor_family(
}
}
-static void dmi_processor_id(const struct dmi_header *h)
+static enum cpuid_type dmi_get_cpuid_type(const struct dmi_header *h)
{
- /* Intel AP-485 revision 36, table 2-4 */
- static const char *flags[32] = {
- "FPU (Floating-point unit on-chip)", /* 0 */
- "VME (Virtual mode extension)",
- "DE (Debugging extension)",
- "PSE (Page size extension)",
- "TSC (Time stamp counter)",
- "MSR (Model specific registers)",
- "PAE (Physical address extension)",
- "MCE (Machine check exception)",
- "CX8 (CMPXCHG8 instruction supported)",
- "APIC (On-chip APIC hardware supported)",
- NULL, /* 10 */
- "SEP (Fast system call)",
- "MTRR (Memory type range registers)",
- "PGE (Page global enable)",
- "MCA (Machine check architecture)",
- "CMOV (Conditional move instruction supported)",
- "PAT (Page attribute table)",
- "PSE-36 (36-bit page size extension)",
- "PSN (Processor serial number present and enabled)",
- "CLFSH (CLFLUSH instruction supported)",
- NULL, /* 20 */
- "DS (Debug store)",
- "ACPI (ACPI supported)",
- "MMX (MMX technology supported)",
- "FXSR (FXSAVE and FXSTOR instructions supported)",
- "SSE (Streaming SIMD extensions)",
- "SSE2 (Streaming SIMD extensions 2)",
- "SS (Self-snoop)",
- "HTT (Multi-threading)",
- "TM (Thermal monitor supported)",
- NULL, /* 30 */
- "PBE (Pending break enabled)" /* 31 */
- };
const u8 *data = h->data;
const u8 *p = data + 0x08;
- u32 eax, edx;
- int sig = 0;
u16 type;
type = (data[0x06] == 0xFE && h->length >= 0x2A) ?
WORD(data + 0x28) : data[0x06];
- /*
- * This might help learn about new processors supporting the
- * CPUID instruction or another form of identification.
- */
- if (!(opt.flags & FLAG_QUIET))
- pr_attr("ID", "%02X %02X %02X %02X %02X %02X %02X %02X",
- p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
-
if (type == 0x05) /* 80386 */
{
- u16 dx = WORD(p);
- /*
- * 80386 have a different signature.
- */
- pr_attr("Signature",
- "Type %u, Family %u, Major Stepping %u, Minor Stepping
%u",
- dx >> 12, (dx >> 8) & 0xF,
- (dx >> 4) & 0xF, dx & 0xF);
- return;
+ return cpuid_80386;
}
- if (type == 0x06) /* 80486 */
+ else if (type == 0x06) /* 80486 */
{
u16 dx = WORD(p);
/*
@@ -1114,32 +1063,14 @@ static void dmi_processor_id(const struc
if ((dx & 0x0F00) == 0x0400
&& ((dx & 0x00F0) == 0x0040 || (dx & 0x00F0) >= 0x0070)
&& ((dx & 0x000F) >= 0x0003))
- sig = 1;
+ return cpuid_x86_intel;
else
- {
- pr_attr("Signature",
- "Type %u, Family %u, Model %u, Stepping %u",
- (dx >> 12) & 0x3, (dx >> 8) & 0xF,
- (dx >> 4) & 0xF, dx & 0xF);
- return;
- }
+ return cpuid_80486;
}
else if ((type >= 0x100 && type <= 0x101) /* ARM */
|| (type >= 0x118 && type <= 0x119)) /* ARM */
{
- u32 midr = DWORD(p);
- /*
- * The format of this field was not defined for ARM processors
- * before version 3.1.0 of the SMBIOS specification, so we
- * silently skip it if it reads all zeroes.
- */
- if (midr == 0)
- return;
- pr_attr("Signature",
- "Implementor 0x%02x, Variant 0x%x, Architecture %u,
Part 0x%03x, Revision %u",
- midr >> 24, (midr >> 20) & 0xF,
- (midr >> 16) & 0xF, (midr >> 4) & 0xFFF, midr & 0xF);
- return;
+ return cpuid_arm;
}
else if ((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */
|| (type >= 0x28 && type <= 0x2F) /* Intel */
@@ -1149,7 +1080,7 @@ static void dmi_processor_id(const struc
|| (type >= 0xCD && type <= 0xCF) /* Intel */
|| (type >= 0xD2 && type <= 0xDB) /* VIA, Intel */
|| (type >= 0xDD && type <= 0xE0)) /* Intel */
- sig = 1;
+ return cpuid_x86_intel;
else if ((type >= 0x18 && type <= 0x1D) /* AMD */
|| type == 0x1F /* AMD */
|| (type >= 0x38 && type <= 0x3F) /* AMD */
@@ -1158,7 +1089,7 @@ static void dmi_processor_id(const struc
|| (type >= 0x83 && type <= 0x8F) /* AMD */
|| (type >= 0xB6 && type <= 0xB7) /* AMD */
|| (type >= 0xE4 && type <= 0xEF)) /* AMD */
- sig = 2;
+ return cpuid_x86_amd;
else if (type == 0x01 || type == 0x02)
{
const char *version = dmi_string(h, data[0x10]);
@@ -1171,26 +1102,112 @@ static void dmi_processor_id(const struc
|| strncmp(version, "Intel(R) Core(TM)2", 18) == 0
|| strncmp(version, "Intel(R) Pentium(R)", 19) == 0
|| strcmp(version, "Genuine Intel(R) CPU U1400") == 0)
- sig = 1;
+ return cpuid_x86_intel;
else if (strncmp(version, "AMD Athlon(TM)", 14) == 0
|| strncmp(version, "AMD Opteron(tm)", 15) == 0
|| strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0)
- sig = 2;
- else
- return;
+ return cpuid_x86_amd;
}
- else /* neither X86 nor ARM */
- return;
+
+ /* neither X86 nor ARM */
+ return cpuid_none;
+}
+
+static void dmi_processor_id(const struct dmi_header *h)
+{
+ /* Intel AP-485 revision 36, table 2-4 */
+ static const char *flags[32] = {
+ "FPU (Floating-point unit on-chip)", /* 0 */
+ "VME (Virtual mode extension)",
+ "DE (Debugging extension)",
+ "PSE (Page size extension)",
+ "TSC (Time stamp counter)",
+ "MSR (Model specific registers)",
+ "PAE (Physical address extension)",
+ "MCE (Machine check exception)",
+ "CX8 (CMPXCHG8 instruction supported)",
+ "APIC (On-chip APIC hardware supported)",
+ NULL, /* 10 */
+ "SEP (Fast system call)",
+ "MTRR (Memory type range registers)",
+ "PGE (Page global enable)",
+ "MCA (Machine check architecture)",
+ "CMOV (Conditional move instruction supported)",
+ "PAT (Page attribute table)",
+ "PSE-36 (36-bit page size extension)",
+ "PSN (Processor serial number present and enabled)",
+ "CLFSH (CLFLUSH instruction supported)",
+ NULL, /* 20 */
+ "DS (Debug store)",
+ "ACPI (ACPI supported)",
+ "MMX (MMX technology supported)",
+ "FXSR (FXSAVE and FXSTOR instructions supported)",
+ "SSE (Streaming SIMD extensions)",
+ "SSE2 (Streaming SIMD extensions 2)",
+ "SS (Self-snoop)",
+ "HTT (Multi-threading)",
+ "TM (Thermal monitor supported)",
+ NULL, /* 30 */
+ "PBE (Pending break enabled)" /* 31 */
+ };
+ const u8 *data = h->data;
+ const u8 *p = data + 0x08;
+ enum cpuid_type sig = dmi_get_cpuid_type(h);
+ u32 eax, edx, midr;
+ u16 dx;
/*
- * Extra flags are now returned in the ECX register when one calls
- * the CPUID instruction. Their meaning is explained in table 3-5, but
- * DMI doesn't support this yet.
+ * This might help learn about new processors supporting the
+ * CPUID instruction or another form of identification.
*/
- eax = DWORD(p);
+ if (!(opt.flags & FLAG_QUIET))
+ pr_attr("ID", "%02X %02X %02X %02X %02X %02X %02X %02X",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+
switch (sig)
{
- case 1: /* Intel */
+ case cpuid_80386:
+ dx = WORD(p);
+ /*
+ * 80386 have a different signature.
+ */
+ pr_attr("Signature",
+ "Type %u, Family %u, Major Stepping %u, Minor
Stepping %u",
+ dx >> 12, (dx >> 8) & 0xF,
+ (dx >> 4) & 0xF, dx & 0xF);
+ return;
+
+ case cpuid_80486:
+ dx = WORD(p);
+ pr_attr("Signature",
+ "Type %u, Family %u, Model %u, Stepping %u",
+ (dx >> 12) & 0x3, (dx >> 8) & 0xF,
+ (dx >> 4) & 0xF, dx & 0xF);
+ return;
+
+ case cpuid_arm: /* ARM */
+ midr = DWORD(p);
+ /*
+ * The format of this field was not defined for ARM
processors
+ * before version 3.1.0 of the SMBIOS specification, so
we
+ * silently skip it if it reads all zeroes.
+ */
+ if (midr == 0)
+ return;
+ pr_attr("Signature",
+ "Implementor 0x%02x, Variant 0x%x, Architecture
%u, Part 0x%03x, Revision %u",
+ midr >> 24, (midr >> 20) & 0xF,
+ (midr >> 16) & 0xF, (midr >> 4) & 0xFFF, midr &
0xF);
+ return;
+
+ case cpuid_x86_intel: /* Intel */
+ eax = DWORD(p);
+ /*
+ * Extra flags are now returned in the ECX register when
+ * one calls the CPUID instruction. Their meaning is
+ * explained in table 3-5, but DMI doesn't support this
+ * yet.
+ */
pr_attr("Signature",
"Type %u, Family %u, Model %u, Stepping %u",
(eax >> 12) & 0x3,
@@ -1198,12 +1215,16 @@ static void dmi_processor_id(const struc
((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F),
eax & 0xF);
break;
- case 2: /* AMD, publication #25481 revision 2.28 */
+
+ case cpuid_x86_amd: /* AMD, publication #25481 revision 2.28 */
+ eax = DWORD(p);
pr_attr("Signature", "Family %u, Model %u, Stepping %u",
((eax >> 8) & 0xF) + (((eax >> 8) & 0xF) == 0xF
? (eax >> 20) & 0xFF : 0),
((eax >> 4) & 0xF) | (((eax >> 8) & 0xF) == 0xF
? (eax >> 12) & 0xF0 : 0),
eax & 0xF);
break;
+ default:
+ return;
}
edx = DWORD(p + 4);
--- dmidecode.orig/dmidecode.h 2021-03-04 15:41:02.176098460 +0100
+++ dmidecode/dmidecode.h 2021-03-04 15:45:57.860593149 +0100
@@ -31,6 +31,18 @@ struct dmi_header
u8 *data;
};
+enum cpuid_type
+{
+ cpuid_none,
+ cpuid_80386,
+ cpuid_80486,
+ cpuid_arm,
+ cpuid_x86_intel,
+ cpuid_x86_amd,
+};
+
+enum cpuid_type cpuid_type;
+
int is_printable(const u8 *data, int len);
const char *dmi_string(const struct dmi_header *dm, u8 s);
void dmi_print_memory_size(const char *addr, u64 code, int shift);
--
Jean Delvare
SUSE L3 Support