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