xref: /aosp_15_r20/external/coreboot/src/cpu/intel/common/hyperthreading.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <cpu/cpu.h>
4 #include <cpu/intel/common/common.h>
5 #include <types.h>
6 
intel_ht_supported(void)7 bool intel_ht_supported(void)
8 {
9 	/* Is HyperThreading supported? */
10 	return !!(cpuid_edx(1) & CPUID_FEATURE_HTT);
11 }
12 
13 /*
14  * Return true if running thread does not have the smallest lapic ID
15  * within a CPU core.
16  */
intel_ht_sibling(void)17 bool intel_ht_sibling(void)
18 {
19 	struct cpuid_result result;
20 	unsigned int core_ids, apic_ids;
21 	unsigned int max_leaf;
22 	uint32_t initial_lapicid, threads;
23 
24 	if (!intel_ht_supported())
25 		return false;
26 
27 	max_leaf = cpuid_get_max_func();
28 
29 	/* Detect from 32-bit X2APIC ID. */
30 	if (max_leaf >= 0xb) {
31 		result = cpuid_ext(0xb, 0);
32 		threads = 1 << (result.eax & 0x1f);
33 		initial_lapicid = result.edx;
34 		return initial_lapicid % threads > 0;
35 	}
36 
37 	/* Detect from 8-bit XAPIC ID. */
38 	result = cpuid_ext(0x1, 0);
39 	initial_lapicid = result.ebx >> 24;
40 	apic_ids = (result.ebx >> 16) & 0xff;
41 	if (apic_ids == 0)
42 		apic_ids = 1;
43 
44 	core_ids = 1;
45 	if (max_leaf >= 4) {
46 		result = cpuid_ext(4, 0);
47 		core_ids += (result.eax >> 26) & 0x3f;
48 	}
49 
50 	threads = (apic_ids / core_ids);
51 	return initial_lapicid % threads > 0;
52 }
53