From e59f8f6b3670e37687778f4294d8f59fec0c5dcb Mon Sep 17 00:00:00 2001 From: Jeff Fan Date: Wed, 20 Jul 2016 23:33:25 +0800 Subject: [PATCH] UefiCpuPkg/MpInitLib: Allocate and initialize memory of MP Data buffer v5: 1. Add comment block for enum AP_INIT_STATE and structure CPU_AP_DATA. 2. Add more comment for structure CPU_INFO_IN_HOB. 3. Add more clarification in structure _CPU_MP_DATA for those fields pass from PEI to DXE. Cc: Michael Kinney Cc: Feng Tian Cc: Giri P Mudusuru Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan Reviewed-by: Michael Kinney Tested-by: Laszlo Ersek Tested-by: Michael Kinney --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 49 ++++++++++++++++ UefiCpuPkg/Library/MpInitLib/MpLib.h | 88 ++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 32bbaee5cc..f05db7c2a5 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -93,15 +93,64 @@ MpInitLibInitialize ( VOID ) { + UINT32 MaxLogicalProcessorNumber; + UINT32 ApStackSize; MP_ASSEMBLY_ADDRESS_MAP AddressMap; + UINTN BufferSize; UINT32 MonitorFilterSize; + VOID *MpBuffer; + UINTN Buffer; + CPU_MP_DATA *CpuMpData; UINT8 ApLoopMode; + UINT8 *MonitorBuffer; UINTN ApResetVectorSize; + UINTN BackupBufferAddr; + MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber); AsmGetAddressMap (&AddressMap); ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO); + ApStackSize = PcdGet32(PcdCpuApStackSize); ApLoopMode = GetApLoopMode (&MonitorFilterSize); + BufferSize = ApStackSize * MaxLogicalProcessorNumber; + BufferSize += MonitorFilterSize * MaxLogicalProcessorNumber; + BufferSize += sizeof (CPU_MP_DATA); + BufferSize += ApResetVectorSize; + BufferSize += (sizeof (CPU_AP_DATA) + sizeof (CPU_INFO_IN_HOB))* MaxLogicalProcessorNumber; + MpBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize)); + ASSERT (MpBuffer != NULL); + ZeroMem (MpBuffer, BufferSize); + Buffer = (UINTN) MpBuffer; + + MonitorBuffer = (UINT8 *) (Buffer + ApStackSize * MaxLogicalProcessorNumber); + BackupBufferAddr = (UINTN) MonitorBuffer + MonitorFilterSize * MaxLogicalProcessorNumber; + CpuMpData = (CPU_MP_DATA *) (BackupBufferAddr + ApResetVectorSize); + CpuMpData->Buffer = Buffer; + CpuMpData->CpuApStackSize = ApStackSize; + CpuMpData->BackupBuffer = BackupBufferAddr; + CpuMpData->BackupBufferSize = ApResetVectorSize; + CpuMpData->EndOfPeiFlag = FALSE; + CpuMpData->WakeupBuffer = (UINTN) -1; + CpuMpData->CpuCount = 1; + CpuMpData->BspNumber = 0; + CpuMpData->WaitEvent = NULL; + CpuMpData->CpuData = (CPU_AP_DATA *) (CpuMpData + 1); + CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber); + InitializeSpinLock(&CpuMpData->MpLock); + // + // Save assembly code information + // + CopyMem (&CpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP)); + // + // Finally set AP loop mode + // + CpuMpData->ApLoopMode = ApLoopMode; + DEBUG ((DEBUG_INFO, "AP Loop Mode is %d\n", CpuMpData->ApLoopMode)); + // + // Store BSP's MTRR setting + // + MtrrGetAllMtrrs (&CpuMpData->MtrrTable); + return EFI_SUCCESS; } diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index 317facc80c..e605f8de41 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -45,6 +45,47 @@ typedef enum { ApInRunLoop = 3 } AP_LOOP_MODE; +// +// AP initialization state during APs wakeup +// +typedef enum { + ApInitConfig = 1, + ApInitReconfig = 2, + ApInitDone = 3 +} AP_INIT_STATE; + +// +// AP related data +// +typedef struct { + SPIN_LOCK ApLock; + volatile UINT32 *StartupApSignal; + volatile UINTN ApFunction; + volatile UINTN ApFunctionArgument; + UINT32 InitialApicId; + UINT32 ApicId; + UINT32 Health; + BOOLEAN CpuHealthy; + BOOLEAN Waiting; + BOOLEAN *Finished; + UINT64 ExpectedTime; + UINT64 CurrentTime; + UINT64 TotalTime; + EFI_EVENT WaitEvent; +} CPU_AP_DATA; + +// +// Basic CPU information saved in Guided HOB. +// Because the contents will be shard between PEI and DXE, +// we need to make sure the each fields offset same in different +// architecture. +// +typedef struct { + UINT32 InitialApicId; + UINT32 ApicId; + UINT32 Health; +} CPU_INFO_IN_HOB; + // // AP reset code information including code address and size, // this structure will be shared be C code and assembly code. @@ -58,6 +99,8 @@ typedef struct { UINTN RelocateApLoopFuncSize; } MP_ASSEMBLY_ADDRESS_MAP; +typedef struct _CPU_MP_DATA CPU_MP_DATA; + #pragma pack(1) // @@ -79,9 +122,54 @@ typedef struct { UINTN DataSegment; UINTN EnableExecuteDisable; UINTN Cr3; + CPU_MP_DATA *CpuMpData; } MP_CPU_EXCHANGE_INFO; #pragma pack() + +// +// CPU MP Data save in memory +// +struct _CPU_MP_DATA { + UINT64 CpuInfoInHob; + UINT32 CpuCount; + UINT32 BspNumber; + // + // The above fields data will be passed from PEI to DXE + // Please make sure the fields offset same in the different + // architecture. + // + SPIN_LOCK MpLock; + UINTN Buffer; + UINTN CpuApStackSize; + MP_ASSEMBLY_ADDRESS_MAP AddressMap; + UINTN WakeupBuffer; + UINTN BackupBuffer; + UINTN BackupBufferSize; + BOOLEAN EndOfPeiFlag; + + volatile UINT32 StartCount; + volatile UINT32 FinishedCount; + volatile UINT32 RunningCount; + BOOLEAN SingleThread; + EFI_AP_PROCEDURE Procedure; + VOID *ProcArguments; + BOOLEAN *Finished; + UINT64 ExpectedTime; + UINT64 CurrentTime; + UINT64 TotalTime; + EFI_EVENT WaitEvent; + UINTN **FailedCpuList; + + AP_INIT_STATE InitFlag; + BOOLEAN X2ApicEnable; + MTRR_SETTINGS MtrrTable; + UINT8 ApLoopMode; + UINT8 ApTargetCState; + UINT16 PmCodeSegment; + CPU_AP_DATA *CpuData; + volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo; +}; /** Assembly code to place AP into safe loop mode. -- 2.39.2