From 0e9b124f9c67b3aa3bd3bb5c8eee4d30408fe359 Mon Sep 17 00:00:00 2001 From: Abdul Lateef Attar Date: Thu, 18 Jan 2024 09:24:09 +0530 Subject: UefiCpuPkg/BaseXApic[X2]ApicLib: Implements AMD extended cpu topology This patch adds support for AMD's new extended topology. If processor supports CPUID 80000026 leaf then obtain the topology information using new method. Algorithm: if CPUID is AMD: then check for AMD's extended cpu tology leaf. if yes then extract cpu tology based on AMD programmer manual's instruction. else then fallback to existing topology function. endif endif Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Signed-off-by: Abdul Lateef Attar Message-Id: Acked-by: Ray Ni Acked-by: Tom Lendacky --- UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c | 126 ++++++++++++++++++++- .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 126 ++++++++++++++++++++- 2 files changed, 250 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c index efb9d71ca1..c4457d98b3 100644 --- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c @@ -4,7 +4,7 @@ This local APIC library instance supports xAPIC mode only. Copyright (c) 2010 - 2023, Intel Corporation. All rights reserved.
- Copyright (c) 2017 - 2020, AMD Inc. All rights reserved.
+ Copyright (c) 2017 - 2024, AMD Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -1157,6 +1157,125 @@ GetProcessorLocationByApicId ( } } +/** + Get Package ID/Die ID/Module ID/Core ID/Thread ID of a AMD processor family. + + The algorithm assumes the target system has symmetry across physical + package boundaries with respect to the number of threads per core, number of + cores per module, number of modules per die, number + of dies per package. + + @param[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Die Returns the processor die ID. + @param[out] Tile Returns zero. + @param[out] Module Returns the processor module ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +AmdGetProcessorLocation2ByApicId ( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Die OPTIONAL, + OUT UINT32 *Tile OPTIONAL, + OUT UINT32 *Module OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ) +{ + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; + CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx; + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; + UINT32 MaxExtendedCpuIdIndex; + UINT32 TopologyLevel; + UINT32 PreviousLevel; + UINT32 Data; + + if (Die != NULL) { + *Die = 0; + } + + if (Tile != NULL) { + *Tile = 0; + } + + if (Module != NULL) { + *Module = 0; + } + + PreviousLevel = 0; + TopologyLevel = 0; + + /// Check if extended toplogy supported + AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NULL); + if (MaxExtendedCpuIdIndex >= AMD_CPUID_EXTENDED_TOPOLOGY) { + do { + AsmCpuidEx ( + AMD_CPUID_EXTENDED_TOPOLOGY, + TopologyLevel, + &ExtendedTopologyEax.Uint32, + &ExtendedTopologyEbx.Uint32, + &ExtendedTopologyEcx.Uint32, + NULL + ); + + if (ExtendedTopologyEbx.Bits.LogicalProcessors == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { + /// if this fails at first level + /// then will fall back to non-extended topology + break; + } + + Data = InitialApicId >> PreviousLevel; + Data &= (1 << (ExtendedTopologyEax.Bits.ApicIdShift - PreviousLevel)) - 1; + + switch (ExtendedTopologyEcx.Bits.LevelType) { + case CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT: + if (Thread != NULL) { + *Thread = Data; + } + + break; + case CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE: + if (Core != NULL) { + *Core = Data; + } + + break; + case CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_MODULE: + if (Module != NULL) { + *Module = Data; + } + + break; + case CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE: + if (Die != NULL) { + *Die = Data; + } + + break; + default: + break; + } + + TopologyLevel++; + PreviousLevel = ExtendedTopologyEax.Bits.ApicIdShift; + } while (ExtendedTopologyEbx.Bits.LogicalProcessors != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID); + + if (Package != NULL) { + *Package = InitialApicId >> PreviousLevel; + } + } + + /// If extended topology CPUID is not supported + /// OR, execution of AMD_CPUID_EXTENDED_TOPOLOGY at level 0 fails(return 0). + if (TopologyLevel == 0) { + GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread); + } + + return; +} + /** Get Package ID/Die ID/Tile ID/Module ID/Core ID/Thread ID of a processor. @@ -1194,6 +1313,11 @@ GetProcessorLocation2ByApicId ( UINT32 Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; UINT32 *Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; + if (StandardSignatureIsAuthenticAMD ()) { + AmdGetProcessorLocation2ByApicId (InitialApicId, Package, Die, Tile, Module, Core, Thread); + return; + } + for (LevelType = 0; LevelType < ARRAY_SIZE (Bits); LevelType++) { Bits[LevelType] = 0; } diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c index c0a8475833..0560d38ce5 100644 --- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c @@ -5,7 +5,7 @@ which have xAPIC and x2APIC modes. Copyright (c) 2010 - 2023, Intel Corporation. All rights reserved.
- Copyright (c) 2017 - 2020, AMD Inc. All rights reserved.
+ Copyright (c) 2017 - 2024, AMD Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -1396,6 +1396,125 @@ GetProcessorLocationByApicId ( } } +/** + Get Package ID/Die ID/Module ID/Core ID/Thread ID of a AMD processor family. + + The algorithm assumes the target system has symmetry across physical + package boundaries with respect to the number of threads per core, number of + cores per module, number of modules per die, number + of dies per package. + + @param[in] InitialApicId Initial APIC ID of the target logical processor. + @param[out] Package Returns the processor package ID. + @param[out] Die Returns the processor die ID. + @param[out] Tile Returns zero. + @param[out] Module Returns the processor module ID. + @param[out] Core Returns the processor core ID. + @param[out] Thread Returns the processor thread ID. +**/ +VOID +AmdGetProcessorLocation2ByApicId ( + IN UINT32 InitialApicId, + OUT UINT32 *Package OPTIONAL, + OUT UINT32 *Die OPTIONAL, + OUT UINT32 *Tile OPTIONAL, + OUT UINT32 *Module OPTIONAL, + OUT UINT32 *Core OPTIONAL, + OUT UINT32 *Thread OPTIONAL + ) +{ + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; + CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx; + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; + UINT32 MaxExtendedCpuIdIndex; + UINT32 TopologyLevel; + UINT32 PreviousLevel; + UINT32 Data; + + if (Die != NULL) { + *Die = 0; + } + + if (Tile != NULL) { + *Tile = 0; + } + + if (Module != NULL) { + *Module = 0; + } + + PreviousLevel = 0; + TopologyLevel = 0; + + /// Check if extended toplogy supported + AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NULL); + if (MaxExtendedCpuIdIndex >= AMD_CPUID_EXTENDED_TOPOLOGY) { + do { + AsmCpuidEx ( + AMD_CPUID_EXTENDED_TOPOLOGY, + TopologyLevel, + &ExtendedTopologyEax.Uint32, + &ExtendedTopologyEbx.Uint32, + &ExtendedTopologyEcx.Uint32, + NULL + ); + + if (ExtendedTopologyEbx.Bits.LogicalProcessors == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { + /// if this fails at first level + /// then will fall back to non-extended topology + break; + } + + Data = InitialApicId >> PreviousLevel; + Data &= (1 << (ExtendedTopologyEax.Bits.ApicIdShift - PreviousLevel)) - 1; + + switch (ExtendedTopologyEcx.Bits.LevelType) { + case CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT: + if (Thread != NULL) { + *Thread = Data; + } + + break; + case CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE: + if (Core != NULL) { + *Core = Data; + } + + break; + case CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_MODULE: + if (Module != NULL) { + *Module = Data; + } + + break; + case CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE: + if (Die != NULL) { + *Die = Data; + } + + break; + default: + break; + } + + TopologyLevel++; + PreviousLevel = ExtendedTopologyEax.Bits.ApicIdShift; + } while (ExtendedTopologyEbx.Bits.LogicalProcessors != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID); + + if (Package != NULL) { + *Package = InitialApicId >> PreviousLevel; + } + } + + /// If extended topology CPUID is not supported + /// OR, execution of AMD_CPUID_EXTENDED_TOPOLOGY at level 0 fails(return 0). + if (TopologyLevel == 0) { + GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread); + } + + return; +} + /** Get Package ID/Die ID/Tile ID/Module ID/Core ID/Thread ID of a processor. @@ -1433,6 +1552,11 @@ GetProcessorLocation2ByApicId ( UINT32 Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; UINT32 *Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; + if (StandardSignatureIsAuthenticAMD ()) { + AmdGetProcessorLocation2ByApicId (InitialApicId, Package, Die, Tile, Module, Core, Thread); + return; + } + for (LevelType = 0; LevelType < ARRAY_SIZE (Bits); LevelType++) { Bits[LevelType] = 0; } -- cgit v1.2.3