]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
UefiCpuPkg/PiSmmCpuDxeSmm: Add SmmMemoryAttribute protocol
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / PiSmmCpuDxeSmm.h
index 9920cd1d1e1a2738afe2cc07dc716b0cb800fe36..a2d5f55045b19d7eb143e892c33bd645c525f7bb 100644 (file)
@@ -1,7 +1,9 @@
 /** @file\r
 Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.\r
 \r
-Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
+\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
@@ -23,8 +25,10 @@ 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 <Guid/AcpiS3Context.h>\r
+#include <Guid/PiSmmMemoryAttributesTable.h>\r
 \r
 #include <Library/BaseLib.h>\r
 #include <Library/IoLib.h>\r
@@ -53,6 +57,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <CpuHotPlugData.h>\r
 \r
 #include <Register/Cpuid.h>\r
+#include <Register/Msr.h>\r
 \r
 #include "CpuService.h"\r
 #include "SmmProfile.h"\r
@@ -82,13 +87,40 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #define IA32_PG_PMNT                BIT62\r
 #define IA32_PG_NX                  BIT63\r
 \r
-#define PAGE_ATTRIBUTE_BITS         (IA32_PG_RW | IA32_PG_P)\r
+#define PAGE_ATTRIBUTE_BITS         (IA32_PG_D | IA32_PG_A | IA32_PG_U | IA32_PG_RW | IA32_PG_P)\r
 //\r
 // Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE\r
 // X64 PAE PDPTE does not have such restriction\r
 //\r
 #define IA32_PAE_PDPTE_ATTRIBUTE_BITS    (IA32_PG_P)\r
 \r
+#define PAGE_PROGATE_BITS           (IA32_PG_NX | PAGE_ATTRIBUTE_BITS)\r
+\r
+#define PAGING_4K_MASK  0xFFF\r
+#define PAGING_2M_MASK  0x1FFFFF\r
+#define PAGING_1G_MASK  0x3FFFFFFF\r
+\r
+#define PAGING_PAE_INDEX_MASK  0x1FF\r
+\r
+#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull\r
+#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
+  Page2M,\r
+  Page1G,\r
+} PAGE_ATTRIBUTE;\r
+\r
+typedef struct {\r
+  PAGE_ATTRIBUTE   Attribute;\r
+  UINT64           Length;\r
+  UINT64           AddressMask;\r
+} PAGE_ATTRIBUTE_TABLE;\r
+\r
 //\r
 // Size of Task-State Segment defined in IA32 Manual\r
 //\r
@@ -97,6 +129,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #define TSS_IA32_CR3_OFFSET   28\r
 #define TSS_IA32_ESP_OFFSET   56\r
 \r
+#define CR0_WP                BIT16\r
+\r
 //\r
 // Code select value\r
 //\r
@@ -148,7 +182,6 @@ extern SMM_CPU_PRIVATE_DATA  *gSmmCpuPrivate;
 extern CPU_HOT_PLUG_DATA      mCpuHotPlugData;\r
 extern UINTN                  mMaxNumberOfCpus;\r
 extern UINTN                  mNumberOfCpus;\r
-extern BOOLEAN                mRestoreSmmConfigurationInS3;\r
 extern EFI_SMM_CPU_PROTOCOL   mSmmCpu;\r
 \r
 ///\r
@@ -156,7 +189,6 @@ extern EFI_SMM_CPU_PROTOCOL   mSmmCpu;
 ///\r
 extern UINT8  mSmmSaveStateRegisterLma;\r
 \r
-\r
 //\r
 // SMM CPU Protocol function prototypes.\r
 //\r
@@ -294,11 +326,11 @@ SmmRelocationSemaphoreComplete (
 /// The type of SMM CPU Information\r
 ///\r
 typedef struct {\r
-  SPIN_LOCK                         Busy;\r
+  SPIN_LOCK                         *Busy;\r
   volatile EFI_AP_PROCEDURE         Procedure;\r
   volatile VOID                     *Parameter;\r
-  volatile UINT32                   Run;\r
-  volatile BOOLEAN                  Present;\r
+  volatile UINT32                   *Run;\r
+  volatile BOOLEAN                  *Present;\r
 } SMM_CPU_DATA_BLOCK;\r
 \r
 typedef enum {\r
@@ -313,73 +345,97 @@ typedef struct {
   // so that UC cache-ability can be set together.\r
   //\r
   SMM_CPU_DATA_BLOCK            *CpuData;\r
-  volatile UINT32               Counter;\r
+  volatile UINT32               *Counter;\r
   volatile UINT32               BspIndex;\r
-  volatile BOOLEAN              InsideSmm;\r
-  volatile BOOLEAN              AllCpusInSync;\r
+  volatile BOOLEAN              *InsideSmm;\r
+  volatile BOOLEAN              *AllCpusInSync;\r
   volatile SMM_CPU_SYNC_MODE    EffectiveSyncMode;\r
   volatile BOOLEAN              SwitchBsp;\r
   volatile BOOLEAN              *CandidateBsp;\r
 } SMM_DISPATCHER_MP_SYNC_DATA;\r
 \r
+#define MSR_SPIN_LOCK_INIT_NUM 15\r
+\r
 typedef struct {\r
-  SPIN_LOCK    SpinLock;\r
+  SPIN_LOCK    *SpinLock;\r
   UINT32       MsrIndex;\r
 } MP_MSR_LOCK;\r
 \r
 #define SMM_PSD_OFFSET              0xfb00\r
 \r
+///\r
+/// All global semaphores' pointer\r
+///\r
+typedef struct {\r
+  volatile UINT32      *Counter;\r
+  volatile BOOLEAN     *InsideSmm;\r
+  volatile BOOLEAN     *AllCpusInSync;\r
+  SPIN_LOCK            *PFLock;\r
+  SPIN_LOCK            *CodeAccessCheckLock;\r
+  SPIN_LOCK            *MemoryMappedLock;\r
+} SMM_CPU_SEMAPHORE_GLOBAL;\r
+\r
+///\r
+/// All semaphores for each processor\r
+///\r
+typedef struct {\r
+  SPIN_LOCK                         *Busy;\r
+  volatile UINT32                   *Run;\r
+  volatile BOOLEAN                  *Present;\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
-  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
+  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
+extern EFI_PHYSICAL_ADDRESS                mGdtBuffer;\r
+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 ACPI_CPU_DATA                       mAcpiCpuData;\r
 extern SMM_DISPATCHER_MP_SYNC_DATA         *mSmmMpSyncData;\r
-extern VOID                                *mGdtForAp;\r
-extern VOID                                *mIdtForAp;\r
-extern VOID                                *mMachineCheckHandlerForAp;\r
 extern UINTN                               mSmmStackArrayBase;\r
 extern UINTN                               mSmmStackArrayEnd;\r
 extern UINTN                               mSmmStackSize;\r
 extern EFI_SMM_CPU_SERVICE_PROTOCOL        mSmmCpuService;\r
 extern IA32_DESCRIPTOR                     gcSmiInitGdtr;\r
+extern SMM_CPU_SEMAPHORES                  mSmmCpuSemaphores;\r
+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
 \r
-  @param          ExtraPages       Additional page numbers besides for 4G memory\r
-  @param          Is32BitPageTable Whether the page table is 32-bit PAE\r
+  @param[in]      Is32BitPageTable Whether the page table is 32-bit PAE\r
   @return         PageTable Address\r
 \r
 **/\r
 UINT32\r
 Gen4GPageTable (\r
-  IN      UINTN                     ExtraPages,\r
   IN      BOOLEAN                   Is32BitPageTable\r
   );\r
 \r
