Cc: Michael Kinney <michael.d.kin...@intel.com> Cc: Feng Tian <feng.t...@intel.com> Cc: Giri P Mudusuru <giri.p.mudus...@intel.com> Cc: Laszlo Ersek <ler...@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff....@intel.com> --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 49 +++++++++++++++++++++++ UefiCpuPkg/Library/MpInitLib/MpLib.h | 77 ++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 32bbaee..f05db7c 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 c6dd0b5..955de96 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -41,6 +41,38 @@ typedef enum { ApInRunLoop = 3 } AP_LOOP_MODE; +typedef enum { + ApInitConfig = 1, + ApInitReconfig = 2, + ApInitDone = 3 +} AP_INIT_STATE; + +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 +// +typedef struct { + UINT32 InitialApicId; + UINT32 ApicId; + UINT32 Health; +} CPU_INFO_IN_HOB; + // // AP reset code information // @@ -52,6 +84,8 @@ typedef struct { UINTN RelocateApLoopFuncSize; } MP_ASSEMBLY_ADDRESS_MAP; +typedef struct _CPU_MP_DATA CPU_MP_DATA; + #pragma pack(1) // @@ -73,9 +107,52 @@ 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 + // + 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.7.4.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel