This patch uses cpuid to determine the number of packages/sockets in which to generate the proper number of DMI/SMBIOS Type 4 (Processor Information) records.
Use "dmidevcode -t 4" to show that only the configured number of packages/sockets are shown versus the number of CPUs (sockets*cores*threads).
Signed-off-by: Bret Ketchum <bcketchum at gmail.com> --- src/fw/smbios.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-)
diff --git a/src/fw/smbios.c b/src/fw/smbios.c index affb9be..23869b1 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -505,6 +505,52 @@ smbios_init_type_127(void *start)
#define TEMPSMBIOSSIZE (32 * 1024)
+static inline void +cpuid_count(u32 index, u32 sub, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) +{ + asm volatile("cpuid" + : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) + : "0" (index), "c" (sub)); +} + +static int package_count(void) +{ + char vendor[12]; + int ret = CountCPUs; + u32 cpuid_features, cpuid_high, cpuid_procinfo, cpuid_signature; + u32 eax, ebx, ecx, edx; + + cpuid(0, &cpuid_high, &ebx, &ecx, &edx); + ((u32 *)&vendor)[0] = ebx; + ((u32 *)&vendor)[1] = edx; + ((u32 *)&vendor)[2] = ecx; + + cpuid(1, &cpuid_signature, &cpuid_procinfo, &ecx, &cpuid_features); + + if (memcmp(vendor, "GenuineIntel", sizeof(vendor)) == 0) { + int logical = (cpuid_features & 0x10000000) != 0 + ? (cpuid_procinfo >> 16) & 0xff + : 1; + + cpuid_count(4, 0, &eax, &ebx, &ecx, &edx); + + /* number of packages/sockets equals the number ACPI IDs + * divided by the "Maximum number of addressable IDs for + * logical processors in this physical package. + */ + ret = MaxCountCPUs / ((logical == 1) + ? (((eax >> 26) & 0x3f) + 1) + : logical); + + } else { + cpuid(0x80000008, &eax, &ebx, &ecx, &edx); + + ret = ((cpuid_procinfo >> 16) & 0xff) / ((ecx & 0xff) + 1); + } + + return(ret); +} + void smbios_setup(void) { @@ -538,8 +584,8 @@ smbios_setup(void) add_struct(1, p); add_struct(3, p);
- int cpu_num; - for (cpu_num = 1; cpu_num <= MaxCountCPUs; cpu_num++) + int cpu_num, pkg_count = package_count(); + for (cpu_num = 1; cpu_num <= pkg_count; cpu_num++) add_struct(4, p, cpu_num);
int ram_mb = (RamSize + RamSizeOver4G) >> 20;