IN CPU_MP_DATA *CpuMpData\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
+ EFI_PHYSICAL_ADDRESS Address;\r
\r
SaveCpuMpData (CpuMpData);\r
\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
+ // Avoid APs access invalid buffer data which allocated by BootServices,\r
+ // so we will allocate reserved data for AP loop code. We also need to\r
+ // allocate this buffer below 4GB due to APs may be transferred to 32bit\r
+ // protected mode on long mode DXE.\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
+ Address = BASE_4GB - 1;\r
+ Status = gBS->AllocatePages (\r
+ AllocateMaxAddress,\r
+ EfiReservedMemoryType,\r
+ EFI_SIZE_TO_PAGES (sizeof (CpuMpData->AddressMap.RelocateApLoopFuncSize)),\r
+ &Address\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ mReservedApLoopFunc = (VOID *) (UINTN) Address;\r
ASSERT (mReservedApLoopFunc != NULL);\r
+ CopyMem (\r
+ mReservedApLoopFunc,\r
+ CpuMpData->AddressMap.RelocateApLoopFuncAddress,\r
+ CpuMpData->AddressMap.RelocateApLoopFuncSize\r
+ );\r
\r
Status = gBS->CreateEvent (\r
EVT_TIMER | EVT_NOTIFY_SIGNAL,\r