From: Abdul Lateef Attar <abdullateef.at...@amd.com> 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 <michael.d.kin...@intel.com> Cc: Liming Gao <gaolim...@byosoft.com.cn> Cc: Zhiguang Liu <zhiguang....@intel.com> Cc: Ray Ni <ray...@intel.com> Cc: Rahul Kumar <rahul1.ku...@intel.com> Cc: Gerd Hoffmann <kra...@redhat.com> Signed-off-by: Abdul Lateef Attar <abdullateef.at...@amd.com> --- .../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.<BR> - Copyright (c) 2017 - 2020, AMD Inc. All rights reserved.<BR> + Copyright (c) 2017 - 2024, AMD Inc. All rights reserved.<BR> 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.<BR> - Copyright (c) 2017 - 2020, AMD Inc. All rights reserved.<BR> + Copyright (c) 2017 - 2024, AMD Inc. All rights reserved.<BR> 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; } -- 2.34.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113983): https://edk2.groups.io/g/devel/message/113983 Mute This Topic: https://groups.io/mt/103802342/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-