cpu/intel/hyperthreading: Use initial LAPIC IDs

For older CPU models where CPUID leaf 0xb is not supported, use
initial LAPIC ID from CPUID instead of LAPIC register space to
to detect if logical CPU is a hyperthreading sibling. The one
in LAPIC space is more complex to read, and might not reflect
CPU topology as it can be modified in XAPIC mode.

Change-Id: I8c458824db1ea66948126622a3e0d0604e391e4b
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/58385
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
This commit is contained in:
Kyösti Mälkki 2021-10-16 13:35:04 +03:00 committed by Felix Held
parent a000922e07
commit 5791123356
1 changed files with 12 additions and 8 deletions

View File

@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
#include <cpu/x86/lapic.h>
#include <cpu/intel/common/common.h> #include <cpu/intel/common/common.h>
#include <arch/cpu.h> #include <arch/cpu.h>
#include <types.h> #include <types.h>
@ -18,22 +17,27 @@ bool intel_ht_supported(void)
bool intel_ht_sibling(void) bool intel_ht_sibling(void)
{ {
struct cpuid_result result; struct cpuid_result result;
unsigned int core_ids, apic_ids, threads; unsigned int core_ids, apic_ids;
unsigned int max_leaf; unsigned int max_leaf;
uint32_t initial_lapicid, threads;
if (!intel_ht_supported()) if (!intel_ht_supported())
return false; return false;
max_leaf = cpuid_get_max_func(); max_leaf = cpuid_get_max_func();
/* Detect from 32-bit X2APIC ID. */
if (max_leaf >= 0xb) { if (max_leaf >= 0xb) {
result = cpuid_ext(0xb, 0); result = cpuid_ext(0xb, 0);
const uint32_t div = 1 << (result.eax & 0x1f); threads = 1 << (result.eax & 0x1f);
return result.edx % div > 0; initial_lapicid = result.edx;
return initial_lapicid % threads > 0;
} }
apic_ids = 1; /* Detect from 8-bit XAPIC ID. */
if (max_leaf >= 1) result = cpuid_ext(0x1, 0);
apic_ids = (cpuid_ebx(1) >> 16) & 0xff; initial_lapicid = result.ebx >> 24;
apic_ids = (result.ebx >> 16) & 0xff;
if (apic_ids == 0) if (apic_ids == 0)
apic_ids = 1; apic_ids = 1;
@ -44,5 +48,5 @@ bool intel_ht_sibling(void)
} }
threads = (apic_ids / core_ids); threads = (apic_ids / core_ids);
return !!(lapicid() & (threads - 1)); return initial_lapicid % threads > 0;
} }