/** @file\r
Common header file for MP Initialize Library.\r
\r
- Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>\r
Copyright (c) 2020, AMD Inc. All rights reserved.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
#include <Register/Intel/Cpuid.h>\r
#include <Register/Amd/Cpuid.h>\r
+#include <Register/Amd/Ghcb.h>\r
#include <Register/Intel/Msr.h>\r
#include <Register/Intel/LocalApic.h>\r
#include <Register/Intel/Microcode.h>\r
#include <Library/HobLib.h>\r
#include <Library/PcdLib.h>\r
#include <Library/MicrocodeLib.h>\r
+#include <ConfidentialComputingGuestAttr.h>\r
\r
#include <Register/Amd/Fam17Msr.h>\r
#include <Register/Amd/Ghcb.h>\r
UINTN Size;\r
} MICROCODE_PATCH_INFO;\r
\r
+//\r
+// CPU volatile registers around INIT-SIPI-SIPI\r
+//\r
+typedef struct {\r
+ UINTN Cr0;\r
+ UINTN Cr3;\r
+ UINTN Cr4;\r
+ UINTN Dr0;\r
+ UINTN Dr1;\r
+ UINTN Dr2;\r
+ UINTN Dr3;\r
+ UINTN Dr6;\r
+ UINTN Dr7;\r
+ IA32_DESCRIPTOR Gdtr;\r
+ IA32_DESCRIPTOR Idtr;\r
+ UINT16 Tr;\r
+} CPU_VOLATILE_REGISTERS;\r
+\r
//\r
// CPU exchange information for switch BSP\r
//\r
typedef struct {\r
- UINT8 State; // offset 0\r
- UINTN StackPointer; // offset 4 / 8\r
- IA32_DESCRIPTOR Gdtr; // offset 8 / 16\r
- IA32_DESCRIPTOR Idtr; // offset 14 / 26\r
+ UINT8 State; // offset 0\r
+ UINTN StackPointer; // offset 4 / 8\r
+ CPU_VOLATILE_REGISTERS VolatileRegisters; // offset 8 / 16\r
} CPU_EXCHANGE_ROLE_INFO;\r
\r
//\r
CpuStateDisabled\r
} CPU_STATE;\r
\r
-//\r
-// CPU volatile registers around INIT-SIPI-SIPI\r
-//\r
-typedef struct {\r
- UINTN Cr0;\r
- UINTN Cr3;\r
- UINTN Cr4;\r
- UINTN Dr0;\r
- UINTN Dr1;\r
- UINTN Dr2;\r
- UINTN Dr3;\r
- UINTN Dr6;\r
- UINTN Dr7;\r
- IA32_DESCRIPTOR Gdtr;\r
- IA32_DESCRIPTOR Idtr;\r
- UINT16 Tr;\r
-} CPU_VOLATILE_REGISTERS;\r
-\r
//\r
// AP related data\r
//\r
UINT8 PlatformId;\r
UINT64 MicrocodeEntryAddr;\r
UINT32 MicrocodeRevision;\r
+ SEV_ES_SAVE_AREA *SevEsSaveArea;\r
} CPU_AP_DATA;\r
\r
//\r
UINT8 *RendezvousFunnelAddress;\r
UINTN ModeEntryOffset;\r
UINTN RendezvousFunnelSize;\r
- UINT8 *RelocateApLoopFuncAddress;\r
- UINTN RelocateApLoopFuncSize;\r
+ UINT8 *RelocateApLoopFuncAddressGeneric;\r
+ UINTN RelocateApLoopFuncSizeGeneric;\r
+ UINT8 *RelocateApLoopFuncAddressAmdSev;\r
+ UINTN RelocateApLoopFuncSizeAmdSev;\r
UINTN ModeTransitionOffset;\r
- UINTN SwitchToRealSize;\r
- UINTN SwitchToRealOffset;\r
UINTN SwitchToRealNoNxOffset;\r
UINTN SwitchToRealPM16ModeOffset;\r
UINTN SwitchToRealPM16ModeSize;\r
//\r
BOOLEAN Enable5LevelPaging;\r
BOOLEAN SevEsIsEnabled;\r
+ BOOLEAN SevSnpIsEnabled;\r
UINTN GhcbBase;\r
+ BOOLEAN ExtTopoAvail;\r
} MP_CPU_EXCHANGE_INFO;\r
\r
#pragma pack()\r
BOOLEAN WakeUpByInitSipiSipi;\r
\r
BOOLEAN SevEsIsEnabled;\r
+ BOOLEAN SevSnpIsEnabled;\r
+ BOOLEAN UseSevEsAPMethod;\r
UINTN SevEsAPBuffer;\r
UINTN SevEsAPResetStackStart;\r
CPU_MP_DATA *NewCpuMpData;\r
UINT64 GhcbBase;\r
};\r
\r
+//\r
+// AP_STACK_DATA is stored at the top of each AP stack.\r
+//\r
+typedef struct {\r
+ UINTN Bist;\r
+ CPU_MP_DATA *MpData;\r
+} AP_STACK_DATA;\r
+\r
#define AP_SAFE_STACK_SIZE 128\r
#define AP_RESET_STACK_SIZE AP_SAFE_STACK_SIZE\r
+STATIC_ASSERT ((AP_SAFE_STACK_SIZE & (CPU_STACK_ALIGNMENT - 1)) == 0, "AP_SAFE_STACK_SIZE is not aligned with CPU_STACK_ALIGNMENT");\r
\r
#pragma pack(1)\r
\r
**/\r
typedef\r
VOID\r
-(EFIAPI *ASM_RELOCATE_AP_LOOP)(\r
+(EFIAPI *ASM_RELOCATE_AP_LOOP_GENERIC)(\r
+ IN BOOLEAN MwaitSupport,\r
+ IN UINTN ApTargetCState,\r
+ IN UINTN TopOfApStack,\r
+ IN UINTN NumberToFinish,\r
+ IN UINTN Cr3\r
+ );\r
+\r
+/**\r
+ Assembly code to place AP into safe loop mode for Amd processors\r
+ with Sev enabled.\r
+ Place AP into targeted C-State if MONITOR is supported, otherwise\r
+ place AP into hlt state.\r
+ Place AP in protected mode if the current is long mode. Due to AP maybe\r
+ wakeup by some hardware event. It could avoid accessing page table that\r
+ may not available during booting to OS.\r
+ @param[in] MwaitSupport TRUE indicates MONITOR is supported.\r
+ FALSE indicates MONITOR is not supported.\r
+ @param[in] ApTargetCState Target C-State value.\r
+ @param[in] PmCodeSegment Protected mode code segment value.\r
+**/\r
+typedef\r
+ VOID\r
+(EFIAPI *ASM_RELOCATE_AP_LOOP_AMDSEV)(\r
IN BOOLEAN MwaitSupport,\r
IN UINTN ApTargetCState,\r
IN UINTN PmCodeSegment,\r
IN CPU_EXCHANGE_ROLE_INFO *OthersInfo\r
);\r
\r
+typedef union {\r
+ VOID *Data;\r
+ ASM_RELOCATE_AP_LOOP_AMDSEV AmdSevEntry; // 64-bit AMD Sev processors\r
+ ASM_RELOCATE_AP_LOOP_GENERIC GenericEntry; // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or AMD non-Sev processors\r
+} RELOCATE_AP_LOOP_ENTRY;\r
+\r
/**\r
Get the pointer to CPU MP Data structure.\r
\r
@retval 0 Cannot find free memory below 4GB.\r
**/\r
UINTN\r
-GetModeTransitionBuffer (\r
+AllocateCodeBuffer (\r
IN UINTN BufferSize\r
);\r
\r
VOID\r
);\r
\r
+/**\r
+ Create 1:1 mapping page table in reserved memory to map the specified address range.\r
+ @param[in] LinearAddress The start of the linear address range.\r
+ @param[in] Length The length of the linear address range.\r
+ @return The page table to be created.\r
+**/\r
+UINTN\r
+CreatePageTable (\r
+ IN UINTN Address,\r
+ IN UINTN Length\r
+ );\r
+\r
/**\r
This function will be called by BSP to wakeup AP.\r
\r
IN UINTN ProcessorNumber,\r
IN EFI_AP_PROCEDURE Procedure OPTIONAL,\r
IN VOID *ProcedureArgument OPTIONAL,\r
- IN BOOLEAN WakeUpDisabledAps OPTIONAL\r
+ IN BOOLEAN WakeUpDisabledAps\r
);\r
\r
/**\r
CPU_MP_DATA *CpuMpData\r
);\r
\r
+/**\r
+ Check if the specified confidential computing attribute is active.\r
+\r
+ @retval TRUE The specified Attr is active.\r
+ @retval FALSE The specified Attr is not active.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ConfidentialComputingGuestHas (\r
+ CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr\r
+ );\r
+\r
+/**\r
+ The function fills the exchange data for the AP.\r
+\r
+ @param[in] ExchangeInfo The pointer to CPU Exchange Data structure\r
+**/\r
+VOID\r
+FillExchangeInfoDataSevEs (\r
+ IN volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo\r
+ );\r
+\r
+/**\r
+ Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.\r
+\r
+ @param[in] PageAddress\r
+ @param[in] VmsaPage\r
+\r
+ @return RMPADJUST return value\r
+**/\r
+UINT32\r
+SevSnpRmpAdjust (\r
+ IN EFI_PHYSICAL_ADDRESS PageAddress,\r
+ IN BOOLEAN VmsaPage\r
+ );\r
+\r
+/**\r
+ Create an SEV-SNP AP save area (VMSA) for use in running the vCPU.\r
+\r
+ @param[in] CpuMpData Pointer to CPU MP Data\r
+ @param[in] CpuData Pointer to CPU AP Data\r
+ @param[in] ApicId APIC ID of the vCPU\r
+**/\r
+VOID\r
+SevSnpCreateSaveArea (\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ IN CPU_AP_DATA *CpuData,\r
+ UINT32 ApicId\r
+ );\r
+\r
+/**\r
+ Create SEV-SNP APs.\r
+\r
+ @param[in] CpuMpData Pointer to CPU MP Data\r
+ @param[in] ProcessorNumber The handle number of specified processor\r
+ (-1 for all APs)\r
+**/\r
+VOID\r
+SevSnpCreateAP (\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ IN INTN ProcessorNumber\r
+ );\r
+\r
#endif\r