]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
UefiCpuPkg: Make the comments align with the functions
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / DxeMpLib.c
index 50b5b270fe507cf262928d79751f339055f7bddc..e75c26930db3b12a07d996e627efdd3a6e00a8ab 100644 (file)
 #include <Library/UefiBootServicesTableLib.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        mMpInitExitBootServicesEvent = 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
   Get the pointer to CPU MP Data structure.\r
@@ -172,7 +176,7 @@ CheckAndUpdateApsStatus (
 /**\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
@@ -240,11 +244,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) Buffer;\r
-  AsmRelocateApLoopFunc (MwaitSupport, CpuMpData->ApTargetCState, CpuMpData->PmCodeSegment);\r
+  AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP) (UINTN) mReservedApLoopFunc;\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
@@ -261,7 +273,7 @@ RelocateApLoop (
 **/\r
 VOID\r
 EFIAPI\r
-MpInitExitBootServicesCallback (\r
+MpInitChangeApLoopCallback (\r
   IN EFI_EVENT                Event,\r
   IN VOID                     *Context\r
   )\r
@@ -272,8 +284,12 @@ MpInitExitBootServicesCallback (
   CpuMpData->SaveRestoreFlag = TRUE;\r
   CpuMpData->PmCodeSegment = GetProtectedModeCS ();\r
   CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode);\r
-  WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, mReservedApLoopFunc);\r
-  DEBUG ((DEBUG_INFO, "MpInitExitBootServicesCallback() done!\n"));\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
@@ -286,21 +302,47 @@ InitMpGlobalData (
   IN CPU_MP_DATA               *CpuMpData\r
   )\r
 {\r
-  EFI_STATUS     Status;\r
+  EFI_STATUS                 Status;\r
+  EFI_PHYSICAL_ADDRESS       Address;\r
+  UINTN                      ApSafeBufferSize;\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
+  // 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
+  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 (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
+    CpuMpData->AddressMap.RelocateApLoopFuncSize\r
+    );\r
 \r
   Status = gBS->CreateEvent (\r
                   EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
@@ -320,14 +362,25 @@ InitMpGlobalData (
                   AP_CHECK_INTERVAL\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
+\r
   Status = gBS->CreateEvent (\r
                   EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
                   TPL_CALLBACK,\r
-                  MpInitExitBootServicesCallback,\r
+                  MpInitChangeApLoopCallback,\r
                   NULL,\r
                   &mMpInitExitBootServicesEvent\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_CALLBACK,\r
+                  MpInitChangeApLoopCallback,\r
+                  NULL,\r
+                  &gEfiEventLegacyBootGuid,\r
+                  &mLegacyBootEvent\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
 /**\r
@@ -357,7 +410,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
@@ -467,7 +520,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