VOID\r
)\r
{\r
+ UINT32 MaxLogicalProcessorNumber;\r
+ UINT32 ApStackSize;\r
MP_ASSEMBLY_ADDRESS_MAP AddressMap;\r
+ UINTN BufferSize;\r
UINT32 MonitorFilterSize;\r
+ VOID *MpBuffer;\r
+ UINTN Buffer;\r
+ CPU_MP_DATA *CpuMpData;\r
UINT8 ApLoopMode;\r
+ UINT8 *MonitorBuffer;\r
UINTN ApResetVectorSize;\r
+ UINTN BackupBufferAddr;\r
+ MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber);\r
\r
AsmGetAddressMap (&AddressMap);\r
ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);\r
+ ApStackSize = PcdGet32(PcdCpuApStackSize);\r
ApLoopMode = GetApLoopMode (&MonitorFilterSize);\r
\r
+ BufferSize = ApStackSize * MaxLogicalProcessorNumber;\r
+ BufferSize += MonitorFilterSize * MaxLogicalProcessorNumber;\r
+ BufferSize += sizeof (CPU_MP_DATA);\r
+ BufferSize += ApResetVectorSize;\r
+ BufferSize += (sizeof (CPU_AP_DATA) + sizeof (CPU_INFO_IN_HOB))* MaxLogicalProcessorNumber;\r
+ MpBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));\r
+ ASSERT (MpBuffer != NULL);\r
+ ZeroMem (MpBuffer, BufferSize);\r
+ Buffer = (UINTN) MpBuffer;\r
+\r
+ MonitorBuffer = (UINT8 *) (Buffer + ApStackSize * MaxLogicalProcessorNumber);\r
+ BackupBufferAddr = (UINTN) MonitorBuffer + MonitorFilterSize * MaxLogicalProcessorNumber;\r
+ CpuMpData = (CPU_MP_DATA *) (BackupBufferAddr + ApResetVectorSize);\r
+ CpuMpData->Buffer = Buffer;\r
+ CpuMpData->CpuApStackSize = ApStackSize;\r
+ CpuMpData->BackupBuffer = BackupBufferAddr;\r
+ CpuMpData->BackupBufferSize = ApResetVectorSize;\r
+ CpuMpData->EndOfPeiFlag = FALSE;\r
+ CpuMpData->WakeupBuffer = (UINTN) -1;\r
+ CpuMpData->CpuCount = 1;\r
+ CpuMpData->BspNumber = 0;\r
+ CpuMpData->WaitEvent = NULL;\r
+ CpuMpData->CpuData = (CPU_AP_DATA *) (CpuMpData + 1);\r
+ CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);\r
+ InitializeSpinLock(&CpuMpData->MpLock);\r
+ //\r
+ // Save assembly code information\r
+ //\r
+ CopyMem (&CpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP));\r
+ //\r
+ // Finally set AP loop mode\r
+ //\r
+ CpuMpData->ApLoopMode = ApLoopMode;\r
+ DEBUG ((DEBUG_INFO, "AP Loop Mode is %d\n", CpuMpData->ApLoopMode));\r
+ //\r
+ // Store BSP's MTRR setting\r
+ //\r
+ MtrrGetAllMtrrs (&CpuMpData->MtrrTable);\r
+\r
return EFI_SUCCESS;\r
}\r
\r
ApInRunLoop = 3\r
} AP_LOOP_MODE;\r
\r
+//\r
+// AP initialization state during APs wakeup\r
+//\r
+typedef enum {\r
+ ApInitConfig = 1,\r
+ ApInitReconfig = 2,\r
+ ApInitDone = 3\r
+} AP_INIT_STATE;\r
+\r
+//\r
+// AP related data\r
+//\r
+typedef struct {\r
+ SPIN_LOCK ApLock;\r
+ volatile UINT32 *StartupApSignal;\r
+ volatile UINTN ApFunction;\r
+ volatile UINTN ApFunctionArgument;\r
+ UINT32 InitialApicId;\r
+ UINT32 ApicId;\r
+ UINT32 Health;\r
+ BOOLEAN CpuHealthy;\r
+ BOOLEAN Waiting;\r
+ BOOLEAN *Finished;\r
+ UINT64 ExpectedTime;\r
+ UINT64 CurrentTime;\r
+ UINT64 TotalTime;\r
+ EFI_EVENT WaitEvent;\r
+} CPU_AP_DATA;\r
+\r
+//\r
+// Basic CPU information saved in Guided HOB.\r
+// Because the contents will be shard between PEI and DXE,\r
+// we need to make sure the each fields offset same in different\r
+// architecture.\r
+//\r
+typedef struct {\r
+ UINT32 InitialApicId;\r
+ UINT32 ApicId;\r
+ UINT32 Health;\r
+} CPU_INFO_IN_HOB;\r
+\r
//\r
// AP reset code information including code address and size,\r
// this structure will be shared be C code and assembly code.\r
UINTN RelocateApLoopFuncSize;\r
} MP_ASSEMBLY_ADDRESS_MAP;\r
\r
+typedef struct _CPU_MP_DATA CPU_MP_DATA;\r
+\r
#pragma pack(1)\r
\r
//\r
UINTN DataSegment;\r
UINTN EnableExecuteDisable;\r
UINTN Cr3;\r
+ CPU_MP_DATA *CpuMpData;\r
} MP_CPU_EXCHANGE_INFO;\r
\r
#pragma pack()\r
+\r
+//\r
+// CPU MP Data save in memory\r
+//\r
+struct _CPU_MP_DATA {\r
+ UINT64 CpuInfoInHob;\r
+ UINT32 CpuCount;\r
+ UINT32 BspNumber;\r
+ //\r
+ // The above fields data will be passed from PEI to DXE\r
+ // Please make sure the fields offset same in the different\r
+ // architecture.\r
+ //\r
+ SPIN_LOCK MpLock;\r
+ UINTN Buffer;\r
+ UINTN CpuApStackSize;\r
+ MP_ASSEMBLY_ADDRESS_MAP AddressMap;\r
+ UINTN WakeupBuffer;\r
+ UINTN BackupBuffer;\r
+ UINTN BackupBufferSize;\r
+ BOOLEAN EndOfPeiFlag;\r
+\r
+ volatile UINT32 StartCount;\r
+ volatile UINT32 FinishedCount;\r
+ volatile UINT32 RunningCount;\r
+ BOOLEAN SingleThread;\r
+ EFI_AP_PROCEDURE Procedure;\r
+ VOID *ProcArguments;\r
+ BOOLEAN *Finished;\r
+ UINT64 ExpectedTime;\r
+ UINT64 CurrentTime;\r
+ UINT64 TotalTime;\r
+ EFI_EVENT WaitEvent;\r
+ UINTN **FailedCpuList;\r
+\r
+ AP_INIT_STATE InitFlag;\r
+ BOOLEAN X2ApicEnable;\r
+ MTRR_SETTINGS MtrrTable;\r
+ UINT8 ApLoopMode;\r
+ UINT8 ApTargetCState;\r
+ UINT16 PmCodeSegment;\r
+ CPU_AP_DATA *CpuData;\r
+ volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;\r
+};\r
/**\r
Assembly code to place AP into safe loop mode.\r
\r