Revision: 18007
http://sourceforge.net/p/edk2/code/18007
Author: vanjeff
Date: 2015-07-15 03:42:45 +0000 (Wed, 15 Jul 2015)
Log Message:
-----------
UefiCpuPkg/CpuMpPei: Implementation of PeiGetProcessorInfo ()
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <[email protected]>
Reviewed-by: Feng Tian <[email protected]>
Reviewed-by: Jiewen Yao <[email protected]>
Modified Paths:
--------------
trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.c
trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.h
Modified: trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.c
===================================================================
--- trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.c 2015-07-15 03:42:22 UTC
(rev 18006)
+++ trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.c 2015-07-15 03:42:45 UTC
(rev 18007)
@@ -15,7 +15,116 @@
#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.
@@ -125,6 +234,87 @@
}
/**
+ 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
called from the BSP and APs.
Modified: trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.h
===================================================================
--- trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.h 2015-07-15 03:42:22 UTC
(rev 18006)
+++ trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.h 2015-07-15 03:42:45 UTC
(rev 18007)
@@ -60,7 +60,42 @@
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
called from the BSP and APs.
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits