(UINTN) mGdtEntries
};
+/**
+ Sort the APIC ID of all processors.
+
+ This function sorts the APIC ID of all processors so that processor number is
+ assigned in the ascending order of APIC ID which eases MP debugging.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+**/
+VOID
+SortApicId (
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ )
+{
+ UINTN Index1;
+ UINTN Index2;
+ UINTN Index3;
+ UINT32 ApicId;
+ EFI_HEALTH_FLAGS Health;
+ UINT32 ApCount;
+
+ ApCount = PeiCpuMpData->CpuCount - 1;
+
+ if (ApCount != 0) {
+ for (Index1 = 0; Index1 < ApCount; Index1++) {
+ Index3 = Index1;
+ //
+ // Sort key is the hardware default APIC ID
+ //
+ ApicId = PeiCpuMpData->CpuData[Index1].ApicId;
+ for (Index2 = Index1 + 1; Index2 <= ApCount; Index2++) {
+ if (ApicId > PeiCpuMpData->CpuData[Index2].ApicId) {
+ Index3 = Index2;
+ ApicId = PeiCpuMpData->CpuData[Index2].ApicId;
+ }
+ }
+ if (Index3 != Index1) {
+ PeiCpuMpData->CpuData[Index3].ApicId = PeiCpuMpData->CpuData[Index1].ApicId;
+ PeiCpuMpData->CpuData[Index1].ApicId = ApicId;
+ Health = PeiCpuMpData->CpuData[Index3].Health;
+ PeiCpuMpData->CpuData[Index3].Health = PeiCpuMpData->CpuData[Index1].Health;
+ PeiCpuMpData->CpuData[Index1].Health = Health;
+ }
+ }
+
+ //
+ // Get the processor number for the BSP
+ //
+ ApicId = GetInitialApicId ();
+ for (Index1 = 0; Index1 < PeiCpuMpData->CpuCount; Index1++) {
+ if (PeiCpuMpData->CpuData[Index1].ApicId == ApicId) {
+ PeiCpuMpData->BspNumber = (UINT32) Index1;
+ break;
+ }
+ }
+ }
+}
+
+/**
+ Get CPU MP Data pointer from the Guided HOB.
+
+ @return Pointer to Pointer to PEI CPU MP Data
+**/
+PEI_CPU_MP_DATA *
+GetMpHobData (
+ VOID
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VOID *DataInHob;
+ PEI_CPU_MP_DATA *CpuMpData;
+
+ CpuMpData = NULL;
+ GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);
+ if (GuidHob != NULL) {
+ DataInHob = GET_GUID_HOB_DATA (GuidHob);
+ CpuMpData = (PEI_CPU_MP_DATA *)(*(UINTN *)DataInHob);
+ }
+ ASSERT (CpuMpData != NULL);
+ return CpuMpData;
+}
+
/**
This function will be called from AP reset code if BSP uses WakeUpAP.
)
{
PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINTN ProcessorNumber;
+ EFI_AP_PROCEDURE Procedure;
UINTN BistData;
PeiCpuMpData = ExchangeInfo->PeiCpuMpData;
BistData = *(UINTN *) (PeiCpuMpData->Buffer + NumApsExecuting * PeiCpuMpData->CpuApStackSize - sizeof (UINTN));
PeiCpuMpData->CpuData[NumApsExecuting].ApicId = GetInitialApicId ();
PeiCpuMpData->CpuData[NumApsExecuting].Health.Uint32 = (UINT32) BistData;
+ //
+ // Sync BSP's Mtrr table to all wakeup APs and load microcode on APs.
+ //
+ MtrrSetAllMtrrs (&PeiCpuMpData->MtrrTable);
+ MicrocodeDetect ();
+ } else {
+ //
+ // Execute AP function if AP is not disabled
+ //
+ GetProcessorNumber (PeiCpuMpData, &ProcessorNumber);
+ if ((PeiCpuMpData->CpuData[ProcessorNumber].State != CpuStateDisabled) &&
+ (PeiCpuMpData->ApFunction != 0)) {
+ PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateBusy;
+ Procedure = (EFI_AP_PROCEDURE)(UINTN)PeiCpuMpData->ApFunction;
+ Procedure ((VOID *)(UINTN)PeiCpuMpData->ApFunctionArgument);
+ PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;
+ }
}
//
IN PEI_CPU_MP_DATA *PeiCpuMpData
)
{
-
+ //
+ // Load Microcode on BSP
+ //
+ MicrocodeDetect ();
+ //
+ // Store BSP's MTRR setting
+ //
+ MtrrGetAllMtrrs (&PeiCpuMpData->MtrrTable);
//
// Send broadcast IPI to APs to wakeup APs
//
MicroSecondDelay (PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
PeiCpuMpData->InitFlag = 0;
PeiCpuMpData->CpuCount += (UINT32) PeiCpuMpData->MpCpuExchangeInfo->NumApsExecuting;
+ //
+ // Sort BSP/Aps by CPU APIC ID in ascending order
+ //
+ SortApicId (PeiCpuMpData);
DEBUG ((EFI_D_INFO, "CpuMpPei: Find %d processors in system.\n", PeiCpuMpData->CpuCount));
return PeiCpuMpData->CpuCount;
// Count processor number and collect processor information
//
ProcessorCount = CountProcessorNumber (PeiCpuMpData);
+ //
+ // Build location of PEI CPU MP DATA buffer in HOB
+ //
+ BuildGuidDataHob (
+ &gEfiCallerIdGuid,
+ (VOID *)&PeiCpuMpData,
+ sizeof(UINT64)
+ );
+ //
+ // Update and publish CPU BIST information
+ //
+ CollectBistDataFromPpi (PeiServices, PeiCpuMpData);
return EFI_SUCCESS;
}