UINTN gPollInterval = 100; // 100 microseconds\r
\r
MP_SYSTEM_DATA mMpSystemData;\r
+EFI_HANDLE mMpServiceHandle = NULL;\r
+EFI_EVENT mExitBootServicesEvent = (EFI_EVENT)NULL;\r
\r
VOID *mCommonStack = 0;\r
VOID *mTopOfApCommonStack = 0;\r
while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {\r
CpuPause ();\r
}\r
+ CpuData->LockSelf = GetApicId ();\r
}\r
\r
/**\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ //\r
+ // temporarily stop checkAllAPsStatus for avoid resource dead-lock.\r
+ //\r
+ mStopCheckAllAPsStatus = TRUE;\r
+\r
for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) {\r
CpuData = &mMpSystemData.CpuDatas[Number];\r
if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {\r
}\r
}\r
\r
- //\r
- // temporarily stop checkAllAPsStatus for initialize parameters.\r
- //\r
- mStopCheckAllAPsStatus = TRUE;\r
-\r
mMpSystemData.Procedure = Procedure;\r
mMpSystemData.ProcedureArgument = ProcedureArgument;\r
mMpSystemData.WaitEvent = WaitEvent;\r
return EFI_SUCCESS;\r
}\r
\r
+ //\r
+ // Blocking temporarily stop CheckAllAPsStatus()\r
+ //\r
+ mStopCheckAllAPsStatus = TRUE;\r
+\r
while (TRUE) {\r
CheckAndUpdateAllAPsToIdleState ();\r
if (mMpSystemData.FinishCount == mMpSystemData.StartCount) {\r
return EFI_NOT_FOUND;\r
}\r
\r
+ //\r
+ // temporarily stop checkAllAPsStatus for avoid resource dead-lock.\r
+ //\r
+ mStopCheckAllAPsStatus = TRUE;\r
+\r
CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];\r
if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT) ||\r
!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) {\r
return EFI_NOT_READY;\r
}\r
\r
- //\r
- // temporarily stop checkAllAPsStatus for initialize parameters.\r
- //\r
- mStopCheckAllAPsStatus = TRUE;\r
-\r
SetApState (CpuData, CpuStateReady);\r
\r
SetApProcedure (CpuData, Procedure, ProcedureArgument);\r
)\r
{\r
CPU_DATA_BLOCK *CpuData;\r
+ BOOLEAN TempStopCheckState;\r
+\r
+ CpuData = NULL;\r
+ TempStopCheckState = FALSE;\r
\r
if (!IsBSP ()) {\r
return EFI_DEVICE_ERROR;\r
return EFI_NOT_FOUND;\r
}\r
\r
+ //\r
+ // temporarily stop checkAllAPsStatus for initialize parameters.\r
+ //\r
+ if (!mStopCheckAllAPsStatus) {\r
+ mStopCheckAllAPsStatus = TRUE;\r
+ TempStopCheckState = TRUE;\r
+ }\r
+\r
CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];\r
if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) {\r
return EFI_INVALID_PARAMETER;\r
CpuStatusFlagOr (CpuData, (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT));\r
}\r
\r
+ if (TempStopCheckState) {\r
+ mStopCheckAllAPsStatus = FALSE;\r
+ }\r
+\r
return EFI_SUCCESS;\r
}\r
\r
WhoAmI (&mMpServicesTemplate, &ProcessorNumber);\r
CpuData = &mMpSystemData.CpuDatas[ProcessorNumber];\r
\r
+ //\r
+ // Avoid forcibly reset AP caused the AP got lock not release.\r
+ //\r
+ if (CpuData->LockSelf == (INTN) GetApicId ()) {\r
+ ReleaseSpinLock (&CpuData->CpuDataLock);\r
+ }\r
+\r
//\r
// Avoid forcibly reset AP caused the AP State is not updated.\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
if (CpuData->WaitEvent) {\r
CheckThisAPStatus (NULL, (VOID *)CpuData);\r
}\r
CpuData->Procedure = NULL;\r
CpuData->Parameter = NULL;\r
InitializeSpinLock (&CpuData->CpuDataLock);\r
+ CpuData->LockSelf = -1;\r
\r
return EFI_SUCCESS;\r
}\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Callback function for ExitBootServices.\r
+\r
+ @param Event Event whose notification function is being invoked.\r
+ @param Context The pointer to the notification function's context,\r
+ which is implementation-dependent.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ExitBootServicesCallback (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ //\r
+ // Avoid APs access invalid buff datas which allocated by BootServices,\r
+ // so we send INIT IPI to APs to let them wait for SIPI state.\r
+ //\r
+ SendInitIpiAllExcludingSelf ();\r
+}\r
+\r
/**\r
Initialize Multi-processor support.\r
\r
VOID\r
)\r
{\r
+ EFI_STATUS Status;\r
+\r
gMaxLogicalProcessorNumber = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber);\r
if (gMaxLogicalProcessorNumber < 1) {\r
DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n"));\r
\r
PrepareAPStartupCode ();\r
\r
+ StartApsStackless ();\r
+\r
+ DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", mMpSystemData.NumberOfProcessors));\r
if (mMpSystemData.NumberOfProcessors == 1) {\r
FreeApStartupCode ();\r
FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize));\r
\r
mAPsAlreadyInitFinished = TRUE;\r
\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mMpServiceHandle,\r
+ &gEfiMpServiceProtocolGuid, &mMpServicesTemplate,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
if (mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) {\r
FreePages (mApStackStart, EFI_SIZE_TO_PAGES (\r
(gMaxLogicalProcessorNumber - mMpSystemData.NumberOfProcessors) *\r
gApStackSize));\r
}\r
+\r
+ Status = gBS->CreateEvent (\r
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+ TPL_CALLBACK,\r
+ ExitBootServicesCallback,\r
+ NULL,\r
+ &mExitBootServicesEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
}\r