summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
diff options
context:
space:
mode:
authorXie, Yuanhao <yuanhao.xie@intel.com>2022-12-20 05:40:15 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2022-12-20 08:38:28 +0000
commit73ccde8f6d04a246377cabaed2875e69d4b6b719 (patch)
treea81994659df453fd0c08bcef1cda819f6097e93d /UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
parent7bda8c648192d76f7b3f7cee54bd7b1c86a6a84f (diff)
downloadedk2-73ccde8f6d04a246377cabaed2875e69d4b6b719.tar.gz
edk2-73ccde8f6d04a246377cabaed2875e69d4b6b719.tar.bz2
edk2-73ccde8f6d04a246377cabaed2875e69d4b6b719.zip
UefiCpuPkg: Has APs in 64 bit long-mode before booting to OS.
During the finalization of Mp initialization before booting into the OS, depending on whether Mwait is supported or not, AsmRelocateApLoop places Aps in MWAIT-loop or HLT-loop. Since paging is necessary for long mode, the original implementation of moving APs to 32-bit was to disable paging to ensure that the booting does not crash. The current modification creates a page table in reserved memory, avoiding switching modes and reclaiming memory by OS. This modification is only for 64 bit mode. More specifically, we keep the AMD logic as the original code flow, extract and update the Intel-related code, where the APs would stay in 64-bit, and run in a Mwait or Hlt loop until the OS wake them up. Signed-off-by: Ray Ni <ray.ni@intel.com> Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
Diffstat (limited to 'UefiCpuPkg/Library/MpInitLib/DxeMpLib.c')
-rw-r--r--UefiCpuPkg/Library/MpInitLib/DxeMpLib.c84
1 files changed, 33 insertions, 51 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 445e0853d2..beab06a5b1 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -28,6 +28,7 @@ volatile BOOLEAN mStopCheckAllApsStatus = TRUE;
VOID *mReservedApLoopFunc = NULL;
UINTN mReservedTopOfApStack;
volatile UINT32 mNumberToFinish = 0;
+UINTN mApPageTable;
//
// Begin wakeup buffer allocation below 0x88000
@@ -407,12 +408,9 @@ RelocateApLoop (
AsmRelocateApLoopFunc (
MwaitSupport,
CpuMpData->ApTargetCState,
- CpuMpData->PmCodeSegment,
StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
(UINTN)&mNumberToFinish,
- CpuMpData->Pm16CodeSegment,
- CpuMpData->SevEsAPBuffer,
- CpuMpData->WakeupBuffer
+ mApPageTable
);
}
@@ -477,7 +475,6 @@ InitMpGlobalData (
)
{
EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS Address;
UINTN ApSafeBufferSize;
UINTN Index;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc;
@@ -545,60 +542,45 @@ InitMpGlobalData (
// Allocating it in advance since memory services are not available in
// Exit Boot Services callback function.
//
- ApSafeBufferSize = EFI_PAGES_TO_SIZE (
- EFI_SIZE_TO_PAGES (
- CpuMpData->AddressMap.RelocateApLoopFuncSize
- )
- );
- Address = BASE_4GB - 1;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiReservedMemoryType,
- EFI_SIZE_TO_PAGES (ApSafeBufferSize),
- &Address
- );
- ASSERT_EFI_ERROR (Status);
-
- mReservedApLoopFunc = (VOID *)(UINTN)Address;
- ASSERT (mReservedApLoopFunc != NULL);
-
- //
- // 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.
+ // +------------+
+ // | Ap Loop |
+ // +------------+
+ // | Stack * N |
+ // +------------+ (low address)
//
- Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc);
- if (!EFI_ERROR (Status)) {
- gDS->SetMemorySpaceAttributes (
- Address,
- ApSafeBufferSize,
- MemDesc.Attributes & (~EFI_MEMORY_XP)
- );
- }
-
ApSafeBufferSize = EFI_PAGES_TO_SIZE (
EFI_SIZE_TO_PAGES (
CpuMpData->CpuCount * AP_SAFE_STACK_SIZE
+ + CpuMpData->AddressMap.RelocateApLoopFuncSize
)
);
- Address = BASE_4GB - 1;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiReservedMemoryType,
- EFI_SIZE_TO_PAGES (ApSafeBufferSize),
- &Address
- );
- ASSERT_EFI_ERROR (Status);
- mReservedTopOfApStack = (UINTN)Address + ApSafeBufferSize;
+ mReservedTopOfApStack = (UINTN)AllocateReservedPages (EFI_SIZE_TO_PAGES (ApSafeBufferSize));
+ ASSERT (mReservedTopOfApStack != 0);
ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
- CopyMem (
- mReservedApLoopFunc,
- CpuMpData->AddressMap.RelocateApLoopFuncAddress,
- CpuMpData->AddressMap.RelocateApLoopFuncSize
- );
+ ASSERT ((AP_SAFE_STACK_SIZE & (CPU_STACK_ALIGNMENT - 1)) == 0);
+
+ mReservedApLoopFunc = (VOID *)(mReservedTopOfApStack + CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
+ if (StandardSignatureIsAuthenticAMD ()) {
+ CopyMem (
+ mReservedApLoopFunc,
+ CpuMpData->AddressMap.RelocateApLoopFuncAddressAmd,
+ CpuMpData->AddressMap.RelocateApLoopFuncSizeAmd
+ );
+ } else {
+ CopyMem (
+ mReservedApLoopFunc,
+ CpuMpData->AddressMap.RelocateApLoopFuncAddress,
+ CpuMpData->AddressMap.RelocateApLoopFuncSize
+ );
+
+ mApPageTable = CreatePageTable (
+ mReservedTopOfApStack,
+ ApSafeBufferSize
+ );
+ }
+
+ mReservedTopOfApStack += CpuMpData->CpuCount * AP_SAFE_STACK_SIZE;
Status = gBS->CreateEvent (
EVT_TIMER | EVT_NOTIFY_SIGNAL,