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. | ||||
|  | ||||
|   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; | ||||
|   } | ||||
|   | ||||
| @@ -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; | ||||
|   } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user