]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
UefiCpuPkg/DxeMpInitLib: Support source debugging on AP function
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / DxeMpLib.c
index a0d5eebc9497620efa48b15ee59ae6580b7f09da..1204abd577b2fdd5425d761f0edf0d0764dbace1 100644 (file)
 \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
@@ -25,6 +27,23 @@ EFI_EVENT        mMpInitExitBootServicesEvent = NULL;
 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
@@ -241,11 +260,19 @@ RelocateApLoop (
   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
@@ -273,7 +300,11 @@ MpInitChangeApLoopCallback (
   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
@@ -289,6 +320,7 @@ InitMpGlobalData (
 {\r
   EFI_STATUS                 Status;\r
   EFI_PHYSICAL_ADDRESS       Address;\r
+  UINTN                      ApSafeBufferSize;\r
 \r
   SaveCpuMpData (CpuMpData);\r
 \r
@@ -307,16 +339,21 @@ InitMpGlobalData (
   // 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
@@ -389,7 +426,7 @@ InitMpGlobalData (
                                       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
@@ -499,7 +536,7 @@ MpInitLibStartupAllAPs (
                                       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