]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / PeiMpLib.c
index 90015c650c68127096ee338b37ac8429ac53d482..e732371ddd2195de7e0eedd6967cadff778adc8f 100644 (file)
@@ -11,7 +11,7 @@
 #include <Guid/S3SmmInitDone.h>\r
 #include <Ppi/ShadowMicrocode.h>\r
 \r
-STATIC UINT64 mSevEsPeiWakeupBuffer = BASE_1MB;\r
+STATIC UINT64  mSevEsPeiWakeupBuffer = BASE_1MB;\r
 \r
 /**\r
   S3 SMM Init Done notification function.\r
@@ -26,16 +26,15 @@ STATIC UINT64 mSevEsPeiWakeupBuffer = BASE_1MB;
 EFI_STATUS\r
 EFIAPI\r
 NotifyOnS3SmmInitDonePpi (\r
-  IN  EFI_PEI_SERVICES                              **PeiServices,\r
-  IN  EFI_PEI_NOTIFY_DESCRIPTOR                     *NotifyDesc,\r
-  IN  VOID                                          *InvokePpi\r
+  IN  EFI_PEI_SERVICES           **PeiServices,\r
+  IN  EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDesc,\r
+  IN  VOID                       *InvokePpi\r
   );\r
 \r
-\r
 //\r
 // Global function\r
 //\r
-EFI_PEI_NOTIFY_DESCRIPTOR        mS3SmmInitDoneNotifyDesc = {\r
+EFI_PEI_NOTIFY_DESCRIPTOR  mS3SmmInitDoneNotifyDesc = {\r
   EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
   &gEdkiiS3SmmInitDoneGuid,\r
   NotifyOnS3SmmInitDonePpi\r
@@ -54,12 +53,12 @@ EFI_PEI_NOTIFY_DESCRIPTOR        mS3SmmInitDoneNotifyDesc = {
 EFI_STATUS\r
 EFIAPI\r
 NotifyOnS3SmmInitDonePpi (\r
-  IN  EFI_PEI_SERVICES                              **PeiServices,\r
-  IN  EFI_PEI_NOTIFY_DESCRIPTOR                     *NotifyDesc,\r
-  IN  VOID                                          *InvokePpi\r
+  IN  EFI_PEI_SERVICES           **PeiServices,\r
+  IN  EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDesc,\r
+  IN  VOID                       *InvokePpi\r
   )\r
 {\r
-  CPU_MP_DATA     *CpuMpData;\r
+  CPU_MP_DATA  *CpuMpData;\r
 \r
   CpuMpData = GetCpuMpData ();\r
 \r
@@ -76,7 +75,6 @@ NotifyOnS3SmmInitDonePpi (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Enable Debug Agent to support source debugging on AP function.\r
 \r
@@ -91,7 +89,7 @@ EnableDebugAgent (
 /**\r
   Get pointer to CPU MP Data structure.\r
   For BSP, the pointer is retrieved from HOB.\r
-  For AP, the structure is just after IDT.\r
+  For AP, the structure is stored in the top of each AP's stack.\r
 \r
   @return  The pointer to CPU MP Data structure.\r
 **/\r
