mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-22 05:04:24 +02:00
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:
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user