x86[_64]: Add CPU topology detection for AMD processors
This commit is contained in:
@@ -538,6 +538,68 @@ dump_feature_string(int currentCPU, cpu_ent* cpu)
|
|||||||
#endif // DUMP_FEATURE_STRING
|
#endif // DUMP_FEATURE_STRING
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
computeCPUHierarchyMasks(int maxLogicalID, int maxCoreID)
|
||||||
|
{
|
||||||
|
ASSERT(maxLogicalID >= maxCoreID);
|
||||||
|
const int kMaxSMTID = maxLogicalID / maxCoreID;
|
||||||
|
|
||||||
|
sHierarchyMask[CPU_TOPOLOGY_SMT] = kMaxSMTID - 1;
|
||||||
|
sHierarchyShift[CPU_TOPOLOGY_SMT] = 0;
|
||||||
|
|
||||||
|
sHierarchyMask[CPU_TOPOLOGY_CORE] = (maxCoreID - 1) * kMaxSMTID;
|
||||||
|
sHierarchyShift[CPU_TOPOLOGY_CORE]
|
||||||
|
= countSetBits(sHierarchyMask[CPU_TOPOLOGY_SMT]);
|
||||||
|
|
||||||
|
const uint32 kSinglePackageMask = sHierarchyMask[CPU_TOPOLOGY_SMT]
|
||||||
|
| sHierarchyMask[CPU_TOPOLOGY_CORE];
|
||||||
|
sHierarchyMask[CPU_TOPOLOGY_PACKAGE] = ~kSinglePackageMask;
|
||||||
|
sHierarchyShift[CPU_TOPOLOGY_PACKAGE] = countSetBits(kSinglePackageMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32
|
||||||
|
getCPULegacyInitialAPICID(int currentCPU)
|
||||||
|
{
|
||||||
|
(void)currentCPU;
|
||||||
|
|
||||||
|
cpuid_info cpuid;
|
||||||
|
get_current_cpuid(&cpuid, 1, 0);
|
||||||
|
return cpuid.regs.ebx >> 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline status_t
|
||||||
|
detectAMDCPUTopology(int maxBasicLeaf, int maxExtendedLeaf)
|
||||||
|
{
|
||||||
|
getCPUTopologyID = getCPULegacyInitialAPICID;
|
||||||
|
|
||||||
|
cpuid_info cpuid;
|
||||||
|
get_current_cpuid(&cpuid, 1, 0);
|
||||||
|
int maxLogicalID = nextPowerOf2((cpuid.regs.ebx >> 16) & 0xff);
|
||||||
|
|
||||||
|
int maxCoreID = 1;
|
||||||
|
if (maxExtendedLeaf >= 0x80000008) {
|
||||||
|
get_current_cpuid(&cpuid, 0x80000008, 0);
|
||||||
|
maxCoreID = (cpuid.regs.ecx >> 12) & 0xf;
|
||||||
|
if (maxCoreID != 0)
|
||||||
|
maxCoreID = 1 << maxCoreID;
|
||||||
|
else
|
||||||
|
maxCoreID = nextPowerOf2((cpuid.regs.edx & 0xf) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxExtendedLeaf >= 0x80000001) {
|
||||||
|
get_current_cpuid(&cpuid, 0x80000001, 0);
|
||||||
|
if ((cpuid.regs.ecx & 2) != 0)
|
||||||
|
maxCoreID = maxLogicalID;
|
||||||
|
}
|
||||||
|
|
||||||
|
computeCPUHierarchyMasks(maxLogicalID, maxCoreID);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32
|
static uint32
|
||||||
getIntelCPUInitialx2APICID(int currentCPU)
|
getIntelCPUInitialx2APICID(int currentCPU)
|
||||||
{
|
{
|
||||||
@@ -599,21 +661,10 @@ detectIntelCPUTopologyx2APIC(int maxBasicLeaf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32
|
|
||||||
getIntelCPULegacyInitialAPICID(int currentCPU)
|
|
||||||
{
|
|
||||||
(void)currentCPU;
|
|
||||||
|
|
||||||
cpuid_info cpuid;
|
|
||||||
get_current_cpuid(&cpuid, 1, 0);
|
|
||||||
return cpuid.regs.ebx >> 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline status_t
|
static inline status_t
|
||||||
detectIntelCPUTopologyLegacy(int maxBasicLeaf)
|
detectIntelCPUTopologyLegacy(int maxBasicLeaf)
|
||||||
{
|
{
|
||||||
getCPUTopologyID = getIntelCPULegacyInitialAPICID;
|
getCPUTopologyID = getCPULegacyInitialAPICID;
|
||||||
|
|
||||||
cpuid_info cpuid;
|
cpuid_info cpuid;
|
||||||
|
|
||||||
@@ -626,20 +677,7 @@ detectIntelCPUTopologyLegacy(int maxBasicLeaf)
|
|||||||
maxCoreID = nextPowerOf2((cpuid.regs.eax >> 26) + 1);
|
maxCoreID = nextPowerOf2((cpuid.regs.eax >> 26) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(maxLogicalID >= maxCoreID);
|
computeCPUHierarchyMasks(maxLogicalID, maxCoreID);
|
||||||
const int kMaxSMTID = maxLogicalID / maxCoreID;
|
|
||||||
|
|
||||||
sHierarchyMask[CPU_TOPOLOGY_SMT] = kMaxSMTID - 1;
|
|
||||||
sHierarchyShift[CPU_TOPOLOGY_SMT] = 0;
|
|
||||||
|
|
||||||
sHierarchyMask[CPU_TOPOLOGY_CORE] = (maxCoreID - 1) * kMaxSMTID;
|
|
||||||
sHierarchyShift[CPU_TOPOLOGY_CORE]
|
|
||||||
= countSetBits(sHierarchyMask[CPU_TOPOLOGY_SMT]);
|
|
||||||
|
|
||||||
const uint32 kSinglePackageMask = sHierarchyMask[CPU_TOPOLOGY_SMT]
|
|
||||||
| sHierarchyMask[CPU_TOPOLOGY_CORE];
|
|
||||||
sHierarchyMask[CPU_TOPOLOGY_PACKAGE] = ~kSinglePackageMask;
|
|
||||||
sHierarchyShift[CPU_TOPOLOGY_PACKAGE] = countSetBits(kSinglePackageMask);
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -661,11 +699,14 @@ getTopologyLevelID(uint32 id, cpu_topology_level level)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
detectCPUTopology(int currentCPU, cpu_ent* cpu, int maxBasicLeaf)
|
detectCPUTopology(int currentCPU, cpu_ent* cpu, int maxBasicLeaf,
|
||||||
|
int maxExtendedLeaf)
|
||||||
{
|
{
|
||||||
if (currentCPU == 0) {
|
if (currentCPU == 0) {
|
||||||
status_t result = B_UNSUPPORTED;
|
status_t result = B_UNSUPPORTED;
|
||||||
if (x86_check_feature(IA32_FEATURE_HTT, FEATURE_COMMON)) {
|
if (x86_check_feature(IA32_FEATURE_HTT, FEATURE_COMMON)) {
|
||||||
|
if (cpu->arch.vendor == VENDOR_AMD)
|
||||||
|
result = detectAMDCPUTopology(maxBasicLeaf, maxExtendedLeaf);
|
||||||
if (cpu->arch.vendor == VENDOR_INTEL) {
|
if (cpu->arch.vendor == VENDOR_INTEL) {
|
||||||
result = detectIntelCPUTopologyx2APIC(maxBasicLeaf);
|
result = detectIntelCPUTopologyx2APIC(maxBasicLeaf);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
@@ -818,7 +859,7 @@ detect_cpu(int currentCPU)
|
|||||||
cpu->arch.feature[FEATURE_6_ECX] = cpuid.regs.ecx;
|
cpu->arch.feature[FEATURE_6_ECX] = cpuid.regs.ecx;
|
||||||
}
|
}
|
||||||
|
|
||||||
detectCPUTopology(currentCPU, cpu, maxBasicLeaf);
|
detectCPUTopology(currentCPU, cpu, maxBasicLeaf, maxExtendedLeaf);
|
||||||
|
|
||||||
#if DUMP_FEATURE_STRING
|
#if DUMP_FEATURE_STRING
|
||||||
dump_feature_string(currentCPU, cpu);
|
dump_feature_string(currentCPU, cpu);
|
||||||
|
|||||||
Reference in New Issue
Block a user