EFI_EVENT mCheckAllApsEvent = NULL;\r
EFI_EVENT mMpInitExitBootServicesEvent = NULL;\r
volatile BOOLEAN mStopCheckAllApsStatus = TRUE;\r
-\r
+VOID *mReservedApLoopFunc = NULL;\r
\r
/**\r
Get the pointer to CPU MP Data structure.\r
UINTN ApResetVectorSize;\r
EFI_PHYSICAL_ADDRESS StartAddress;\r
\r
- ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +\r
- sizeof (MP_CPU_EXCHANGE_INFO);\r
-\r
- StartAddress = BASE_1MB;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (ApResetVectorSize),\r
- &StartAddress\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- CpuMpData->WakeupBuffer = (UINTN) StartAddress;\r
- CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN)\r
+ if (CpuMpData->SaveRestoreFlag) {\r
+ BackupAndPrepareWakeupBuffer (CpuMpData);\r
+ } else {\r
+ ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +\r
+ sizeof (MP_CPU_EXCHANGE_INFO);\r
+\r
+ StartAddress = BASE_1MB;\r
+ Status = gBS->AllocatePages (\r
+ AllocateMaxAddress,\r
+ EfiACPIMemoryNVS,\r
+ EFI_SIZE_TO_PAGES (ApResetVectorSize),\r
+ &StartAddress\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ CpuMpData->WakeupBuffer = (UINTN) StartAddress;\r
+ CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN)\r
(CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize);\r
- //\r
- // copy AP reset code in it\r
- //\r
- CopyMem (\r
- (VOID *) CpuMpData->WakeupBuffer,\r
- (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress,\r
- CpuMpData->AddressMap.RendezvousFunnelSize\r
- );\r
+ //\r
+ // copy AP reset code in it\r
+ //\r
+ CopyMem (\r
+ (VOID *) CpuMpData->WakeupBuffer,\r
+ (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress,\r
+ CpuMpData->AddressMap.RendezvousFunnelSize\r
+ );\r
+ }\r
}\r
\r
/**\r
{\r
EFI_STATUS Status;\r
UINTN ApResetVectorSize;\r
- ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +\r
- sizeof (MP_CPU_EXCHANGE_INFO);\r
- Status = gBS->FreePages(\r
- (EFI_PHYSICAL_ADDRESS)CpuMpData->WakeupBuffer,\r
- EFI_SIZE_TO_PAGES (ApResetVectorSize)\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+\r
+ if (CpuMpData->SaveRestoreFlag) {\r
+ RestoreWakeupBuffer (CpuMpData);\r
+ } else {\r
+ ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +\r
+ sizeof (MP_CPU_EXCHANGE_INFO);\r
+ Status = gBS->FreePages(\r
+ (EFI_PHYSICAL_ADDRESS)CpuMpData->WakeupBuffer,\r
+ EFI_SIZE_TO_PAGES (ApResetVectorSize)\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
}\r
\r
/**\r
/**\r
Checks APs' status periodically.\r
\r
- This function is triggerred by timer perodically to check the\r
+ This function is triggered by timer periodically to check the\r
state of APs for StartupAllAPs() and StartupThisAP() executed\r
in non-blocking mode.\r
\r
/**\r
Get Protected mode code segment from current GDT table.\r
\r
- @returen Protected mode code segment value.\r
+ @return Protected mode code segment value.\r
**/\r
UINT16\r
GetProtectedModeCS (\r
)\r
{\r
CPU_MP_DATA *CpuMpData;\r
- VOID *ReservedApLoopFunc;\r
- //\r
- // Avoid APs access invalid buff data which allocated by BootServices,\r
- // so we will allocate reserved data for AP loop code.\r
- //\r
+\r
CpuMpData = GetCpuMpData ();\r
+ CpuMpData->SaveRestoreFlag = TRUE;\r
CpuMpData->PmCodeSegment = GetProtectedModeCS ();\r
CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode);\r
- ReservedApLoopFunc = AllocateReservedCopyPool (\r
- CpuMpData->AddressMap.RelocateApLoopFuncSize,\r
- CpuMpData->AddressMap.RelocateApLoopFuncAddress\r
- );\r
- WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, ReservedApLoopFunc);\r
+ WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, mReservedApLoopFunc);\r
DEBUG ((DEBUG_INFO, "MpInitExitBootServicesCallback() done!\n"));\r
}\r
\r
\r
SaveCpuMpData (CpuMpData);\r
\r
+ if (CpuMpData->CpuCount == 1) {\r
+ //\r
+ // If only BSP exists, return\r
+ //\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Avoid APs access invalid buff data which allocated by BootServices,\r
+ // so we will allocate reserved data for AP loop code.\r
+ // Allocating it in advance since memory services are not available in\r
+ // Exit Boot Services callback function.\r
+ //\r
+ mReservedApLoopFunc = AllocateReservedCopyPool (\r
+ CpuMpData->AddressMap.RelocateApLoopFuncSize,\r
+ CpuMpData->AddressMap.RelocateApLoopFuncAddress\r
+ );\r
+ ASSERT (mReservedApLoopFunc != NULL);\r
+\r
Status = gBS->CreateEvent (\r
EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
TPL_NOTIFY,\r