@@ -102,16 +100,19 @@ GetCpuMpData (
 {\r
   CPU_MP_DATA                  *CpuMpData;\r
   MSR_IA32_APIC_BASE_REGISTER  ApicBaseMsr;\r
-  IA32_DESCRIPTOR              Idtr;\r
+  UINTN                        ApTopOfStack;\r
+  AP_STACK_DATA                *ApStackData;\r
 \r
   ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
   if (ApicBaseMsr.Bits.BSP == 1) {\r
     CpuMpData = GetCpuMpDataFromGuidedHob ();\r
     ASSERT (CpuMpData != NULL);\r
   } else {\r
-    AsmReadIdtr (&Idtr);\r
-    CpuMpData = (CPU_MP_DATA *) (Idtr.Base + Idtr.Limit + 1);\r
+    ApTopOfStack = ALIGN_VALUE ((UINTN)&ApTopOfStack, (UINTN)PcdGet32 (PcdCpuApStackSize));\r
+    ApStackData  = (AP_STACK_DATA *)((UINTN)ApTopOfStack- sizeof (AP_STACK_DATA));\r
+    CpuMpData    = (CPU_MP_DATA *)ApStackData->MpData;\r
   }\r
+\r
   return CpuMpData;\r
 }\r
 \r
@@ -122,17 +123,18 @@ GetCpuMpData (
 **/\r
 VOID\r
 SaveCpuMpData (\r
-  IN CPU_MP_DATA   *CpuMpData\r
+  IN CPU_MP_DATA  *CpuMpData\r
   )\r
 {\r
-  UINT64           Data64;\r
+  UINT64  Data64;\r
+\r
   //\r
   // Build location of CPU MP DATA buffer in HOB\r
   //\r
-  Data64 = (UINT64) (UINTN) CpuMpData;\r
+  Data64 = (UINT64)(UINTN)CpuMpData;\r
   BuildGuidDataHob (\r
     &mCpuInitMpLibHobGuid,\r
-    (VOID *) &Data64,\r
+    (VOID *)&Data64,\r
     sizeof (UINT64)\r
     );\r
 }\r
@@ -148,15 +150,15 @@ SaveCpuMpData (
 **/\r
 BOOLEAN\r
 CheckOverlapWithAllocatedBuffer (\r
-  IN UINT64               WakeupBufferStart,\r
-  IN UINT64               WakeupBufferEnd\r
+  IN UINT64  WakeupBufferStart,\r
+  IN UINT64  WakeupBufferEnd\r
   )\r
 {\r
-  EFI_PEI_HOB_POINTERS      Hob;\r
-  EFI_HOB_MEMORY_ALLOCATION *MemoryHob;\r
-  BOOLEAN                   Overlapped;\r
-  UINT64                    MemoryStart;\r
-  UINT64                    MemoryEnd;\r
+  EFI_PEI_HOB_POINTERS       Hob;\r
+  EFI_HOB_MEMORY_ALLOCATION  *MemoryHob;\r
+  BOOLEAN                    Overlapped;\r
+  UINT64                     MemoryStart;\r
+  UINT64                     MemoryEnd;\r
 \r
   Overlapped = FALSE;\r
   //\r
@@ -176,8 +178,10 @@ CheckOverlapWithAllocatedBuffer (
         break;\r
       }\r
     }\r
+\r
     Hob.Raw = GET_NEXT_HOB (Hob);\r
   }\r
+\r
   return Overlapped;\r
 }\r
 \r
@@ -191,12 +195,12 @@ CheckOverlapWithAllocatedBuffer (
 **/\r
 UINTN\r
 GetWakeupBuffer (\r
-  IN UINTN                WakeupBufferSize\r
+  IN UINTN  WakeupBufferSize\r
   )\r
 {\r
-  EFI_PEI_HOB_POINTERS    Hob;\r
-  UINT64                  WakeupBufferStart;\r
-  UINT64                  WakeupBufferEnd;\r
+  EFI_PEI_HOB_POINTERS  Hob;\r
+  UINT64                WakeupBufferStart;\r
+  UINT64                WakeupBufferEnd;\r
 \r
   WakeupBufferSize = (WakeupBufferSize + SIZE_4KB - 1) & ~(SIZE_4KB - 1);\r
 \r
@@ -216,14 +220,16 @@ GetWakeupBuffer (
             (EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |\r
              EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |\r
              EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED\r
-             )) == 0)\r
-           ) {\r
+            )) == 0)\r
+          )\r
+      {\r
         //\r
         // Need memory under 1MB to be collected here\r
         //\r
         WakeupBufferEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;\r
-        if (PcdGetBool (PcdSevEsIsEnabled) &&\r
-            WakeupBufferEnd > mSevEsPeiWakeupBuffer) {\r
+        if (ConfidentialComputingGuestHas (CCAttrAmdSevEs) &&\r
+            (WakeupBufferEnd > mSevEsPeiWakeupBuffer))\r
+        {\r
           //\r
           // SEV-ES Wakeup buffer should be under 1MB and under any previous one\r
           //\r
@@ -234,6 +240,7 @@ GetWakeupBuffer (
           //\r
           WakeupBufferEnd = BASE_1MB;\r
         }\r
+\r
         while (WakeupBufferEnd > WakeupBufferSize) {\r
           //\r
           // Wakeup buffer should be aligned on 4KB\r
@@ -242,6 +249,7 @@ GetWakeupBuffer (
           if (WakeupBufferStart < Hob.ResourceDescriptor->PhysicalStart) {\r
             break;\r
           }\r
+\r
           if (CheckOverlapWithAllocatedBuffer (WakeupBufferStart, WakeupBufferEnd)) {\r
             //\r
             // If this range is overlapped with existing allocated buffer, skip it\r
@@ -250,10 +258,15 @@ GetWakeupBuffer (
             WakeupBufferEnd -= WakeupBufferSize;\r
             continue;\r
           }\r
-          DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n",\r
-                               WakeupBufferStart, WakeupBufferSize));\r
 \r
-          if (PcdGetBool (PcdSevEsIsEnabled)) {\r
+          DEBUG ((\r
+            DEBUG_INFO,\r
+            "WakeupBufferStart = %x, WakeupBufferSize = %x\n",\r
+            WakeupBufferStart,\r
+            WakeupBufferSize\r
+            ));\r
+\r
+          if (ConfidentialComputingGuestHas (CCAttrAmdSevEs)) {\r
             //\r
             // Next SEV-ES wakeup buffer allocation must be below this\r
             // allocation\r
@@ -265,13 +278,14 @@ GetWakeupBuffer (
         }\r
       }\r
     }\r
+\r
     //\r
     // Find the next HOB\r
     //\r
     Hob.Raw = GET_NEXT_HOB (Hob);\r
   }\r
 \r
-  return (UINTN) -1;\r
+  return (UINTN)-1;\r
 }\r
 \r
 /**\r
@@ -287,14 +301,19 @@ GetWakeupBuffer (
   @retval 0       Cannot find free memory below 4GB.\r
 **/\r
 UINTN\r
-GetModeTransitionBuffer (\r
-  IN UINTN                BufferSize\r
+AllocateCodeBuffer (\r
+  IN UINTN  BufferSize\r
   )\r
 {\r
-  //\r
-  // PEI phase doesn't need to do such transition. So simply return 0.\r
-  //\r
-  return 0;\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  Address;\r
+\r
+  Status = PeiServicesAllocatePages (EfiBootServicesCode, EFI_SIZE_TO_PAGES (BufferSize), &Address);\r
+  if (EFI_ERROR (Status)) {\r
+    Address = 0;\r
+  }\r
+\r
+  return (UINTN)Address;\r
 }\r
 \r
 /**\r
@@ -336,17 +355,17 @@ CheckAndUpdateApsStatus (
 **/\r
 VOID\r
 BuildMicrocodeCacheHob (\r
-  IN CPU_MP_DATA    *CpuMpData\r
+  IN CPU_MP_DATA  *CpuMpData\r
   )\r
 {\r
-  EDKII_MICROCODE_PATCH_HOB    *MicrocodeHob;\r
-  UINTN                        HobDataLength;\r
-  UINT32                       Index;\r
+  EDKII_MICROCODE_PATCH_HOB  *MicrocodeHob;\r
+  UINTN                      HobDataLength;\r
+  UINT32                     Index;\r
 \r
   HobDataLength = sizeof (EDKII_MICROCODE_PATCH_HOB) +\r
                   sizeof (UINT64) * CpuMpData->CpuCount;\r
 \r
-  MicrocodeHob  = AllocatePool (HobDataLength);\r
+  MicrocodeHob = AllocatePool (HobDataLength);\r
   if (MicrocodeHob == NULL) {\r
     ASSERT (FALSE);\r
     return;\r
@@ -387,7 +406,7 @@ BuildMicrocodeCacheHob (
 **/\r
 VOID\r
 InitMpGlobalData (\r
-  IN CPU_MP_DATA               *CpuMpData\r
+  IN CPU_MP_DATA  *CpuMpData\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -480,12 +499,12 @@ InitMpGlobalData (
 EFI_STATUS\r
 EFIAPI\r
 MpInitLibStartupAllAPs (\r
-  IN  EFI_AP_PROCEDURE          Procedure,\r
-  IN  BOOLEAN                   SingleThread,\r
-  IN  EFI_EVENT                 WaitEvent               OPTIONAL,\r
-  IN  UINTN                     TimeoutInMicroseconds,\r
-  IN  VOID                      *ProcedureArgument      OPTIONAL,\r
-  OUT UINTN                     **FailedCpuList         OPTIONAL\r
+  IN  EFI_AP_PROCEDURE  Procedure,\r
+  IN  BOOLEAN           SingleThread,\r
+  IN  EFI_EVENT         WaitEvent               OPTIONAL,\r
+  IN  UINTN             TimeoutInMicroseconds,\r
+  IN  VOID              *ProcedureArgument      OPTIONAL,\r
+  OUT UINTN             **FailedCpuList         OPTIONAL\r
   )\r
 {\r
   if (WaitEvent != NULL) {\r
@@ -577,12 +596,12 @@ MpInitLibStartupAllAPs (
 EFI_STATUS\r
 EFIAPI\r
 MpInitLibStartupThisAP (\r
-  IN  EFI_AP_PROCEDURE          Procedure,\r
-  IN  UINTN                     ProcessorNumber,\r
-  IN  EFI_EVENT                 WaitEvent               OPTIONAL,\r
-  IN  UINTN                     TimeoutInMicroseconds,\r
-  IN  VOID                      *ProcedureArgument      OPTIONAL,\r
-  OUT BOOLEAN                   *Finished               OPTIONAL\r
+  IN  EFI_AP_PROCEDURE  Procedure,\r
+  IN  UINTN             ProcessorNumber,\r
+  IN  EFI_EVENT         WaitEvent               OPTIONAL,\r
+  IN  UINTN             TimeoutInMicroseconds,\r
+  IN  VOID              *ProcedureArgument      OPTIONAL,\r
+  OUT BOOLEAN           *Finished               OPTIONAL\r
   )\r
 {\r
   if (WaitEvent != NULL) {\r
@@ -628,8 +647,8 @@ MpInitLibStartupThisAP (
 EFI_STATUS\r
 EFIAPI\r
 MpInitLibSwitchBSP (\r
-  IN UINTN                     ProcessorNumber,\r
-  IN  BOOLEAN                  EnableOldBSP\r
+  IN UINTN     ProcessorNumber,\r
+  IN  BOOLEAN  EnableOldBSP\r
   )\r
 {\r
   return SwitchBSPWorker (ProcessorNumber, EnableOldBSP);\r
@@ -668,9 +687,9 @@ MpInitLibSwitchBSP (
 EFI_STATUS\r
 EFIAPI\r
 MpInitLibEnableDisableAP (\r
-  IN  UINTN                     ProcessorNumber,\r
-  IN  BOOLEAN                   EnableAP,\r
-  IN  UINT32                    *HealthFlag OPTIONAL\r
+  IN  UINTN    ProcessorNumber,\r
+  IN  BOOLEAN  EnableAP,\r
+  IN  UINT32   *HealthFlag OPTIONAL\r
   )\r
 {\r
   return EnableDisableApWorker (ProcessorNumber, EnableAP, HealthFlag);\r
@@ -689,29 +708,29 @@ MpInitLibEnableDisableAP (
 **/\r
 EFI_STATUS\r
 PlatformShadowMicrocode (\r
-  IN OUT CPU_MP_DATA             *CpuMpData\r
+  IN OUT CPU_MP_DATA  *CpuMpData\r
   )\r
 {\r
-  EFI_STATUS                         Status;\r
-  EDKII_PEI_SHADOW_MICROCODE_PPI     *ShadowMicrocodePpi;\r
-  UINTN                              CpuCount;\r
-  EDKII_PEI_MICROCODE_CPU_ID         *MicrocodeCpuId;\r
-  UINTN                              Index;\r
-  UINTN                              BufferSize;\r
-  VOID                               *Buffer;\r
+  EFI_STATUS                      Status;\r
+  EDKII_PEI_SHADOW_MICROCODE_PPI  *ShadowMicrocodePpi;\r
+  UINTN                           CpuCount;\r
+  EDKII_PEI_MICROCODE_CPU_ID      *MicrocodeCpuId;\r
+  UINTN                           Index;\r
+  UINTN                           BufferSize;\r
+  VOID                            *Buffer;\r
 \r
   Status = PeiServicesLocatePpi (\r
              &gEdkiiPeiShadowMicrocodePpiGuid,\r
              0,\r
              NULL,\r
-             (VOID **) &ShadowMicrocodePpi\r
+             (VOID **)&ShadowMicrocodePpi\r
              );\r
   if (EFI_ERROR (Status)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  CpuCount = CpuMpData->CpuCount;\r
-  MicrocodeCpuId = (EDKII_PEI_MICROCODE_CPU_ID *) AllocateZeroPool (sizeof (EDKII_PEI_MICROCODE_CPU_ID) * CpuCount);\r
+  CpuCount       = CpuMpData->CpuCount;\r
+  MicrocodeCpuId = (EDKII_PEI_MICROCODE_CPU_ID *)AllocateZeroPool (sizeof (EDKII_PEI_MICROCODE_CPU_ID) * CpuCount);\r
   if (MicrocodeCpuId == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -722,24 +741,26 @@ PlatformShadowMicrocode (
   }\r
 \r
   Status = ShadowMicrocodePpi->ShadowMicrocode (\r
-             ShadowMicrocodePpi,\r
-             CpuCount,\r
-             MicrocodeCpuId,\r
-             &BufferSize,\r
-             &Buffer\r
-             );\r
+                                 ShadowMicrocodePpi,\r
+                                 CpuCount,\r
+                                 MicrocodeCpuId,\r
+                                 &BufferSize,\r
+                                 &Buffer\r
+                                 );\r
   FreePool (MicrocodeCpuId);\r
   if (EFI_ERROR (Status)) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  CpuMpData->MicrocodePatchAddress    = (UINTN) Buffer;\r
+  CpuMpData->MicrocodePatchAddress    = (UINTN)Buffer;\r
   CpuMpData->MicrocodePatchRegionSize = BufferSize;\r
 \r
   DEBUG ((\r
     DEBUG_INFO,\r
     "%a: Required microcode patches have been loaded at 0x%lx, with size 0x%lx.\n",\r
-    __FUNCTION__, CpuMpData->MicrocodePatchAddress, CpuMpData->MicrocodePatchRegionSize\r
+    __FUNCTION__,\r
+    CpuMpData->MicrocodePatchAddress,\r
+    CpuMpData->MicrocodePatchRegionSize\r
     ));\r
 \r
   return EFI_SUCCESS;\r