mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-23 13:44:33 +02:00
UefiCpuPkg/CpuMpPei: Implementation of PeiGetProcessorInfo ()
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Feng Tian <feng.tian@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18007 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
a2cc8caead
commit
bf55f5b274
@ -15,6 +15,115 @@
|
|||||||
#include "PeiMpServices.h"
|
#include "PeiMpServices.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get CPU Package/Core/Thread location information.
|
||||||
|
|
||||||
|
@param InitialApicId CPU APIC ID
|
||||||
|
@param Location Pointer to CPU location information
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
ExtractProcessorLocation (
|
||||||
|
IN UINT32 InitialApicId,
|
||||||
|
OUT EFI_CPU_PHYSICAL_LOCATION *Location
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN TopologyLeafSupported;
|
||||||
|
UINTN ThreadBits;
|
||||||
|
UINTN CoreBits;
|
||||||
|
UINT32 RegEax;
|
||||||
|
UINT32 RegEbx;
|
||||||
|
UINT32 RegEcx;
|
||||||
|
UINT32 RegEdx;
|
||||||
|
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, &RegEdx);
|
||||||
|
if ((RegEdx & BIT28) == 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, &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 != 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);
|
||||||
|
ThreadBits = RegEax & 0x1f;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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 = InitialApicId & ~((-1) << ThreadBits);
|
||||||
|
Location->Core = (InitialApicId >> ThreadBits) & ~((-1) << CoreBits);
|
||||||
|
Location->Package = (InitialApicId >> (ThreadBits + CoreBits));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Find the current Processor number by APIC ID.
|
Find the current Processor number by APIC ID.
|
||||||
@ -124,6 +233,87 @@ PeiGetNumberOfProcessors (
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets detailed MP-related information on the requested processor at the
|
||||||
|
instant this call is made. This service may only be called from the BSP.
|
||||||
|
|
||||||
|
This service retrieves detailed MP-related information about any processor
|
||||||
|
on the platform. Note the following:
|
||||||
|
- The processor information may change during the course of a boot session.
|
||||||
|
- The information presented here is entirely MP related.
|
||||||
|
|
||||||
|
Information regarding the number of caches and their sizes, frequency of operation,
|
||||||
|
slot numbers is all considered platform-related information and is not provided
|
||||||
|
by this service.
|
||||||
|
|
||||||
|
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
||||||
|
published by the PEI Foundation.
|
||||||
|
@param[in] This Pointer to this instance of the PPI.
|
||||||
|
@param[in] ProcessorNumber Pointer to the total number of logical processors in
|
||||||
|
the system, including the BSP and disabled APs.
|
||||||
|
@param[out] ProcessorInfoBuffer Number of processors in the system that are enabled.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Processor information was returned.
|
||||||
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
|
@retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
|
||||||
|
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||||
|
ProcessorNumber does not exist in the platform.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
PeiGetProcessorInfo (
|
||||||
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
|
IN EFI_PEI_MP_SERVICES_PPI *This,
|
||||||
|
IN UINTN ProcessorNumber,
|
||||||
|
OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PEI_CPU_MP_DATA *PeiCpuMpData;
|
||||||
|
UINTN CallerNumber;
|
||||||
|
|
||||||
|
PeiCpuMpData = GetMpHobData ();
|
||||||
|
if (PeiCpuMpData == NULL) {
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check whether caller processor is BSP
|
||||||
|
//
|
||||||
|
PeiWhoAmI (PeiServices, This, &CallerNumber);
|
||||||
|
if (CallerNumber != PeiCpuMpData->BspNumber) {
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProcessorInfoBuffer == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessorInfoBuffer->ProcessorId = (UINT64) PeiCpuMpData->CpuData[ProcessorNumber].ApicId;
|
||||||
|
ProcessorInfoBuffer->StatusFlag = 0;
|
||||||
|
if (PeiCpuMpData->CpuData[ProcessorNumber].ApicId == GetInitialApicId()) {
|
||||||
|
ProcessorInfoBuffer->StatusFlag |= PROCESSOR_AS_BSP_BIT;
|
||||||
|
}
|
||||||
|
if (PeiCpuMpData->CpuData[ProcessorNumber].Health.Uint32 == 0) {
|
||||||
|
ProcessorInfoBuffer->StatusFlag |= PROCESSOR_HEALTH_STATUS_BIT;
|
||||||
|
}
|
||||||
|
if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {
|
||||||
|
ProcessorInfoBuffer->StatusFlag &= ~PROCESSOR_ENABLED_BIT;
|
||||||
|
} else {
|
||||||
|
ProcessorInfoBuffer->StatusFlag |= PROCESSOR_ENABLED_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get processor location information
|
||||||
|
//
|
||||||
|
ExtractProcessorLocation (PeiCpuMpData->CpuData[ProcessorNumber].ApicId, &ProcessorInfoBuffer->Location);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This return the handle number for the calling processor. This service may be
|
This return the handle number for the calling processor. This service may be
|
||||||
called from the BSP and APs.
|
called from the BSP and APs.
|
||||||
|
@ -60,6 +60,41 @@ PeiGetNumberOfProcessors (
|
|||||||
OUT UINTN *NumberOfEnabledProcessors
|
OUT UINTN *NumberOfEnabledProcessors
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets detailed MP-related information on the requested processor at the
|
||||||
|
instant this call is made. This service may only be called from the BSP.
|
||||||
|
|
||||||
|
This service retrieves detailed MP-related information about any processor
|
||||||
|
on the platform. Note the following:
|
||||||
|
- The processor information may change during the course of a boot session.
|
||||||
|
- The information presented here is entirely MP related.
|
||||||
|
|
||||||
|
Information regarding the number of caches and their sizes, frequency of operation,
|
||||||
|
slot numbers is all considered platform-related information and is not provided
|
||||||
|
by this service.
|
||||||
|
|
||||||
|
@param[in] PeiServices An indirect pointer to the PEI Services Table
|
||||||
|
published by the PEI Foundation.
|
||||||
|
@param[in] This Pointer to this instance of the PPI.
|
||||||
|
@param[in] ProcessorNumber Pointer to the total number of logical processors in
|
||||||
|
the system, including the BSP and disabled APs.
|
||||||
|
@param[out] ProcessorInfoBuffer Number of processors in the system that are enabled.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Processor information was returned.
|
||||||
|
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||||
|
@retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
|
||||||
|
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||||
|
ProcessorNumber does not exist in the platform.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
PeiGetProcessorInfo (
|
||||||
|
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||||
|
IN EFI_PEI_MP_SERVICES_PPI *This,
|
||||||
|
IN UINTN ProcessorNumber,
|
||||||
|
OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This return the handle number for the calling processor. This service may be
|
This return the handle number for the calling processor. This service may be
|
||||||
|
Loading…
x
Reference in New Issue
Block a user