This function will be called from AP reset code if BSP uses WakeUpAP.\r
\r
@param ExchangeInfo Pointer to the MP exchange info buffer\r
- @param NumApsExecuting Number of curret executing AP\r
+ @param NumApsExecuting Number of current executing AP\r
**/\r
VOID\r
EFIAPI\r
\r
PeiCpuMpData = ExchangeInfo->PeiCpuMpData;\r
if (PeiCpuMpData->InitFlag) {\r
+ ProcessorNumber = NumApsExecuting;\r
+ //\r
+ // Sync BSP's Control registers to APs\r
+ //\r
+ RestoreVolatileRegisters (&PeiCpuMpData->CpuData[0].VolatileRegisters, FALSE);\r
//\r
// This is first time AP wakeup, get BIST information from AP stack\r
//\r
- BistData = *(UINTN *) (PeiCpuMpData->Buffer + NumApsExecuting * PeiCpuMpData->CpuApStackSize - sizeof (UINTN));\r
- PeiCpuMpData->CpuData[NumApsExecuting].Health.Uint32 = (UINT32) BistData;\r
- PeiCpuMpData->CpuData[NumApsExecuting].ApicId = GetInitialApicId ();\r
- if (PeiCpuMpData->CpuData[NumApsExecuting].ApicId >= 0xFF) {\r
+ BistData = *(UINTN *) (PeiCpuMpData->Buffer + ProcessorNumber * PeiCpuMpData->CpuApStackSize - sizeof (UINTN));\r
+ PeiCpuMpData->CpuData[ProcessorNumber].Health.Uint32 = (UINT32) BistData;\r
+ PeiCpuMpData->CpuData[ProcessorNumber].ApicId = GetInitialApicId ();\r
+ if (PeiCpuMpData->CpuData[ProcessorNumber].ApicId >= 0xFF) {\r
//\r
// Set x2APIC mode if there are any logical processor reporting\r
// an APIC ID of 255 or greater.\r
//\r
MtrrSetAllMtrrs (&PeiCpuMpData->MtrrTable);\r
MicrocodeDetect ();\r
+ PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;\r
} else {\r
//\r
// Execute AP function if AP is not disabled\r
//\r
GetProcessorNumber (PeiCpuMpData, &ProcessorNumber);\r
+ //\r
+ // Restore AP's volatile registers saved\r
+ //\r
+ RestoreVolatileRegisters (&PeiCpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);\r
+\r
if ((PeiCpuMpData->CpuData[ProcessorNumber].State != CpuStateDisabled) &&\r
(PeiCpuMpData->ApFunction != 0)) {\r
PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateBusy;\r
Procedure = (EFI_AP_PROCEDURE)(UINTN)PeiCpuMpData->ApFunction;\r
+ //\r
+ // Invoke AP function here\r
+ //\r
Procedure ((VOID *)(UINTN)PeiCpuMpData->ApFunctionArgument);\r
PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;\r
}\r
//\r
InterlockedIncrement ((UINT32 *)&PeiCpuMpData->FinishedCount);\r
\r
+ //\r
+ // Save AP volatile registers\r
+ //\r
+ SaveVolatileRegisters (&PeiCpuMpData->CpuData[ProcessorNumber].VolatileRegisters);\r
+\r
AsmCliHltLoop ();\r
}\r
\r
PeiCpuMpData->CpuData[0].Health.Uint32 = 0;\r
PeiCpuMpData->EndOfPeiFlag = FALSE;\r
InitializeSpinLock(&PeiCpuMpData->MpLock);\r
+ SaveVolatileRegisters (&PeiCpuMpData->CpuData[0].VolatileRegisters);\r
CopyMem (&PeiCpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP));\r
\r
//\r
EFI_PEI_HOB_POINTERS Hob;\r
EFI_HOB_MEMORY_ALLOCATION *MemoryHob;\r
\r
- DEBUG ((EFI_D_INFO, "CpuMpPei: CpuMpEndOfPeiCallback () invokded\n"));\r
+ DEBUG ((EFI_D_INFO, "CpuMpPei: CpuMpEndOfPeiCallback () invoked\n"));\r
\r
Status = PeiServicesGetBootMode (&BootMode);\r
ASSERT_EFI_ERROR (Status);\r