+/**\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