/** @file\r
MP initialize support functions for DXE phase.\r
\r
- Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/DebugAgentLib.h>\r
#include <Library/DxeServicesTableLib.h>\r
-#include <Library/VmgExitLib.h>\r
+#include <Library/CcExitLib.h>\r
#include <Register/Amd/Fam17Msr.h>\r
#include <Register/Amd/Ghcb.h>\r
\r
\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
+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
+RELOCATE_AP_LOOP_ENTRY mReservedApLoop;\r
+UINTN mReservedTopOfApStack;\r
+volatile UINT32 mNumberToFinish = 0;\r
+UINTN mApPageTable;\r
\r
//\r
// Begin wakeup buffer allocation below 0x88000\r
EFI_PHYSICAL_ADDRESS StartAddress;\r
EFI_MEMORY_TYPE MemoryType;\r
\r
- if (PcdGetBool (PcdSevEsIsEnabled)) {\r
+ if (ConfidentialComputingGuestHas (CCAttrAmdSevEs) &&\r
+ !ConfidentialComputingGuestHas (CCAttrAmdSevSnp))\r
+ {\r
+ //\r
+ // An SEV-ES-only guest requires the memory to be reserved. SEV-SNP, which\r
+ // is also considered SEV-ES, uses a different AP startup method, though,\r
+ // which does not have the same requirement.\r
+ //\r
MemoryType = EfiReservedMemoryType;\r
} else {\r
MemoryType = EfiBootServicesData;\r
// LagacyBios driver depends on CPU Arch protocol which guarantees below\r
// allocation runs earlier than LegacyBios driver.\r
//\r
- if (PcdGetBool (PcdSevEsIsEnabled)) {\r
+ if (ConfidentialComputingGuestHas (CCAttrAmdSevEs)) {\r
//\r
// SEV-ES Wakeup buffer should be under 0x88000 and under any previous one\r
//\r
ASSERT_EFI_ERROR (Status);\r
if (EFI_ERROR (Status)) {\r
StartAddress = (EFI_PHYSICAL_ADDRESS)-1;\r
- } else if (PcdGetBool (PcdSevEsIsEnabled)) {\r
+ } else if (ConfidentialComputingGuestHas (CCAttrAmdSevEs)) {\r
//\r
// Next SEV-ES wakeup buffer allocation must be below this allocation\r
//\r
@retval 0 Cannot find free memory below 4GB.\r
**/\r
UINTN\r
-GetModeTransitionBuffer (\r
+AllocateCodeBuffer (\r
IN UINTN BufferSize\r
)\r
{\r
Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);\r
Ghcb = Msr.Ghcb;\r
\r
- VmgInit (Ghcb, &InterruptState);\r
- VmgExit (Ghcb, SVM_EXIT_AP_JUMP_TABLE, 0, (UINT64)(UINTN)StartAddress);\r
- VmgDone (Ghcb, InterruptState);\r
+ CcExitVmgInit (Ghcb, &InterruptState);\r
+ CcExitVmgExit (Ghcb, SVM_EXIT_AP_JUMP_TABLE, 0, (UINT64)(UINTN)StartAddress);\r
+ CcExitVmgDone (Ghcb, InterruptState);\r
\r
return (UINTN)StartAddress;\r
}\r
IN OUT VOID *Buffer\r
)\r
{\r
- CPU_MP_DATA *CpuMpData;\r
- BOOLEAN MwaitSupport;\r
- ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc;\r
- UINTN ProcessorNumber;\r
- UINTN StackStart;\r
+ CPU_MP_DATA *CpuMpData;\r
+ BOOLEAN MwaitSupport;\r
+ UINTN ProcessorNumber;\r
+ UINTN StackStart;\r
\r
MpInitLibWhoAmI (&ProcessorNumber);\r
CpuMpData = GetCpuMpData ();\r
MwaitSupport = IsMwaitSupport ();\r
- if (CpuMpData->SevEsIsEnabled) {\r
+ if (CpuMpData->UseSevEsAPMethod) {\r
+ //\r
+ // 64-bit AMD processors with SEV-ES\r
+ //\r
StackStart = CpuMpData->SevEsAPResetStackStart;\r
+ mReservedApLoop.AmdSevEntry (\r
+ MwaitSupport,\r
+ CpuMpData->ApTargetCState,\r
+ CpuMpData->PmCodeSegment,\r
+ StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,\r
+ (UINTN)&mNumberToFinish,\r
+ CpuMpData->Pm16CodeSegment,\r
+ CpuMpData->SevEsAPBuffer,\r
+ CpuMpData->WakeupBuffer\r
+ );\r
} else {\r
+ //\r
+ // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES\r
+ //\r
StackStart = mReservedTopOfApStack;\r
+ mReservedApLoop.GenericEntry (\r
+ MwaitSupport,\r
+ CpuMpData->ApTargetCState,\r
+ StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,\r
+ (UINTN)&mNumberToFinish,\r
+ mApPageTable\r
+ );\r
}\r
\r
- AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP)(UINTN)mReservedApLoopFunc;\r
- AsmRelocateApLoopFunc (\r
- MwaitSupport,\r
- CpuMpData->ApTargetCState,\r
- CpuMpData->PmCodeSegment,\r
- StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,\r
- (UINTN)&mNumberToFinish,\r
- CpuMpData->Pm16CodeSegment,\r
- CpuMpData->SevEsAPBuffer,\r
- CpuMpData->WakeupBuffer\r
- );\r
//\r
// It should never reach here\r
//\r
CpuPause ();\r
}\r
\r
- if (CpuMpData->SevEsIsEnabled && (CpuMpData->WakeupBuffer != (UINTN)-1)) {\r
+ if (CpuMpData->UseSevEsAPMethod && (CpuMpData->WakeupBuffer != (UINTN)-1)) {\r
//\r
// There are APs present. Re-use reserved memory area below 1MB from\r
// WakeupBuffer as the area to be used for transitioning to 16-bit mode\r
{\r
EFI_STATUS Status;\r
EFI_PHYSICAL_ADDRESS Address;\r
- UINTN ApSafeBufferSize;\r
UINTN Index;\r
EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc;\r
UINTN StackBase;\r
CPU_INFO_IN_HOB *CpuInfoInHob;\r
+ MP_ASSEMBLY_ADDRESS_MAP *AddressMap;\r
+ UINT8 *ApLoopFunc;\r
+ UINTN ApLoopFuncSize;\r
+ UINTN StackPages;\r
+ UINTN FuncPages;\r
\r
SaveCpuMpData (CpuMpData);\r
\r
}\r
}\r
\r
+ AddressMap = &CpuMpData->AddressMap;\r
+ if (CpuMpData->UseSevEsAPMethod) {\r
+ //\r
+ // 64-bit AMD processors with SEV-ES\r
+ //\r
+ Address = BASE_4GB - 1;\r
+ ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmdSev;\r
+ ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev;\r
+ } else {\r
+ //\r
+ // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES\r
+ //\r
+ Address = MAX_ADDRESS;\r
+ ApLoopFunc = AddressMap->RelocateApLoopFuncAddressGeneric;\r
+ ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric;\r
+ }\r
+\r
//\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
// Allocating it in advance since memory services are not available in\r
// Exit Boot Services callback function.\r
//\r
- ApSafeBufferSize = EFI_PAGES_TO_SIZE (\r
- EFI_SIZE_TO_PAGES (\r
- CpuMpData->AddressMap.RelocateApLoopFuncSize\r
- )\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
+ // +------------+ (TopOfApStack)\r
+ // | Stack * N |\r
+ // +------------+ (stack base, 4k aligned)\r
+ // | Padding |\r
+ // +------------+\r
+ // | Ap Loop |\r
+ // +------------+ ((low address, 4k-aligned)\r
+ //\r
\r
- mReservedApLoopFunc = (VOID *)(UINTN)Address;\r
- ASSERT (mReservedApLoopFunc != NULL);\r
+ StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);\r
+ FuncPages = EFI_SIZE_TO_PAGES (ApLoopFuncSize);\r
+\r
+ Status = gBS->AllocatePages (\r
+ AllocateMaxAddress,\r
+ EfiReservedMemoryType,\r
+ StackPages + FuncPages,\r
+ &Address\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
\r
//\r
// Make sure that the buffer memory is executable if NX protection is enabled\r
if (!EFI_ERROR (Status)) {\r
gDS->SetMemorySpaceAttributes (\r
Address,\r
- ApSafeBufferSize,\r
+ EFI_PAGES_TO_SIZE (FuncPages),\r
MemDesc.Attributes & (~EFI_MEMORY_XP)\r
);\r
}\r
\r
- ApSafeBufferSize = EFI_PAGES_TO_SIZE (\r
- EFI_SIZE_TO_PAGES (\r
- CpuMpData->CpuCount * AP_SAFE_STACK_SIZE\r
- )\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
-\r
- mReservedTopOfApStack = (UINTN)Address + ApSafeBufferSize;\r
+ mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages);\r
ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);\r
- CopyMem (\r
- mReservedApLoopFunc,\r
- CpuMpData->AddressMap.RelocateApLoopFuncAddress,\r
- CpuMpData->AddressMap.RelocateApLoopFuncSize\r
- );\r
+ mReservedApLoop.Data = (VOID *)(UINTN)Address;\r
+ ASSERT (mReservedApLoop.Data != NULL);\r
+ CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize);\r
+ if (!CpuMpData->UseSevEsAPMethod) {\r
+ //\r
+ // processors without SEV-ES\r
+ //\r
+ mApPageTable = CreatePageTable (\r
+ (UINTN)Address,\r
+ EFI_PAGES_TO_SIZE (StackPages+FuncPages)\r
+ );\r
+ }\r
\r
Status = gBS->CreateEvent (\r
EVT_TIMER | EVT_NOTIFY_SIGNAL,\r