\r
#include <Library/UefiLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DebugAgentLib.h>\r
\r
#define AP_CHECK_INTERVAL (EFI_TIMER_PERIOD_MILLISECONDS (100))\r
+#define AP_SAFE_STACK_SIZE 128\r
\r
CPU_MP_DATA *mCpuMpData = NULL;\r
EFI_EVENT mCheckAllApsEvent = NULL;\r
EFI_EVENT mLegacyBootEvent = NULL;\r
volatile BOOLEAN mStopCheckAllApsStatus = TRUE;\r
VOID *mReservedApLoopFunc = NULL;\r
+UINTN mReservedTopOfApStack;\r
+volatile UINT32 mNumberToFinish = 0;\r
+\r
+/**\r
+ Enable Debug Agent to support source debugging on AP function.\r
+\r
+**/\r
+VOID\r
+EnableDebugAgent (\r
+ VOID\r
+ )\r
+{\r
+ //\r
+ // Initialize Debug Agent to support source level debug in DXE phase\r
+ //\r
+ InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_AP, NULL, NULL);\r
+}\r
\r
/**\r
Get the pointer to CPU MP Data structure.\r
CPU_MP_DATA *CpuMpData;\r
BOOLEAN MwaitSupport;\r
ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc;\r
+ UINTN ProcessorNumber;\r
\r
+ MpInitLibWhoAmI (&ProcessorNumber); \r
CpuMpData = GetCpuMpData ();\r
MwaitSupport = IsMwaitSupport ();\r
AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP) (UINTN) mReservedApLoopFunc;\r
- AsmRelocateApLoopFunc (MwaitSupport, CpuMpData->ApTargetCState, CpuMpData->PmCodeSegment);\r
+ AsmRelocateApLoopFunc (\r
+ MwaitSupport,\r
+ CpuMpData->ApTargetCState,\r
+ CpuMpData->PmCodeSegment,\r
+ mReservedTopOfApStack - ProcessorNumber * AP_SAFE_STACK_SIZE,\r
+ (UINTN) &mNumberToFinish\r
+ );\r
//\r
// It should never reach here\r
//\r
CpuMpData->SaveRestoreFlag = TRUE;\r
CpuMpData->PmCodeSegment = GetProtectedModeCS ();\r
CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode);\r
+ mNumberToFinish = CpuMpData->CpuCount - 1;\r
WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL);\r
+ while (mNumberToFinish > 0) {\r
+ CpuPause ();\r
+ }\r
DEBUG ((DEBUG_INFO, "%a() done!\n", __FUNCTION__));\r
}\r
\r
{\r
EFI_STATUS Status;\r
EFI_PHYSICAL_ADDRESS Address;\r
+ UINTN ApSafeBufferSize;\r
\r
SaveCpuMpData (CpuMpData);\r
\r
// Allocating it in advance since memory services are not available in\r
// Exit Boot Services callback function.\r
//\r
+ ApSafeBufferSize = CpuMpData->AddressMap.RelocateApLoopFuncSize;\r
+ ApSafeBufferSize += CpuMpData->CpuCount * AP_SAFE_STACK_SIZE;\r
+\r
Address = BASE_4GB - 1;\r
Status = gBS->AllocatePages (\r
AllocateMaxAddress,\r
EfiReservedMemoryType,\r
- EFI_SIZE_TO_PAGES (sizeof (CpuMpData->AddressMap.RelocateApLoopFuncSize)),\r
+ EFI_SIZE_TO_PAGES (ApSafeBufferSize),\r
&Address\r
);\r
ASSERT_EFI_ERROR (Status);\r
mReservedApLoopFunc = (VOID *) (UINTN) Address;\r
ASSERT (mReservedApLoopFunc != NULL);\r
+ mReservedTopOfApStack = (UINTN) Address + EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (ApSafeBufferSize));\r
+ ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);\r
CopyMem (\r
mReservedApLoopFunc,\r
CpuMpData->AddressMap.RelocateApLoopFuncAddress,\r
EFI_EVENT is defined in CreateEvent() in\r
the Unified Extensible Firmware Interface\r
Specification.\r
- @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for\r
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for\r
APs to return from Procedure, either for\r
blocking or non-blocking mode. Zero means\r
infinity. If the timeout expires before\r
EFI_EVENT is defined in CreateEvent() in\r
the Unified Extensible Firmware Interface\r
Specification.\r
- @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for\r
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for\r
this AP to finish this Procedure, either for\r
blocking or non-blocking mode. Zero means\r
infinity. If the timeout expires before\r