]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/MpLib.h
UefiCpuPkg/MpInitLib: use PcdConfidentialComputingAttr to check SEV status
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / MpLib.h
index 2be13516aa4e07b3c8fd90b2decbfc18ebf5dffb..a84df60519ed75a7cd3e5fe251a2dfbbc15bb536 100644 (file)
@@ -1,14 +1,10 @@
 /** @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/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
+} 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
 // 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
+\r
 #pragma pack(1)\r
 \r
 //\r
@@ -56,22 +196,145 @@ typedef struct {
 // 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
+  UINTN              GhcbBase;\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
+  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
@@ -87,11 +350,16 @@ typedef struct {
   @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
@@ -103,8 +371,419 @@ VOID
 VOID\r
 EFIAPI\r
 AsmGetAddressMap (\r
-  OUT MP_ASSEMBLY_ADDRESS_MAP    *AddressMap\r
+  OUT MP_ASSEMBLY_ADDRESS_MAP  *AddressMap\r
   );\r
 \r
-#endif\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
+\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       OPTIONAL\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
+#endif\r