]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/MpLib.c
UefiCpuPkg: Use Top of each AP's stack to save CpuMpData
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / MpLib.c
index 041a32e6591234a91a7662de2d44b3a4b72d1e44..1c053f87a4c64c5d8baef0feb2b2e2ebd600ab3d 100644 (file)
@@ -599,6 +599,7 @@ InitializeApData (
 {\r
   CPU_INFO_IN_HOB                *CpuInfoInHob;\r
   MSR_IA32_PLATFORM_ID_REGISTER  PlatformIdMsr;\r
+  AP_STACK_DATA                  *ApStackData;\r
 \r
   CpuInfoInHob                                = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;\r
   CpuInfoInHob[ProcessorNumber].InitialApicId = GetInitialApicId ();\r
@@ -606,6 +607,12 @@ InitializeApData (
   CpuInfoInHob[ProcessorNumber].Health        = BistData;\r
   CpuInfoInHob[ProcessorNumber].ApTopOfStack  = ApTopOfStack;\r
 \r
+  //\r
+  // AP_STACK_DATA is stored at the top of AP Stack\r
+  //\r
+  ApStackData         = (AP_STACK_DATA *)((UINTN)ApTopOfStack - sizeof (AP_STACK_DATA));\r
+  ApStackData->MpData = CpuMpData;\r
+\r
   CpuMpData->CpuData[ProcessorNumber].Waiting    = FALSE;\r
   CpuMpData->CpuData[ProcessorNumber].CpuHealthy = (BistData == 0) ? TRUE : FALSE;\r
 \r
@@ -651,6 +658,7 @@ ApWakeupFunction (
   CPU_INFO_IN_HOB   *CpuInfoInHob;\r
   UINT64            ApTopOfStack;\r
   UINTN             CurrentApicMode;\r
+  AP_STACK_DATA     *ApStackData;\r
 \r
   //\r
   // AP finished assembly code and begin to execute C code\r
@@ -676,7 +684,9 @@ ApWakeupFunction (
       // This is first time AP wakeup, get BIST information from AP stack\r
       //\r
       ApTopOfStack = CpuMpData->Buffer + (ProcessorNumber + 1) * CpuMpData->CpuApStackSize;\r
-      BistData     = *(UINT32 *)((UINTN)ApTopOfStack - sizeof (UINTN));\r
+      ApStackData  = (AP_STACK_DATA *)((UINTN)ApTopOfStack - sizeof (AP_STACK_DATA));\r
+      BistData     = (UINT32)ApStackData->Bist;\r
+\r
       //\r
       // CpuMpData->CpuData[0].VolatileRegisters is initialized based on BSP environment,\r
       //   to initialize AP in InitConfig path.\r
@@ -1824,14 +1834,22 @@ MpInitLibInitialize (
   AsmGetAddressMap (&AddressMap);\r
   GetApResetVectorSize (&AddressMap, &ApResetVectorSizeBelow1Mb, &ApResetVectorSizeAbove1Mb);\r
   ApStackSize = PcdGet32 (PcdCpuApStackSize);\r
-  ApLoopMode  = GetApLoopMode (&MonitorFilterSize);\r
+  //\r
+  // ApStackSize must be power of 2\r
+  //\r
+  ASSERT ((ApStackSize & (ApStackSize - 1)) == 0);\r
+  ApLoopMode = GetApLoopMode (&MonitorFilterSize);\r
 \r
   //\r
   // Save BSP's Control registers for APs.\r
   //\r
   SaveVolatileRegisters (&VolatileRegisters);\r
 \r
-  BufferSize  = ApStackSize * MaxLogicalProcessorNumber;\r
+  BufferSize = ApStackSize * MaxLogicalProcessorNumber;\r
+  //\r
+  // Allocate extra ApStackSize to let AP stack align on ApStackSize bounday\r
+  //\r
+  BufferSize += ApStackSize;\r
   BufferSize += MonitorFilterSize * MaxLogicalProcessorNumber;\r
   BufferSize += ApResetVectorSizeBelow1Mb;\r
   BufferSize  = ALIGN_VALUE (BufferSize, 8);\r
@@ -1841,13 +1859,13 @@ MpInitLibInitialize (
   MpBuffer    = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));\r
   ASSERT (MpBuffer != NULL);\r
   ZeroMem (MpBuffer, BufferSize);\r
-  Buffer = (UINTN)MpBuffer;\r
+  Buffer = ALIGN_VALUE ((UINTN)MpBuffer, ApStackSize);\r
 \r
   //\r
-  //  The layout of the Buffer is as below:\r
+  //  The layout of the Buffer is as below (lower address on top):\r
   //\r
-  //    +--------------------+ <-- Buffer\r
-  //        AP Stacks (N)\r
+  //    +--------------------+ <-- Buffer (Pointer of CpuMpData is stored in the top of each AP's stack.)\r
+  //        AP Stacks (N)                 (StackTop = (RSP + ApStackSize) & ~ApStackSize))\r
   //    +--------------------+ <-- MonitorBuffer\r
   //    AP Monitor Filters (N)\r
   //    +--------------------+ <-- BackupBufferAddr (CpuMpData->BackupBuffer)\r
@@ -1855,7 +1873,7 @@ MpInitLibInitialize (
   //    +--------------------+\r
   //           Padding\r
   //    +--------------------+ <-- ApIdtBase (8-byte boundary)\r
-  //           AP IDT          All APs share one separate IDT. So AP can get address of CPU_MP_DATA from IDT Base.\r
+  //           AP IDT          All APs share one separate IDT.\r
   //    +--------------------+ <-- CpuMpData\r
   //         CPU_MP_DATA\r
   //    +--------------------+ <-- CpuMpData->CpuData\r
@@ -1892,10 +1910,11 @@ MpInitLibInitialize (
 \r
   //\r
   // Make sure no memory usage outside of the allocated buffer.\r
+  // (ApStackSize - (Buffer - (UINTN)MpBuffer)) is the redundant caused by alignment\r
   //\r
   ASSERT (\r
     (CpuMpData->CpuInfoInHob + sizeof (CPU_INFO_IN_HOB) * MaxLogicalProcessorNumber) ==\r
-    Buffer + BufferSize\r
+    (UINTN)MpBuffer + BufferSize - (ApStackSize - Buffer + (UINTN)MpBuffer)\r
     );\r
 \r
   //\r