/** @file | |
Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU. | |
Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR> | |
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#ifndef _CPU_PISMMCPUDXESMM_H_ | |
#define _CPU_PISMMCPUDXESMM_H_ | |
#include <PiSmm.h> | |
#include <Protocol/MpService.h> | |
#include <Protocol/SmmConfiguration.h> | |
#include <Protocol/SmmCpu.h> | |
#include <Protocol/SmmAccess2.h> | |
#include <Protocol/SmmReadyToLock.h> | |
#include <Protocol/SmmCpuService.h> | |
#include <Protocol/SmmMemoryAttribute.h> | |
#include <Protocol/MmMp.h> | |
#include <Guid/AcpiS3Context.h> | |
#include <Guid/MemoryAttributesTable.h> | |
#include <Guid/PiSmmMemoryAttributesTable.h> | |
#include <Library/BaseLib.h> | |
#include <Library/IoLib.h> | |
#include <Library/TimerLib.h> | |
#include <Library/SynchronizationLib.h> | |
#include <Library/DebugLib.h> | |
#include <Library/BaseMemoryLib.h> | |
#include <Library/PcdLib.h> | |
#include <Library/MtrrLib.h> | |
#include <Library/SmmCpuPlatformHookLib.h> | |
#include <Library/SmmServicesTableLib.h> | |
#include <Library/MemoryAllocationLib.h> | |
#include <Library/UefiBootServicesTableLib.h> | |
#include <Library/UefiRuntimeServicesTableLib.h> | |
#include <Library/DebugAgentLib.h> | |
#include <Library/UefiLib.h> | |
#include <Library/HobLib.h> | |
#include <Library/LocalApicLib.h> | |
#include <Library/UefiCpuLib.h> | |
#include <Library/CpuExceptionHandlerLib.h> | |
#include <Library/ReportStatusCodeLib.h> | |
#include <Library/SmmCpuFeaturesLib.h> | |
#include <Library/PeCoffGetEntryPointLib.h> | |
#include <Library/RegisterCpuFeaturesLib.h> | |
#include <AcpiCpuData.h> | |
#include <CpuHotPlugData.h> | |
#include <Register/Intel/Cpuid.h> | |
#include <Register/Intel/Msr.h> | |
#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 | |
// | |
#define EFI_MSR_SMM_MCA_CAP 0x17D | |
#define SMM_CODE_ACCESS_CHK_BIT BIT58 | |
#define SMM_FEATURE_CONTROL_LOCK_BIT BIT0 | |
#define SMM_CODE_CHK_EN_BIT BIT2 | |
/// | |
/// Page Table Entry | |
/// | |
#define IA32_PG_P BIT0 | |
#define IA32_PG_RW BIT1 | |
#define IA32_PG_U BIT2 | |
#define IA32_PG_WT BIT3 | |
#define IA32_PG_CD BIT4 | |
#define IA32_PG_A BIT5 | |
#define IA32_PG_D BIT6 | |
#define IA32_PG_PS BIT7 | |
#define IA32_PG_PAT_2M BIT12 | |
#define IA32_PG_PAT_4K IA32_PG_PS | |
#define IA32_PG_PMNT BIT62 | |
#define IA32_PG_NX BIT63 | |
#define PAGE_ATTRIBUTE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_U | IA32_PG_RW | IA32_PG_P) | |
// | |
// Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE | |
// X64 PAE PDPTE does not have such restriction | |
// | |
#define IA32_PAE_PDPTE_ATTRIBUTE_BITS (IA32_PG_P) | |
#define PAGE_PROGATE_BITS (IA32_PG_NX | PAGE_ATTRIBUTE_BITS) | |
#define PAGING_4K_MASK 0xFFF | |
#define PAGING_2M_MASK 0x1FFFFF | |
#define PAGING_1G_MASK 0x3FFFFFFF | |
#define PAGING_PAE_INDEX_MASK 0x1FF | |
#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull | |
#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull | |
#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull | |
#define SMRR_MAX_ADDRESS BASE_4GB | |
typedef enum { | |
PageNone, | |
Page4K, | |
Page2M, | |
Page1G, | |
} PAGE_ATTRIBUTE; | |
typedef struct { | |
PAGE_ATTRIBUTE Attribute; | |
UINT64 Length; | |
UINT64 AddressMask; | |
} PAGE_ATTRIBUTE_TABLE; | |
// | |
// 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 | |
// | |
// Code select value | |
// | |
#define PROTECT_MODE_CODE_SEGMENT 0x08 | |
#define LONG_MODE_CODE_SEGMENT 0x38 | |
// | |
// The size 0x20 must be bigger than | |
// the size of template code of SmmInit. Currently, | |
// the size of SmmInit requires the 0x16 Bytes buffer | |
// at least. | |
// | |
#define BACK_BUF_SIZE 0x20 | |
#define EXCEPTION_VECTOR_NUMBER 0x20 | |
#define INVALID_APIC_ID 0xFFFFFFFFFFFFFFFFULL | |
typedef UINT32 SMM_CPU_ARRIVAL_EXCEPTIONS; | |
#define ARRIVAL_EXCEPTION_BLOCKED 0x1 | |
#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 *SpinLock; | |
volatile UINT32 RunningApCount; | |
} 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. | |
// Contains a mix of DXE and SMM contents. All the fields must be used properly. | |
// | |
#define SMM_CPU_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('s', 'c', 'p', 'u') | |
typedef struct { | |
UINTN Signature; | |
EFI_HANDLE SmmCpuHandle; | |
EFI_PROCESSOR_INFORMATION *ProcessorInfo; | |
SMM_CPU_OPERATION *Operation; | |
UINTN *CpuSaveStateSize; | |
VOID **CpuSaveState; | |
EFI_SMM_RESERVED_SMRAM_REGION SmmReservedSmramRegion[1]; | |
EFI_SMM_ENTRY_CONTEXT SmmCoreEntryContext; | |
EFI_SMM_ENTRY_POINT SmmCoreEntry; | |
EFI_SMM_CONFIGURATION_PROTOCOL SmmConfiguration; | |
PROCEDURE_WRAPPER *ApWrapperFunc; | |
LIST_ENTRY TokenList; | |
LIST_ENTRY *FirstFreeToken; | |
} SMM_CPU_PRIVATE_DATA; | |
extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate; | |
extern CPU_HOT_PLUG_DATA mCpuHotPlugData; | |
extern UINTN mMaxNumberOfCpus; | |
extern UINTN mNumberOfCpus; | |
extern EFI_SMM_CPU_PROTOCOL mSmmCpu; | |
extern EFI_MM_MP_PROTOCOL mSmmMp; | |
extern UINTN mInternalCr3; | |
/// | |
/// The mode of the CPU at the time an SMI occurs | |
/// | |
extern UINT8 mSmmSaveStateRegisterLma; | |
// | |
// SMM CPU Protocol function prototypes. | |
// | |
/** | |
Read information from the CPU save state. | |
@param This EFI_SMM_CPU_PROTOCOL instance | |
@param Width The number of bytes to read from the CPU save state. | |
@param Register Specifies the CPU register to read form the save state. | |
@param CpuIndex Specifies the zero-based index of the CPU save state | |
@param Buffer Upon return, this holds the CPU register value read from the save state. | |
@retval EFI_SUCCESS The register was read from Save State | |
@retval EFI_NOT_FOUND The register is not defined for the Save State of Processor | |
@retval EFI_INVALID_PARAMETER This or Buffer is NULL. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
SmmReadSaveState ( | |
IN CONST EFI_SMM_CPU_PROTOCOL *This, | |
IN UINTN Width, | |
IN EFI_SMM_SAVE_STATE_REGISTER Register, | |
IN UINTN CpuIndex, | |
OUT VOID *Buffer | |
); | |
/** | |
Write data to the CPU save state. | |
@param This EFI_SMM_CPU_PROTOCOL instance | |
@param Width The number of bytes to read from the CPU save state. | |
@param Register Specifies the CPU register to write to the save state. | |
@param CpuIndex Specifies the zero-based index of the CPU save state | |
@param Buffer Upon entry, this holds the new CPU register value. | |
@retval EFI_SUCCESS The register was written from Save State | |
@retval EFI_NOT_FOUND The register is not defined for the Save State of Processor | |
@retval EFI_INVALID_PARAMETER ProcessorIndex or Width is not correct | |
**/ | |
EFI_STATUS | |
EFIAPI | |
SmmWriteSaveState ( | |
IN CONST EFI_SMM_CPU_PROTOCOL *This, | |
IN UINTN Width, | |
IN EFI_SMM_SAVE_STATE_REGISTER Register, | |
IN UINTN CpuIndex, | |
IN CONST VOID *Buffer | |
); | |
/** | |
Read a CPU Save State register on the target processor. | |
This function abstracts the differences that whether the CPU Save State register is in the | |
IA32 CPU Save State Map or X64 CPU Save State Map. | |
This function supports reading a CPU Save State register in SMBase relocation handler. | |
@param[in] CpuIndex Specifies the zero-based index of the CPU save state. | |
@param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table. | |
@param[in] Width The number of bytes to read from the CPU save state. | |
@param[out] Buffer Upon return, this holds the CPU register value read from the save state. | |
@retval EFI_SUCCESS The register was read from Save State. | |
@retval EFI_NOT_FOUND The register is not defined for the Save State of Processor. | |
@retval EFI_INVALID_PARAMETER Buffer is NULL, or Width does not meet requirement per Register type. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
ReadSaveStateRegister ( | |
IN UINTN CpuIndex, | |
IN EFI_SMM_SAVE_STATE_REGISTER Register, | |
IN UINTN Width, | |
OUT VOID *Buffer | |
); | |
/** | |
Write value to a CPU Save State register on the target processor. | |
This function abstracts the differences that whether the CPU Save State register is in the | |
IA32 CPU Save State Map or X64 CPU Save State Map. | |
This function supports writing a CPU Save State register in SMBase relocation handler. | |
@param[in] CpuIndex Specifies the zero-based index of the CPU save state. | |
@param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table. | |
@param[in] Width The number of bytes to read from the CPU save state. | |
@param[in] Buffer Upon entry, this holds the new CPU register value. | |
@retval EFI_SUCCESS The register was written to Save State. | |
@retval EFI_NOT_FOUND The register is not defined for the Save State of Processor. | |
@retval EFI_INVALID_PARAMETER ProcessorIndex or Width is not correct. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
WriteSaveStateRegister ( | |
IN UINTN CpuIndex, | |
IN EFI_SMM_SAVE_STATE_REGISTER Register, | |
IN UINTN Width, | |
IN CONST VOID *Buffer | |
); | |
extern CONST UINT8 gcSmmInitTemplate[]; | |
extern CONST UINT16 gcSmmInitSize; | |
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. | |
**/ | |
VOID | |
EFIAPI | |
SmmRelocationSemaphoreComplete ( | |
VOID | |
); | |
/// | |
/// The type of SMM CPU Information | |
/// | |
typedef struct { | |
SPIN_LOCK *Busy; | |
volatile EFI_AP_PROCEDURE2 Procedure; | |
volatile VOID *Parameter; | |
volatile UINT32 *Run; | |
volatile BOOLEAN *Present; | |
PROCEDURE_TOKEN *Token; | |
EFI_STATUS *Status; | |
} SMM_CPU_DATA_BLOCK; | |
typedef enum { | |
SmmCpuSyncModeTradition, | |
SmmCpuSyncModeRelaxedAp, | |
SmmCpuSyncModeMax | |
} SMM_CPU_SYNC_MODE; | |
typedef struct { | |
// | |
// Pointer to an array. The array should be located immediately after this structure | |
// so that UC cache-ability can be set together. | |
// | |
SMM_CPU_DATA_BLOCK *CpuData; | |
volatile UINT32 *Counter; | |
volatile UINT32 BspIndex; | |
volatile BOOLEAN *InsideSmm; | |
volatile BOOLEAN *AllCpusInSync; | |
volatile SMM_CPU_SYNC_MODE EffectiveSyncMode; | |
volatile BOOLEAN SwitchBsp; | |
volatile BOOLEAN *CandidateBsp; | |
EFI_AP_PROCEDURE StartupProcedure; | |
VOID *StartupProcArgs; | |
} SMM_DISPATCHER_MP_SYNC_DATA; | |
#define SMM_PSD_OFFSET 0xfb00 | |
/// | |
/// All global semaphores' pointer | |
/// | |
typedef struct { | |
volatile UINT32 *Counter; | |
volatile BOOLEAN *InsideSmm; | |
volatile BOOLEAN *AllCpusInSync; | |
SPIN_LOCK *PFLock; | |
SPIN_LOCK *CodeAccessCheckLock; | |
} SMM_CPU_SEMAPHORE_GLOBAL; | |
/// | |
/// All semaphores for each processor | |
/// | |
typedef struct { | |
SPIN_LOCK *Busy; | |
volatile UINT32 *Run; | |
volatile BOOLEAN *Present; | |
SPIN_LOCK *Token; | |
} SMM_CPU_SEMAPHORE_CPU; | |
/// | |
/// All semaphores' information | |
/// | |
typedef struct { | |
SMM_CPU_SEMAPHORE_GLOBAL SemaphoreGlobal; | |
SMM_CPU_SEMAPHORE_CPU SemaphoreCpu; | |
} SMM_CPU_SEMAPHORES; | |
extern IA32_DESCRIPTOR gcSmiGdtr; | |
extern EFI_PHYSICAL_ADDRESS mGdtBuffer; | |
extern UINTN mGdtBufferSize; | |
extern IA32_DESCRIPTOR gcSmiIdtr; | |
extern VOID *gcSmiIdtrPtr; | |
extern UINT64 gPhyMask; | |
extern SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData; | |
extern UINTN mSmmStackArrayBase; | |
extern UINTN mSmmStackArrayEnd; | |
extern UINTN mSmmStackSize; | |
extern EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService; | |
extern IA32_DESCRIPTOR gcSmiInitGdtr; | |
extern SMM_CPU_SEMAPHORES mSmmCpuSemaphores; | |
extern UINTN mSemaphoreSize; | |
extern SPIN_LOCK *mPFLock; | |
extern SPIN_LOCK *mConfigSmmCodeAccessCheckLock; | |
extern EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges; | |
extern UINTN mSmmCpuSmramRangeCount; | |
extern UINT8 mPhysicalAddressBits; | |
// | |
// Copy of the PcdPteMemoryEncryptionAddressOrMask | |
// | |
extern UINT64 mAddressEncMask; | |
/** | |
Create 4G PageTable in SMRAM. | |
@param[in] Is32BitPageTable Whether the page table is 32-bit PAE | |
@return PageTable Address | |
**/ | |
UINT32 | |
Gen4GPageTable ( | |
IN BOOLEAN Is32BitPageTable | |
); | |
/** | |
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 ShadowStackSize Shadow Stack size for each processor in SMM. | |
**/ | |
UINT32 | |
InitializeMpServiceData ( | |
IN VOID *Stacks, | |
IN UINTN StackSize, | |
IN UINTN ShadowStackSize | |
); | |
/** | |
Initialize Timer for SMM AP Sync. | |
**/ | |
VOID | |
InitializeSmmTimer ( | |
VOID | |
); | |
/** | |
Start Timer for SMM AP Sync. | |
**/ | |
UINT64 | |
EFIAPI | |
StartSyncTimer ( | |
VOID | |
); | |
/** | |
Check if the SMM AP Sync timer is timeout. | |
@param Timer The start timer from the begin. | |
**/ | |
BOOLEAN | |
EFIAPI | |
IsSyncTimerTimeout ( | |
IN UINT64 Timer | |
); | |
/** | |
Initialize IDT for SMM Stack Guard. | |
**/ | |
VOID | |
EFIAPI | |
InitializeIDTSmmStackGuard ( | |
VOID | |
); | |
/** | |
Initialize IDT IST Field. | |
@param[in] ExceptionType Exception type. | |
@param[in] Ist IST value. | |
**/ | |
VOID | |
EFIAPI | |
InitializeIdtIst ( | |
IN EFI_EXCEPTION_TYPE ExceptionType, | |
IN UINT8 Ist | |
); | |
/** | |
Initialize Gdt for all processors. | |
@param[in] Cr3 CR3 value. | |
@param[out] GdtStepSize The step size for GDT table. | |
@return GdtBase for processor 0. | |
GdtBase for processor X is: GdtBase + (GdtStepSize * X) | |
**/ | |
VOID * | |
InitGdt ( | |
IN UINTN Cr3, | |
OUT UINTN *GdtStepSize | |
); | |
/** | |
Register the SMM Foundation entry point. | |
@param This Pointer to EFI_SMM_CONFIGURATION_PROTOCOL instance | |
@param SmmEntryPoint SMM Foundation EntryPoint | |
@retval EFI_SUCCESS Successfully to register SMM foundation entry point | |
**/ | |
EFI_STATUS | |
EFIAPI | |
RegisterSmmEntry ( | |
IN CONST EFI_SMM_CONFIGURATION_PROTOCOL *This, | |
IN EFI_SMM_ENTRY_POINT SmmEntryPoint | |
); | |
/** | |
Create PageTable for SMM use. | |
@return PageTable Address | |
**/ | |
UINT32 | |
SmmInitPageTable ( | |
VOID | |
); | |
/** | |
Schedule a procedure to run on the specified CPU. | |
@param Procedure The address of the procedure to run | |
@param CpuIndex Target CPU number | |
@param ProcArguments The parameter to pass to the procedure | |
@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 | |
EFIAPI | |
SmmStartupThisAp ( | |
IN EFI_AP_PROCEDURE Procedure, | |
IN UINTN CpuIndex, | |
IN OUT VOID *ProcArguments OPTIONAL | |
); | |
/** | |
Schedule a procedure to run on the specified CPU in a blocking fashion. | |
@param Procedure The address of the procedure to run | |
@param CpuIndex Target CPU Index | |
@param ProcArguments The parameter to pass to the procedure | |
@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 | |
EFIAPI | |
SmmBlockingStartupThisAp ( | |
IN EFI_AP_PROCEDURE Procedure, | |
IN UINTN CpuIndex, | |
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. | |
**/ | |
VOID | |
EFIAPI | |
InitializeMpSyncData ( | |
VOID | |
); | |
/** | |
Find out SMRAM information including SMRR base and SMRR size. | |
@param SmrrBase SMRR base | |
@param SmrrSize SMRR size | |
**/ | |
VOID | |
FindSmramInfo ( | |
OUT UINT32 *SmrrBase, | |
OUT UINT32 *SmrrSize | |
); | |
/** | |
Relocate SmmBases for each processor. | |
Execute on first boot and all S3 resumes | |
**/ | |
VOID | |
EFIAPI | |
SmmRelocateBases ( | |
VOID | |
); | |
/** | |
Page Fault handler for SMM use. | |
@param InterruptType Defines the type of interrupt or exception that | |
occurred on the processor.This parameter is processor architecture specific. | |
@param SystemContext A pointer to the processor context when | |
the interrupt occurred on the processor. | |
**/ | |
VOID | |
EFIAPI | |
SmiPFHandler ( | |
IN EFI_EXCEPTION_TYPE InterruptType, | |
IN EFI_SYSTEM_CONTEXT SystemContext | |
); | |
/** | |
Perform the remaining tasks. | |
**/ | |
VOID | |
PerformRemainingTasks ( | |
VOID | |
); | |
/** | |
Perform the pre tasks. | |
**/ | |
VOID | |
PerformPreTasks ( | |
VOID | |
); | |
/** | |
Initialize MSR spin lock by MSR index. | |
@param MsrIndex MSR index value. | |
**/ | |
VOID | |
InitMsrSpinLockByIndex ( | |
IN UINT32 MsrIndex | |
); | |
/** | |
Hook return address of SMM Save State so that semaphore code | |
can be executed immediately after AP exits SMM to indicate to | |
the BSP that an AP has exited SMM after SMBASE relocation. | |
@param[in] CpuIndex The processor index. | |
@param[in] RebasedFlag A pointer to a flag that is set to TRUE | |
immediately after AP exits SMM. | |
**/ | |
VOID | |
SemaphoreHook ( | |
IN UINTN CpuIndex, | |
IN volatile BOOLEAN *RebasedFlag | |
); | |
/** | |
Configure SMM Code Access Check feature for all processors. | |
SMM Feature Control MSR will be locked after configuration. | |
**/ | |
VOID | |
ConfigSmmCodeAccessCheck ( | |
VOID | |
); | |
/** | |
Hook the code executed immediately after an RSM instruction on the currently | |
executing CPU. The mode of code executed immediately after RSM must be | |
detected, and the appropriate hook must be selected. Always clear the auto | |
HALT restart flag if it is set. | |
@param[in] CpuIndex The processor index for the currently | |
executing CPU. | |
@param[in] CpuState Pointer to SMRAM Save State Map for the | |
currently executing CPU. | |
@param[in] NewInstructionPointer32 Instruction pointer to use if resuming to | |
32-bit mode from 64-bit SMM. | |
@param[in] NewInstructionPointer Instruction pointer to use if resuming to | |
same mode as SMM. | |
@retval The value of the original instruction pointer before it was hooked. | |
**/ | |
UINT64 | |
EFIAPI | |
HookReturnFromSmm ( | |
IN UINTN CpuIndex, | |
SMRAM_SAVE_STATE_MAP *CpuState, | |
UINT64 NewInstructionPointer32, | |
UINT64 NewInstructionPointer | |
); | |
/** | |
Get the size of the SMI Handler in bytes. | |
@retval The size, in bytes, of the SMI Handler. | |
**/ | |
UINTN | |
EFIAPI | |
GetSmiHandlerSize ( | |
VOID | |
); | |
/** | |
Install the SMI handler for the CPU specified by CpuIndex. This function | |
is called by the CPU that was elected as monarch during System Management | |
Mode initialization. | |
@param[in] CpuIndex The index of the CPU to install the custom SMI handler. | |
The value must be between 0 and the NumberOfCpus field | |
in the System Management System Table (SMST). | |
@param[in] SmBase The SMBASE address for the CPU specified by CpuIndex. | |
@param[in] SmiStack The stack to use when an SMI is processed by the | |
the CPU specified by CpuIndex. | |
@param[in] StackSize The size, in bytes, if the stack used when an SMI is | |
processed by the CPU specified by CpuIndex. | |
@param[in] GdtBase The base address of the GDT to use when an SMI is | |
processed by the CPU specified by CpuIndex. | |
@param[in] GdtSize The size, in bytes, of the GDT used when an SMI is | |
processed by the CPU specified by CpuIndex. | |
@param[in] IdtBase The base address of the IDT to use when an SMI is | |
processed by the CPU specified by CpuIndex. | |
@param[in] IdtSize The size, in bytes, of the IDT used when an SMI is | |
processed by the CPU specified by CpuIndex. | |
@param[in] Cr3 The base address of the page tables to use when an SMI | |
is processed by the CPU specified by CpuIndex. | |
**/ | |
VOID | |
EFIAPI | |
InstallSmiHandler ( | |
IN UINTN CpuIndex, | |
IN UINT32 SmBase, | |
IN VOID *SmiStack, | |
IN UINTN StackSize, | |
IN UINTN GdtBase, | |
IN UINTN GdtSize, | |
IN UINTN IdtBase, | |
IN UINTN IdtSize, | |
IN UINT32 Cr3 | |
); | |
/** | |
Search module name by input IP address and output it. | |
@param CallerIpAddress Caller instruction pointer. | |
**/ | |
VOID | |
DumpModuleInfoByIp ( | |
IN UINTN CallerIpAddress | |
); | |
/** | |
This function sets memory attribute according to MemoryAttributesTable. | |
**/ | |
VOID | |
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. | |
**/ | |
VOID | |
SetPageTableAttributes ( | |
VOID | |
); | |
/** | |
Get page table base address and the depth of the page table. | |
@param[out] Base Page table base address. | |
@param[out] FiveLevels TRUE means 5 level paging. FALSE means 4 level paging. | |
**/ | |
VOID | |
GetPageTable ( | |
OUT UINTN *Base, | |
OUT BOOLEAN *FiveLevels 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. | |
@param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted. | |
@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 | |
SmmSetMemoryAttributesEx ( | |
IN EFI_PHYSICAL_ADDRESS BaseAddress, | |
IN UINT64 Length, | |
IN UINT64 Attributes, | |
OUT BOOLEAN *IsSplitted OPTIONAL | |
); | |
/** | |
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. | |
@param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted. | |
@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 | |
SmmClearMemoryAttributesEx ( | |
IN EFI_PHYSICAL_ADDRESS BaseAddress, | |
IN UINT64 Length, | |
IN UINT64 Attributes, | |
OUT BOOLEAN *IsSplitted OPTIONAL | |
); | |
/** | |
This API provides a way to allocate memory for page table. | |
This API can be called more once to allocate memory for page tables. | |
Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the | |
allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL | |
is returned. If there is not enough memory remaining to satisfy the request, then NULL is | |
returned. | |
@param Pages The number of 4 KB pages to allocate. | |
@return A pointer to the allocated buffer or NULL if allocation fails. | |
**/ | |
VOID * | |
AllocatePageTableMemory ( | |
IN UINTN Pages | |
); | |
/** | |
Allocate pages for code. | |
@param[in] Pages Number of pages to be allocated. | |
@return Allocated memory. | |
**/ | |
VOID * | |
AllocateCodePages ( | |
IN UINTN Pages | |
); | |
/** | |
Allocate aligned pages for code. | |
@param[in] Pages Number of pages to be allocated. | |
@param[in] Alignment The requested alignment of the allocation. | |
Must be a power of two. | |
If Alignment is zero, then byte alignment is used. | |
@return Allocated memory. | |
**/ | |
VOID * | |
AllocateAlignedCodePages ( | |
IN UINTN Pages, | |
IN UINTN Alignment | |
); | |
// | |
// S3 related global variable and function prototype. | |
// | |
extern BOOLEAN mSmmS3Flag; | |
/** | |
Initialize SMM S3 resume state structure used during S3 Resume. | |
@param[in] Cr3 The base address of the page tables to use in SMM. | |
**/ | |
VOID | |
InitSmmS3ResumeState ( | |
IN UINT32 Cr3 | |
); | |
/** | |
Get ACPI CPU data. | |
**/ | |
VOID | |
GetAcpiCpuData ( | |
VOID | |
); | |
/** | |
Restore SMM Configuration in S3 boot path. | |
**/ | |
VOID | |
RestoreSmmConfigurationInS3 ( | |
VOID | |
); | |
/** | |
Get ACPI S3 enable flag. | |
**/ | |
VOID | |
GetAcpiS3EnableFlag ( | |
VOID | |
); | |
/** | |
Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch. | |
@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 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 absolute address. | |
**/ | |
VOID | |
EFIAPI | |
PiSmmCpuSmmInitFixupAddress ( | |
); | |
/** | |
This function fixes up the address of the global variable or function | |
referred in SmiEntry assembly files to be the absolute 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 |