X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=UefiCpuPkg%2FCpuDxe%2FCpuMp.c;h=9659bd280725c56a5a6ed325a191a4ff3f7bd83a;hp=8f7a56c40daa2bbb1559061f9871d5859571f124;hb=367284e7735478b0c4ad37d8f6bf17d3c4a473d0;hpb=0b9f0dd635b82cad34fcd47e20ce9c0c9c46c893 diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c index 8f7a56c40d..9659bd2807 100644 --- a/UefiCpuPkg/CpuDxe/CpuMp.c +++ b/UefiCpuPkg/CpuDxe/CpuMp.c @@ -15,20 +15,8 @@ #include "CpuDxe.h" #include "CpuMp.h" -UINTN gMaxLogicalProcessorNumber; -UINTN gApStackSize; -UINTN gPollInterval = 100; // 100 microseconds - -MP_SYSTEM_DATA mMpSystemData; EFI_HANDLE mMpServiceHandle = NULL; UINTN mNumberOfProcessors = 1; -EFI_EVENT mExitBootServicesEvent = (EFI_EVENT)NULL; - -VOID *mCommonStack = 0; -VOID *mTopOfApCommonStack = 0; -VOID *mApStackStart = 0; - -volatile BOOLEAN mAPsAlreadyInitFinished = FALSE; EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = { GetNumberOfProcessors, @@ -40,372 +28,6 @@ EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = { WhoAmI }; -/** - Get Mp Service Lock. - - @param CpuData the pointer to CPU_DATA_BLOCK of specified processor - -**/ -VOID -GetMpSpinLock ( - IN CPU_DATA_BLOCK *CpuData - ) -{ - while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) { - CpuPause (); - } - CpuData->LockSelf = GetApicId (); -} - -/** - Release Mp Service Lock. - - @param CpuData the pointer to CPU_DATA_BLOCK of specified processor - -**/ -VOID -ReleaseMpSpinLock ( - IN CPU_DATA_BLOCK *CpuData - ) -{ - ReleaseSpinLock (&CpuData->CpuDataLock); -} - -/** - Check whether caller processor is BSP. - - @retval TRUE the caller is BSP - @retval FALSE the caller is AP - -**/ -BOOLEAN -IsBSP ( - VOID - ) -{ - UINTN CpuIndex; - CPU_DATA_BLOCK *CpuData; - - CpuData = NULL; - - WhoAmI (&mMpServicesTemplate, &CpuIndex); - CpuData = &mMpSystemData.CpuDatas[CpuIndex]; - - return CpuData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT ? TRUE : FALSE; -} - -/** - Get the Application Processors state. - - @param CpuData the pointer to CPU_DATA_BLOCK of specified AP - - @retval CPU_STATE the AP status - -**/ -STATIC -CPU_STATE -GetApState ( - IN CPU_DATA_BLOCK *CpuData - ) -{ - CPU_STATE State; - - GetMpSpinLock (CpuData); - State = CpuData->State; - ReleaseMpSpinLock (CpuData); - - return State; -} - -/** - Set the Application Processors state. - - @param CpuData The pointer to CPU_DATA_BLOCK of specified AP - @param State The AP status - -**/ -STATIC -VOID -SetApState ( - IN CPU_DATA_BLOCK *CpuData, - IN CPU_STATE State - ) -{ - GetMpSpinLock (CpuData); - CpuData->State = State; - ReleaseMpSpinLock (CpuData); -} - -/** - Set the Application Processor prepare to run a function specified - by Params. - - @param CpuData the pointer to CPU_DATA_BLOCK of specified AP - @param Procedure A pointer to the function to be run on enabled APs of the system - @param ProcedureArgument Pointer to the optional parameter of the assigned function - -**/ -VOID -SetApProcedure ( - IN CPU_DATA_BLOCK *CpuData, - IN EFI_AP_PROCEDURE Procedure, - IN VOID *ProcedureArgument - ) -{ - GetMpSpinLock (CpuData); - CpuData->Parameter = ProcedureArgument; - CpuData->Procedure = Procedure; - ReleaseMpSpinLock (CpuData); -} - -/** - Check the Application Processors Status whether contains the Flags. - - @param CpuData the pointer to CPU_DATA_BLOCK of specified AP - @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION - - @retval TRUE the AP status includes the StatusFlag - @retval FALSE the AP status excludes the StatusFlag - -**/ -BOOLEAN -TestCpuStatusFlag ( - IN CPU_DATA_BLOCK *CpuData, - IN UINT32 Flags - ) -{ - UINT32 Ret; - - GetMpSpinLock (CpuData); - Ret = CpuData->Info.StatusFlag & Flags; - ReleaseMpSpinLock (CpuData); - - return (BOOLEAN) (Ret != 0); -} - -/** - Bitwise-Or of the Application Processors Status with the Flags. - - @param CpuData the pointer to CPU_DATA_BLOCK of specified AP - @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION - -**/ -VOID -CpuStatusFlagOr ( - IN CPU_DATA_BLOCK *CpuData, - IN UINT32 Flags - ) -{ - GetMpSpinLock (CpuData); - CpuData->Info.StatusFlag |= Flags; - ReleaseMpSpinLock (CpuData); -} - -/** - Bitwise-AndNot of the Application Processors Status with the Flags. - - @param CpuData the pointer to CPU_DATA_BLOCK of specified AP - @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION - -**/ -VOID -CpuStatusFlagAndNot ( - IN CPU_DATA_BLOCK *CpuData, - IN UINT32 Flags - ) -{ - GetMpSpinLock (CpuData); - CpuData->Info.StatusFlag &= ~Flags; - ReleaseMpSpinLock (CpuData); -} - -/** - Searches for the next blocking AP. - - Search for the next AP that is put in blocking state by single-threaded StartupAllAPs(). - - @param NextNumber Pointer to the processor number of the next blocking AP. - - @retval EFI_SUCCESS The next blocking AP has been found. - @retval EFI_NOT_FOUND No blocking AP exists. - -**/ -EFI_STATUS -GetNextBlockedNumber ( - OUT UINTN *NextNumber - ) -{ - UINTN Number; - CPU_STATE CpuState; - CPU_DATA_BLOCK *CpuData; - - for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) { - CpuData = &mMpSystemData.CpuDatas[Number]; - if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) { - // - // Skip BSP - // - continue; - } - - CpuState = GetApState (CpuData); - if (CpuState == CpuStateBlocked) { - *NextNumber = Number; - return EFI_SUCCESS; - } - } - - return EFI_NOT_FOUND; -} - -/** - Check if the APs state are finished, and update them to idle state - by StartupAllAPs(). - -**/ -VOID -CheckAndUpdateAllAPsToIdleState ( - VOID - ) -{ - UINTN ProcessorNumber; - UINTN NextNumber; - CPU_DATA_BLOCK *CpuData; - EFI_STATUS Status; - CPU_STATE CpuState; - - for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) { - CpuData = &mMpSystemData.CpuDatas[ProcessorNumber]; - if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) { - // - // Skip BSP - // - continue; - } - - if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) { - // - // Skip Disabled processors - // - continue; - } - - CpuState = GetApState (CpuData); - if (CpuState == CpuStateFinished) { - mMpSystemData.FinishCount++; - if (mMpSystemData.SingleThread) { - Status = GetNextBlockedNumber (&NextNumber); - if (!EFI_ERROR (Status)) { - SetApState (&mMpSystemData.CpuDatas[NextNumber], CpuStateReady); - SetApProcedure (&mMpSystemData.CpuDatas[NextNumber], - mMpSystemData.Procedure, - mMpSystemData.ProcedureArgument); - // - // If this AP previous state is blocked, we should - // wake up this AP by sent a SIPI. and avoid - // re-involve the sleeping state. we must call - // SetApProcedure() first. - // - ResetProcessorToIdleState (&mMpSystemData.CpuDatas[NextNumber]); - } - } - SetApState (CpuData, CpuStateIdle); - } - } -} - -/** - Check if all APs are in state CpuStateSleeping. - - Return TRUE if all APs are in the CpuStateSleeping state. Do not - check the state of the BSP or any disabled APs. - - @retval TRUE All APs are in CpuStateSleeping state. - @retval FALSE One or more APs are not in CpuStateSleeping state. - -**/ -BOOLEAN -CheckAllAPsSleeping ( - VOID - ) -{ - UINTN ProcessorNumber; - CPU_DATA_BLOCK *CpuData; - - for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) { - CpuData = &mMpSystemData.CpuDatas[ProcessorNumber]; - if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) { - // - // Skip BSP - // - continue; - } - - if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) { - // - // Skip Disabled processors - // - continue; - } - - if (GetApState (CpuData) != CpuStateSleeping) { - return FALSE; - } - } - return TRUE; -} - -/** - If the timeout expires before all APs returns from Procedure, - we should forcibly terminate the executing AP and fill FailedList back - by StartupAllAPs(). - -**/ -VOID -ResetAllFailedAPs ( - VOID - ) -{ - CPU_DATA_BLOCK *CpuData; - UINTN Number; - CPU_STATE CpuState; - - if (mMpSystemData.FailedList != NULL) { - *mMpSystemData.FailedList = AllocatePool ((mMpSystemData.StartCount - mMpSystemData.FinishCount + 1) * sizeof(UINTN)); - ASSERT (*mMpSystemData.FailedList != NULL); - } - - for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) { - CpuData = &mMpSystemData.CpuDatas[Number]; - if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) { - // - // Skip BSP - // - continue; - } - - if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) { - // - // Skip Disabled processors - // - continue; - } - - CpuState = GetApState (CpuData); - if (CpuState != CpuStateIdle && - CpuState != CpuStateSleeping) { - if (mMpSystemData.FailedList != NULL) { - (*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex++] = Number; - } - ResetProcessorToIdleState (CpuData); - } - } - - if (mMpSystemData.FailedList != NULL) { - (*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex] = END_OF_CPU_LIST; - } -} - /** This service retrieves the number of logical processor in the platform and the number of those logical processors that are enabled on this boot. @@ -677,8 +299,8 @@ StartupAllAPs ( @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. - @param[in] Procedure A pointer to the function to be run on - enabled APs of the system. See type + @param[in] Procedure A pointer to the function to be run on the + designated AP of the system. See type EFI_AP_PROCEDURE. @param[in] ProcessorNumber The handle number of the AP. The range is from 0 to the total number of logical @@ -687,13 +309,13 @@ StartupAllAPs ( EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). @param[in] WaitEvent The event created by the caller with CreateEvent() service. If it is NULL, then execute in - blocking mode. BSP waits until all APs finish - or TimeoutInMicroseconds expires. If it's + blocking mode. BSP waits until this AP finish + or TimeoutInMicroSeconds expires. If it's not NULL, then execute in non-blocking mode. BSP requests the function specified by - Procedure to be started on all the enabled - APs, and go on executing immediately. If - all return from Procedure or TimeoutInMicroseconds + Procedure to be started on this AP, + and go on executing immediately. If this AP + return from Procedure or TimeoutInMicroSeconds expires, this event is signaled. The BSP can use the CheckEvent() or WaitForEvent() services to check the state of event. Type @@ -701,20 +323,20 @@ StartupAllAPs ( the Unified Extensible Firmware Interface Specification. @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for - APs to return from Procedure, either for + this AP to finish this Procedure, either for blocking or non-blocking mode. Zero means infinity. If the timeout expires before - all APs return from Procedure, then Procedure - on the failed APs is terminated. All enabled - APs are available for next function assigned + this AP returns from Procedure, then Procedure + on the AP is terminated. The + AP is available for next function assigned by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() or EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If the timeout expires in blocking mode, BSP returns EFI_TIMEOUT. If the timeout expires in non-blocking mode, WaitEvent is signaled with SignalEvent(). - @param[in] ProcedureArgument The parameter passed into Procedure for - all APs. + @param[in] ProcedureArgument The parameter passed into Procedure on the + specified AP. @param[out] Finished If NULL, this parameter is ignored. In blocking mode, this parameter is ignored. In non-blocking mode, if AP returns from @@ -825,8 +447,8 @@ SwitchBSP ( from this service, then EFI_UNSUPPORTED must be returned. @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. - @param[in] ProcessorNumber The handle number of AP that is to become the new - BSP. The range is from 0 to the total number of + @param[in] ProcessorNumber The handle number of AP. + The range is from 0 to the total number of logical processors minus 1. The total number of logical processors can be retrieved by EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). @@ -875,8 +497,8 @@ EnableDisableAP ( ProcessorNumber, and EFI_SUCCESS is returned. @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. - @param[out] ProcessorNumber The handle number of AP that is to become the new - BSP. The range is from 0 to the total number of + @param[out] ProcessorNumber Pointer to the handle number of AP. + The range is from 0 to the total number of logical processors minus 1. The total number of logical processors can be retrieved by EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). @@ -917,6 +539,7 @@ CollectBistDataFromHob ( UINTN ProcessorNumber; EFI_PROCESSOR_INFORMATION ProcessorInfo; EFI_HEALTH_FLAGS BistData; + UINTN CpuInstanceNumber; SecPlatformInformation2 = NULL; SecPlatformInformation = NULL; @@ -956,50 +579,28 @@ CollectBistDataFromHob ( } } - while ((NumberOfData--) > 0) { - for (ProcessorNumber = 0; ProcessorNumber < mNumberOfProcessors; ProcessorNumber++) { - MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData); - if (ProcessorInfo.ProcessorId == CpuInstance[NumberOfData].CpuLocation) { + for (ProcessorNumber = 0; ProcessorNumber < mNumberOfProcessors; ProcessorNumber++) { + MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData); + for (CpuInstanceNumber = 0; CpuInstanceNumber < NumberOfData; CpuInstanceNumber++) { + if (ProcessorInfo.ProcessorId == CpuInstance[CpuInstanceNumber].CpuLocation) { // // Update CPU health status for MP Services Protocol according to BIST data. // - BistData = CpuInstance[NumberOfData].InfoRecord.IA32HealthFlags; - } - if (BistData.Uint32 != 0) { - // - // Report Status Code that self test is failed - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MAJOR, - (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST) - ); + BistData = CpuInstance[CpuInstanceNumber].InfoRecord.IA32HealthFlags; } } + if (BistData.Uint32 != 0) { + // + // Report Status Code that self test is failed + // + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MAJOR, + (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST) + ); + } } } -/** - Callback function for ExitBootServices. - - @param Event Event whose notification function is being invoked. - @param Context The pointer to the notification function's context, - which is implementation-dependent. - -**/ -VOID -EFIAPI -ExitBootServicesCallback ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - // - // Avoid APs access invalid buff datas which allocated by BootServices, - // so we send INIT IPI to APs to let them wait for SIPI state. - // - SendInitIpiAllExcludingSelf (); -} - /** Initialize Multi-processor support. @@ -1013,22 +614,14 @@ InitializeMpSupport ( UINTN NumberOfProcessors; UINTN NumberOfEnabledProcessors; - NumberOfProcessors = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber); - if (NumberOfProcessors < 1) { - DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n")); - return; - } - // - // Only perform AP detection if PcdCpuMaxLogicalProcessorNumber is greater than 1 + // Wakeup APs to do initialization // - if (NumberOfProcessors > 1) { - Status = MpInitLibInitialize (); - ASSERT_EFI_ERROR (Status); + Status = MpInitLibInitialize (); + ASSERT_EFI_ERROR (Status); - MpInitLibGetNumberOfProcessors (&NumberOfProcessors, &NumberOfEnabledProcessors); - mNumberOfProcessors = NumberOfProcessors; - } + MpInitLibGetNumberOfProcessors (&NumberOfProcessors, &NumberOfEnabledProcessors); + mNumberOfProcessors = NumberOfProcessors; DEBUG ((EFI_D_ERROR, "Detect CPU count: %d\n", mNumberOfProcessors)); //