UefiCpuPkg/CpuMpPei: Consume MpInitLib to produce CPU MP PPI services

Consume MP initialize library to produce CPU MP PPI, it could simply the code.

Add STATIC for some internal functions to avoid build issue with the same
functions name in PeiMpInit instance. They will be removed by the next patch.

v4:
  1. Update BistData type from UINT32 to EFI_HEALTH_FLAGS.

v3:
  1. Rename MpInitLibSwitchBSP to MpInitLibSwitchBSP
  2. Add PeiMpInitLib.inf in DSC file

Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Michael Kinney <michael.d.kinney@intel.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Michael Kinney <michael.d.kinney@intel.com>
This commit is contained in:
Jeff Fan 2016-07-22 10:12:51 +08:00
parent ee78341e26
commit a1a4c7a467
6 changed files with 113 additions and 491 deletions

View File

@ -44,15 +44,18 @@ SecPlatformInformation2 (
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2 OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
) )
{ {
PEI_CPU_MP_DATA *PeiCpuMpData;
UINTN BistInformationSize; UINTN BistInformationSize;
UINTN CpuIndex; UINTN CpuIndex;
EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance; EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
EFI_PROCESSOR_INFORMATION ProcessorInfo;
EFI_HEALTH_FLAGS BistData;
UINTN NumberOfProcessors;
UINTN NumberOfEnabledProcessors;
PeiCpuMpData = GetMpHobData (); MpInitLibGetNumberOfProcessors(&NumberOfProcessors, &NumberOfEnabledProcessors);
BistInformationSize = sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2) + BistInformationSize = sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2) +
sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * PeiCpuMpData->CpuCount; sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * NumberOfProcessors;
// //
// return the information size if input buffer size is too small // return the information size if input buffer size is too small
// //
@ -61,11 +64,12 @@ SecPlatformInformation2 (
return EFI_BUFFER_TOO_SMALL; return EFI_BUFFER_TOO_SMALL;
} }
PlatformInformationRecord2->NumberOfCpus = PeiCpuMpData->CpuCount; PlatformInformationRecord2->NumberOfCpus = (UINT32)NumberOfProcessors;
CpuInstance = PlatformInformationRecord2->CpuInstance; CpuInstance = PlatformInformationRecord2->CpuInstance;
for (CpuIndex = 0; CpuIndex < PeiCpuMpData->CpuCount; CpuIndex ++) { for (CpuIndex = 0; CpuIndex < NumberOfProcessors; CpuIndex ++) {
CpuInstance[CpuIndex].CpuLocation = PeiCpuMpData->CpuData[CpuIndex].ApicId; MpInitLibGetProcessorInfo (CpuIndex, &ProcessorInfo, &BistData);
CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags = PeiCpuMpData->CpuData[CpuIndex].Health; CpuInstance[CpuIndex].CpuLocation = (UINT32) ProcessorInfo.ProcessorId;
CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags = BistData;
} }
return EFI_SUCCESS; return EFI_SUCCESS;
@ -152,13 +156,11 @@ GetBistInfoFromPpi (
or SEC Platform Information PPI. or SEC Platform Information PPI.
@param PeiServices Pointer to PEI Services Table @param PeiServices Pointer to PEI Services Table
@param PeiCpuMpData Pointer to PEI CPU MP Data
**/ **/
VOID VOID
CollectBistDataFromPpi ( CollectBistDataFromPpi (
IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_SERVICES **PeiServices
IN PEI_CPU_MP_DATA *PeiCpuMpData
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -170,7 +172,12 @@ CollectBistDataFromPpi (
EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance; EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance;
UINTN ProcessorNumber; UINTN ProcessorNumber;
UINTN CpuIndex; UINTN CpuIndex;
PEI_CPU_DATA *CpuData; EFI_PROCESSOR_INFORMATION ProcessorInfo;
EFI_HEALTH_FLAGS BistData;
UINTN NumberOfProcessors;
UINTN NumberOfEnabledProcessors;
MpInitLibGetNumberOfProcessors(&NumberOfProcessors, &NumberOfEnabledProcessors);
SecPlatformInformation2 = NULL; SecPlatformInformation2 = NULL;
SecPlatformInformation = NULL; SecPlatformInformation = NULL;
@ -215,21 +222,18 @@ CollectBistDataFromPpi (
DEBUG ((EFI_D_INFO, "Does not find any stored CPU BIST information from PPI!\n")); DEBUG ((EFI_D_INFO, "Does not find any stored CPU BIST information from PPI!\n"));
} }
} }
for (ProcessorNumber = 0; ProcessorNumber < PeiCpuMpData->CpuCount; ProcessorNumber ++) { for (ProcessorNumber = 0; ProcessorNumber < NumberOfProcessors; ProcessorNumber ++) {
CpuData = &PeiCpuMpData->CpuData[ProcessorNumber]; MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData);
for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex ++) { for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex ++) {
ASSERT (CpuInstance != NULL); ASSERT (CpuInstance != NULL);
if (CpuData->ApicId == CpuInstance[CpuIndex].CpuLocation) { if (ProcessorInfo.ProcessorId == CpuInstance[CpuIndex].CpuLocation) {
// //
// Update processor's BIST data if it is already stored before // Update processor's BIST data if it is already stored before
// //
CpuData->Health = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags; BistData = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags;
} }
} }
if (CpuData->Health.Uint32 == 0) { if (BistData.Uint32 != 0) {
CpuData->CpuHealthy = TRUE;
} else {
CpuData->CpuHealthy = FALSE;
// //
// Report Status Code that self test is failed // Report Status Code that self test is failed
// //
@ -239,14 +243,14 @@ CollectBistDataFromPpi (
); );
} }
DEBUG ((EFI_D_INFO, " APICID - 0x%08x, BIST - 0x%08x\n", DEBUG ((EFI_D_INFO, " APICID - 0x%08x, BIST - 0x%08x\n",
PeiCpuMpData->CpuData[ProcessorNumber].ApicId, ProcessorInfo.ProcessorId,
PeiCpuMpData->CpuData[ProcessorNumber].Health.Uint32 BistData
)); ));
} }
if (SecPlatformInformation2 != NULL && NumberOfData < PeiCpuMpData->CpuCount) { if (SecPlatformInformation2 != NULL && NumberOfData < NumberOfProcessors) {
// //
// Reinstall SecPlatformInformation2 PPI to include new BIST inforamtion // Reinstall SecPlatformInformation2 PPI to include new BIST information
// //
Status = PeiServicesReInstallPpi ( Status = PeiServicesReInstallPpi (
SecInformationDescriptor, SecInformationDescriptor,
@ -255,9 +259,10 @@ CollectBistDataFromPpi (
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
} else { } else {
// //
// Install SecPlatformInformation2 PPI to include new BIST inforamtion // Install SecPlatformInformation2 PPI to include new BIST information
// //
Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi); Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi);
ASSERT_EFI_ERROR(Status); ASSERT_EFI_ERROR(Status);
} }
} }

View File

@ -28,6 +28,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
@param PeiCpuMpData Pointer to PEI CPU MP Data @param PeiCpuMpData Pointer to PEI CPU MP Data
**/ **/
STATIC
VOID VOID
SortApicId ( SortApicId (
IN PEI_CPU_MP_DATA *PeiCpuMpData IN PEI_CPU_MP_DATA *PeiCpuMpData
@ -84,6 +85,7 @@ SortApicId (
@param Buffer Pointer to private data buffer. @param Buffer Pointer to private data buffer.
**/ **/
STATIC
VOID VOID
EFIAPI EFIAPI
ApFuncEnableX2Apic ( ApFuncEnableX2Apic (
@ -100,6 +102,7 @@ ApFuncEnableX2Apic (
@return The AP loop mode. @return The AP loop mode.
**/ **/
STATIC
UINT8 UINT8
GetApLoopMode ( GetApLoopMode (
OUT UINT16 *MonitorFilterSize OUT UINT16 *MonitorFilterSize
@ -170,6 +173,7 @@ GetMpHobData (
@param VolatileRegisters Returns buffer saved the volatile resisters @param VolatileRegisters Returns buffer saved the volatile resisters
**/ **/
STATIC
VOID VOID
SaveVolatileRegisters ( SaveVolatileRegisters (
OUT CPU_VOLATILE_REGISTERS *VolatileRegisters OUT CPU_VOLATILE_REGISTERS *VolatileRegisters
@ -203,6 +207,7 @@ SaveVolatileRegisters (
@param IsRestoreDr TRUE: Restore DRx if supported @param IsRestoreDr TRUE: Restore DRx if supported
FALSE: Do not restore DRx FALSE: Do not restore DRx
**/ **/
STATIC
VOID VOID
RestoreVolatileRegisters ( RestoreVolatileRegisters (
IN CPU_VOLATILE_REGISTERS *VolatileRegisters, IN CPU_VOLATILE_REGISTERS *VolatileRegisters,
@ -232,12 +237,42 @@ RestoreVolatileRegisters (
} }
} }
/**
Find the current Processor number by APIC ID.
@param PeiCpuMpData Pointer to PEI CPU MP Data
@param ProcessorNumber Return the pocessor number found
@retval EFI_SUCCESS ProcessorNumber is found and returned.
@retval EFI_NOT_FOUND ProcessorNumber is not found.
**/
STATIC
EFI_STATUS
GetProcessorNumber (
IN PEI_CPU_MP_DATA *PeiCpuMpData,
OUT UINTN *ProcessorNumber
)
{
UINTN TotalProcessorNumber;
UINTN Index;
TotalProcessorNumber = PeiCpuMpData->CpuCount;
for (Index = 0; Index < TotalProcessorNumber; Index ++) {
if (PeiCpuMpData->CpuData[Index].ApicId == GetInitialApicId ()) {
*ProcessorNumber = Index;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
/** /**
This function will be called from AP reset code if BSP uses WakeUpAP. This function will be called from AP reset code if BSP uses WakeUpAP.
@param ExchangeInfo Pointer to the MP exchange info buffer @param ExchangeInfo Pointer to the MP exchange info buffer
@param NumApsExecuting Number of current executing AP @param NumApsExecuting Number of current executing AP
**/ **/
STATIC
VOID VOID
EFIAPI EFIAPI
ApCFunction ( ApCFunction (
@ -407,6 +442,7 @@ WriteStartupSignal (
@param Procedure The function to be invoked by AP @param Procedure The function to be invoked by AP
@param ProcedureArgument The argument to be passed into AP function @param ProcedureArgument The argument to be passed into AP function
**/ **/
STATIC
VOID VOID
WakeUpAP ( WakeUpAP (
IN PEI_CPU_MP_DATA *PeiCpuMpData, IN PEI_CPU_MP_DATA *PeiCpuMpData,
@ -487,6 +523,7 @@ WakeUpAP (
@retval other Return wakeup buffer address below 1MB. @retval other Return wakeup buffer address below 1MB.
@retval -1 Cannot find free memory below 1MB. @retval -1 Cannot find free memory below 1MB.
**/ **/
STATIC
UINTN UINTN
GetWakeupBuffer ( GetWakeupBuffer (
IN UINTN WakeupBufferSize IN UINTN WakeupBufferSize
@ -556,6 +593,7 @@ GetWakeupBuffer (
@param PeiCpuMpData Pointer to PEI CPU MP Data @param PeiCpuMpData Pointer to PEI CPU MP Data
**/ **/
STATIC
VOID VOID
BackupAndPrepareWakeupBuffer( BackupAndPrepareWakeupBuffer(
IN PEI_CPU_MP_DATA *PeiCpuMpData IN PEI_CPU_MP_DATA *PeiCpuMpData
@ -578,6 +616,7 @@ BackupAndPrepareWakeupBuffer(
@param PeiCpuMpData Pointer to PEI CPU MP Data @param PeiCpuMpData Pointer to PEI CPU MP Data
**/ **/
STATIC
VOID VOID
RestoreWakeupBuffer( RestoreWakeupBuffer(
IN PEI_CPU_MP_DATA *PeiCpuMpData IN PEI_CPU_MP_DATA *PeiCpuMpData
@ -760,6 +799,7 @@ PrepareAPStartupVector (
@retval EFI_SUCCESS When everything is OK. @retval EFI_SUCCESS When everything is OK.
**/ **/
STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
CpuMpEndOfPeiCallback ( CpuMpEndOfPeiCallback (
@ -829,8 +869,7 @@ CpuMpPeimInit (
IN CONST EFI_PEI_SERVICES **PeiServices IN CONST EFI_PEI_SERVICES **PeiServices
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
PEI_CPU_MP_DATA *PeiCpuMpData;
EFI_VECTOR_HANDOFF_INFO *VectorInfo; EFI_VECTOR_HANDOFF_INFO *VectorInfo;
EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi; EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;
@ -849,31 +888,18 @@ CpuMpPeimInit (
} }
Status = InitializeCpuExceptionHandlers (VectorInfo); Status = InitializeCpuExceptionHandlers (VectorInfo);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
// //
// Get wakeup buffer and copy AP reset code in it // Wakeup APs to do initialization
// //
PeiCpuMpData = PrepareAPStartupVector (); Status = MpInitLibInitialize ();
// ASSERT_EFI_ERROR (Status);
// Count processor number and collect processor information
//
CountProcessorNumber (PeiCpuMpData);
//
// Build location of PEI CPU MP DATA buffer in HOB
//
BuildGuidDataHob (
&gEfiCallerIdGuid,
(VOID *)&PeiCpuMpData,
sizeof(UINT64)
);
// //
// Update and publish CPU BIST information // Update and publish CPU BIST information
// //
CollectBistDataFromPpi (PeiServices, PeiCpuMpData); CollectBistDataFromPpi (PeiServices);
//
// register an event for EndOfPei
//
Status = PeiServicesNotifyPpi (&mNotifyList);
ASSERT_EFI_ERROR (Status);
// //
// Install CPU MP PPI // Install CPU MP PPI
// //

View File

@ -42,6 +42,7 @@
#include <Library/UefiCpuLib.h> #include <Library/UefiCpuLib.h>
#include <Library/CpuLib.h> #include <Library/CpuLib.h>
#include <Library/CpuExceptionHandlerLib.h> #include <Library/CpuExceptionHandlerLib.h>
#include <Library/MpInitLib.h>
#include "Microcode.h" #include "Microcode.h"
@ -187,6 +188,7 @@ AsmInitializeGdt (
@param PeiCpuMpData Pointer to PEI CPU MP Data @param PeiCpuMpData Pointer to PEI CPU MP Data
**/ **/
STATIC
VOID VOID
BackupAndPrepareWakeupBuffer( BackupAndPrepareWakeupBuffer(
IN PEI_CPU_MP_DATA *PeiCpuMpData IN PEI_CPU_MP_DATA *PeiCpuMpData
@ -197,6 +199,7 @@ BackupAndPrepareWakeupBuffer(
@param PeiCpuMpData Pointer to PEI CPU MP Data @param PeiCpuMpData Pointer to PEI CPU MP Data
**/ **/
STATIC
VOID VOID
RestoreWakeupBuffer( RestoreWakeupBuffer(
IN PEI_CPU_MP_DATA *PeiCpuMpData IN PEI_CPU_MP_DATA *PeiCpuMpData
@ -215,6 +218,7 @@ RestoreWakeupBuffer(
@retval EFI_SUCCESS When everything is OK. @retval EFI_SUCCESS When everything is OK.
**/ **/
STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
CpuMpEndOfPeiCallback ( CpuMpEndOfPeiCallback (
@ -233,6 +237,7 @@ CpuMpEndOfPeiCallback (
@param Procedure The function to be invoked by AP @param Procedure The function to be invoked by AP
@param ProcedureArgument The argument to be passed into AP function @param ProcedureArgument The argument to be passed into AP function
**/ **/
STATIC
VOID VOID
WakeUpAP ( WakeUpAP (
IN PEI_CPU_MP_DATA *PeiCpuMpData, IN PEI_CPU_MP_DATA *PeiCpuMpData,
@ -261,6 +266,7 @@ GetMpHobData (
@retval EFI_SUCCESS ProcessorNumber is found and returned. @retval EFI_SUCCESS ProcessorNumber is found and returned.
@retval EFI_NOT_FOUND ProcessorNumber is not found. @retval EFI_NOT_FOUND ProcessorNumber is not found.
**/ **/
STATIC
EFI_STATUS EFI_STATUS
GetProcessorNumber ( GetProcessorNumber (
IN PEI_CPU_MP_DATA *PeiCpuMpData, IN PEI_CPU_MP_DATA *PeiCpuMpData,
@ -274,13 +280,11 @@ GetProcessorNumber (
or SEC Platform Information PPI. or SEC Platform Information PPI.
@param PeiServices Pointer to PEI Services Table @param PeiServices Pointer to PEI Services Table
@param PeiCpuMpData Pointer to PEI CPU MP Data
**/ **/
VOID VOID
CollectBistDataFromPpi ( CollectBistDataFromPpi (
IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_SERVICES **PeiServices
IN PEI_CPU_MP_DATA *PeiCpuMpData
); );
/** /**

View File

@ -67,6 +67,7 @@
UefiCpuLib UefiCpuLib
CpuLib CpuLib
CpuExceptionHandlerLib CpuExceptionHandlerLib
MpInitLib
[Ppis] [Ppis]
gEfiPeiMpServicesPpiGuid ## PRODUCES gEfiPeiMpServicesPpiGuid ## PRODUCES

View File

@ -33,12 +33,14 @@ EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc = {
&mMpServicesPpi &mMpServicesPpi
}; };
/** /**
Get CPU Package/Core/Thread location information. Get CPU Package/Core/Thread location information.
@param InitialApicId CPU APIC ID @param InitialApicId CPU APIC ID
@param Location Pointer to CPU location information @param Location Pointer to CPU location information
**/ **/
STATIC
VOID VOID
ExtractProcessorLocation ( ExtractProcessorLocation (
IN UINT32 InitialApicId, IN UINT32 InitialApicId,
@ -143,34 +145,6 @@ ExtractProcessorLocation (
Location->Package = (InitialApicId >> (ThreadBits + CoreBits)); Location->Package = (InitialApicId >> (ThreadBits + CoreBits));
} }
/**
Find the current Processor number by APIC ID.
@param PeiCpuMpData Pointer to PEI CPU MP Data
@param ProcessorNumber Return the pocessor number found
@retval EFI_SUCCESS ProcessorNumber is found and returned.
@retval EFI_NOT_FOUND ProcessorNumber is not found.
**/
EFI_STATUS
GetProcessorNumber (
IN PEI_CPU_MP_DATA *PeiCpuMpData,
OUT UINTN *ProcessorNumber
)
{
UINTN TotalProcessorNumber;
UINTN Index;
TotalProcessorNumber = PeiCpuMpData->CpuCount;
for (Index = 0; Index < TotalProcessorNumber; Index ++) {
if (PeiCpuMpData->CpuData[Index].ApicId == GetInitialApicId ()) {
*ProcessorNumber = Index;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
/** /**
Worker function for SwitchBSP(). Worker function for SwitchBSP().
@ -178,6 +152,7 @@ GetProcessorNumber (
@param Buffer Pointer to CPU MP Data @param Buffer Pointer to CPU MP Data
**/ **/
STATIC
VOID VOID
EFIAPI EFIAPI
FutureBSPProc ( FutureBSPProc (
@ -233,41 +208,14 @@ PeiGetNumberOfProcessors (
OUT UINTN *NumberOfEnabledProcessors OUT UINTN *NumberOfEnabledProcessors
) )
{ {
PEI_CPU_MP_DATA *PeiCpuMpData;
UINTN CallerNumber;
UINTN ProcessorNumber;
UINTN EnabledProcessorNumber;
UINTN Index;
PeiCpuMpData = GetMpHobData ();
if (PeiCpuMpData == NULL) {
return EFI_NOT_FOUND;
}
if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) { if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
// return MpInitLibGetNumberOfProcessors (
// Check whether caller processor is BSP NumberOfProcessors,
// NumberOfEnabledProcessors
PeiWhoAmI (PeiServices, This, &CallerNumber); );
if (CallerNumber != PeiCpuMpData->BspNumber) {
return EFI_DEVICE_ERROR;
}
ProcessorNumber = PeiCpuMpData->CpuCount;
EnabledProcessorNumber = 0;
for (Index = 0; Index < ProcessorNumber; Index++) {
if (PeiCpuMpData->CpuData[Index].State != CpuStateDisabled) {
EnabledProcessorNumber ++;
}
}
*NumberOfProcessors = ProcessorNumber;
*NumberOfEnabledProcessors = EnabledProcessorNumber;
return EFI_SUCCESS;
} }
/** /**
@ -305,50 +253,7 @@ PeiGetProcessorInfo (
OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
) )
{ {
PEI_CPU_MP_DATA *PeiCpuMpData; return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL);
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].CpuHealthy) {
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;
} }
/** /**
@ -425,131 +330,14 @@ PeiStartupAllAPs (
IN VOID *ProcedureArgument OPTIONAL IN VOID *ProcedureArgument OPTIONAL
) )
{ {
PEI_CPU_MP_DATA *PeiCpuMpData; return MpInitLibStartupAllAPs (
UINTN ProcessorNumber; Procedure,
UINTN Index; SingleThread,
UINTN CallerNumber; NULL,
BOOLEAN HasEnabledAp; TimeoutInMicroSeconds,
BOOLEAN HasEnabledIdleAp; ProcedureArgument,
volatile UINT32 *FinishedCount; NULL
EFI_STATUS Status; );
UINTN WaitCountIndex;
UINTN WaitCountNumber;
PeiCpuMpData = GetMpHobData ();
if (PeiCpuMpData == NULL) {
return EFI_NOT_FOUND;
}
if (Procedure == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Check whether caller processor is BSP
//
PeiWhoAmI (PeiServices, This, &CallerNumber);
if (CallerNumber != PeiCpuMpData->BspNumber) {
return EFI_DEVICE_ERROR;
}
ProcessorNumber = PeiCpuMpData->CpuCount;
HasEnabledAp = FALSE;
HasEnabledIdleAp = FALSE;
for (Index = 0; Index < ProcessorNumber; Index ++) {
if (Index == CallerNumber) {
//
// Skip BSP
//
continue;
}
if (PeiCpuMpData->CpuData[Index].State != CpuStateDisabled) {
HasEnabledAp = TRUE;
if (PeiCpuMpData->CpuData[Index].State != CpuStateBusy) {
HasEnabledIdleAp = TRUE;
}
}
}
if (!HasEnabledAp) {
//
// If no enabled AP exists, return EFI_NOT_STARTED.
//
return EFI_NOT_STARTED;
}
if (!HasEnabledIdleAp) {
//
// If any enabled APs are busy, return EFI_NOT_READY.
//
return EFI_NOT_READY;
}
if (PeiCpuMpData->EndOfPeiFlag) {
//
// Backup original data and copy AP reset vector in it
//
BackupAndPrepareWakeupBuffer(PeiCpuMpData);
}
WaitCountNumber = TimeoutInMicroSeconds / CPU_CHECK_AP_INTERVAL + 1;
WaitCountIndex = 0;
FinishedCount = &PeiCpuMpData->FinishedCount;
if (!SingleThread) {
WakeUpAP (PeiCpuMpData, TRUE, 0, Procedure, ProcedureArgument);
//
// Wait to finish
//
if (TimeoutInMicroSeconds == 0) {
while (*FinishedCount < ProcessorNumber - 1) {
CpuPause ();
}
Status = EFI_SUCCESS;
} else {
Status = EFI_TIMEOUT;
for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {
MicroSecondDelay (CPU_CHECK_AP_INTERVAL);
if (*FinishedCount >= ProcessorNumber - 1) {
Status = EFI_SUCCESS;
break;
}
}
}
} else {
Status = EFI_SUCCESS;
for (Index = 0; Index < ProcessorNumber; Index++) {
if (Index == CallerNumber) {
continue;
}
WakeUpAP (PeiCpuMpData, FALSE, Index, Procedure, ProcedureArgument);
//
// Wait to finish
//
if (TimeoutInMicroSeconds == 0) {
while (*FinishedCount < 1) {
CpuPause ();
}
} else {
for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {
MicroSecondDelay (CPU_CHECK_AP_INTERVAL);
if (*FinishedCount >= 1) {
break;
}
}
if (WaitCountIndex == WaitCountNumber) {
Status = EFI_TIMEOUT;
}
}
}
}
if (PeiCpuMpData->EndOfPeiFlag) {
//
// Restore original data
//
RestoreWakeupBuffer(PeiCpuMpData);
}
return Status;
} }
/** /**
@ -609,81 +397,14 @@ PeiStartupThisAP (
IN VOID *ProcedureArgument OPTIONAL IN VOID *ProcedureArgument OPTIONAL
) )
{ {
PEI_CPU_MP_DATA *PeiCpuMpData; return MpInitLibStartupThisAP (
UINTN CallerNumber; Procedure,
volatile UINT32 *FinishedCount; ProcessorNumber,
EFI_STATUS Status; NULL,
UINTN WaitCountIndex; TimeoutInMicroseconds,
UINTN WaitCountNumber; ProcedureArgument,
NULL
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 (ProcessorNumber >= PeiCpuMpData->CpuCount) {
return EFI_NOT_FOUND;
}
if (ProcessorNumber == PeiCpuMpData->BspNumber || Procedure == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Check whether specified AP is disabled
//
if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {
return EFI_INVALID_PARAMETER;
}
if (PeiCpuMpData->EndOfPeiFlag) {
//
// Backup original data and copy AP reset vector in it
//
BackupAndPrepareWakeupBuffer(PeiCpuMpData);
}
WaitCountNumber = TimeoutInMicroseconds / CPU_CHECK_AP_INTERVAL + 1;
WaitCountIndex = 0;
FinishedCount = &PeiCpuMpData->FinishedCount;
WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument);
//
// Wait to finish
//
if (TimeoutInMicroseconds == 0) {
while (*FinishedCount < 1) {
CpuPause() ;
}
Status = EFI_SUCCESS;
} else {
Status = EFI_TIMEOUT;
for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {
MicroSecondDelay (CPU_CHECK_AP_INTERVAL);
if (*FinishedCount >= 1) {
Status = EFI_SUCCESS;
break;
}
}
}
if (PeiCpuMpData->EndOfPeiFlag) {
//
// Backup original data and copy AP reset vector in it
//
RestoreWakeupBuffer(PeiCpuMpData);
}
return Status;
} }
/** /**
@ -729,97 +450,7 @@ PeiSwitchBSP (
IN BOOLEAN EnableOldBSP IN BOOLEAN EnableOldBSP
) )
{ {
PEI_CPU_MP_DATA *PeiCpuMpData; return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP);
UINTN CallerNumber;
MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
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_SUCCESS;
}
if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
return EFI_NOT_FOUND;
}
//
// Check whether specified AP is disabled
//
if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {
return EFI_INVALID_PARAMETER;
}
//
// Check whether ProcessorNumber specifies the current BSP
//
if (ProcessorNumber == PeiCpuMpData->BspNumber) {
return EFI_INVALID_PARAMETER;
}
//
// Check whether specified AP is busy
//
if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateBusy) {
return EFI_NOT_READY;
}
//
// Clear the BSP bit of MSR_IA32_APIC_BASE
//
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
ApicBaseMsr.Bits.BSP = 0;
AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
PeiCpuMpData->BSPInfo.State = CPU_SWITCH_STATE_IDLE;
PeiCpuMpData->APInfo.State = CPU_SWITCH_STATE_IDLE;
if (PeiCpuMpData->EndOfPeiFlag) {
//
// Backup original data and copy AP reset vector in it
//
BackupAndPrepareWakeupBuffer(PeiCpuMpData);
}
//
// Need to wakeUp AP (future BSP).
//
WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, FutureBSPProc, PeiCpuMpData);
AsmExchangeRole (&PeiCpuMpData->BSPInfo, &PeiCpuMpData->APInfo);
if (PeiCpuMpData->EndOfPeiFlag) {
//
// Backup original data and copy AP reset vector in it
//
RestoreWakeupBuffer(PeiCpuMpData);
}
//
// Set the BSP bit of MSR_IA32_APIC_BASE on new BSP
//
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
ApicBaseMsr.Bits.BSP = 1;
AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
//
// Set old BSP enable state
//
if (!EnableOldBSP) {
PeiCpuMpData->CpuData[PeiCpuMpData->BspNumber].State = CpuStateDisabled;
}
//
// Save new BSP number
//
PeiCpuMpData->BspNumber = (UINT32) ProcessorNumber;
return EFI_SUCCESS;
} }
/** /**
@ -871,41 +502,7 @@ PeiEnableDisableAP (
IN UINT32 *HealthFlag OPTIONAL IN UINT32 *HealthFlag OPTIONAL
) )
{ {
PEI_CPU_MP_DATA *PeiCpuMpData; return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag);
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 (ProcessorNumber == PeiCpuMpData->BspNumber) {
return EFI_INVALID_PARAMETER;
}
if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
return EFI_NOT_FOUND;
}
if (!EnableAP) {
PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateDisabled;
} else {
PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;
}
if (HealthFlag != NULL) {
PeiCpuMpData->CpuData[ProcessorNumber].CpuHealthy =
(BOOLEAN) ((*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT) != 0);
}
return EFI_SUCCESS;
} }
/** /**
@ -940,17 +537,5 @@ PeiWhoAmI (
OUT UINTN *ProcessorNumber OUT UINTN *ProcessorNumber
) )
{ {
PEI_CPU_MP_DATA *PeiCpuMpData; return MpInitLibWhoAmI (ProcessorNumber);
PeiCpuMpData = GetMpHobData ();
if (PeiCpuMpData == NULL) {
return EFI_NOT_FOUND;
}
if (ProcessorNumber == NULL) {
return EFI_INVALID_PARAMETER;
}
return GetProcessorNumber (PeiCpuMpData, ProcessorNumber);
} }

View File

@ -70,6 +70,7 @@
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
[LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM] [LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM]
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf