mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg: Move GetProcessorLocation() to LocalApicLib library
1) Remove SmmGetProcessorLocation() from PiSmmCpuDxeSmm driver. 2) Remove ExtractProcessorLocation() from MpInitLib library. 3) Add GetProcessorLocation() to BaseXApicLib and BaseXApicX2ApicLib. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Leo Duran <leo.duran@amd.com> Signed-off-by: Michael Kinney <Michael.d.kinney@intel.com> Tested-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Michael Kinney <Michael.d.kinney@intel.com> Reviewed-by: Jeff Fan <jeff.fan@intel.com>
This commit is contained in:
parent
ac55b92554
commit
73152f19c0
|
@ -411,5 +411,25 @@ GetApicMsiValue (
|
||||||
IN BOOLEAN AssertionLevel
|
IN BOOLEAN AssertionLevel
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get Package ID/Core ID/Thread ID of a processor.
|
||||||
|
|
||||||
|
The algorithm assumes the target system has symmetry across physical
|
||||||
|
package boundaries with respect to the number of logical processors
|
||||||
|
per package, number of cores per package.
|
||||||
|
|
||||||
|
@param[in] InitialApicId Initial APIC ID of the target logical processor.
|
||||||
|
@param[out] Package Returns the processor package ID.
|
||||||
|
@param[out] Core Returns the processor core ID.
|
||||||
|
@param[out] Thread Returns the processor thread ID.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
GetProcessorLocation(
|
||||||
|
IN UINT32 InitialApicId,
|
||||||
|
OUT UINT32 *Package OPTIONAL,
|
||||||
|
OUT UINT32 *Core OPTIONAL,
|
||||||
|
OUT UINT32 *Thread OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -941,3 +941,149 @@ GetApicMsiValue (
|
||||||
}
|
}
|
||||||
return MsiData.Uint64;
|
return MsiData.Uint64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get Package ID/Core ID/Thread ID of a processor.
|
||||||
|
|
||||||
|
The algorithm assumes the target system has symmetry across physical
|
||||||
|
package boundaries with respect to the number of logical processors
|
||||||
|
per package, number of cores per package.
|
||||||
|
|
||||||
|
@param[in] InitialApicId Initial APIC ID of the target logical processor.
|
||||||
|
@param[out] Package Returns the processor package ID.
|
||||||
|
@param[out] Core Returns the processor core ID.
|
||||||
|
@param[out] Thread Returns the processor thread ID.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
GetProcessorLocation(
|
||||||
|
IN UINT32 InitialApicId,
|
||||||
|
OUT UINT32 *Package OPTIONAL,
|
||||||
|
OUT UINT32 *Core OPTIONAL,
|
||||||
|
OUT UINT32 *Thread OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN TopologyLeafSupported;
|
||||||
|
UINTN ThreadBits;
|
||||||
|
UINTN CoreBits;
|
||||||
|
CPUID_VERSION_INFO_EBX VersionInfoEbx;
|
||||||
|
CPUID_VERSION_INFO_EDX VersionInfoEdx;
|
||||||
|
CPUID_CACHE_PARAMS_EAX CacheParamsEax;
|
||||||
|
CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax;
|
||||||
|
CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx;
|
||||||
|
CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx;
|
||||||
|
UINT32 MaxCpuIdIndex;
|
||||||
|
UINT32 SubIndex;
|
||||||
|
UINTN LevelType;
|
||||||
|
UINT32 MaxLogicProcessorsPerPackage;
|
||||||
|
UINT32 MaxCoresPerPackage;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if the processor is capable of supporting more than one logical processor.
|
||||||
|
//
|
||||||
|
AsmCpuid(CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
|
||||||
|
if (VersionInfoEdx.Bits.HTT == 0) {
|
||||||
|
if (Thread != NULL) {
|
||||||
|
*Thread = 0;
|
||||||
|
}
|
||||||
|
if (Core != NULL) {
|
||||||
|
*Core = 0;
|
||||||
|
}
|
||||||
|
if (Package != NULL) {
|
||||||
|
*Package = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadBits = 0;
|
||||||
|
CoreBits = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assume three-level mapping of APIC ID: Package:Core:SMT.
|
||||||
|
//
|
||||||
|
TopologyLeafSupported = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the max index of basic CPUID
|
||||||
|
//
|
||||||
|
AsmCpuid(CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If the extended topology enumeration leaf is available, it
|
||||||
|
// is the preferred mechanism for enumerating topology.
|
||||||
|
//
|
||||||
|
if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
|
||||||
|
AsmCpuidEx(
|
||||||
|
CPUID_EXTENDED_TOPOLOGY,
|
||||||
|
0,
|
||||||
|
&ExtendedTopologyEax.Uint32,
|
||||||
|
&ExtendedTopologyEbx.Uint32,
|
||||||
|
&ExtendedTopologyEcx.Uint32,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
//
|
||||||
|
// If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for
|
||||||
|
// basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not
|
||||||
|
// supported on that processor.
|
||||||
|
//
|
||||||
|
if (ExtendedTopologyEbx.Uint32 != 0) {
|
||||||
|
TopologyLeafSupported = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract
|
||||||
|
// the SMT sub-field of x2APIC ID.
|
||||||
|
//
|
||||||
|
LevelType = ExtendedTopologyEcx.Bits.LevelType;
|
||||||
|
ASSERT(LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT);
|
||||||
|
ThreadBits = ExtendedTopologyEax.Bits.ApicIdShift;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Software must not assume any "level type" encoding
|
||||||
|
// value to be related to any sub-leaf index, except sub-leaf 0.
|
||||||
|
//
|
||||||
|
SubIndex = 1;
|
||||||
|
do {
|
||||||
|
AsmCpuidEx(
|
||||||
|
CPUID_EXTENDED_TOPOLOGY,
|
||||||
|
SubIndex,
|
||||||
|
&ExtendedTopologyEax.Uint32,
|
||||||
|
NULL,
|
||||||
|
&ExtendedTopologyEcx.Uint32,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
LevelType = ExtendedTopologyEcx.Bits.LevelType;
|
||||||
|
if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) {
|
||||||
|
CoreBits = ExtendedTopologyEax.Bits.ApicIdShift - ThreadBits;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SubIndex++;
|
||||||
|
} while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TopologyLeafSupported) {
|
||||||
|
AsmCpuid(CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL);
|
||||||
|
MaxLogicProcessorsPerPackage = VersionInfoEbx.Bits.MaximumAddressableIdsForLogicalProcessors;
|
||||||
|
if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) {
|
||||||
|
AsmCpuidEx(CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL);
|
||||||
|
MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//
|
||||||
|
// Must be a single-core processor.
|
||||||
|
//
|
||||||
|
MaxCoresPerPackage = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadBits = (UINTN)(HighBitSet32(MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1);
|
||||||
|
CoreBits = (UINTN)(HighBitSet32(MaxCoresPerPackage - 1) + 1); }
|
||||||
|
|
||||||
|
if (Thread != NULL) {
|
||||||
|
*Thread = InitialApicId & ((1 << ThreadBits) - 1);
|
||||||
|
}
|
||||||
|
if (Core != NULL) {
|
||||||
|
*Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1);
|
||||||
|
}
|
||||||
|
if (Package != NULL) {
|
||||||
|
*Package = (InitialApicId >> (ThreadBits + CoreBits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1036,3 +1036,149 @@ GetApicMsiValue (
|
||||||
}
|
}
|
||||||
return MsiData.Uint64;
|
return MsiData.Uint64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get Package ID/Core ID/Thread ID of a processor.
|
||||||
|
|
||||||
|
The algorithm assumes the target system has symmetry across physical
|
||||||
|
package boundaries with respect to the number of logical processors
|
||||||
|
per package, number of cores per package.
|
||||||
|
|
||||||
|
@param[in] InitialApicId Initial APIC ID of the target logical processor.
|
||||||
|
@param[out] Package Returns the processor package ID.
|
||||||
|
@param[out] Core Returns the processor core ID.
|
||||||
|
@param[out] Thread Returns the processor thread ID.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
GetProcessorLocation(
|
||||||
|
IN UINT32 InitialApicId,
|
||||||
|
OUT UINT32 *Package OPTIONAL,
|
||||||
|
OUT UINT32 *Core OPTIONAL,
|
||||||
|
OUT UINT32 *Thread OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN TopologyLeafSupported;
|
||||||
|
UINTN ThreadBits;
|
||||||
|
UINTN CoreBits;
|
||||||
|
CPUID_VERSION_INFO_EBX VersionInfoEbx;
|
||||||
|
CPUID_VERSION_INFO_EDX VersionInfoEdx;
|
||||||
|
CPUID_CACHE_PARAMS_EAX CacheParamsEax;
|
||||||
|
CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax;
|
||||||
|
CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx;
|
||||||
|
CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx;
|
||||||
|
UINT32 MaxCpuIdIndex;
|
||||||
|
UINT32 SubIndex;
|
||||||
|
UINTN LevelType;
|
||||||
|
UINT32 MaxLogicProcessorsPerPackage;
|
||||||
|
UINT32 MaxCoresPerPackage;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if the processor is capable of supporting more than one logical processor.
|
||||||
|
//
|
||||||
|
AsmCpuid(CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
|
||||||
|
if (VersionInfoEdx.Bits.HTT == 0) {
|
||||||
|
if (Thread != NULL) {
|
||||||
|
*Thread = 0;
|
||||||
|
}
|
||||||
|
if (Core != NULL) {
|
||||||
|
*Core = 0;
|
||||||
|
}
|
||||||
|
if (Package != NULL) {
|
||||||
|
*Package = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadBits = 0;
|
||||||
|
CoreBits = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assume three-level mapping of APIC ID: Package:Core:SMT.
|
||||||
|
//
|
||||||
|
TopologyLeafSupported = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the max index of basic CPUID
|
||||||
|
//
|
||||||
|
AsmCpuid(CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If the extended topology enumeration leaf is available, it
|
||||||
|
// is the preferred mechanism for enumerating topology.
|
||||||
|
//
|
||||||
|
if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
|
||||||
|
AsmCpuidEx(
|
||||||
|
CPUID_EXTENDED_TOPOLOGY,
|
||||||
|
0,
|
||||||
|
&ExtendedTopologyEax.Uint32,
|
||||||
|
&ExtendedTopologyEbx.Uint32,
|
||||||
|
&ExtendedTopologyEcx.Uint32,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
//
|
||||||
|
// If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for
|
||||||
|
// basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not
|
||||||
|
// supported on that processor.
|
||||||
|
//
|
||||||
|
if (ExtendedTopologyEbx.Uint32 != 0) {
|
||||||
|
TopologyLeafSupported = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract
|
||||||
|
// the SMT sub-field of x2APIC ID.
|
||||||
|
//
|
||||||
|
LevelType = ExtendedTopologyEcx.Bits.LevelType;
|
||||||
|
ASSERT(LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT);
|
||||||
|
ThreadBits = ExtendedTopologyEax.Bits.ApicIdShift;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Software must not assume any "level type" encoding
|
||||||
|
// value to be related to any sub-leaf index, except sub-leaf 0.
|
||||||
|
//
|
||||||
|
SubIndex = 1;
|
||||||
|
do {
|
||||||
|
AsmCpuidEx(
|
||||||
|
CPUID_EXTENDED_TOPOLOGY,
|
||||||
|
SubIndex,
|
||||||
|
&ExtendedTopologyEax.Uint32,
|
||||||
|
NULL,
|
||||||
|
&ExtendedTopologyEcx.Uint32,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
LevelType = ExtendedTopologyEcx.Bits.LevelType;
|
||||||
|
if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) {
|
||||||
|
CoreBits = ExtendedTopologyEax.Bits.ApicIdShift - ThreadBits;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SubIndex++;
|
||||||
|
} while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TopologyLeafSupported) {
|
||||||
|
AsmCpuid(CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL);
|
||||||
|
MaxLogicProcessorsPerPackage = VersionInfoEbx.Bits.MaximumAddressableIdsForLogicalProcessors;
|
||||||
|
if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) {
|
||||||
|
AsmCpuidEx(CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL);
|
||||||
|
MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//
|
||||||
|
// Must be a single-core processor.
|
||||||
|
//
|
||||||
|
MaxCoresPerPackage = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadBits = (UINTN)(HighBitSet32(MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1);
|
||||||
|
CoreBits = (UINTN)(HighBitSet32(MaxCoresPerPackage - 1) + 1); }
|
||||||
|
|
||||||
|
if (Thread != NULL) {
|
||||||
|
*Thread = InitialApicId & ((1 << ThreadBits) - 1);
|
||||||
|
}
|
||||||
|
if (Core != NULL) {
|
||||||
|
*Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1);
|
||||||
|
}
|
||||||
|
if (Package != NULL) {
|
||||||
|
*Package = (InitialApicId >> (ThreadBits + CoreBits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -57,132 +57,6 @@ IsBspExecuteDisableEnabled (
|
||||||
return Enabled;
|
return Enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Get CPU Package/Core/Thread location information.
|
|
||||||
|
|
||||||
@param[in] InitialApicId CPU APIC ID
|
|
||||||
@param[out] Location Pointer to CPU location information
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
ExtractProcessorLocation (
|
|
||||||
IN UINT32 InitialApicId,
|
|
||||||
OUT EFI_CPU_PHYSICAL_LOCATION *Location
|
|
||||||
)
|
|
||||||
{
|
|
||||||
BOOLEAN TopologyLeafSupported;
|
|
||||||
UINTN ThreadBits;
|
|
||||||
UINTN CoreBits;
|
|
||||||
CPUID_VERSION_INFO_EBX VersionInfoEbx;
|
|
||||||
CPUID_VERSION_INFO_EDX VersionInfoEdx;
|
|
||||||
CPUID_CACHE_PARAMS_EAX CacheParamsEax;
|
|
||||||
CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax;
|
|
||||||
CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx;
|
|
||||||
CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx;
|
|
||||||
UINT32 MaxCpuIdIndex;
|
|
||||||
UINT32 SubIndex;
|
|
||||||
UINTN LevelType;
|
|
||||||
UINT32 MaxLogicProcessorsPerPackage;
|
|
||||||
UINT32 MaxCoresPerPackage;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if the processor is capable of supporting more than one logical processor.
|
|
||||||
//
|
|
||||||
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
|
|
||||||
if (VersionInfoEdx.Bits.HTT == 0) {
|
|
||||||
Location->Thread = 0;
|
|
||||||
Location->Core = 0;
|
|
||||||
Location->Package = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadBits = 0;
|
|
||||||
CoreBits = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Assume three-level mapping of APIC ID: Package:Core:SMT.
|
|
||||||
//
|
|
||||||
|
|
||||||
TopologyLeafSupported = FALSE;
|
|
||||||
//
|
|
||||||
// Get the max index of basic CPUID
|
|
||||||
//
|
|
||||||
AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// If the extended topology enumeration leaf is available, it
|
|
||||||
// is the preferred mechanism for enumerating topology.
|
|
||||||
//
|
|
||||||
if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
|
|
||||||
AsmCpuidEx (
|
|
||||||
CPUID_EXTENDED_TOPOLOGY,
|
|
||||||
0,
|
|
||||||
&ExtendedTopologyEax.Uint32,
|
|
||||||
&ExtendedTopologyEbx.Uint32,
|
|
||||||
&ExtendedTopologyEcx.Uint32,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
//
|
|
||||||
// If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for
|
|
||||||
// basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not
|
|
||||||
// supported on that processor.
|
|
||||||
//
|
|
||||||
if (ExtendedTopologyEbx.Uint32 != 0) {
|
|
||||||
TopologyLeafSupported = TRUE;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract
|
|
||||||
// the SMT sub-field of x2APIC ID.
|
|
||||||
//
|
|
||||||
LevelType = ExtendedTopologyEcx.Bits.LevelType;
|
|
||||||
ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT);
|
|
||||||
ThreadBits = ExtendedTopologyEax.Bits.ApicIdShift;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Software must not assume any "level type" encoding
|
|
||||||
// value to be related to any sub-leaf index, except sub-leaf 0.
|
|
||||||
//
|
|
||||||
SubIndex = 1;
|
|
||||||
do {
|
|
||||||
AsmCpuidEx (
|
|
||||||
CPUID_EXTENDED_TOPOLOGY,
|
|
||||||
SubIndex,
|
|
||||||
&ExtendedTopologyEax.Uint32,
|
|
||||||
NULL,
|
|
||||||
&ExtendedTopologyEcx.Uint32,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
LevelType = ExtendedTopologyEcx.Bits.LevelType;
|
|
||||||
if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) {
|
|
||||||
CoreBits = ExtendedTopologyEax.Bits.ApicIdShift - ThreadBits;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SubIndex++;
|
|
||||||
} while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TopologyLeafSupported) {
|
|
||||||
AsmCpuid (CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL);
|
|
||||||
MaxLogicProcessorsPerPackage = VersionInfoEbx.Bits.MaximumAddressableIdsForLogicalProcessors;
|
|
||||||
if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) {
|
|
||||||
AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL);
|
|
||||||
MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1;
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// Must be a single-core processor.
|
|
||||||
//
|
|
||||||
MaxCoresPerPackage = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadBits = (UINTN) (HighBitSet32 (MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1);
|
|
||||||
CoreBits = (UINTN) (HighBitSet32 (MaxCoresPerPackage - 1) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Location->Thread = InitialApicId & ((1 << ThreadBits) - 1);
|
|
||||||
Location->Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1);
|
|
||||||
Location->Package = (InitialApicId >> (ThreadBits + CoreBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Worker function for SwitchBSP().
|
Worker function for SwitchBSP().
|
||||||
|
|
||||||
|
@ -1451,7 +1325,12 @@ MpInitLibGetProcessorInfo (
|
||||||
//
|
//
|
||||||
// Get processor location information
|
// Get processor location information
|
||||||
//
|
//
|
||||||
ExtractProcessorLocation (CpuMpData->CpuData[ProcessorNumber].ApicId, &ProcessorInfoBuffer->Location);
|
GetProcessorLocation (
|
||||||
|
CpuMpData->CpuData[ProcessorNumber].ApicId,
|
||||||
|
&ProcessorInfoBuffer->Location.Package,
|
||||||
|
&ProcessorInfoBuffer->Location.Core,
|
||||||
|
&ProcessorInfoBuffer->Location.Thread
|
||||||
|
);
|
||||||
|
|
||||||
if (HealthData != NULL) {
|
if (HealthData != NULL) {
|
||||||
HealthData->Uint32 = CpuMpData->CpuData[ProcessorNumber].Health;
|
HealthData->Uint32 = CpuMpData->CpuData[ProcessorNumber].Health;
|
||||||
|
|
|
@ -26,125 +26,6 @@ EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService = {
|
||||||
SmmRegisterExceptionHandler
|
SmmRegisterExceptionHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
Get Package ID/Core ID/Thread ID of a processor.
|
|
||||||
|
|
||||||
APIC ID must be an initial APIC ID.
|
|
||||||
|
|
||||||
The algorithm below assumes the target system has symmetry across physical package boundaries
|
|
||||||
with respect to the number of logical processors per package, number of cores per package.
|
|
||||||
|
|
||||||
@param ApicId APIC ID of the target logical processor.
|
|
||||||
@param Location Returns the processor location information.
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SmmGetProcessorLocation (
|
|
||||||
IN UINT32 ApicId,
|
|
||||||
OUT EFI_CPU_PHYSICAL_LOCATION *Location
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINTN ThreadBits;
|
|
||||||
UINTN CoreBits;
|
|
||||||
UINT32 RegEax;
|
|
||||||
UINT32 RegEbx;
|
|
||||||
UINT32 RegEcx;
|
|
||||||
UINT32 RegEdx;
|
|
||||||
UINT32 MaxCpuIdIndex;
|
|
||||||
UINT32 SubIndex;
|
|
||||||
UINTN LevelType;
|
|
||||||
UINT32 MaxLogicProcessorsPerPackage;
|
|
||||||
UINT32 MaxCoresPerPackage;
|
|
||||||
BOOLEAN TopologyLeafSupported;
|
|
||||||
|
|
||||||
ASSERT (Location != NULL);
|
|
||||||
|
|
||||||
ThreadBits = 0;
|
|
||||||
CoreBits = 0;
|
|
||||||
TopologyLeafSupported = FALSE;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if the processor is capable of supporting more than one logical processor.
|
|
||||||
//
|
|
||||||
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx);
|
|
||||||
ASSERT ((RegEdx & BIT28) != 0);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Assume three-level mapping of APIC ID: Package:Core:SMT.
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the max index of basic CPUID
|
|
||||||
//
|
|
||||||
AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// If the extended topology enumeration leaf is available, it
|
|
||||||
// is the preferred mechanism for enumerating topology.
|
|
||||||
//
|
|
||||||
if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
|
|
||||||
AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, &RegEax, &RegEbx, &RegEcx, NULL);
|
|
||||||
//
|
|
||||||
// If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for
|
|
||||||
// basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not
|
|
||||||
// supported on that processor.
|
|
||||||
//
|
|
||||||
if ((RegEbx & 0xffff) != 0) {
|
|
||||||
TopologyLeafSupported = TRUE;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract
|
|
||||||
// the SMT sub-field of x2APIC ID.
|
|
||||||
//
|
|
||||||
LevelType = (RegEcx >> 8) & 0xff;
|
|
||||||
ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT);
|
|
||||||
if ((RegEbx & 0xffff) > 1 ) {
|
|
||||||
ThreadBits = RegEax & 0x1f;
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// HT is not supported
|
|
||||||
//
|
|
||||||
ThreadBits = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Software must not assume any "level type" encoding
|
|
||||||
// value to be related to any sub-leaf index, except sub-leaf 0.
|
|
||||||
//
|
|
||||||
SubIndex = 1;
|
|
||||||
do {
|
|
||||||
AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, SubIndex, &RegEax, NULL, &RegEcx, NULL);
|
|
||||||
LevelType = (RegEcx >> 8) & 0xff;
|
|
||||||
if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) {
|
|
||||||
CoreBits = (RegEax & 0x1f) - ThreadBits;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SubIndex++;
|
|
||||||
} while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TopologyLeafSupported) {
|
|
||||||
AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL);
|
|
||||||
MaxLogicProcessorsPerPackage = (RegEbx >> 16) & 0xff;
|
|
||||||
if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) {
|
|
||||||
AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &RegEax, NULL, NULL, NULL);
|
|
||||||
MaxCoresPerPackage = (RegEax >> 26) + 1;
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// Must be a single-core processor.
|
|
||||||
//
|
|
||||||
MaxCoresPerPackage = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadBits = (UINTN) (HighBitSet32 (MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1);
|
|
||||||
CoreBits = (UINTN) (HighBitSet32 (MaxCoresPerPackage - 1) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Location->Thread = ApicId & ~((-1) << ThreadBits);
|
|
||||||
Location->Core = (ApicId >> ThreadBits) & ~((-1) << CoreBits);
|
|
||||||
Location->Package = (ApicId >> (ThreadBits+ CoreBits));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets processor information on the requested processor at the instant this call is made.
|
Gets processor information on the requested processor at the instant this call is made.
|
||||||
|
|
||||||
|
@ -280,7 +161,12 @@ SmmAddProcessor (
|
||||||
gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID) {
|
gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID) {
|
||||||
gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId = ProcessorId;
|
gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId = ProcessorId;
|
||||||
gSmmCpuPrivate->ProcessorInfo[Index].StatusFlag = 0;
|
gSmmCpuPrivate->ProcessorInfo[Index].StatusFlag = 0;
|
||||||
SmmGetProcessorLocation ((UINT32)ProcessorId, &gSmmCpuPrivate->ProcessorInfo[Index].Location);
|
GetProcessorLocation (
|
||||||
|
(UINT32)ProcessorId,
|
||||||
|
&gSmmCpuPrivate->ProcessorInfo[Index].Location.Package,
|
||||||
|
&gSmmCpuPrivate->ProcessorInfo[Index].Location.Core,
|
||||||
|
&gSmmCpuPrivate->ProcessorInfo[Index].Location.Thread
|
||||||
|
);
|
||||||
|
|
||||||
*ProcessorNumber = Index;
|
*ProcessorNumber = Index;
|
||||||
gSmmCpuPrivate->Operation[Index] = SmmCpuAdd;
|
gSmmCpuPrivate->Operation[Index] = SmmCpuAdd;
|
||||||
|
|
Loading…
Reference in New Issue