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 <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
Message-Id: <d93822d37fd25dafd32795758cf47263b432e102.1705549445.git.AbdulLateef.Attar@amd.com>
Acked-by: Ray Ni <ray.ni@intel.com>
Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
			
			
This commit is contained in:
		
				
					committed by
					
						![mergify[bot]](/avatar/e3df20cd7a67969c41a65f03bea54961?size=40) mergify[bot]
						mergify[bot]
					
				
			
			
				
	
			
			
			
						parent
						
							d14526372d
						
					
				
				
					commit
					0e9b124f9c
				
			| @@ -4,7 +4,7 @@ | |||||||
|   This local APIC library instance supports xAPIC mode only. |   This local APIC library instance supports xAPIC mode only. | ||||||
|  |  | ||||||
|   Copyright (c) 2010 - 2023, Intel Corporation. All rights reserved.<BR> |   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 |   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. |   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                       Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; | ||||||
|   UINT32                       *Location[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++) { |   for (LevelType = 0; LevelType < ARRAY_SIZE (Bits); LevelType++) { | ||||||
|     Bits[LevelType] = 0; |     Bits[LevelType] = 0; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|   which have xAPIC and x2APIC modes. |   which have xAPIC and x2APIC modes. | ||||||
|  |  | ||||||
|   Copyright (c) 2010 - 2023, Intel Corporation. All rights reserved.<BR> |   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 |   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. |   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                       Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; | ||||||
|   UINT32                       *Location[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++) { |   for (LevelType = 0; LevelType < ARRAY_SIZE (Bits); LevelType++) { | ||||||
|     Bits[LevelType] = 0; |     Bits[LevelType] = 0; | ||||||
|   } |   } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user