]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
UefiCpuPkg/PiSmmCpuDxeSmm: Avoid allocate Token every time
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / PiSmmCpuDxeSmm.h
index 907526e40680d4965be712bd54e1ef50761e519e..5c1a01e42bf33ebd4eb2e04640bfb583563d07f7 100644 (file)
@@ -1,14 +1,10 @@
 /** @file\r
 Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.\r
 \r
-Copyright (c) 2009 - 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) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017, AMD Incorporated. 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
@@ -23,8 +19,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/SmmAccess2.h>\r
 #include <Protocol/SmmReadyToLock.h>\r
 #include <Protocol/SmmCpuService.h>\r
+#include <Protocol/SmmMemoryAttribute.h>\r
+#include <Protocol/MmMp.h>\r
 \r
 #include <Guid/AcpiS3Context.h>\r
+#include <Guid/MemoryAttributesTable.h>\r
 #include <Guid/PiSmmMemoryAttributesTable.h>\r
 \r
 #include <Library/BaseLib.h>\r
@@ -34,7 +33,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/PcdLib.h>\r
-#include <Library/CacheMaintenanceLib.h>\r
 #include <Library/MtrrLib.h>\r
 #include <Library/SmmCpuPlatformHookLib.h>\r
 #include <Library/SmmServicesTableLib.h>\r
@@ -42,6 +40,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiRuntimeServicesTableLib.h>\r
 #include <Library/DebugAgentLib.h>\r
+#include <Library/UefiLib.h>\r
 #include <Library/HobLib.h>\r
 #include <Library/LocalApicLib.h>\r
 #include <Library/UefiCpuLib.h>\r
@@ -49,16 +48,62 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/ReportStatusCodeLib.h>\r
 #include <Library/SmmCpuFeaturesLib.h>\r
 #include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/RegisterCpuFeaturesLib.h>\r
 \r
 #include <AcpiCpuData.h>\r
 #include <CpuHotPlugData.h>\r
 \r
-#include <Register/Cpuid.h>\r
-#include <Register/Msr.h>\r
+#include <Register/Intel/Cpuid.h>\r
+#include <Register/Intel/Msr.h>\r
 \r
 #include "CpuService.h"\r
 #include "SmmProfile.h"\r
 \r
+//\r
+// CET definition\r
+//\r
+#define CPUID_CET_SS   BIT7\r
+#define CPUID_CET_IBT  BIT20\r
+\r
+#define CR4_CET_ENABLE  BIT23\r
+\r
+#define MSR_IA32_S_CET                     0x6A2\r
+#define MSR_IA32_PL0_SSP                   0x6A4\r
+#define MSR_IA32_INTERRUPT_SSP_TABLE_ADDR  0x6A8\r
+\r
+typedef union {\r
+  struct {\r
+    // enable shadow stacks\r
+    UINT32  SH_STK_ENP:1;\r
+    // enable the WRSS{D,Q}W instructions.\r
+    UINT32  WR_SHSTK_EN:1;\r
+    // enable tracking of indirect call/jmp targets to be ENDBRANCH instruction.\r
+    UINT32  ENDBR_EN:1;\r
+    // enable legacy compatibility treatment for indirect call/jmp tracking.\r
+    UINT32  LEG_IW_EN:1;\r
+    // enable use of no-track prefix on indirect call/jmp.\r
+    UINT32  NO_TRACK_EN:1;\r
+    // disable suppression of CET indirect branch tracking on legacy compatibility.\r
+    UINT32  SUPPRESS_DIS:1;\r
+    UINT32  RSVD:4;\r
+    // indirect branch tracking is suppressed.\r
+    // This bit can be written to 1 only if TRACKER is written as IDLE.\r
+    UINT32  SUPPRESS:1;\r
+    // Value of the endbranch state machine\r
+    // Values: IDLE (0), WAIT_FOR_ENDBRANCH(1).\r
+    UINT32  TRACKER:1;\r
+    // linear address of a bitmap in memory indicating valid\r
+    // pages as target of CALL/JMP_indirect that do not land on ENDBRANCH when CET is enabled\r
+    // and not suppressed. Valid when ENDBR_EN is 1. Must be machine canonical when written on\r
+    // parts that support 64 bit mode. On parts that do not support 64 bit mode, the bits 63:32 are\r
+    // reserved and must be 0. This value is extended by 12 bits at the low end to form the base address\r
+    // (this automatically aligns the address on a 4-Kbyte boundary).\r
+    UINT32  EB_LEG_BITMAP_BASE_low:12;\r
+    UINT32  EB_LEG_BITMAP_BASE_high:32;\r
+  } Bits;\r
+  UINT64   Uint64;\r
+} MSR_IA32_CET;\r
+\r
 //\r
 // MSRs required for configuration of SMM Code Access Check\r
 //\r
@@ -103,6 +148,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull\r
 #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull\r
 \r
+#define SMRR_MAX_ADDRESS       BASE_4GB\r
+\r
 typedef enum {\r
   PageNone,\r
   Page4K,\r
@@ -120,9 +167,11 @@ typedef struct {
 // Size of Task-State Segment defined in IA32 Manual\r
 //\r
 #define TSS_SIZE              104\r
+#define EXCEPTION_TSS_SIZE    (TSS_SIZE + 4) // Add 4 bytes SSP\r
 #define TSS_X64_IST1_OFFSET   36\r
 #define TSS_IA32_CR3_OFFSET   28\r
 #define TSS_IA32_ESP_OFFSET   56\r
+#define TSS_IA32_SSP_OFFSET   104\r
 \r
 #define CR0_WP                BIT16\r
 \r
@@ -149,6 +198,36 @@ typedef UINT32                              SMM_CPU_ARRIVAL_EXCEPTIONS;
 #define ARRIVAL_EXCEPTION_DELAYED           0x2\r
 #define ARRIVAL_EXCEPTION_SMI_DISABLED      0x4\r
 \r
+//\r
+// Wrapper used to convert EFI_AP_PROCEDURE2 and EFI_AP_PROCEDURE.\r
+//\r
+typedef struct {\r
+  EFI_AP_PROCEDURE  Procedure;\r
+  VOID              *ProcedureArgument;\r
+} PROCEDURE_WRAPPER;\r
+\r
+#define PROCEDURE_TOKEN_SIGNATURE  SIGNATURE_32 ('P', 'R', 'T', 'S')\r
+\r
+typedef struct {\r
+  UINTN                   Signature;\r
+  LIST_ENTRY              Link;\r
+\r
+  SPIN_LOCK               *ProcedureToken;\r
+} PROCEDURE_TOKEN;\r
+\r
+#define PROCEDURE_TOKEN_FROM_LINK(a)  CR (a, PROCEDURE_TOKEN, Link, PROCEDURE_TOKEN_SIGNATURE)\r
+\r
+#define TOKEN_BUFFER_SIGNATURE  SIGNATURE_32 ('T', 'K', 'B', 'S')\r
+\r
+typedef struct {\r
+  UINTN                   Signature;\r
+  LIST_ENTRY              Link;\r
+\r
+  UINT8                   *Buffer;\r
+} TOKEN_BUFFER;\r
+\r
+#define TOKEN_BUFFER_FROM_LINK(a)  CR (a, TOKEN_BUFFER, Link, TOKEN_BUFFER_SIGNATURE)\r
+\r
 //\r
 // Private structure for the SMM CPU module that is stored in DXE Runtime memory\r
 // Contains the SMM Configuration Protocols that is produced.\r
@@ -171,6 +250,14 @@ typedef struct {
   EFI_SMM_ENTRY_POINT             SmmCoreEntry;\r
 \r
   EFI_SMM_CONFIGURATION_PROTOCOL  SmmConfiguration;\r
+\r
+  PROCEDURE_WRAPPER               *ApWrapperFunc;\r
+  LIST_ENTRY                      TokenList;\r
+\r
+  LIST_ENTRY                      OldTokenBufList;\r
+\r
+  UINT8                           *CurrentTokenBuf;\r
+  UINT32                          UsedTokenNum;     // Only record tokens used in CurrentTokenBuf.\r
 } SMM_CPU_PRIVATE_DATA;\r
 \r
 extern SMM_CPU_PRIVATE_DATA  *gSmmCpuPrivate;\r
@@ -178,13 +265,13 @@ extern CPU_HOT_PLUG_DATA      mCpuHotPlugData;
 extern UINTN                  mMaxNumberOfCpus;\r
 extern UINTN                  mNumberOfCpus;\r
 extern EFI_SMM_CPU_PROTOCOL   mSmmCpu;\r
+extern EFI_MM_MP_PROTOCOL     mSmmMp;\r
 \r
 ///\r
 /// The mode of the CPU at the time an SMI occurs\r
 ///\r
 extern UINT8  mSmmSaveStateRegisterLma;\r
 \r
-\r
 //\r
 // SMM CPU Protocol function prototypes.\r
 //\r
@@ -291,23 +378,16 @@ WriteSaveStateRegister (
   IN CONST VOID                   *Buffer\r
   );\r
 \r
-//\r
-//\r
-//\r
-typedef struct {\r
-  UINT32                            Offset;\r
-  UINT16                            Segment;\r
-  UINT16                            Reserved;\r
-} IA32_FAR_ADDRESS;\r
-\r
-extern IA32_FAR_ADDRESS             gSmmJmpAddr;\r
-\r
 extern CONST UINT8                  gcSmmInitTemplate[];\r
 extern CONST UINT16                 gcSmmInitSize;\r
-extern UINT32                       gSmmCr0;\r
-extern UINT32                       gSmmCr3;\r
-extern UINT32                       gSmmCr4;\r
-extern UINTN                        gSmmInitStack;\r
+X86_ASSEMBLY_PATCH_LABEL            gPatchSmmCr0;\r
+extern UINT32                       mSmmCr0;\r
+X86_ASSEMBLY_PATCH_LABEL            gPatchSmmCr3;\r
+extern UINT32                       mSmmCr4;\r
+X86_ASSEMBLY_PATCH_LABEL            gPatchSmmCr4;\r
+X86_ASSEMBLY_PATCH_LABEL            gPatchSmmInitStack;\r
+X86_ASSEMBLY_PATCH_LABEL            mPatchCetSupported;\r
+extern BOOLEAN                      mCetSupported;\r
 \r
 /**\r
   Semaphore operation for all processor relocate SMMBase.\r
@@ -323,10 +403,12 @@ SmmRelocationSemaphoreComplete (
 ///\r
 typedef struct {\r
   SPIN_LOCK                         *Busy;\r
-  volatile EFI_AP_PROCEDURE         Procedure;\r
+  volatile EFI_AP_PROCEDURE2        Procedure;\r
   volatile VOID                     *Parameter;\r
   volatile UINT32                   *Run;\r
   volatile BOOLEAN                  *Present;\r
+  SPIN_LOCK                         *Token;\r
+  EFI_STATUS                        *Status;\r
 } SMM_CPU_DATA_BLOCK;\r
 \r
 typedef enum {\r
@@ -348,42 +430,12 @@ typedef struct {
   volatile SMM_CPU_SYNC_MODE    EffectiveSyncMode;\r
   volatile BOOLEAN              SwitchBsp;\r
   volatile BOOLEAN              *CandidateBsp;\r
+  EFI_AP_PROCEDURE              StartupProcedure;\r
+  VOID                          *StartupProcArgs;\r
 } SMM_DISPATCHER_MP_SYNC_DATA;\r
 \r
-#define MSR_SPIN_LOCK_INIT_NUM 15\r
-\r
-typedef struct {\r
-  SPIN_LOCK    *SpinLock;\r
-  UINT32       MsrIndex;\r
-} MP_MSR_LOCK;\r
-\r
 #define SMM_PSD_OFFSET              0xfb00\r
 \r
-typedef struct {\r
-  UINT64                            Signature;              // Offset 0x00\r
-  UINT16                            Reserved1;              // Offset 0x08\r
-  UINT16                            Reserved2;              // Offset 0x0A\r
-  UINT16                            Reserved3;              // Offset 0x0C\r
-  UINT16                            SmmCs;                  // Offset 0x0E\r
-  UINT16                            SmmDs;                  // Offset 0x10\r
-  UINT16                            SmmSs;                  // Offset 0x12\r
-  UINT16                            SmmOtherSegment;        // Offset 0x14\r
-  UINT16                            Reserved4;              // Offset 0x16\r
-  UINT64                            Reserved5;              // Offset 0x18\r
-  UINT64                            Reserved6;              // Offset 0x20\r
-  UINT64                            Reserved7;              // Offset 0x28\r
-  UINT64                            SmmGdtPtr;              // Offset 0x30\r
-  UINT32                            SmmGdtSize;             // Offset 0x38\r
-  UINT32                            Reserved8;              // Offset 0x3C\r
-  UINT64                            Reserved9;              // Offset 0x40\r
-  UINT64                            Reserved10;             // Offset 0x48\r
-  UINT16                            Reserved11;             // Offset 0x50\r
-  UINT16                            Reserved12;             // Offset 0x52\r
-  UINT32                            Reserved13;             // Offset 0x54\r
-  UINT64                            MtrrBaseMaskPtr;        // Offset 0x58\r
-} PROCESSOR_SMM_DESCRIPTOR;\r
-\r
-\r
 ///\r
 /// All global semaphores' pointer\r
 ///\r
@@ -393,7 +445,6 @@ typedef struct {
   volatile BOOLEAN     *AllCpusInSync;\r
   SPIN_LOCK            *PFLock;\r
   SPIN_LOCK            *CodeAccessCheckLock;\r
-  SPIN_LOCK            *MemoryMappedLock;\r
 } SMM_CPU_SEMAPHORE_GLOBAL;\r
 \r
 ///\r
@@ -403,23 +454,15 @@ typedef struct {
   SPIN_LOCK                         *Busy;\r
   volatile UINT32                   *Run;\r
   volatile BOOLEAN                  *Present;\r
+  SPIN_LOCK                         *Token;\r
 } SMM_CPU_SEMAPHORE_CPU;\r
 \r
-///\r
-/// All MSRs semaphores' pointer and counter\r
-///\r
-typedef struct {\r
-  SPIN_LOCK            *Msr;\r
-  UINTN                AvailableCounter;\r
-} SMM_CPU_SEMAPHORE_MSR;\r
-\r
 ///\r
 /// All semaphores' information\r
 ///\r
 typedef struct {\r
   SMM_CPU_SEMAPHORE_GLOBAL          SemaphoreGlobal;\r
   SMM_CPU_SEMAPHORE_CPU             SemaphoreCpu;\r
-  SMM_CPU_SEMAPHORE_MSR             SemaphoreMsr;\r
 } SMM_CPU_SEMAPHORES;\r
 \r
 extern IA32_DESCRIPTOR                     gcSmiGdtr;\r
@@ -427,7 +470,6 @@ extern EFI_PHYSICAL_ADDRESS                mGdtBuffer;
 extern UINTN                               mGdtBufferSize;\r
 extern IA32_DESCRIPTOR                     gcSmiIdtr;\r
 extern VOID                                *gcSmiIdtrPtr;\r
-extern CONST PROCESSOR_SMM_DESCRIPTOR      gcPsd;\r
 extern UINT64                              gPhyMask;\r
 extern SMM_DISPATCHER_MP_SYNC_DATA         *mSmmMpSyncData;\r
 extern UINTN                               mSmmStackArrayBase;\r
@@ -439,7 +481,14 @@ extern SMM_CPU_SEMAPHORES                  mSmmCpuSemaphores;
 extern UINTN                               mSemaphoreSize;\r
 extern SPIN_LOCK                           *mPFLock;\r
 extern SPIN_LOCK                           *mConfigSmmCodeAccessCheckLock;\r
-extern SPIN_LOCK                           *mMemoryMappedLock;\r
+extern EFI_SMRAM_DESCRIPTOR                *mSmmCpuSmramRanges;\r
+extern UINTN                               mSmmCpuSmramRangeCount;\r
+extern UINT8                               mPhysicalAddressBits;\r
+\r
+//\r
+// Copy of the PcdPteMemoryEncryptionAddressOrMask\r
+//\r
+extern UINT64  mAddressEncMask;\r
 \r
 /**\r
   Create 4G PageTable in SMRAM.\r
@@ -457,14 +506,16 @@ Gen4GPageTable (
 /**\r
   Initialize global data for MP synchronization.\r
 \r
-  @param Stacks       Base address of SMI stack buffer for all processors.\r
-  @param StackSize    Stack size for each processor in SMM.\r
+  @param Stacks             Base address of SMI stack buffer for all processors.\r
+  @param StackSize          Stack size for each processor in SMM.\r
+  @param ShadowStackSize    Shadow Stack size for each processor in SMM.\r
 \r
 **/\r
 UINT32\r
 InitializeMpServiceData (\r
   IN VOID        *Stacks,\r
-  IN UINTN       StackSize\r
+  IN UINTN       StackSize,\r
+  IN UINTN       ShadowStackSize\r
   );\r
 \r
 /**\r
@@ -595,6 +646,66 @@ SmmBlockingStartupThisAp (
   IN OUT  VOID                      *ProcArguments OPTIONAL\r
   );\r
 \r
+/**\r
+  This function sets the attributes for the memory region specified by BaseAddress and\r
+  Length from their current attributes to the attributes specified by Attributes.\r
+\r
+  @param[in]  BaseAddress      The physical address that is the start address of a memory region.\r
+  @param[in]  Length           The size in bytes of the memory region.\r
+  @param[in]  Attributes       The bit mask of attributes to set for the memory region.\r
+\r
+  @retval EFI_SUCCESS           The attributes were set for the memory region.\r
+  @retval EFI_ACCESS_DENIED     The attributes for the memory resource range specified by\r
+                                BaseAddress and Length cannot be modified.\r
+  @retval EFI_INVALID_PARAMETER Length is zero.\r
+                                Attributes specified an illegal combination of attributes that\r
+                                cannot be set together.\r
+  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of\r
+                                the memory resource range.\r
+  @retval EFI_UNSUPPORTED       The processor does not support one or more bytes of the memory\r
+                                resource range specified by BaseAddress and Length.\r
+                                The bit mask of attributes is not support for the memory resource\r
+                                range specified by BaseAddress and Length.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmSetMemoryAttributes (\r
+  IN  EFI_PHYSICAL_ADDRESS                       BaseAddress,\r
+  IN  UINT64                                     Length,\r
+  IN  UINT64                                     Attributes\r
+  );\r
+\r
+/**\r
+  This function clears the attributes for the memory region specified by BaseAddress and\r
+  Length from their current attributes to the attributes specified by Attributes.\r
+\r
+  @param[in]  BaseAddress      The physical address that is the start address of a memory region.\r
+  @param[in]  Length           The size in bytes of the memory region.\r
+  @param[in]  Attributes       The bit mask of attributes to clear for the memory region.\r
+\r
+  @retval EFI_SUCCESS           The attributes were cleared for the memory region.\r
+  @retval EFI_ACCESS_DENIED     The attributes for the memory resource range specified by\r
+                                BaseAddress and Length cannot be modified.\r
+  @retval EFI_INVALID_PARAMETER Length is zero.\r
+                                Attributes specified an illegal combination of attributes that\r
+                                cannot be set together.\r
+  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of\r
+                                the memory resource range.\r
+  @retval EFI_UNSUPPORTED       The processor does not support one or more bytes of the memory\r
+                                resource range specified by BaseAddress and Length.\r
+                                The bit mask of attributes is not support for the memory resource\r
+                                range specified by BaseAddress and Length.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmClearMemoryAttributes (\r
+  IN  EFI_PHYSICAL_ADDRESS                       BaseAddress,\r
+  IN  UINT64                                     Length,\r
+  IN  UINT64                                     Attributes\r
+  );\r
+\r
 /**\r
   Initialize MP synchronization data.\r
 \r
@@ -642,8 +753,8 @@ SmmRelocateBases (
 VOID\r
 EFIAPI\r
 SmiPFHandler (\r
-    IN EFI_EXCEPTION_TYPE   InterruptType,\r
-    IN EFI_SYSTEM_CONTEXT   SystemContext\r
+  IN EFI_EXCEPTION_TYPE   InterruptType,\r
+  IN EFI_SYSTEM_CONTEXT   SystemContext\r
   );\r
 \r
 /**\r
@@ -796,6 +907,35 @@ SetMemMapAttributes (
   VOID\r
   );\r
 \r
+/**\r
+  This function sets UEFI memory attribute according to UEFI memory map.\r
+**/\r
+VOID\r
+SetUefiMemMapAttributes (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Return if the Address is forbidden as SMM communication buffer.\r
+\r
+  @param[in] Address the address to be checked\r
+\r
+  @return TRUE  The address is forbidden as SMM communication buffer.\r
+  @return FALSE The address is allowed as SMM communication buffer.\r
+**/\r
+BOOLEAN\r
+IsSmmCommBufferForbiddenAddress (\r
+  IN UINT64  Address\r
+  );\r
+\r
+/**\r
+  This function caches the UEFI memory map information.\r
+**/\r
+VOID\r
+GetUefiMemoryMap (\r
+  VOID\r
+  );\r
+\r
 /**\r
   This function sets memory attribute for page table.\r
 **/\r
@@ -974,16 +1114,366 @@ GetAcpiS3EnableFlag (
 /**\r
   Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.\r
 \r
-  @param[in] ApHltLoopCode    The 32-bit address of the safe hlt-loop function.\r
-  @param[in] TopOfStack       A pointer to the new stack to use for the ApHltLoopCode.\r
-  @param[in] NumberToFinish   Semaphore of APs finish count.\r
+  @param[in] ApHltLoopCode          The address of the safe hlt-loop function.\r
+  @param[in] TopOfStack             A pointer to the new stack to use for the ApHltLoopCode.\r
+  @param[in] NumberToFinishAddress  Address of Semaphore of APs finish count.\r
 \r
 **/\r
 VOID\r
 TransferApToSafeState (\r
-  IN UINT32             ApHltLoopCode,\r
-  IN UINT32             TopOfStack,\r
-  IN UINT32             *NumberToFinish\r
+  IN UINTN  ApHltLoopCode,\r
+  IN UINTN  TopOfStack,\r
+  IN UINTN  NumberToFinishAddress\r
+  );\r
+\r
+/**\r
+  Set ShadowStack memory.\r
+\r
+  @param[in]  Cr3              The page table base address.\r
+  @param[in]  BaseAddress      The physical address that is the start address of a memory region.\r
+  @param[in]  Length           The size in bytes of the memory region.\r
+\r
+  @retval EFI_SUCCESS           The shadow stack memory is set.\r
+**/\r
+EFI_STATUS\r
+SetShadowStack (\r
+  IN  UINTN                                      Cr3,\r
+  IN  EFI_PHYSICAL_ADDRESS                       BaseAddress,\r
+  IN  UINT64                                     Length\r
+  );\r
+\r
+/**\r
+  Set not present memory.\r
+\r
+  @param[in]  Cr3              The page table base address.\r
+  @param[in]  BaseAddress      The physical address that is the start address of a memory region.\r
+  @param[in]  Length           The size in bytes of the memory region.\r
+\r
+  @retval EFI_SUCCESS           The not present memory is set.\r
+**/\r
+EFI_STATUS\r
+SetNotPresentPage (\r
+  IN  UINTN                                      Cr3,\r
+  IN  EFI_PHYSICAL_ADDRESS                       BaseAddress,\r
+  IN  UINT64                                     Length\r
+  );\r
+\r
+/**\r
+  Initialize the shadow stack related data structure.\r
+\r
+  @param CpuIndex     The index of CPU.\r
+  @param ShadowStack  The bottom of the shadow stack for this CPU.\r
+**/\r
+VOID\r
+InitShadowStack (\r
+  IN UINTN  CpuIndex,\r
+  IN VOID   *ShadowStack\r
+  );\r
+\r
+/**\r
+  This function set given attributes of the memory region specified by\r
+  BaseAddress and Length.\r
+\r
+  @param  This              The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.\r
+  @param  BaseAddress       The physical address that is the start address of\r
+                            a memory region.\r
+  @param  Length            The size in bytes of the memory region.\r
+  @param  Attributes        The bit mask of attributes to set for the memory\r
+                            region.\r
+\r
+  @retval EFI_SUCCESS           The attributes were set for the memory region.\r
+  @retval EFI_INVALID_PARAMETER Length is zero.\r
+                                Attributes specified an illegal combination of\r
+                                attributes that cannot be set together.\r
+  @retval EFI_UNSUPPORTED       The processor does not support one or more\r
+                                bytes of the memory resource range specified\r
+                                by BaseAddress and Length.\r
+                                The bit mask of attributes is not supported for\r
+                                the memory resource range specified by\r
+                                BaseAddress and Length.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EdkiiSmmSetMemoryAttributes (\r
+  IN  EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL   *This,\r
+  IN  EFI_PHYSICAL_ADDRESS                  BaseAddress,\r
+  IN  UINT64                                Length,\r
+  IN  UINT64                                Attributes\r
+  );\r
+\r
+/**\r
+  This function clears given attributes of the memory region specified by\r
+  BaseAddress and Length.\r
+\r
+  @param  This              The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.\r
+  @param  BaseAddress       The physical address that is the start address of\r
+                            a memory region.\r
+  @param  Length            The size in bytes of the memory region.\r
+  @param  Attributes        The bit mask of attributes to clear for the memory\r
+                            region.\r
+\r
+  @retval EFI_SUCCESS           The attributes were cleared for the memory region.\r
+  @retval EFI_INVALID_PARAMETER Length is zero.\r
+                                Attributes specified an illegal combination of\r
+                                attributes that cannot be cleared together.\r
+  @retval EFI_UNSUPPORTED       The processor does not support one or more\r
+                                bytes of the memory resource range specified\r
+                                by BaseAddress and Length.\r
+                                The bit mask of attributes is not supported for\r
+                                the memory resource range specified by\r
+                                BaseAddress and Length.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EdkiiSmmClearMemoryAttributes (\r
+  IN  EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL   *This,\r
+  IN  EFI_PHYSICAL_ADDRESS                  BaseAddress,\r
+  IN  UINT64                                Length,\r
+  IN  UINT64                                Attributes\r
+  );\r
+\r
+/**\r
+  This function retrieves the attributes of the memory region specified by\r
+  BaseAddress and Length. If different attributes are got from different part\r
+  of the memory region, EFI_NO_MAPPING will be returned.\r
+\r
+  @param  This              The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.\r
+  @param  BaseAddress       The physical address that is the start address of\r
+                            a memory region.\r
+  @param  Length            The size in bytes of the memory region.\r
+  @param  Attributes        Pointer to attributes returned.\r
+\r
+  @retval EFI_SUCCESS           The attributes got for the memory region.\r
+  @retval EFI_INVALID_PARAMETER Length is zero.\r
+                                Attributes is NULL.\r
+  @retval EFI_NO_MAPPING        Attributes are not consistent cross the memory\r
+                                region.\r
+  @retval EFI_UNSUPPORTED       The processor does not support one or more\r
+                                bytes of the memory resource range specified\r
+                                by BaseAddress and Length.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EdkiiSmmGetMemoryAttributes (\r
+  IN  EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL   *This,\r
+  IN  EFI_PHYSICAL_ADDRESS                  BaseAddress,\r
+  IN  UINT64                                Length,\r
+  IN  UINT64                                *Attributes\r
+  );\r
+\r
+/**\r
+  This function fixes up the address of the global variable or function\r
+  referred in SmmInit assembly files to be the absoute address.\r
+**/\r
+VOID\r
+EFIAPI\r
+PiSmmCpuSmmInitFixupAddress (\r
+ );\r
+\r
+/**\r
+  This function fixes up the address of the global variable or function\r
+  referred in SmiEntry assembly files to be the absoute address.\r
+**/\r
+VOID\r
+EFIAPI\r
+PiSmmCpuSmiEntryFixupAddress (\r
+ );\r
+\r
+/**\r
+  This function reads CR2 register when on-demand paging is enabled\r
+  for 64 bit and no action for 32 bit.\r
+\r
+  @param[out]  *Cr2  Pointer to variable to hold CR2 register value.\r
+**/\r
+VOID\r
+SaveCr2 (\r
+  OUT UINTN  *Cr2\r
+  );\r
+\r
+/**\r
+  This function writes into CR2 register when on-demand paging is enabled\r
+  for 64 bit and no action for 32 bit.\r
+\r
+  @param[in]  Cr2  Value to write into CR2 register.\r
+**/\r
+VOID\r
+RestoreCr2 (\r
+  IN UINTN  Cr2\r
+  );\r
+\r
+/**\r
+  Schedule a procedure to run on the specified CPU.\r
+\r
+  @param[in]       Procedure                The address of the procedure to run\r
+  @param[in]       CpuIndex                 Target CPU Index\r
+  @param[in,out]   ProcArguments            The parameter to pass to the procedure\r
+  @param[in,out]   Token                    This is an optional parameter that allows the caller to execute the\r
+                                            procedure in a blocking or non-blocking fashion. If it is NULL the\r
+                                            call is blocking, and the call will not return until the AP has\r
+                                            completed the procedure. If the token is not NULL, the call will\r
+                                            return immediately. The caller can check whether the procedure has\r
+                                            completed with CheckOnProcedure or WaitForProcedure.\r
+  @param[in]       TimeoutInMicroseconds    Indicates the time limit in microseconds for the APs to finish\r
+                                            execution of Procedure, either for blocking or non-blocking mode.\r
+                                            Zero means infinity. If the timeout expires before all APs return\r
+                                            from Procedure, then Procedure on the failed APs is terminated. If\r
+                                            the timeout expires in blocking mode, the call returns EFI_TIMEOUT.\r
+                                            If the timeout expires in non-blocking mode, the timeout determined\r
+                                            can be through CheckOnProcedure or WaitForProcedure.\r
+                                            Note that timeout support is optional. Whether an implementation\r
+                                            supports this feature can be determined via the Attributes data\r
+                                            member.\r
+  @param[in,out]   CpuStatus                This optional pointer may be used to get the status code returned\r
+                                            by Procedure when it completes execution on the target AP, or with\r
+                                            EFI_TIMEOUT if the Procedure fails to complete within the optional\r
+                                            timeout. The implementation will update this variable with\r
+                                            EFI_NOT_READY prior to starting Procedure on the target AP.\r
+\r
+  @retval EFI_INVALID_PARAMETER    CpuNumber not valid\r
+  @retval EFI_INVALID_PARAMETER    CpuNumber specifying BSP\r
+  @retval EFI_INVALID_PARAMETER    The AP specified by CpuNumber did not enter SMM\r
+  @retval EFI_INVALID_PARAMETER    The AP specified by CpuNumber is busy\r
+  @retval EFI_SUCCESS              The procedure has been successfully scheduled\r
+\r
+**/\r
+EFI_STATUS\r
+InternalSmmStartupThisAp (\r
+  IN      EFI_AP_PROCEDURE2              Procedure,\r
+  IN      UINTN                          CpuIndex,\r
+  IN OUT  VOID                           *ProcArguments OPTIONAL,\r
+  IN OUT  MM_COMPLETION                  *Token,\r
+  IN      UINTN                          TimeoutInMicroseconds,\r
+  IN OUT  EFI_STATUS                     *CpuStatus\r
+  );\r
+\r
+/**\r
+  Checks whether the input token is the current used token.\r
+\r
+  @param[in]  Token      This parameter describes the token that was passed into DispatchProcedure or\r
+                         BroadcastProcedure.\r
+\r
+  @retval TRUE           The input token is the current used token.\r
+  @retval FALSE          The input token is not the current used token.\r
+**/\r
+BOOLEAN\r
+IsTokenInUse (\r
+  IN SPIN_LOCK           *Token\r
+  );\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]  Token             This parameter describes the token that was passed into DispatchProcedure or\r
+                                BroadcastProcedure.\r
+\r
+  @retval EFI_SUCCESS           Specified AP has finished task assigned by StartupThisAPs().\r
+  @retval EFI_NOT_READY         Specified AP has not finished task and timeout has not expired.\r
+**/\r
+EFI_STATUS\r
+IsApReady (\r
+  IN SPIN_LOCK  *Token\r
+  );\r
+\r
+/**\r
+  Check whether it is an present AP.\r
+\r
+  @param   CpuIndex      The AP index which calls this function.\r
+\r
+  @retval  TRUE           It's a present AP.\r
+  @retval  TRUE           This is not an AP or it is not present.\r
+\r
+**/\r
+BOOLEAN\r
+IsPresentAp (\r
+  IN UINTN        CpuIndex\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]     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,out] ProcedureArguments      The parameter passed into Procedure for\r
+                                         all APs.\r
+  @param[in,out] Token                   This is an optional parameter that allows the caller to execute the\r
+                                         procedure in a blocking or non-blocking fashion. If it is NULL the\r
+                                         call is blocking, and the call will not return until the AP has\r
+                                         completed the procedure. If the token is not NULL, the call will\r
+                                         return immediately. The caller can check whether the procedure has\r
+                                         completed with CheckOnProcedure or WaitForProcedure.\r
+  @param[in,out] CPUStatus               This optional pointer may be used to get the status code returned\r
+                                         by Procedure when it completes execution on the target AP, or with\r
+                                         EFI_TIMEOUT if the Procedure fails to complete within the optional\r
+                                         timeout. The implementation will update this variable with\r
+                                         EFI_NOT_READY prior to starting Procedure on the target AP.\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
+InternalSmmStartupAllAPs (\r
+  IN       EFI_AP_PROCEDURE2             Procedure,\r
+  IN       UINTN                         TimeoutInMicroseconds,\r
+  IN OUT   VOID                          *ProcedureArguments OPTIONAL,\r
+  IN OUT   MM_COMPLETION                 *Token,\r
+  IN OUT   EFI_STATUS                    *CPUStatus\r
+  );\r
+\r
+/**\r
+\r
+  Register the SMM Foundation entry point.\r
+\r
+  @param[in]      Procedure            A pointer to the code stream to be run on the designated target AP\r
+                                       of the system. Type EFI_AP_PROCEDURE is defined below in Volume 2\r
+                                       with the related definitions of\r
+                                       EFI_MP_SERVICES_PROTOCOL.StartupAllAPs.\r
+                                       If caller may pass a value of NULL to deregister any existing\r
+                                       startup procedure.\r
+  @param[in,out]  ProcedureArguments   Allows the caller to pass a list of parameters to the code that is\r
+                                       run by the AP. It is an optional common mailbox between APs and\r
+                                       the caller to share information\r
+\r
+  @retval EFI_SUCCESS                  The Procedure has been set successfully.\r
+  @retval EFI_INVALID_PARAMETER        The Procedure is NULL but ProcedureArguments not NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+RegisterStartupProcedure (\r
+  IN     EFI_AP_PROCEDURE    Procedure,\r
+  IN OUT VOID                *ProcedureArguments OPTIONAL\r
+  );\r
+\r
+/**\r
+  Allocate buffer for SpinLock and Wrapper function buffer.\r
+\r
+**/\r
+VOID\r
+InitializeDataForMmMp (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Return whether access to non-SMRAM is restricted.\r
+\r
+  @retval TRUE  Access to non-SMRAM is restricted.\r
+  @retval FALSE Access to non-SMRAM is not restricted.\r
+**/\r
+BOOLEAN\r
+IsRestrictedMemoryAccess (\r
+  VOID\r
   );\r
 \r
 #endif\r