/** @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
+#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
+ 0x58eb6a19, 0x3699, 0x4c68, { 0xa8, 0x36, 0xda, 0xcd, 0x8e, 0xdc, 0xad, 0x4a } \\r
+ }\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
+\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
+} CPU_EXCHANGE_ROLE_INFO;\r
+\r
+//\r
+// AP loop state when APs are in idle state\r
+// It's value is the same with PcdCpuApLoopMode\r
+//\r
+typedef enum {\r
+ ApInHltLoop = 1,\r
+ ApInMwaitLoop = 2,\r
+ ApInRunLoop = 3\r
+} AP_LOOP_MODE;\r
+\r
+//\r
+// AP initialization state during APs wakeup\r
+//\r
+typedef enum {\r
+ ApInitConfig = 1,\r
+ ApInitReconfig = 2,\r
+ ApInitDone = 3\r
+} AP_INIT_STATE;\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
+ CpuStateBusy,\r
+ CpuStateFinished,\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
+typedef struct {\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
+// Basic CPU information saved in Guided HOB.\r
+// Because the contents will be shard between PEI and DXE,\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
+ UINT64 ApTopOfStack;\r
+} CPU_INFO_IN_HOB;\r
+#pragma pack ()\r
+\r
+//\r
+// AP reset code information including code address and size,\r
+// this structure will be shared be C code and assembly code.\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
+ 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
\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
+ 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
+\r
+//\r
+// CPU MP Data save in memory\r
+//\r
+struct _CPU_MP_DATA {\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 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
+#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
\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
+ Assembly code to get starting address and size of the rendezvous entry for APs.\r
+ Information for fixing a jump instruction in the code is also returned.\r
+\r
+ @param[out] AddressMap Output buffer for address map information.\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmGetAddressMap (\r
+ OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap\r
+ );\r
+\r
+/**\r
+ This function is called by both the BSP and the AP which is to become the BSP to\r
+ Exchange execution context including stack between them. After return from this\r
+ function, the BSP becomes AP and the AP becomes the BSP.\r
+\r
+ @param[in] MyInfo Pointer to buffer holding the exchanging information for the executing processor.\r
+ @param[in] OthersInfo Pointer to buffer holding the exchanging information for the peer.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmExchangeRole (\r
+ IN CPU_EXCHANGE_ROLE_INFO *MyInfo,\r
+ IN CPU_EXCHANGE_ROLE_INFO *OthersInfo\r
+ );\r
+\r
+/**\r
+ Get the pointer to CPU MP Data structure.\r
+\r
+ @return The pointer to CPU MP Data structure.\r
+**/\r
+CPU_MP_DATA *\r
+GetCpuMpData (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Save the pointer to CPU MP Data structure.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure will be saved.\r
+**/\r
+VOID\r
+SaveCpuMpData (\r
+ IN CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
+/**\r
+ Get available system memory below 1MB by specified size.\r
+\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
+UINTN\r
+GetWakeupBuffer (\r
+ IN UINTN WakeupBufferSize\r
);\r
-#endif\r
\r
+/**\r
+ Get available EfiBootServicesCode memory below 4GB by specified size.\r
+\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
+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
+ This function will be called by BSP to wakeup AP.\r
+\r
+ @param[in] CpuMpData Pointer to CPU MP Data\r
+ @param[in] Broadcast TRUE: Send broadcast IPI to all APs\r
+ FALSE: Send IPI to AP by ApicId\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 BOOLEAN WakeUpDisabledAps\r
+ );\r
+\r
+/**\r
+ Initialize global data for MP support.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+InitMpGlobalData (\r
+ IN CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
+/**\r
+ Worker function to execute a caller provided function on all enabled APs.\r
+\r
+ @param[in] Procedure A pointer to the function to be run on\r
+ enabled APs of the system.\r
+ @param[in] SingleThread If TRUE, then all the enabled APs execute\r
+ the function specified by Procedure one by\r
+ one, in ascending order of processor handle\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] 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
+ all APs.\r
+ @param[out] FailedCpuList If all APs finish successfully, then its\r
+ content is set to NULL. If not all APs\r
+ finish before timeout expires, then its\r
+ content is set to address of the buffer\r
+ holding handle numbers of the failed APs.\r
+\r
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before\r
+ the timeout expired.\r
+ @retval EFI_SUCCESS In non-blocking mode, function has been dispatched\r
+ to all enabled APs.\r
+ @retval others Failed to Startup all APs.\r
+\r
+**/\r
+EFI_STATUS\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
+ Worker function to let the caller get one enabled AP to execute a caller-provided\r
+ function.\r
+\r
+ @param[in] Procedure A pointer to the function to be run on\r
+ enabled APs of the system.\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] 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
+ all APs.\r
+ @param[out] Finished If AP returns from Procedure before the\r
+ timeout expires, its content is set to TRUE.\r
+ Otherwise, the value is set to FALSE.\r
+\r
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before\r
+ the timeout expires.\r
+ @retval others Failed to Startup AP.\r
+\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
+ );\r
+\r
+/**\r
+ Worker function to switch the requested AP to be the BSP from that point onward.\r
+\r
+ @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.\r
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an\r
+ enabled AP. Otherwise, it will be disabled.\r
+\r
+ @retval EFI_SUCCESS BSP successfully switched.\r
+ @retval others Failed to switch BSP.\r
+\r
+**/\r
+EFI_STATUS\r
+SwitchBSPWorker (\r
+ IN UINTN ProcessorNumber,\r
+ IN BOOLEAN EnableOldBSP\r
+ );\r
+\r
+/**\r
+ Worker function to let the caller enable or disable an AP from this point onward.\r
+ This service may only be called from the BSP.\r
+\r
+ @param[in] ProcessorNumber The handle number of AP.\r
+ @param[in] EnableAP Specifies the new state for the processor for\r
+ enabled, FALSE for disabled.\r
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies\r
+ the new health status of the AP.\r
+\r
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.\r
+ @retval others Failed to Enable/Disable AP.\r
+\r
+**/\r
+EFI_STATUS\r
+EnableDisableApWorker (\r
+ IN UINTN ProcessorNumber,\r
+ IN BOOLEAN EnableAP,\r
+ IN UINT32 *HealthFlag OPTIONAL\r
+ );\r
+\r
+/**\r
+ Get pointer to CPU MP Data structure from GUIDed HOB.\r
+\r
+ @return The pointer to CPU MP Data structure.\r
+**/\r
+CPU_MP_DATA *\r
+GetCpuMpDataFromGuidedHob (\r
+ VOID\r
+ );\r
+\r
+/** Checks status of specified AP.\r
+\r
+ This function checks whether the specified AP has finished the task assigned\r
+ by StartupThisAP(), and whether timeout expires.\r
+\r
+ @param[in] ProcessorNumber The handle number of processor.\r
+\r
+ @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs().\r
+ @retval EFI_TIMEOUT The timeout expires.\r
+ @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired.\r
+**/\r
+EFI_STATUS\r
+CheckThisAP (\r
+ IN UINTN ProcessorNumber\r
+ );\r
+\r
+/**\r
+ Checks status of all APs.\r
+\r
+ This function checks whether all APs have finished task assigned by StartupAllAPs(),\r
+ and whether timeout expires.\r
+\r
+ @retval EFI_SUCCESS All APs have finished task assigned by StartupAllAPs().\r
+ @retval EFI_TIMEOUT The timeout expires.\r
+ @retval EFI_NOT_READY APs have not finished task and timeout has not expired.\r
+**/\r
+EFI_STATUS\r
+CheckAllAPs (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Checks APs status and updates APs status if needed.\r
+\r
+**/\r
+VOID\r
+CheckAndUpdateApsStatus (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Detect whether specified processor can find matching microcode patch and load it.\r
+\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 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
+ Detect whether Mwait-monitor feature is supported.\r
+\r
+ @retval TRUE Mwait-monitor feature is supported.\r
+ @retval FALSE Mwait-monitor feature is not supported.\r
+**/\r
+BOOLEAN\r
+IsMwaitSupport (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Enable Debug Agent to support source debugging on AP function.\r
+\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, out] CpuMpData The pointer to CPU MP Data structure.\r
+\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
+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