-/**\r
- Check whether caller processor is BSP.\r
-\r
- @retval TRUE the caller is BSP\r
- @retval FALSE the caller is AP\r
-\r
-**/\r
-BOOLEAN\r
-IsBSP (\r
- VOID\r
- )\r
-{\r
- UINTN CpuIndex;\r
- CPU_DATA_BLOCK *CpuData;\r
-\r
- CpuData = NULL;\r
-\r
- WhoAmI (&mMpServicesTemplate, &CpuIndex);\r
- CpuData = &mMpSystemData.CpuDatas[CpuIndex];\r
-\r
- return CpuData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT ? TRUE : FALSE;\r
-}\r
-\r
-/**\r
- Get the Application Processors state.\r
-\r
- @param CpuData the pointer to CPU_DATA_BLOCK of specified AP\r
-\r
- @retval CPU_STATE the AP status\r
-\r
-**/\r
-CPU_STATE\r
-GetApState (\r
- IN CPU_DATA_BLOCK *CpuData\r
- )\r
-{\r
- CPU_STATE State;\r
-\r
- while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {\r
- CpuPause ();\r
- }\r
-\r
- State = CpuData->State;\r
- ReleaseSpinLock (&CpuData->CpuDataLock);\r
-\r
- return State;\r
-}\r
-\r
-/**\r
- Set the Application Processors state.\r
-\r
- @param CpuData The pointer to CPU_DATA_BLOCK of specified AP\r
- @param State The AP status\r
-\r
-**/\r
-VOID\r
-SetApState (\r
- IN CPU_DATA_BLOCK *CpuData,\r
- IN CPU_STATE State\r
- )\r
-{\r
- while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {\r
- CpuPause ();\r
- }\r
-\r
- CpuData->State = State;\r
- ReleaseSpinLock (&CpuData->CpuDataLock);\r
-}\r
-\r
-/**\r
- Set the Application Processor prepare to run a function specified\r
- by Params.\r
-\r
- @param CpuData the pointer to CPU_DATA_BLOCK of specified AP\r
- @param Procedure A pointer to the function to be run on enabled APs of the system\r
- @param ProcedureArgument Pointer to the optional parameter of the assigned function\r
-\r
-**/\r
-VOID\r
-SetApProcedure (\r
- IN CPU_DATA_BLOCK *CpuData,\r
- IN EFI_AP_PROCEDURE Procedure,\r
- IN VOID *ProcedureArgument\r
- )\r
-{\r
- while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {\r
- CpuPause ();\r
- }\r
-\r
- CpuData->Parameter = ProcedureArgument;\r
- CpuData->Procedure = Procedure;\r
- ReleaseSpinLock (&CpuData->CpuDataLock);\r
-}\r
-\r
-/**\r
- Check the Application Processors Status whether contains the Flags.\r
-\r
- @param CpuData the pointer to CPU_DATA_BLOCK of specified AP\r
- @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION\r
-\r
- @retval TRUE the AP status includes the StatusFlag\r
- @retval FALSE the AP status excludes the StatusFlag\r
-\r
-**/\r
-BOOLEAN\r
-TestCpuStatusFlag (\r
- IN CPU_DATA_BLOCK *CpuData,\r
- IN UINT32 Flags\r
- )\r
-{\r
- UINT32 Ret;\r
-\r
- while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {\r
- CpuPause ();\r
- }\r
-\r
- Ret = CpuData->Info.StatusFlag & Flags;\r
- ReleaseSpinLock (&CpuData->CpuDataLock);\r
-\r
- return !!(Ret);\r
-}\r
-\r
-/**\r
- Bitwise-Or of the Application Processors Status with the Flags.\r
-\r
- @param CpuData the pointer to CPU_DATA_BLOCK of specified AP\r
- @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION\r
-\r
-**/\r
-VOID\r
-CpuStatusFlagOr (\r
- IN CPU_DATA_BLOCK *CpuData,\r
- IN UINT32 Flags\r
- )\r
-{\r
- while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {\r
- CpuPause ();\r
- }\r
-\r
- CpuData->Info.StatusFlag |= Flags;\r
- ReleaseSpinLock (&CpuData->CpuDataLock);\r
-}\r
-\r
-/**\r
- Bitwise-AndNot of the Application Processors Status with the Flags.\r
-\r
- @param CpuData the pointer to CPU_DATA_BLOCK of specified AP\r
- @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION\r
-\r
-**/\r
-VOID\r
-CpuStatusFlagAndNot (\r
- IN CPU_DATA_BLOCK *CpuData,\r
- IN UINT32 Flags\r
- )\r
-{\r
- while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {\r
- CpuPause ();\r
- }\r
-\r
- CpuData->Info.StatusFlag &= ~Flags;\r
- ReleaseSpinLock (&CpuData->CpuDataLock);\r
-}\r
-\r
-/**\r
- Searches for the next blocking AP.\r
-\r
- Search for the next AP that is put in blocking state by single-threaded StartupAllAPs().\r
-\r
- @param NextNumber Pointer to the processor number of the next blocking AP.\r
-\r
- @retval EFI_SUCCESS The next blocking AP has been found.\r
- @retval EFI_NOT_FOUND No blocking AP exists.\r
-\r
-**/\r
-EFI_STATUS\r
-GetNextBlockedNumber (\r
- OUT UINTN *NextNumber\r
- )\r
-{\r
- UINTN Number;\r
- CPU_STATE CpuState;\r
- CPU_DATA_BLOCK *CpuData;\r
-\r
- for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {\r
- CpuData = &mMpSystemData.CpuDatas[Number];\r
- if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {\r
- //\r
- // Skip BSP\r
- //\r
- continue;\r
- }\r
-\r
- CpuState = GetApState (CpuData);\r
- if (CpuState == CpuStateBlocked) {\r
- *NextNumber = Number;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- Check if the APs state are finished, and update them to idle state\r
- by StartupAllAPs().\r
-\r
-**/\r
-VOID\r
-CheckAndUpdateAllAPsToIdleState (\r
- VOID\r
- )\r
-{\r
- UINTN ProcessorNumber;\r
- UINTN NextNumber;\r
- CPU_DATA_BLOCK *CpuData;\r
- EFI_STATUS Status;\r
- CPU_STATE CpuState;\r
-\r
- for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) {\r
- CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];\r
- if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {\r
- //\r
- // Skip BSP\r
- //\r
- continue;\r
- }\r
-\r
- if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {\r
- //\r
- // Skip Disabled processors\r
- //\r
- continue;\r
- }\r
-\r
- CpuState = GetApState (CpuData);\r
- if (CpuState == CpuStateFinished) {\r
- mMpSystemData.FinishCount++;\r
- if (mMpSystemData.SingleThread) {\r
- Status = GetNextBlockedNumber (&NextNumber);\r
- if (!EFI_ERROR (Status)) {\r
- SetApState (&mMpSystemData.CpuDatas[NextNumber], CpuStateReady);\r
- SetApProcedure (&mMpSystemData.CpuDatas[NextNumber],\r
- mMpSystemData.Procedure,\r
- mMpSystemData.ProcedureArgument);\r
- }\r
- }\r
-\r
- SetApState (CpuData, CpuStateIdle);\r
- }\r
- }\r
-}\r
-\r
-/**\r
- If the timeout expires before all APs returns from Procedure,\r
- we should forcibly terminate the executing AP and fill FailedList back\r
- by StartupAllAPs().\r
-\r
-**/\r
-VOID\r
-ResetAllFailedAPs (\r
- VOID\r
- )\r
-{\r
- CPU_DATA_BLOCK *CpuData;\r
- UINTN Number;\r
- CPU_STATE CpuState;\r
-\r
- if (mMpSystemData.FailedList != NULL) {\r
- *mMpSystemData.FailedList = AllocatePool ((mMpSystemData.StartCount - mMpSystemData.FinishCount + 1) * sizeof(UINTN));\r
- ASSERT (*mMpSystemData.FailedList != NULL);\r
- }\r
-\r
- for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {\r
- CpuData = &mMpSystemData.CpuDatas[Number];\r
- if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {\r
- //\r
- // Skip BSP\r
- //\r
- continue;\r
- }\r
-\r
- if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {\r
- //\r
- // Skip Disabled processors\r
- //\r
- continue;\r
- }\r
-\r
- CpuState = GetApState (CpuData);\r
- if (CpuState != CpuStateIdle) {\r
- if (mMpSystemData.FailedList != NULL) {\r
- (*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex++] = Number;\r
- }\r
- ResetProcessorToIdleState (CpuData);\r
- }\r
- }\r
-\r
- if (mMpSystemData.FailedList != NULL) {\r
- (*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex] = END_OF_CPU_LIST;\r
- }\r
-}\r
-\r