kernel/x86: CPUID leaf 0x1f is a preferred superset to leaf 0x0b

Intel recommends first checking for the existence of CPUID leaf 1FH before using leaf 0BH.

Change-Id: Iba677186521e086fa06bcc4fe42eaed4ba030e6d
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4719
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Jérôme Duval
2021-11-11 07:53:23 +00:00
committed by Adrien Destugues
parent cb3199681e
commit cdd2ed5a77
+20 -10
View File
@@ -755,24 +755,35 @@ get_intel_cpu_initial_x2apic_id(int /* currentCPU */)
static inline status_t static inline status_t
detect_intel_cpu_topology_x2apic(uint32 maxBasicLeaf) detect_intel_cpu_topology_x2apic(uint32 maxBasicLeaf)
{ {
if (maxBasicLeaf < 11)
uint32 leaf = 0;
cpuid_info cpuid;
if (maxBasicLeaf >= 0x1f) {
get_current_cpuid(&cpuid, 0x1f, 0);
if (cpuid.regs.ebx != 0)
leaf = 0x1f;
}
if (maxBasicLeaf >= 0xb && leaf == 0) {
get_current_cpuid(&cpuid, 0xb, 0);
if (cpuid.regs.ebx != 0)
leaf = 0xb;
}
if (leaf == 0)
return B_UNSUPPORTED; return B_UNSUPPORTED;
uint8 hierarchyLevels[CPU_TOPOLOGY_LEVELS] = { 0 }; uint8 hierarchyLevels[CPU_TOPOLOGY_LEVELS] = { 0 };
int currentLevel = 0; int currentLevel = 0;
int levelType;
unsigned int levelsSet = 0; unsigned int levelsSet = 0;
do { do {
cpuid_info cpuid; cpuid_info cpuid;
get_current_cpuid(&cpuid, 11, currentLevel); get_current_cpuid(&cpuid, leaf, currentLevel++);
if (currentLevel == 0 && cpuid.regs.ebx == 0) int levelType = (cpuid.regs.ecx >> 8) & 0xff;
return B_UNSUPPORTED;
levelType = (cpuid.regs.ecx >> 8) & 0xff;
int levelValue = cpuid.regs.eax & 0x1f; int levelValue = cpuid.regs.eax & 0x1f;
if (levelType == 0)
break;
switch (levelType) { switch (levelType) {
case 1: // SMT case 1: // SMT
hierarchyLevels[CPU_TOPOLOGY_SMT] = levelValue; hierarchyLevels[CPU_TOPOLOGY_SMT] = levelValue;
@@ -784,8 +795,7 @@ detect_intel_cpu_topology_x2apic(uint32 maxBasicLeaf)
break; break;
} }
currentLevel++; } while (levelsSet != 3);
} while (levelType != 0 && levelsSet != 3);
sGetCPUTopologyID = get_intel_cpu_initial_x2apic_id; sGetCPUTopologyID = get_intel_cpu_initial_x2apic_id;