[BACKPORT] arch/x86: SMBIOS: Improve core count reporting

Current code uses CPUID leaf 0x1, EBX bits 16:23 to determine number for
"core count". However, it turns out this number has little to do with
real number of cores. According to SDM vol 2A, it stays for "maximum
number of addressable IDs for logical processors in this physical
package". This does not seem to take into account fusing of giving
processor.

The new code determines 'core count' by dividing thread-level cpus by
reported logical cores. This seems to be the only way to arrive
to number of cores as it is reported in official CPU datasheet.

TEST=tested on OCP monolake

Change-Id: Id4ba9e3079f92ffe38f9104ffcfafe62582dd259
Signed-off-by: Andrey Petrov <anpetrov@fb.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/36941
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Werner Zeh <werner.zeh@siemens.com>
(cherry picked from commit 515ef38db4)
Reviewed-on: https://review.coreboot.org/c/coreboot/+/37089
This commit is contained in:
Andrey Petrov 2019-11-15 13:19:08 -08:00
parent 9ad9b3a682
commit d491ebfe5b
1 changed files with 20 additions and 1 deletions

View File

@ -657,7 +657,26 @@ static int smbios_write_type4(unsigned long *current, int handle)
t->processor_version = smbios_processor_name(t->eos); t->processor_version = smbios_processor_name(t->eos);
t->processor_family = (res.eax > 0) ? 0x0c : 0x6; t->processor_family = (res.eax > 0) ? 0x0c : 0x6;
t->processor_type = 3; /* System Processor */ t->processor_type = 3; /* System Processor */
t->core_count = (res.ebx >> 16) & 0xff; /*
* If CPUID leaf 11 is available, calculate "core count" by dividing
* SMT_ID (logical processors in a core) by Core_ID (number of cores).
* This seems to be the way to arrive to a number of cores mentioned on
* ark.intel.com.
*/
if (cpu_have_cpuid() && cpuid_get_max_func() >= 0xb) {
uint32_t leaf_b_cores = 0, leaf_b_threads = 0;
res = cpuid_ext(0xb, 1);
leaf_b_cores = res.ebx;
res = cpuid_ext(0xb, 0);
leaf_b_threads = res.ebx;
/* if hyperthreading is not available, pretend this is 1 */
if (leaf_b_threads == 0) {
leaf_b_threads = 1;
}
t->core_count = leaf_b_cores / leaf_b_threads;
} else {
t->core_count = (res.ebx >> 16) & 0xff;
}
/* Assume we enable all the cores always, capped only by MAX_CPUS */ /* Assume we enable all the cores always, capped only by MAX_CPUS */
t->core_enabled = MIN(t->core_count, CONFIG_MAX_CPUS); t->core_enabled = MIN(t->core_count, CONFIG_MAX_CPUS);
t->l1_cache_handle = 0xffff; t->l1_cache_handle = 0xffff;