Abstract some DxeMpLib code to function in this commit.
Some of these internal functions will be moved to common
MpLib.c in following commits. Then PeiMpLib can reuse
the code.

Signed-off-by: Dun Tan <dun....@intel.com>
Reviewed-by: Ray Ni <ray...@intel.com>
Cc: Rahul Kumar <rahul1.ku...@intel.com>
Cc: Gerd Hoffmann <kra...@redhat.com>
Cc: Jiaxin Wu <jiaxin...@intel.com>
---
 UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 222 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------------------
 1 file changed, 140 insertions(+), 82 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c 
b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 57ddb86600..5f0a87c024 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -1,7 +1,7 @@
 /** @file
   MP initialize support functions for DXE phase.
 
-  Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -422,6 +422,144 @@ RelocateApLoop (
   ASSERT (FALSE);
 }
 
+/**
+  Allocate buffer for ApLoopCode.
+
+  @param[in]      Pages    Number of pages to allocate.
+  @param[in, out] Address  Pointer to the allocated buffer.
+**/
+VOID
+AllocateApLoopCodeBuffer (
+  IN UINTN                     Pages,
+  IN OUT EFI_PHYSICAL_ADDRESS  *Address
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->AllocatePages (
+                  AllocateMaxAddress,
+                  EfiReservedMemoryType,
+                  Pages,
+                  Address
+                  );
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  Remove Nx protection for the range specific by BaseAddress and Length.
+
+  The PEI implementation uses CpuPageTableLib to change the attribute.
+  The DXE implementation uses gDS to change the attribute.
+
+  @param[in] BaseAddress  BaseAddress of the range.
+  @param[in] Length       Length of the range.
+**/
+VOID
+RemoveNxprotection (
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
+  IN UINTN                 Length
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  MemDesc;
+
+  //
+  // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD
+  //       service.
+  //
+  Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &MemDesc);
+  if (!EFI_ERROR (Status)) {
+    gDS->SetMemorySpaceAttributes (
+           BaseAddress,
+           Length,
+           MemDesc.Attributes & (~EFI_MEMORY_XP)
+           );
+  }
+}
+
+/**
+  Prepare ApLoopCode.
+
+  @param[in] CpuMpData  Pointer to CpuMpData.
+**/
+VOID
+PrepareApLoopCode (
+  IN CPU_MP_DATA  *CpuMpData
+  )
+{
+  EFI_PHYSICAL_ADDRESS     Address;
+  MP_ASSEMBLY_ADDRESS_MAP  *AddressMap;
+  UINT8                    *ApLoopFunc;
+  UINTN                    ApLoopFuncSize;
+  UINTN                    StackPages;
+  UINTN                    FuncPages;
+  IA32_CR0                 Cr0;
+
+  AddressMap = &CpuMpData->AddressMap;
+  if (CpuMpData->UseSevEsAPMethod) {
+    //
+    // 64-bit AMD processors with SEV-ES
+    //
+    Address        = BASE_4GB - 1;
+    ApLoopFunc     = AddressMap->RelocateApLoopFuncAddressAmdSev;
+    ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev;
+  } else {
+    //
+    // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit 
AMD processors without SEV-ES
+    //
+    Address        = MAX_ADDRESS;
+    ApLoopFunc     = AddressMap->RelocateApLoopFuncAddressGeneric;
+    ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric;
+  }
+
+  //
+  // Avoid APs access invalid buffer data which allocated by BootServices,
+  // so we will allocate reserved data for AP loop code. We also need to
+  // allocate this buffer below 4GB due to APs may be transferred to 32bit
+  // protected mode on long mode DXE.
+  // Allocating it in advance since memory services are not available in
+  // Exit Boot Services callback function.
+  //
+  // +------------+ (TopOfApStack)
+  // |  Stack * N |
+  // +------------+ (stack base, 4k aligned)
+  // |  Padding   |
+  // +------------+
+  // |  Ap Loop   |
+  // +------------+ ((low address, 4k-aligned)
+  //
+
+  StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
+  FuncPages  = EFI_SIZE_TO_PAGES (ApLoopFuncSize);
+
+  AllocateApLoopCodeBuffer (StackPages + FuncPages, &Address);
+  ASSERT (Address != 0);
+
+  Cr0.UintN = AsmReadCr0 ();
+  if (Cr0.Bits.PG != 0) {
+    //
+    // Make sure that the buffer memory is executable if NX protection is 
enabled
+    // for EfiReservedMemoryType.
+    //
+    RemoveNxprotection (Address, EFI_PAGES_TO_SIZE (FuncPages));
+  }
+
+  mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE 
(StackPages+FuncPages);
+  ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
+  mReservedApLoop.Data = (VOID *)(UINTN)Address;
+  ASSERT (mReservedApLoop.Data != NULL);
+  CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize);
+  if (!CpuMpData->UseSevEsAPMethod) {
+    //
+    // processors without SEV-ES and paging is enabled
+    //
+    mApPageTable = CreatePageTable (
+                     (UINTN)Address,
+                     EFI_PAGES_TO_SIZE (StackPages+FuncPages)
+                     );
+  }
+}
+
 /**
   Callback function for ExitBootServices.
 
@@ -477,16 +615,10 @@ InitMpGlobalData (
   )
 {
   EFI_STATUS                       Status;
-  EFI_PHYSICAL_ADDRESS             Address;
   UINTN                            Index;
   EFI_GCD_MEMORY_SPACE_DESCRIPTOR  MemDesc;
   UINTN                            StackBase;
   CPU_INFO_IN_HOB                  *CpuInfoInHob;
-  MP_ASSEMBLY_ADDRESS_MAP          *AddressMap;
-  UINT8                            *ApLoopFunc;
-  UINTN                            ApLoopFuncSize;
-  UINTN                            StackPages;
-  UINTN                            FuncPages;
 
   SaveCpuMpData (CpuMpData);
 
@@ -541,81 +673,7 @@ InitMpGlobalData (
     }
   }
 
-  AddressMap = &CpuMpData->AddressMap;
-  if (CpuMpData->UseSevEsAPMethod) {
-    //
-    // 64-bit AMD processors with SEV-ES
-    //
-    Address        = BASE_4GB - 1;
-    ApLoopFunc     = AddressMap->RelocateApLoopFuncAddressAmdSev;
-    ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev;
-  } else {
-    //
-    // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit 
AMD processors without SEV-ES
-    //
-    Address        = MAX_ADDRESS;
-    ApLoopFunc     = AddressMap->RelocateApLoopFuncAddressGeneric;
-    ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric;
-  }
-
-  //
-  // Avoid APs access invalid buffer data which allocated by BootServices,
-  // so we will allocate reserved data for AP loop code. We also need to
-  // allocate this buffer below 4GB due to APs may be transferred to 32bit
-  // protected mode on long mode DXE.
-  // Allocating it in advance since memory services are not available in
-  // Exit Boot Services callback function.
-  //
-  // +------------+ (TopOfApStack)
-  // |  Stack * N |
-  // +------------+ (stack base, 4k aligned)
-  // |  Padding   |
-  // +------------+
-  // |  Ap Loop   |
-  // +------------+ ((low address, 4k-aligned)
-  //
-
-  StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
-  FuncPages  = EFI_SIZE_TO_PAGES (ApLoopFuncSize);
-
-  Status = gBS->AllocatePages (
-                  AllocateMaxAddress,
-                  EfiReservedMemoryType,
-                  StackPages + FuncPages,
-                  &Address
-                  );
-  ASSERT_EFI_ERROR (Status);
-
-  //
-  // Make sure that the buffer memory is executable if NX protection is enabled
-  // for EfiReservedMemoryType.
-  //
-  // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD
-  //       service.
-  //
-  Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc);
-  if (!EFI_ERROR (Status)) {
-    gDS->SetMemorySpaceAttributes (
-           Address,
-           EFI_PAGES_TO_SIZE (FuncPages),
-           MemDesc.Attributes & (~EFI_MEMORY_XP)
-           );
-  }
-
-  mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE 
(StackPages+FuncPages);
-  ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
-  mReservedApLoop.Data = (VOID *)(UINTN)Address;
-  ASSERT (mReservedApLoop.Data != NULL);
-  CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize);
-  if (!CpuMpData->UseSevEsAPMethod) {
-    //
-    // processors without SEV-ES
-    //
-    mApPageTable = CreatePageTable (
-                     (UINTN)Address,
-                     EFI_PAGES_TO_SIZE (StackPages+FuncPages)
-                     );
-  }
+  PrepareApLoopCode (CpuMpData);
 
   Status = gBS->CreateEvent (
                   EVT_TIMER | EVT_NOTIFY_SIGNAL,
-- 
2.31.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119007): https://edk2.groups.io/g/devel/message/119007
Mute This Topic: https://groups.io/mt/106150768/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to