From cdd2ed5a77b47d926d128f9ed544a702467cdf6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Wed, 10 Nov 2021 18:45:13 +0100 Subject: [PATCH] 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 Reviewed-by: waddlesplash --- src/system/kernel/arch/x86/arch_cpu.cpp | 30 ++++++++++++++++--------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index bf4cf696c6..58337eae55 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -755,24 +755,35 @@ get_intel_cpu_initial_x2apic_id(int /* currentCPU */) static inline status_t 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; uint8 hierarchyLevels[CPU_TOPOLOGY_LEVELS] = { 0 }; int currentLevel = 0; - int levelType; unsigned int levelsSet = 0; - do { cpuid_info cpuid; - get_current_cpuid(&cpuid, 11, currentLevel); - if (currentLevel == 0 && cpuid.regs.ebx == 0) - return B_UNSUPPORTED; - - levelType = (cpuid.regs.ecx >> 8) & 0xff; + get_current_cpuid(&cpuid, leaf, currentLevel++); + int levelType = (cpuid.regs.ecx >> 8) & 0xff; int levelValue = cpuid.regs.eax & 0x1f; + if (levelType == 0) + break; + switch (levelType) { case 1: // SMT hierarchyLevels[CPU_TOPOLOGY_SMT] = levelValue; @@ -784,8 +795,7 @@ detect_intel_cpu_topology_x2apic(uint32 maxBasicLeaf) break; } - currentLevel++; - } while (levelType != 0 && levelsSet != 3); + } while (levelsSet != 3); sGetCPUTopologyID = get_intel_cpu_initial_x2apic_id;