@@ -440,7 +496,7 @@ InitializeIDTSmmStackGuard (
 \r
 /**\r
   Initialize Gdt for all processors.\r
-  \r
+\r
   @param[in]   Cr3          CR3 value.\r
   @param[out]  GdtStepSize  The step size for GDT table.\r
 \r
@@ -453,6 +509,14 @@ InitGdt (
   OUT UINTN  *GdtStepSize\r
   );\r
 \r
+/**\r
+  This function sets GDT/IDT buffer to be RO and XP.\r
+**/\r
+VOID\r
+PatchGdtIdtMap (\r
+  VOID\r
+  );\r
+\r
 /**\r
 \r
   Register the SMM Foundation entry point.\r
@@ -525,6 +589,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
@@ -550,26 +674,14 @@ FindSmramInfo (
   );\r
 \r
 /**\r
-  The function is invoked before SMBASE relocation in S3 path to restores CPU status.\r
+  Relocate SmmBases for each processor.\r
 \r
-  The function is invoked before SMBASE relocation in S3 path. It does first time microcode load\r
-  and restores MTRRs for both BSP and APs.\r
+  Execute on first boot and all S3 resumes\r
 \r
 **/\r
 VOID\r
-EarlyInitializeCpu (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  The function is invoked after SMBASE relocation in S3 path to restores CPU status.\r
-\r
-  The function is invoked after SMBASE relocation in S3 path. It restores configuration according to\r
-  data saved by normal boot path for both BSP and APs.\r
-\r
-**/\r
-VOID\r
-InitializeCpu (\r
+EFIAPI\r
+SmmRelocateBases (\r
   VOID\r
   );\r
 \r
@@ -584,8 +696,8 @@ InitializeCpu (
 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
@@ -730,6 +842,125 @@ DumpModuleInfoByIp (
   IN  UINTN              CallerIpAddress\r
   );\r
 \r
+/**\r
+  This function sets memory attribute according to MemoryAttributesTable.\r
+**/\r
+VOID\r
+SetMemMapAttributes (\r
+  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
+VOID\r
+SetPageTableAttributes (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Return page table base.\r
+\r
+  @return page table base.\r
+**/\r
+UINTN\r
+GetPageTableBase (\r
+  VOID\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
+  @param[out]  IsSplitted       TRUE means page table splitted. FALSE means page table not splitted.\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
+SmmSetMemoryAttributesEx (\r
+  IN  EFI_PHYSICAL_ADDRESS                       BaseAddress,\r
+  IN  UINT64                                     Length,\r
+  IN  UINT64                                     Attributes,\r
+  OUT BOOLEAN                                    *IsSplitted  OPTIONAL\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
+  @param[out]  IsSplitted       TRUE means page table splitted. FALSE means page table not splitted.\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
+SmmClearMemoryAttributesEx (\r
+  IN  EFI_PHYSICAL_ADDRESS                       BaseAddress,\r
+  IN  UINT64                                     Length,\r
+  IN  UINT64                                     Attributes,\r
+  OUT BOOLEAN                                    *IsSplitted  OPTIONAL\r
+  );\r
+\r
 /**\r
   This API provides a way to allocate memory for page table.\r
 \r
@@ -750,4 +981,189 @@ AllocatePageTableMemory (
   IN UINTN           Pages\r
   );\r
 \r
+/**\r
+  Allocate pages for code.\r
+\r
+  @param[in]  Pages Number of pages to be allocated.\r
+\r
+  @return Allocated memory.\r
+**/\r
+VOID *\r
+AllocateCodePages (\r
+  IN UINTN           Pages\r
+  );\r
+\r
+/**\r
+  Allocate aligned pages for code.\r
+\r
+  @param[in]  Pages                 Number of pages to be allocated.\r
+  @param[in]  Alignment             The requested alignment of the allocation.\r
+                                    Must be a power of two.\r
+                                    If Alignment is zero, then byte alignment is used.\r
+\r
+  @return Allocated memory.\r
+**/\r
+VOID *\r
+AllocateAlignedCodePages (\r
+  IN UINTN            Pages,\r
+  IN UINTN            Alignment\r
+  );\r
+\r
+\r
+//\r
+// S3 related global variable and function prototype.\r
+//\r
+\r
+extern BOOLEAN                mSmmS3Flag;\r
+\r
+/**\r
+  Initialize SMM S3 resume state structure used during S3 Resume.\r
+\r
+  @param[in] Cr3    The base address of the page tables to use in SMM.\r
+\r
+**/\r
+VOID\r
+InitSmmS3ResumeState (\r
+  IN UINT32  Cr3\r
+  );\r
+\r
+/**\r
+  Get ACPI CPU data.\r
+\r
+**/\r
+VOID\r
+GetAcpiCpuData (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Restore SMM Configuration in S3 boot path.\r
+\r
+**/\r
+VOID\r
+RestoreSmmConfigurationInS3 (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Get ACPI S3 enable flag.\r
+\r
+**/\r
+VOID\r
+GetAcpiS3EnableFlag (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.\r
+\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 UINTN  ApHltLoopCode,\r
+  IN UINTN  TopOfStack,\r
+  IN UINTN  NumberToFinishAddress\r
+  );\r
+\r
+/**
+  This function set given attributes of the memory region specified by
+  BaseAddress and Length.
+
+  @param  This              The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
+  @param  BaseAddress       The physical address that is the start address of
+                            a memory region.
+  @param  Length            The size in bytes of the memory region.
+  @param  Attributes        The bit mask of attributes to set for the memory
+                            region.
+
+  @retval EFI_SUCCESS           The attributes were set for the memory region.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes specified an illegal combination of
+                                attributes that cannot be set together.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more
+                                bytes of the memory resource range specified
+                                by BaseAddress and Length.
+                                The bit mask of attributes is not support for
+                                the memory resource range specified by
+                                BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+EdkiiSmmSetMemoryAttributes (
+  IN  EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL   *This,
+  IN  EFI_PHYSICAL_ADDRESS                  BaseAddress,
+  IN  UINT64                                Length,
+  IN  UINT64                                Attributes
+  );
+
+/**
+  This function clears given attributes of the memory region specified by
+  BaseAddress and Length.
+
+  @param  This              The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
+  @param  BaseAddress       The physical address that is the start address of
+                            a memory region.
+  @param  Length            The size in bytes of the memory region.
+  @param  Attributes        The bit mask of attributes to set for the memory
+                            region.
+
+  @retval EFI_SUCCESS           The attributes were set for the memory region.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes specified an illegal combination of
+                                attributes that cannot be set together.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more
+                                bytes of the memory resource range specified
+                                by BaseAddress and Length.
+                                The bit mask of attributes is not support for
+                                the memory resource range specified by
+                                BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+EdkiiSmmClearMemoryAttributes (
+  IN  EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL   *This,
+  IN  EFI_PHYSICAL_ADDRESS                  BaseAddress,
+  IN  UINT64                                Length,
+  IN  UINT64                                Attributes
+  );
+
+/**
+  This function retrieve the attributes of the memory region specified by
+  BaseAddress and Length. If different attributes are got from different part
+  of the memory region, EFI_NO_MAPPING will be returned.
+
+  @param  This              The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
+  @param  BaseAddress       The physical address that is the start address of
+                            a memory region.
+  @param  Length            The size in bytes of the memory region.
+  @param  Attributes        Pointer to attributes returned.
+
+  @retval EFI_SUCCESS           The attributes got for the memory region.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes is NULL.
+  @retval EFI_NO_MAPPING        Attributes are not consistent cross the memory
+                                region.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more
+                                bytes of the memory resource range specified
+                                by BaseAddress and Length.
+                                The bit mask of attributes is not support for
+                                the memory resource range specified by
+                                BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+EdkiiSmmGetMemoryAttributes (
+  IN  EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL   *This,
+  IN  EFI_PHYSICAL_ADDRESS                  BaseAddress,
+  IN  UINT64                                Length,
+  IN  UINT64                                *Attributes
+  );
+
 #endif\r