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: 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 | 122 +++++++++++++++++- .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 122 +++++++++++++++++- 2 files changed, 242 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c index efb9d71ca1..5e941d0dc8 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,121 @@ 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 +EFIAPI +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 SubIndex; + UINT32 PreviousLevel; + UINT32 Data; + + if (Die != NULL) { + *Die = 0; + } + + if (Tile != NULL) { + *Tile = 0; + } + + if (Module != NULL) { + *Module = 0; + } + + /// Check if extended toplogy supported + AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NULL); + if (MaxExtendedCpuIdIndex < AMD_CPUID_EXTENDED_TOPOLOGY) { + GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread); + return; + } + + PreviousLevel = 0; + SubIndex = 0; + do { + AsmCpuidEx ( + AMD_CPUID_EXTENDED_TOPOLOGY, + SubIndex, + &ExtendedTopologyEax.Uint32, + &ExtendedTopologyEbx.Uint32, + &ExtendedTopologyEcx.Uint32, + NULL + ); + + if (ExtendedTopologyEbx.Bits.LogicalProcessors == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { + 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; + } + + SubIndex++; + PreviousLevel = ExtendedTopologyEax.Bits.ApicIdShift; + } while (ExtendedTopologyEbx.Bits.LogicalProcessors != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID); + + /// Package value + if ((PreviousLevel != 0) && (Package != NULL)) { + *Package = InitialApicId >> PreviousLevel; + } + + return; +} + /** Get Package ID/Die ID/Tile ID/Module ID/Core ID/Thread ID of a processor. @@ -1194,6 +1309,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..a7563f6596 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,121 @@ 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 +EFIAPI +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 SubIndex; + UINT32 PreviousLevel; + UINT32 Data; + + if (Die != NULL) { + *Die = 0; + } + + if (Tile != NULL) { + *Tile = 0; + } + + if (Module != NULL) { + *Module = 0; + } + + /// Check if extended toplogy supported + AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NULL); + if (MaxExtendedCpuIdIndex < AMD_CPUID_EXTENDED_TOPOLOGY) { + GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread); + return; + } + + PreviousLevel = 0; + SubIndex = 0; + do { + AsmCpuidEx ( + AMD_CPUID_EXTENDED_TOPOLOGY, + SubIndex, + &ExtendedTopologyEax.Uint32, + &ExtendedTopologyEbx.Uint32, + &ExtendedTopologyEcx.Uint32, + NULL + ); + + if (ExtendedTopologyEbx.Bits.LogicalProcessors == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { + 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; + } + + SubIndex++; + PreviousLevel = ExtendedTopologyEax.Bits.ApicIdShift; + } while (ExtendedTopologyEbx.Bits.LogicalProcessors != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID); + + /// Package value + if ((PreviousLevel != 0) && (Package != NULL)) { + *Package = InitialApicId >> PreviousLevel; + } + + return; +} + /** Get Package ID/Die ID/Tile ID/Module ID/Core ID/Thread ID of a processor. @@ -1433,6 +1548,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 (#113869): https://edk2.groups.io/g/devel/message/113869 Mute This Topic: https://groups.io/mt/103757657/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-