/** @file\r
Common header file for MP Initialize Library.\r
\r
- Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
+ Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2020, AMD Inc. All rights reserved.<BR>\r
\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
\r
#include <PiPei.h>\r
\r
-#include <Register/Cpuid.h>\r
-#include <Register/Msr.h>\r
-#include <Register/LocalApic.h>\r
-#include <Register/Microcode.h>\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
\r
#include <Library/MpInitLib.h>\r
#include <Library/BaseLib.h>\r
#include <Library/SynchronizationLib.h>\r
#include <Library/MtrrLib.h>\r
#include <Library/HobLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/MicrocodeLib.h>\r
+#include <ConfidentialComputingGuestAttr.h>\r
\r
-#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')\r
+#include <Register/Amd/Fam17Msr.h>\r
+#include <Register/Amd/Ghcb.h>\r
+\r
+#include <Guid/MicrocodePatchHob.h>\r
+\r
+#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')\r
\r
#define CPU_INIT_MP_LIB_HOB_GUID \\r
{ \\r
//\r
// The MP data for switch BSP\r
//\r
-#define CPU_SWITCH_STATE_IDLE 0\r
-#define CPU_SWITCH_STATE_STORED 1\r
-#define CPU_SWITCH_STATE_LOADED 2\r
+#define CPU_SWITCH_STATE_IDLE 0\r
+#define CPU_SWITCH_STATE_STORED 1\r
+#define CPU_SWITCH_STATE_LOADED 2\r
+\r
+//\r
+// Default maximum number of entries to store the microcode patches information\r
+//\r
+#define DEFAULT_MAX_MICROCODE_PATCH_NUM 8\r
+\r
+//\r
+// Data structure for microcode patch information\r
+//\r
+typedef struct {\r
+ UINTN Address;\r
+ UINTN Size;\r
+} MICROCODE_PATCH_INFO;\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
+ IA32_DESCRIPTOR Gdtr; // offset 8 / 16\r
+ IA32_DESCRIPTOR Idtr; // offset 14 / 26\r
} CPU_EXCHANGE_ROLE_INFO;\r
\r
//\r
//\r
// AP state\r
//\r
+// The state transitions for an AP when it process a procedure are:\r
+// Idle ----> Ready ----> Busy ----> Idle\r
+// [BSP] [AP] [AP]\r
+//\r
typedef enum {\r
CpuStateIdle,\r
CpuStateReady,\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
+ 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
typedef struct {\r
- SPIN_LOCK ApLock;\r
- volatile UINT32 *StartupApSignal;\r
- volatile UINTN ApFunction;\r
- volatile UINTN ApFunctionArgument;\r
- UINT32 InitialApicId;\r
- UINT32 ApicId;\r
- UINT32 Health;\r
- BOOLEAN CpuHealthy;\r
- volatile CPU_STATE State;\r
- CPU_VOLATILE_REGISTERS VolatileRegisters;\r
- BOOLEAN Waiting;\r
- BOOLEAN *Finished;\r
- UINT64 ExpectedTime;\r
- UINT64 CurrentTime;\r
- UINT64 TotalTime;\r
- EFI_EVENT WaitEvent;\r
+ SPIN_LOCK ApLock;\r
+ volatile UINT32 *StartupApSignal;\r
+ volatile UINTN ApFunction;\r
+ volatile UINTN ApFunctionArgument;\r
+ BOOLEAN CpuHealthy;\r
+ volatile CPU_STATE State;\r
+ CPU_VOLATILE_REGISTERS VolatileRegisters;\r
+ BOOLEAN Waiting;\r
+ BOOLEAN *Finished;\r
+ UINT64 ExpectedTime;\r
+ UINT64 CurrentTime;\r
+ UINT64 TotalTime;\r
+ EFI_EVENT WaitEvent;\r
+ UINT32 ProcessorSignature;\r
+ UINT8 PlatformId;\r
+ UINT64 MicrocodeEntryAddr;\r
+ UINT32 MicrocodeRevision;\r
+ SEV_ES_SAVE_AREA *SevEsSaveArea;\r
} CPU_AP_DATA;\r
\r
//\r
// we need to make sure the each fields offset same in different\r
// architecture.\r
//\r
+#pragma pack (1)\r
typedef struct {\r
- UINT32 InitialApicId;\r
- UINT32 ApicId;\r
- UINT32 Health;\r
+ UINT32 InitialApicId;\r
+ UINT32 ApicId;\r
+ UINT32 Health;\r
+ UINT64 ApTopOfStack;\r
} CPU_INFO_IN_HOB;\r
+#pragma pack ()\r
\r
//\r
// AP reset code information including code address and size,\r
// It is natural aligned by design.\r
//\r
typedef struct {\r
- UINT8 *RendezvousFunnelAddress;\r
- UINTN ModeEntryOffset;\r
- UINTN RendezvousFunnelSize;\r
- UINT8 *RelocateApLoopFuncAddress;\r
- UINTN RelocateApLoopFuncSize;\r
+ UINT8 *RendezvousFunnelAddress;\r
+ UINTN ModeEntryOffset;\r
+ UINTN RendezvousFunnelSize;\r
+ UINT8 *RelocateApLoopFuncAddress;\r
+ UINTN RelocateApLoopFuncSize;\r
+ UINTN ModeTransitionOffset;\r
+ UINTN SwitchToRealSize;\r
+ UINTN SwitchToRealOffset;\r
+ UINTN SwitchToRealNoNxOffset;\r
+ UINTN SwitchToRealPM16ModeOffset;\r
+ UINTN SwitchToRealPM16ModeSize;\r
} MP_ASSEMBLY_ADDRESS_MAP;\r
\r
-typedef struct _CPU_MP_DATA CPU_MP_DATA;\r
+typedef struct _CPU_MP_DATA CPU_MP_DATA;\r
\r
#pragma pack(1)\r
\r
// into this structure are used in assembly code in this module\r
//\r
typedef struct {\r
- UINTN Lock;\r
- UINTN StackStart;\r
- UINTN StackSize;\r
- UINTN CFunction;\r
- IA32_DESCRIPTOR GdtrProfile;\r
- IA32_DESCRIPTOR IdtrProfile;\r
- UINTN BufferStart;\r
- UINTN ModeOffset;\r
- UINTN NumApsExecuting;\r
- UINTN CodeSegment;\r
- UINTN DataSegment;\r
- UINTN EnableExecuteDisable;\r
- UINTN Cr3;\r
- CPU_MP_DATA *CpuMpData;\r
+ UINTN StackStart;\r
+ UINTN StackSize;\r
+ UINTN CFunction;\r
+ IA32_DESCRIPTOR GdtrProfile;\r
+ IA32_DESCRIPTOR IdtrProfile;\r
+ UINTN BufferStart;\r
+ UINTN ModeOffset;\r
+ UINTN ApIndex;\r
+ UINTN CodeSegment;\r
+ UINTN DataSegment;\r
+ UINTN EnableExecuteDisable;\r
+ UINTN Cr3;\r
+ UINTN InitFlag;\r
+ CPU_INFO_IN_HOB *CpuInfo;\r
+ UINTN NumApsExecuting;\r
+ CPU_MP_DATA *CpuMpData;\r
+ UINTN InitializeFloatingPointUnitsAddress;\r
+ UINT32 ModeTransitionMemory;\r
+ UINT16 ModeTransitionSegment;\r
+ UINT32 ModeHighMemory;\r
+ UINT16 ModeHighSegment;\r
+ //\r
+ // Enable5LevelPaging indicates whether 5-level paging is enabled in long mode.\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
// CPU MP Data save in memory\r
//\r
struct _CPU_MP_DATA {\r
- UINT64 CpuInfoInHob;\r
- UINT32 CpuCount;\r
- UINT32 BspNumber;\r
+ UINT64 CpuInfoInHob;\r
+ UINT32 CpuCount;\r
+ UINT32 BspNumber;\r
//\r
// The above fields data will be passed from PEI to DXE\r
// Please make sure the fields offset same in the different\r
// architecture.\r
//\r
- SPIN_LOCK MpLock;\r
- UINTN Buffer;\r
- UINTN CpuApStackSize;\r
- MP_ASSEMBLY_ADDRESS_MAP AddressMap;\r
- UINTN WakeupBuffer;\r
- UINTN BackupBuffer;\r
- UINTN BackupBufferSize;\r
- BOOLEAN SaveRestoreFlag;\r
-\r
- volatile UINT32 StartCount;\r
- volatile UINT32 FinishedCount;\r
- volatile UINT32 RunningCount;\r
- BOOLEAN SingleThread;\r
- EFI_AP_PROCEDURE Procedure;\r
- VOID *ProcArguments;\r
- BOOLEAN *Finished;\r
- UINT64 ExpectedTime;\r
- UINT64 CurrentTime;\r
- UINT64 TotalTime;\r
- EFI_EVENT WaitEvent;\r
- UINTN **FailedCpuList;\r
-\r
- AP_INIT_STATE InitFlag;\r
- BOOLEAN X2ApicEnable;\r
- BOOLEAN SwitchBspFlag;\r
- CPU_EXCHANGE_ROLE_INFO BSPInfo;\r
- CPU_EXCHANGE_ROLE_INFO APInfo;\r
- MTRR_SETTINGS MtrrTable;\r
- UINT8 ApLoopMode;\r
- UINT8 ApTargetCState;\r
- UINT16 PmCodeSegment;\r
- CPU_AP_DATA *CpuData;\r
- volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;\r
+ SPIN_LOCK MpLock;\r
+ UINTN Buffer;\r
+ UINTN CpuApStackSize;\r
+ MP_ASSEMBLY_ADDRESS_MAP AddressMap;\r
+ UINTN WakeupBuffer;\r
+ UINTN WakeupBufferHigh;\r
+ UINTN BackupBuffer;\r
+ UINTN BackupBufferSize;\r
+\r
+ volatile UINT32 FinishedCount;\r
+ UINT32 RunningCount;\r
+ BOOLEAN SingleThread;\r
+ EFI_AP_PROCEDURE Procedure;\r
+ VOID *ProcArguments;\r
+ BOOLEAN *Finished;\r
+ UINT64 ExpectedTime;\r
+ UINT64 CurrentTime;\r
+ UINT64 TotalTime;\r
+ EFI_EVENT WaitEvent;\r
+ UINTN **FailedCpuList;\r
+\r
+ AP_INIT_STATE InitFlag;\r
+ BOOLEAN SwitchBspFlag;\r
+ UINTN NewBspNumber;\r
+ CPU_EXCHANGE_ROLE_INFO BSPInfo;\r
+ CPU_EXCHANGE_ROLE_INFO APInfo;\r
+ MTRR_SETTINGS MtrrTable;\r
+ UINT8 ApLoopMode;\r
+ UINT8 ApTargetCState;\r
+ UINT16 PmCodeSegment;\r
+ UINT16 Pm16CodeSegment;\r
+ CPU_AP_DATA *CpuData;\r
+ volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;\r
+\r
+ UINT32 CurrentTimerCount;\r
+ UINTN DivideValue;\r
+ UINT8 Vector;\r
+ BOOLEAN PeriodicMode;\r
+ BOOLEAN TimerInterruptState;\r
+ UINT64 MicrocodePatchAddress;\r
+ UINT64 MicrocodePatchRegionSize;\r
+\r
+ //\r
+ // Whether need to use Init-Sipi-Sipi to wake up the APs.\r
+ // Two cases need to set this value to TRUE. One is in HLT\r
+ // loop mode, the other is resume from S3 which loop mode\r
+ // will be hardcode change to HLT mode by PiSmmCpuDxeSmm\r
+ // driver.\r
+ //\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
+\r
+ UINT64 GhcbBase;\r
};\r
\r
-extern EFI_GUID mCpuInitMpLibHobGuid;\r
+#define AP_SAFE_STACK_SIZE 128\r
+#define AP_RESET_STACK_SIZE AP_SAFE_STACK_SIZE\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+ UINT8 InsnBuffer[8];\r
+ UINT16 Rip;\r
+ UINT16 Segment;\r
+} SEV_ES_AP_JMP_FAR;\r
+\r
+#pragma pack()\r
+\r
+/**\r
+ Assembly code to move an AP from long mode to real mode.\r
+\r
+ Move an AP from long mode to real mode in preparation to invoking\r
+ the reset vector. This is used for SEV-ES guests where a hypervisor\r
+ is not allowed to set the CS and RIP to point to the reset vector.\r
+\r
+ @param[in] BufferStart The reset vector target.\r
+ @param[in] Code16 16-bit protected mode code segment value.\r
+ @param[in] Code32 32-bit protected mode code segment value.\r
+ @param[in] StackStart The start of a stack to be used for transitioning\r
+ from long mode to real mode.\r
+**/\r
+typedef\r
+ VOID\r
+(EFIAPI AP_RESET)(\r
+ IN UINTN BufferStart,\r
+ IN UINT16 Code16,\r
+ IN UINT16 Code32,\r
+ IN UINTN StackStart\r
+ );\r
+\r
+extern EFI_GUID mCpuInitMpLibHobGuid;\r
\r
/**\r
Assembly code to place AP into safe loop mode.\r
@param[in] PmCodeSegment Protected mode code segment value.\r
**/\r
typedef\r
-VOID\r
-(EFIAPI * ASM_RELOCATE_AP_LOOP) (\r
+ VOID\r
+(EFIAPI *ASM_RELOCATE_AP_LOOP)(\r
IN BOOLEAN MwaitSupport,\r
IN UINTN ApTargetCState,\r
- IN UINTN PmCodeSegment\r
+ IN UINTN PmCodeSegment,\r
+ IN UINTN TopOfApStack,\r
+ IN UINTN NumberToFinish,\r
+ IN UINTN Pm16CodeSegment,\r
+ IN UINTN SevEsAPJumpTable,\r
+ IN UINTN WakeupBuffer\r
);\r
\r
/**\r
VOID\r
EFIAPI\r
AsmGetAddressMap (\r
- OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap\r
+ OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap\r
);\r
\r
/**\r
VOID\r
EFIAPI\r
AsmExchangeRole (\r
- IN CPU_EXCHANGE_ROLE_INFO *MyInfo,\r
- IN CPU_EXCHANGE_ROLE_INFO *OthersInfo\r
+ IN CPU_EXCHANGE_ROLE_INFO *MyInfo,\r
+ IN CPU_EXCHANGE_ROLE_INFO *OthersInfo\r
);\r
\r
/**\r
**/\r
VOID\r
SaveCpuMpData (\r
- IN CPU_MP_DATA *CpuMpData\r
+ IN CPU_MP_DATA *CpuMpData\r
);\r
\r
/**\r
- Allocate reset vector buffer.\r
+ Get available system memory below 1MB by specified size.\r
\r
- @param[in, out] CpuMpData The pointer to CPU MP Data structure.\r
+ @param[in] WakeupBufferSize Wakeup buffer size required\r
+\r
+ @retval other Return wakeup buffer address below 1MB.\r
+ @retval -1 Cannot find free memory below 1MB.\r
**/\r
-VOID\r
-AllocateResetVector (\r
- IN OUT CPU_MP_DATA *CpuMpData\r
+UINTN\r
+GetWakeupBuffer (\r
+ IN UINTN WakeupBufferSize\r
);\r
\r
/**\r
- Free AP reset vector buffer.\r
+ Get available EfiBootServicesCode memory below 4GB by specified size.\r
\r
- @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+ This buffer is required to safely transfer AP from real address mode to\r
+ protected mode or long mode, due to the fact that the buffer returned by\r
+ GetWakeupBuffer() may be marked as non-executable.\r
+\r
+ @param[in] BufferSize Wakeup transition buffer size.\r
+\r
+ @retval other Return wakeup transition buffer address below 4GB.\r
+ @retval 0 Cannot find free memory below 4GB.\r
**/\r
-VOID\r
-FreeResetVector (\r
- IN CPU_MP_DATA *CpuMpData\r
+UINTN\r
+GetModeTransitionBuffer (\r
+ IN UINTN BufferSize\r
+ );\r
+\r
+/**\r
+ Return the address of the SEV-ES AP jump table.\r
+\r
+ This buffer is required in order for an SEV-ES guest to transition from\r
+ UEFI into an OS.\r
+\r
+ @return Return SEV-ES AP jump table buffer\r
+**/\r
+UINTN\r
+GetSevEsAPMemory (\r
+ VOID\r
);\r
\r
/**\r
@param[in] ProcessorNumber The handle number of specified processor\r
@param[in] Procedure The function to be invoked by AP\r
@param[in] ProcedureArgument The argument to be passed into AP function\r
+ @param[in] WakeUpDisabledAps Whether need to wake up disabled APs in broadcast mode.\r
**/\r
VOID\r
WakeUpAP (\r
- IN CPU_MP_DATA *CpuMpData,\r
- IN BOOLEAN Broadcast,\r
- IN UINTN ProcessorNumber,\r
- IN EFI_AP_PROCEDURE Procedure, OPTIONAL\r
- IN VOID *ProcedureArgument OPTIONAL\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ IN BOOLEAN Broadcast,\r
+ IN UINTN ProcessorNumber,\r
+ IN EFI_AP_PROCEDURE Procedure OPTIONAL,\r
+ IN VOID *ProcedureArgument OPTIONAL,\r
+ IN BOOLEAN WakeUpDisabledAps\r
);\r
\r
/**\r
**/\r
VOID\r
InitMpGlobalData (\r
- IN CPU_MP_DATA *CpuMpData\r
+ IN CPU_MP_DATA *CpuMpData\r
);\r
\r
/**\r
number. If FALSE, then all the enabled APs\r
execute the function specified by Procedure\r
simultaneously.\r
+ @param[in] ExcludeBsp Whether let BSP also trig this task.\r
@param[in] WaitEvent The event created by the caller with CreateEvent()\r
service.\r
- @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for\r
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for\r
APs to return from Procedure, either for\r
blocking or non-blocking mode.\r
@param[in] ProcedureArgument The parameter passed into Procedure for\r
\r
**/\r
EFI_STATUS\r
-StartupAllAPsWorker (\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
+StartupAllCPUsWorker (\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN BOOLEAN SingleThread,\r
+ IN BOOLEAN ExcludeBsp,\r
+ IN EFI_EVENT WaitEvent OPTIONAL,\r
+ IN UINTN TimeoutInMicroseconds,\r
+ IN VOID *ProcedureArgument OPTIONAL,\r
+ OUT UINTN **FailedCpuList OPTIONAL\r
);\r
\r
/**\r
@param[in] ProcessorNumber The handle number of the AP.\r
@param[in] WaitEvent The event created by the caller with CreateEvent()\r
service.\r
- @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for\r
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for\r
APs to return from Procedure, either for\r
blocking or non-blocking mode.\r
@param[in] ProcedureArgument The parameter passed into Procedure for\r
**/\r
EFI_STATUS\r
StartupThisAPWorker (\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
/**\r
enabled AP. Otherwise, it will be disabled.\r
\r
@retval EFI_SUCCESS BSP successfully switched.\r
- @retval others Failed to switch BSP. \r
+ @retval others Failed to switch BSP.\r
\r
**/\r
EFI_STATUS\r
SwitchBSPWorker (\r
- IN UINTN ProcessorNumber,\r
- IN BOOLEAN EnableOldBSP\r
+ IN UINTN ProcessorNumber,\r
+ IN BOOLEAN EnableOldBSP\r
);\r
\r
/**\r
**/\r
EFI_STATUS\r
EnableDisableApWorker (\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
/**\r
**/\r
EFI_STATUS\r
CheckThisAP (\r
- IN UINTN ProcessorNumber\r
+ IN UINTN ProcessorNumber\r
);\r
\r
/**\r
/**\r
Detect whether specified processor can find matching microcode patch and load it.\r
\r
- @param[in] PeiCpuMpData Pointer to PEI CPU MP Data\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+ @param[in] ProcessorNumber The handle number of the processor. The range is\r
+ from 0 to the total number of logical processors\r
+ minus 1.\r
**/\r
VOID\r
MicrocodeDetect (\r
- IN CPU_MP_DATA *CpuMpData\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ IN UINTN ProcessorNumber\r
+ );\r
+\r
+/**\r
+ Shadow the required microcode patches data into memory.\r
+\r
+ @param[in, out] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+ShadowMicrocodeUpdatePatch (\r
+ IN OUT CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
+/**\r
+ Get the cached microcode patch base address and size from the microcode patch\r
+ information cache HOB.\r
+\r
+ @param[out] Address Base address of the microcode patches data.\r
+ It will be updated if the microcode patch\r
+ information cache HOB is found.\r
+ @param[out] RegionSize Size of the microcode patches data.\r
+ It will be updated if the microcode patch\r
+ information cache HOB is found.\r
+\r
+ @retval TRUE The microcode patch information cache HOB is found.\r
+ @retval FALSE The microcode patch information cache HOB is not found.\r
+\r
+**/\r
+BOOLEAN\r
+GetMicrocodePatchInfoFromHob (\r
+ UINT64 *Address,\r
+ UINT64 *RegionSize\r
);\r
\r
/**\r
);\r
\r
/**\r
- Notify function on End Of PEI PPI.\r
+ Enable Debug Agent to support source debugging on AP function.\r
\r
- On S3 boot, this function will restore wakeup buffer data.\r
- On normal boot, this function will flag wakeup buffer to be un-used type.\r
+**/\r
+VOID\r
+EnableDebugAgent (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Find the current Processor number by APIC ID.\r
+\r
+ @param[in] CpuMpData Pointer to PEI CPU MP Data\r
+ @param[out] ProcessorNumber Return the pocessor number found\r
+\r
+ @retval EFI_SUCCESS ProcessorNumber is found and returned.\r
+ @retval EFI_NOT_FOUND ProcessorNumber is not found.\r
+**/\r
+EFI_STATUS\r
+GetProcessorNumber (\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ OUT UINTN *ProcessorNumber\r
+ );\r
+\r
+/**\r
+ This funtion will try to invoke platform specific microcode shadow logic to\r
+ relocate microcode update patches into memory.\r
\r
- @param[in] PeiServices The pointer to the PEI Services Table.\r
- @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
- @param[in] Ppi Address of the PPI that was installed.\r
+ @param[in, out] CpuMpData The pointer to CPU MP Data structure.\r
\r
- @retval EFI_SUCCESS When everything is OK.\r
+ @retval EFI_SUCCESS Shadow microcode success.\r
+ @retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation.\r
+ @retval EFI_UNSUPPORTED Can't find platform specific microcode shadow\r
+ PPI/Protocol.\r
**/\r
EFI_STATUS\r
+PlatformShadowMicrocode (\r
+ IN OUT CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
+/**\r
+ Allocate the SEV-ES AP jump table buffer.\r
+\r
+ @param[in, out] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+AllocateSevEsAPMemory (\r
+ IN OUT CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
+/**\r
+ Program the SEV-ES AP jump table buffer.\r
+\r
+ @param[in] SipiVector The SIPI vector used for the AP Reset\r
+**/\r
+VOID\r
+SetSevEsJumpTable (\r
+ IN UINTN SipiVector\r
+ );\r
+\r
+/**\r
+ The function puts the AP in halt loop.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+SevEsPlaceApHlt (\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
-CpuMpEndOfPeiCallback (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
- IN VOID *Ppi\r
+ConfidentialComputingGuestHas (\r
+ CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr\r
);\r
\r
-#endif\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