2 Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
4 Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #ifndef _CPU_PISMMCPUDXESMM_H_
12 #define _CPU_PISMMCPUDXESMM_H_
16 #include <Protocol/MpService.h>
17 #include <Protocol/SmmConfiguration.h>
18 #include <Protocol/SmmCpu.h>
19 #include <Protocol/SmmAccess2.h>
20 #include <Protocol/SmmReadyToLock.h>
21 #include <Protocol/SmmCpuService.h>
22 #include <Protocol/SmmMemoryAttribute.h>
23 #include <Protocol/MmMp.h>
25 #include <Guid/AcpiS3Context.h>
26 #include <Guid/MemoryAttributesTable.h>
27 #include <Guid/PiSmmMemoryAttributesTable.h>
28 #include <Guid/SmmBaseHob.h>
30 #include <Library/BaseLib.h>
31 #include <Library/IoLib.h>
32 #include <Library/TimerLib.h>
33 #include <Library/SynchronizationLib.h>
34 #include <Library/DebugLib.h>
35 #include <Library/BaseMemoryLib.h>
36 #include <Library/PcdLib.h>
37 #include <Library/MtrrLib.h>
38 #include <Library/SmmCpuPlatformHookLib.h>
39 #include <Library/SmmServicesTableLib.h>
40 #include <Library/MemoryAllocationLib.h>
41 #include <Library/UefiBootServicesTableLib.h>
42 #include <Library/UefiRuntimeServicesTableLib.h>
43 #include <Library/DebugAgentLib.h>
44 #include <Library/UefiLib.h>
45 #include <Library/HobLib.h>
46 #include <Library/LocalApicLib.h>
47 #include <Library/CpuLib.h>
48 #include <Library/UefiCpuLib.h>
49 #include <Library/CpuExceptionHandlerLib.h>
50 #include <Library/ReportStatusCodeLib.h>
51 #include <Library/SmmCpuFeaturesLib.h>
52 #include <Library/PeCoffGetEntryPointLib.h>
53 #include <Library/RegisterCpuFeaturesLib.h>
55 #include <AcpiCpuData.h>
56 #include <CpuHotPlugData.h>
58 #include <Register/Intel/Cpuid.h>
59 #include <Register/Intel/Msr.h>
61 #include "CpuService.h"
62 #include "SmmProfile.h"
67 #define CPUID_CET_SS BIT7
68 #define CPUID_CET_IBT BIT20
70 #define CR4_CET_ENABLE BIT23
72 #define MSR_IA32_S_CET 0x6A2
73 #define MSR_IA32_PL0_SSP 0x6A4
74 #define MSR_IA32_INTERRUPT_SSP_TABLE_ADDR 0x6A8
78 // enable shadow stacks
79 UINT32 SH_STK_ENP
: 1;
80 // enable the WRSS{D,Q}W instructions.
81 UINT32 WR_SHSTK_EN
: 1;
82 // enable tracking of indirect call/jmp targets to be ENDBRANCH instruction.
84 // enable legacy compatibility treatment for indirect call/jmp tracking.
86 // enable use of no-track prefix on indirect call/jmp.
87 UINT32 NO_TRACK_EN
: 1;
88 // disable suppression of CET indirect branch tracking on legacy compatibility.
89 UINT32 SUPPRESS_DIS
: 1;
91 // indirect branch tracking is suppressed.
92 // This bit can be written to 1 only if TRACKER is written as IDLE.
94 // Value of the endbranch state machine
95 // Values: IDLE (0), WAIT_FOR_ENDBRANCH(1).
97 // linear address of a bitmap in memory indicating valid
98 // pages as target of CALL/JMP_indirect that do not land on ENDBRANCH when CET is enabled
99 // and not suppressed. Valid when ENDBR_EN is 1. Must be machine canonical when written on
100 // parts that support 64 bit mode. On parts that do not support 64 bit mode, the bits 63:32 are
101 // reserved and must be 0. This value is extended by 12 bits at the low end to form the base address
102 // (this automatically aligns the address on a 4-Kbyte boundary).
103 UINT32 EB_LEG_BITMAP_BASE_low
: 12;
104 UINT32 EB_LEG_BITMAP_BASE_high
: 32;
110 // MSRs required for configuration of SMM Code Access Check
112 #define EFI_MSR_SMM_MCA_CAP 0x17D
113 #define SMM_CODE_ACCESS_CHK_BIT BIT58
115 #define SMM_FEATURE_CONTROL_LOCK_BIT BIT0
116 #define SMM_CODE_CHK_EN_BIT BIT2
121 #define IA32_PG_P BIT0
122 #define IA32_PG_RW BIT1
123 #define IA32_PG_U BIT2
124 #define IA32_PG_WT BIT3
125 #define IA32_PG_CD BIT4
126 #define IA32_PG_A BIT5
127 #define IA32_PG_D BIT6
128 #define IA32_PG_PS BIT7
129 #define IA32_PG_PAT_2M BIT12
130 #define IA32_PG_PAT_4K IA32_PG_PS
131 #define IA32_PG_PMNT BIT62
132 #define IA32_PG_NX BIT63
134 #define PAGE_ATTRIBUTE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_U | IA32_PG_RW | IA32_PG_P)
136 // Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE
137 // X64 PAE PDPTE does not have such restriction
139 #define IA32_PAE_PDPTE_ATTRIBUTE_BITS (IA32_PG_P)
141 #define PAGE_PROGATE_BITS (IA32_PG_NX | PAGE_ATTRIBUTE_BITS)
143 #define PAGING_4K_MASK 0xFFF
144 #define PAGING_2M_MASK 0x1FFFFF
145 #define PAGING_1G_MASK 0x3FFFFFFF
147 #define PAGING_PAE_INDEX_MASK 0x1FF
149 #define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull
150 #define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull
151 #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
153 #define SMRR_MAX_ADDRESS BASE_4GB
163 PAGE_ATTRIBUTE Attribute
;
166 } PAGE_ATTRIBUTE_TABLE
;
169 // Size of Task-State Segment defined in IA32 Manual
172 #define EXCEPTION_TSS_SIZE (TSS_SIZE + 4) // Add 4 bytes SSP
173 #define TSS_X64_IST1_OFFSET 36
174 #define TSS_IA32_CR3_OFFSET 28
175 #define TSS_IA32_ESP_OFFSET 56
176 #define TSS_IA32_SSP_OFFSET 104
183 #define PROTECT_MODE_CODE_SEGMENT 0x08
184 #define LONG_MODE_CODE_SEGMENT 0x38
187 // The size 0x20 must be bigger than
188 // the size of template code of SmmInit. Currently,
189 // the size of SmmInit requires the 0x16 Bytes buffer
192 #define BACK_BUF_SIZE 0x20
194 #define EXCEPTION_VECTOR_NUMBER 0x20
196 #define INVALID_APIC_ID 0xFFFFFFFFFFFFFFFFULL
199 // Wrapper used to convert EFI_AP_PROCEDURE2 and EFI_AP_PROCEDURE.
202 EFI_AP_PROCEDURE Procedure
;
203 VOID
*ProcedureArgument
;
206 #define PROCEDURE_TOKEN_SIGNATURE SIGNATURE_32 ('P', 'R', 'T', 'S')
213 volatile UINT32 RunningApCount
;
216 #define PROCEDURE_TOKEN_FROM_LINK(a) CR (a, PROCEDURE_TOKEN, Link, PROCEDURE_TOKEN_SIGNATURE)
218 #define TOKEN_BUFFER_SIGNATURE SIGNATURE_32 ('T', 'K', 'B', 'S')
227 #define TOKEN_BUFFER_FROM_LINK(a) CR (a, TOKEN_BUFFER, Link, TOKEN_BUFFER_SIGNATURE)
230 // Private structure for the SMM CPU module that is stored in DXE Runtime memory
231 // Contains the SMM Configuration Protocols that is produced.
232 // Contains a mix of DXE and SMM contents. All the fields must be used properly.
234 #define SMM_CPU_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('s', 'c', 'p', 'u')
239 EFI_HANDLE SmmCpuHandle
;
241 EFI_PROCESSOR_INFORMATION
*ProcessorInfo
;
242 SMM_CPU_OPERATION
*Operation
;
243 UINTN
*CpuSaveStateSize
;
246 EFI_SMM_RESERVED_SMRAM_REGION SmmReservedSmramRegion
[1];
247 EFI_SMM_ENTRY_CONTEXT SmmCoreEntryContext
;
248 EFI_SMM_ENTRY_POINT SmmCoreEntry
;
250 EFI_SMM_CONFIGURATION_PROTOCOL SmmConfiguration
;
252 PROCEDURE_WRAPPER
*ApWrapperFunc
;
253 LIST_ENTRY TokenList
;
254 LIST_ENTRY
*FirstFreeToken
;
255 } SMM_CPU_PRIVATE_DATA
;
257 extern SMM_CPU_PRIVATE_DATA
*gSmmCpuPrivate
;
258 extern CPU_HOT_PLUG_DATA mCpuHotPlugData
;
259 extern UINTN mMaxNumberOfCpus
;
260 extern UINTN mNumberOfCpus
;
261 extern EFI_SMM_CPU_PROTOCOL mSmmCpu
;
262 extern EFI_MM_MP_PROTOCOL mSmmMp
;
263 extern BOOLEAN m5LevelPagingNeeded
;
266 /// The mode of the CPU at the time an SMI occurs
268 extern UINT8 mSmmSaveStateRegisterLma
;
270 #define PAGE_TABLE_POOL_ALIGNMENT BASE_128KB
271 #define PAGE_TABLE_POOL_UNIT_SIZE BASE_128KB
272 #define PAGE_TABLE_POOL_UNIT_PAGES EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE)
273 #define PAGE_TABLE_POOL_ALIGN_MASK \
274 (~(EFI_PHYSICAL_ADDRESS)(PAGE_TABLE_POOL_ALIGNMENT - 1))
301 // SMM CPU Protocol function prototypes.
305 Read information from the CPU save state.
307 @param This EFI_SMM_CPU_PROTOCOL instance
308 @param Width The number of bytes to read from the CPU save state.
309 @param Register Specifies the CPU register to read form the save state.
310 @param CpuIndex Specifies the zero-based index of the CPU save state
311 @param Buffer Upon return, this holds the CPU register value read from the save state.
313 @retval EFI_SUCCESS The register was read from Save State
314 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
315 @retval EFI_INVALID_PARAMETER This or Buffer is NULL.
321 IN CONST EFI_SMM_CPU_PROTOCOL
*This
,
323 IN EFI_SMM_SAVE_STATE_REGISTER Register
,
329 Write data to the CPU save state.
331 @param This EFI_SMM_CPU_PROTOCOL instance
332 @param Width The number of bytes to read from the CPU save state.
333 @param Register Specifies the CPU register to write to the save state.
334 @param CpuIndex Specifies the zero-based index of the CPU save state
335 @param Buffer Upon entry, this holds the new CPU register value.
337 @retval EFI_SUCCESS The register was written from Save State
338 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
339 @retval EFI_INVALID_PARAMETER ProcessorIndex or Width is not correct
345 IN CONST EFI_SMM_CPU_PROTOCOL
*This
,
347 IN EFI_SMM_SAVE_STATE_REGISTER Register
,
349 IN CONST VOID
*Buffer
353 C function for SMI handler. To change all processor's SMMBase Register.
363 Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init.
367 ExecuteFirstSmiInit (
372 Read a CPU Save State register on the target processor.
374 This function abstracts the differences that whether the CPU Save State register is in the
375 IA32 CPU Save State Map or X64 CPU Save State Map.
377 This function supports reading a CPU Save State register in SMBase relocation handler.
379 @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
380 @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
381 @param[in] Width The number of bytes to read from the CPU save state.
382 @param[out] Buffer Upon return, this holds the CPU register value read from the save state.
384 @retval EFI_SUCCESS The register was read from Save State.
385 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
386 @retval EFI_INVALID_PARAMETER Buffer is NULL, or Width does not meet requirement per Register type.
391 ReadSaveStateRegister (
393 IN EFI_SMM_SAVE_STATE_REGISTER Register
,
399 Write value to a CPU Save State register on the target processor.
401 This function abstracts the differences that whether the CPU Save State register is in the
402 IA32 CPU Save State Map or X64 CPU Save State Map.
404 This function supports writing a CPU Save State register in SMBase relocation handler.
406 @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
407 @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
408 @param[in] Width The number of bytes to read from the CPU save state.
409 @param[in] Buffer Upon entry, this holds the new CPU register value.
411 @retval EFI_SUCCESS The register was written to Save State.
412 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
413 @retval EFI_INVALID_PARAMETER ProcessorIndex or Width is not correct.
418 WriteSaveStateRegister (
420 IN EFI_SMM_SAVE_STATE_REGISTER Register
,
422 IN CONST VOID
*Buffer
425 extern BOOLEAN mSmmRelocated
;
426 extern volatile BOOLEAN
*mSmmInitialized
;
427 extern UINT32 mBspApicId
;
429 extern CONST UINT8 gcSmmInitTemplate
[];
430 extern CONST UINT16 gcSmmInitSize
;
431 X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr0
;
432 extern UINT32 mSmmCr0
;
433 X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr3
;
434 extern UINT32 mSmmCr4
;
435 X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr4
;
436 X86_ASSEMBLY_PATCH_LABEL gPatchSmmInitStack
;
437 X86_ASSEMBLY_PATCH_LABEL mPatchCetSupported
;
438 extern BOOLEAN mCetSupported
;
441 Semaphore operation for all processor relocate SMMBase.
445 SmmRelocationSemaphoreComplete (
450 /// The type of SMM CPU Information
454 volatile EFI_AP_PROCEDURE2 Procedure
;
455 volatile VOID
*Parameter
;
456 volatile UINT32
*Run
;
457 volatile BOOLEAN
*Present
;
458 PROCEDURE_TOKEN
*Token
;
460 } SMM_CPU_DATA_BLOCK
;
463 SmmCpuSyncModeTradition
,
464 SmmCpuSyncModeRelaxedAp
,
470 // Pointer to an array. The array should be located immediately after this structure
471 // so that UC cache-ability can be set together.
473 SMM_CPU_DATA_BLOCK
*CpuData
;
474 volatile UINT32
*Counter
;
475 volatile UINT32 BspIndex
;
476 volatile BOOLEAN
*InsideSmm
;
477 volatile BOOLEAN
*AllCpusInSync
;
478 volatile SMM_CPU_SYNC_MODE EffectiveSyncMode
;
479 volatile BOOLEAN SwitchBsp
;
480 volatile BOOLEAN
*CandidateBsp
;
481 volatile BOOLEAN AllApArrivedWithException
;
482 EFI_AP_PROCEDURE StartupProcedure
;
483 VOID
*StartupProcArgs
;
484 } SMM_DISPATCHER_MP_SYNC_DATA
;
486 #define SMM_PSD_OFFSET 0xfb00
489 /// All global semaphores' pointer
492 volatile UINT32
*Counter
;
493 volatile BOOLEAN
*InsideSmm
;
494 volatile BOOLEAN
*AllCpusInSync
;
496 SPIN_LOCK
*CodeAccessCheckLock
;
497 } SMM_CPU_SEMAPHORE_GLOBAL
;
500 /// All semaphores for each processor
504 volatile UINT32
*Run
;
505 volatile BOOLEAN
*Present
;
507 } SMM_CPU_SEMAPHORE_CPU
;
510 /// All semaphores' information
513 SMM_CPU_SEMAPHORE_GLOBAL SemaphoreGlobal
;
514 SMM_CPU_SEMAPHORE_CPU SemaphoreCpu
;
515 } SMM_CPU_SEMAPHORES
;
517 extern IA32_DESCRIPTOR gcSmiGdtr
;
518 extern EFI_PHYSICAL_ADDRESS mGdtBuffer
;
519 extern UINTN mGdtBufferSize
;
520 extern IA32_DESCRIPTOR gcSmiIdtr
;
521 extern VOID
*gcSmiIdtrPtr
;
522 extern UINT64 gPhyMask
;
523 extern SMM_DISPATCHER_MP_SYNC_DATA
*mSmmMpSyncData
;
524 extern UINTN mSmmStackArrayBase
;
525 extern UINTN mSmmStackArrayEnd
;
526 extern UINTN mSmmStackSize
;
527 extern EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService
;
528 extern IA32_DESCRIPTOR gcSmiInitGdtr
;
529 extern SMM_CPU_SEMAPHORES mSmmCpuSemaphores
;
530 extern UINTN mSemaphoreSize
;
531 extern SPIN_LOCK
*mPFLock
;
532 extern SPIN_LOCK
*mConfigSmmCodeAccessCheckLock
;
533 extern EFI_SMRAM_DESCRIPTOR
*mSmmCpuSmramRanges
;
534 extern UINTN mSmmCpuSmramRangeCount
;
535 extern UINT8 mPhysicalAddressBits
;
538 // Copy of the PcdPteMemoryEncryptionAddressOrMask
540 extern UINT64 mAddressEncMask
;
543 Create 4G PageTable in SMRAM.
545 @param[in] Is32BitPageTable Whether the page table is 32-bit PAE
546 @return PageTable Address
551 IN BOOLEAN Is32BitPageTable
555 Initialize global data for MP synchronization.
557 @param Stacks Base address of SMI stack buffer for all processors.
558 @param StackSize Stack size for each processor in SMM.
559 @param ShadowStackSize Shadow Stack size for each processor in SMM.
563 InitializeMpServiceData (
566 IN UINTN ShadowStackSize
570 Initialize Timer for SMM AP Sync.
579 Start Timer for SMM AP Sync.
589 Check if the SMM AP Sync timer is timeout.
591 @param Timer The start timer from the begin.
601 Initialize IDT for SMM Stack Guard.
606 InitializeIDTSmmStackGuard (
611 Initialize IDT IST Field.
613 @param[in] ExceptionType Exception type.
614 @param[in] Ist IST value.
620 IN EFI_EXCEPTION_TYPE ExceptionType
,
625 Initialize Gdt for all processors.
627 @param[in] Cr3 CR3 value.
628 @param[out] GdtStepSize The step size for GDT table.
630 @return GdtBase for processor 0.
631 GdtBase for processor X is: GdtBase + (GdtStepSize * X)
636 OUT UINTN
*GdtStepSize
641 Register the SMM Foundation entry point.
643 @param This Pointer to EFI_SMM_CONFIGURATION_PROTOCOL instance
644 @param SmmEntryPoint SMM Foundation EntryPoint
646 @retval EFI_SUCCESS Successfully to register SMM foundation entry point
652 IN CONST EFI_SMM_CONFIGURATION_PROTOCOL
*This
,
653 IN EFI_SMM_ENTRY_POINT SmmEntryPoint
657 Create PageTable for SMM use.
659 @return PageTable Address
668 Schedule a procedure to run on the specified CPU.
670 @param Procedure The address of the procedure to run
671 @param CpuIndex Target CPU number
672 @param ProcArguments The parameter to pass to the procedure
674 @retval EFI_INVALID_PARAMETER CpuNumber not valid
675 @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
676 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
677 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
678 @retval EFI_SUCCESS - The procedure has been successfully scheduled
684 IN EFI_AP_PROCEDURE Procedure
,
686 IN OUT VOID
*ProcArguments OPTIONAL
690 Schedule a procedure to run on the specified CPU in a blocking fashion.
692 @param Procedure The address of the procedure to run
693 @param CpuIndex Target CPU Index
694 @param ProcArguments The parameter to pass to the procedure
696 @retval EFI_INVALID_PARAMETER CpuNumber not valid
697 @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
698 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
699 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
700 @retval EFI_SUCCESS The procedure has been successfully scheduled
705 SmmBlockingStartupThisAp (
706 IN EFI_AP_PROCEDURE Procedure
,
708 IN OUT VOID
*ProcArguments OPTIONAL
712 This function sets the attributes for the memory region specified by BaseAddress and
713 Length from their current attributes to the attributes specified by Attributes.
715 @param[in] BaseAddress The physical address that is the start address of a memory region.
716 @param[in] Length The size in bytes of the memory region.
717 @param[in] Attributes The bit mask of attributes to set for the memory region.
719 @retval EFI_SUCCESS The attributes were set for the memory region.
720 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
721 BaseAddress and Length cannot be modified.
722 @retval EFI_INVALID_PARAMETER Length is zero.
723 Attributes specified an illegal combination of attributes that
724 cannot be set together.
725 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
726 the memory resource range.
727 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
728 resource range specified by BaseAddress and Length.
729 The bit mask of attributes is not support for the memory resource
730 range specified by BaseAddress and Length.
734 SmmSetMemoryAttributes (
735 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
741 This function clears the attributes for the memory region specified by BaseAddress and
742 Length from their current attributes to the attributes specified by Attributes.
744 @param[in] BaseAddress The physical address that is the start address of a memory region.
745 @param[in] Length The size in bytes of the memory region.
746 @param[in] Attributes The bit mask of attributes to clear for the memory region.
748 @retval EFI_SUCCESS The attributes were cleared for the memory region.
749 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
750 BaseAddress and Length cannot be modified.
751 @retval EFI_INVALID_PARAMETER Length is zero.
752 Attributes specified an illegal combination of attributes that
753 cannot be set together.
754 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
755 the memory resource range.
756 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
757 resource range specified by BaseAddress and Length.
758 The bit mask of attributes is not support for the memory resource
759 range specified by BaseAddress and Length.
763 SmmClearMemoryAttributes (
764 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
770 Initialize MP synchronization data.
775 InitializeMpSyncData (
781 Find out SMRAM information including SMRR base and SMRR size.
783 @param SmrrBase SMRR base
784 @param SmrrSize SMRR size
789 OUT UINT32
*SmrrBase
,
794 Relocate SmmBases for each processor.
796 Execute on first boot and all S3 resumes
806 Page Fault handler for SMM use.
808 @param InterruptType Defines the type of interrupt or exception that
809 occurred on the processor.This parameter is processor architecture specific.
810 @param SystemContext A pointer to the processor context when
811 the interrupt occurred on the processor.
816 IN EFI_EXCEPTION_TYPE InterruptType
,
817 IN EFI_SYSTEM_CONTEXT SystemContext
821 Perform the remaining tasks.
825 PerformRemainingTasks (
830 Perform the pre tasks.
839 Initialize MSR spin lock by MSR index.
841 @param MsrIndex MSR index value.
845 InitMsrSpinLockByIndex (
850 Hook return address of SMM Save State so that semaphore code
851 can be executed immediately after AP exits SMM to indicate to
852 the BSP that an AP has exited SMM after SMBASE relocation.
854 @param[in] CpuIndex The processor index.
855 @param[in] RebasedFlag A pointer to a flag that is set to TRUE
856 immediately after AP exits SMM.
862 IN
volatile BOOLEAN
*RebasedFlag
866 Configure SMM Code Access Check feature for all processors.
867 SMM Feature Control MSR will be locked after configuration.
870 ConfigSmmCodeAccessCheck (
875 Hook the code executed immediately after an RSM instruction on the currently
876 executing CPU. The mode of code executed immediately after RSM must be
877 detected, and the appropriate hook must be selected. Always clear the auto
878 HALT restart flag if it is set.
880 @param[in] CpuIndex The processor index for the currently
882 @param[in] CpuState Pointer to SMRAM Save State Map for the
883 currently executing CPU.
884 @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to
885 32-bit mode from 64-bit SMM.
886 @param[in] NewInstructionPointer Instruction pointer to use if resuming to
889 @retval The value of the original instruction pointer before it was hooked.
896 SMRAM_SAVE_STATE_MAP
*CpuState
,
897 UINT64 NewInstructionPointer32
,
898 UINT64 NewInstructionPointer
902 Get the size of the SMI Handler in bytes.
904 @retval The size, in bytes, of the SMI Handler.
914 Install the SMI handler for the CPU specified by CpuIndex. This function
915 is called by the CPU that was elected as monarch during System Management
918 @param[in] CpuIndex The index of the CPU to install the custom SMI handler.
919 The value must be between 0 and the NumberOfCpus field
920 in the System Management System Table (SMST).
921 @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex.
922 @param[in] SmiStack The stack to use when an SMI is processed by the
923 the CPU specified by CpuIndex.
924 @param[in] StackSize The size, in bytes, if the stack used when an SMI is
925 processed by the CPU specified by CpuIndex.
926 @param[in] GdtBase The base address of the GDT to use when an SMI is
927 processed by the CPU specified by CpuIndex.
928 @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is
929 processed by the CPU specified by CpuIndex.
930 @param[in] IdtBase The base address of the IDT to use when an SMI is
931 processed by the CPU specified by CpuIndex.
932 @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is
933 processed by the CPU specified by CpuIndex.
934 @param[in] Cr3 The base address of the page tables to use when an SMI
935 is processed by the CPU specified by CpuIndex.
952 Search module name by input IP address and output it.
954 @param CallerIpAddress Caller instruction pointer.
959 IN UINTN CallerIpAddress
963 This function sets memory attribute according to MemoryAttributesTable.
966 SetMemMapAttributes (
971 This function sets UEFI memory attribute according to UEFI memory map.
974 SetUefiMemMapAttributes (
979 Return if the Address is forbidden as SMM communication buffer.
981 @param[in] Address the address to be checked
983 @return TRUE The address is forbidden as SMM communication buffer.
984 @return FALSE The address is allowed as SMM communication buffer.
987 IsSmmCommBufferForbiddenAddress (
992 This function caches the UEFI memory map information.
1000 This function sets memory attribute for page table.
1003 SetPageTableAttributes (
1008 This function sets the attributes for the memory region specified by BaseAddress and
1009 Length from their current attributes to the attributes specified by Attributes.
1011 @param[in] PageTableBase The page table base.
1012 @param[in] EnablePML5Paging If PML5 paging is enabled.
1013 @param[in] BaseAddress The physical address that is the start address of a memory region.
1014 @param[in] Length The size in bytes of the memory region.
1015 @param[in] Attributes The bit mask of attributes to set for the memory region.
1016 @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted.
1018 @retval EFI_SUCCESS The attributes were set for the memory region.
1019 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
1020 BaseAddress and Length cannot be modified.
1021 @retval EFI_INVALID_PARAMETER Length is zero.
1022 Attributes specified an illegal combination of attributes that
1023 cannot be set together.
1024 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
1025 the memory resource range.
1026 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
1027 resource range specified by BaseAddress and Length.
1028 The bit mask of attributes is not support for the memory resource
1029 range specified by BaseAddress and Length.
1033 SmmSetMemoryAttributesEx (
1034 IN UINTN PageTableBase
,
1035 IN BOOLEAN EnablePML5Paging
,
1036 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
1038 IN UINT64 Attributes
,
1039 OUT BOOLEAN
*IsSplitted OPTIONAL
1043 This function clears the attributes for the memory region specified by BaseAddress and
1044 Length from their current attributes to the attributes specified by Attributes.
1046 @param[in] PageTableBase The page table base.
1047 @param[in] EnablePML5Paging If PML5 paging is enabled.
1048 @param[in] BaseAddress The physical address that is the start address of a memory region.
1049 @param[in] Length The size in bytes of the memory region.
1050 @param[in] Attributes The bit mask of attributes to clear for the memory region.
1051 @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted.
1053 @retval EFI_SUCCESS The attributes were cleared for the memory region.
1054 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
1055 BaseAddress and Length cannot be modified.
1056 @retval EFI_INVALID_PARAMETER Length is zero.
1057 Attributes specified an illegal combination of attributes that
1058 cannot be set together.
1059 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
1060 the memory resource range.
1061 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
1062 resource range specified by BaseAddress and Length.
1063 The bit mask of attributes is not support for the memory resource
1064 range specified by BaseAddress and Length.
1068 SmmClearMemoryAttributesEx (
1069 IN UINTN PageTableBase
,
1070 IN BOOLEAN EnablePML5Paging
,
1071 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
1073 IN UINT64 Attributes
,
1074 OUT BOOLEAN
*IsSplitted OPTIONAL
1078 This API provides a way to allocate memory for page table.
1080 This API can be called more once to allocate memory for page tables.
1082 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
1083 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
1084 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
1087 @param Pages The number of 4 KB pages to allocate.
1089 @return A pointer to the allocated buffer or NULL if allocation fails.
1093 AllocatePageTableMemory (
1098 Allocate pages for code.
1100 @param[in] Pages Number of pages to be allocated.
1102 @return Allocated memory.
1110 Allocate aligned pages for code.
1112 @param[in] Pages Number of pages to be allocated.
1113 @param[in] Alignment The requested alignment of the allocation.
1114 Must be a power of two.
1115 If Alignment is zero, then byte alignment is used.
1117 @return Allocated memory.
1120 AllocateAlignedCodePages (
1126 // S3 related global variable and function prototype.
1129 extern BOOLEAN mSmmS3Flag
;
1132 Initialize SMM S3 resume state structure used during S3 Resume.
1134 @param[in] Cr3 The base address of the page tables to use in SMM.
1138 InitSmmS3ResumeState (
1152 Restore SMM Configuration in S3 boot path.
1156 RestoreSmmConfigurationInS3 (
1161 Get ACPI S3 enable flag.
1165 GetAcpiS3EnableFlag (
1170 Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.
1172 @param[in] ApHltLoopCode The address of the safe hlt-loop function.
1173 @param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode.
1174 @param[in] NumberToFinishAddress Address of Semaphore of APs finish count.
1178 TransferApToSafeState (
1179 IN UINTN ApHltLoopCode
,
1180 IN UINTN TopOfStack
,
1181 IN UINTN NumberToFinishAddress
1185 Set ShadowStack memory.
1187 @param[in] Cr3 The page table base address.
1188 @param[in] BaseAddress The physical address that is the start address of a memory region.
1189 @param[in] Length The size in bytes of the memory region.
1191 @retval EFI_SUCCESS The shadow stack memory is set.
1196 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
1201 Set not present memory.
1203 @param[in] Cr3 The page table base address.
1204 @param[in] BaseAddress The physical address that is the start address of a memory region.
1205 @param[in] Length The size in bytes of the memory region.
1207 @retval EFI_SUCCESS The not present memory is set.
1212 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
1217 Initialize the shadow stack related data structure.
1219 @param CpuIndex The index of CPU.
1220 @param ShadowStack The bottom of the shadow stack for this CPU.
1225 IN VOID
*ShadowStack
1229 This function set given attributes of the memory region specified by
1230 BaseAddress and Length.
1232 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1233 @param BaseAddress The physical address that is the start address of
1235 @param Length The size in bytes of the memory region.
1236 @param Attributes The bit mask of attributes to set for the memory
1239 @retval EFI_SUCCESS The attributes were set for the memory region.
1240 @retval EFI_INVALID_PARAMETER Length is zero.
1241 Attributes specified an illegal combination of
1242 attributes that cannot be set together.
1243 @retval EFI_UNSUPPORTED The processor does not support one or more
1244 bytes of the memory resource range specified
1245 by BaseAddress and Length.
1246 The bit mask of attributes is not supported for
1247 the memory resource range specified by
1248 BaseAddress and Length.
1253 EdkiiSmmSetMemoryAttributes (
1254 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL
*This
,
1255 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
1257 IN UINT64 Attributes
1261 This function clears given attributes of the memory region specified by
1262 BaseAddress and Length.
1264 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1265 @param BaseAddress The physical address that is the start address of
1267 @param Length The size in bytes of the memory region.
1268 @param Attributes The bit mask of attributes to clear for the memory
1271 @retval EFI_SUCCESS The attributes were cleared for the memory region.
1272 @retval EFI_INVALID_PARAMETER Length is zero.
1273 Attributes specified an illegal combination of
1274 attributes that cannot be cleared together.
1275 @retval EFI_UNSUPPORTED The processor does not support one or more
1276 bytes of the memory resource range specified
1277 by BaseAddress and Length.
1278 The bit mask of attributes is not supported for
1279 the memory resource range specified by
1280 BaseAddress and Length.
1285 EdkiiSmmClearMemoryAttributes (
1286 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL
*This
,
1287 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
1289 IN UINT64 Attributes
1293 This function retrieves the attributes of the memory region specified by
1294 BaseAddress and Length. If different attributes are got from different part
1295 of the memory region, EFI_NO_MAPPING will be returned.
1297 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1298 @param BaseAddress The physical address that is the start address of
1300 @param Length The size in bytes of the memory region.
1301 @param Attributes Pointer to attributes returned.
1303 @retval EFI_SUCCESS The attributes got for the memory region.
1304 @retval EFI_INVALID_PARAMETER Length is zero.
1306 @retval EFI_NO_MAPPING Attributes are not consistent cross the memory
1308 @retval EFI_UNSUPPORTED The processor does not support one or more
1309 bytes of the memory resource range specified
1310 by BaseAddress and Length.
1315 EdkiiSmmGetMemoryAttributes (
1316 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL
*This
,
1317 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
1319 IN UINT64
*Attributes
1323 This function fixes up the address of the global variable or function
1324 referred in SmmInit assembly files to be the absolute address.
1328 PiSmmCpuSmmInitFixupAddress (
1332 This function fixes up the address of the global variable or function
1333 referred in SmiEntry assembly files to be the absolute address.
1337 PiSmmCpuSmiEntryFixupAddress (
1341 This function reads CR2 register when on-demand paging is enabled
1342 for 64 bit and no action for 32 bit.
1344 @param[out] *Cr2 Pointer to variable to hold CR2 register value.
1352 This function writes into CR2 register when on-demand paging is enabled
1353 for 64 bit and no action for 32 bit.
1355 @param[in] Cr2 Value to write into CR2 register.
1363 Schedule a procedure to run on the specified CPU.
1365 @param[in] Procedure The address of the procedure to run
1366 @param[in] CpuIndex Target CPU Index
1367 @param[in,out] ProcArguments The parameter to pass to the procedure
1368 @param[in,out] Token This is an optional parameter that allows the caller to execute the
1369 procedure in a blocking or non-blocking fashion. If it is NULL the
1370 call is blocking, and the call will not return until the AP has
1371 completed the procedure. If the token is not NULL, the call will
1372 return immediately. The caller can check whether the procedure has
1373 completed with CheckOnProcedure or WaitForProcedure.
1374 @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for the APs to finish
1375 execution of Procedure, either for blocking or non-blocking mode.
1376 Zero means infinity. If the timeout expires before all APs return
1377 from Procedure, then Procedure on the failed APs is terminated. If
1378 the timeout expires in blocking mode, the call returns EFI_TIMEOUT.
1379 If the timeout expires in non-blocking mode, the timeout determined
1380 can be through CheckOnProcedure or WaitForProcedure.
1381 Note that timeout support is optional. Whether an implementation
1382 supports this feature can be determined via the Attributes data
1384 @param[in,out] CpuStatus This optional pointer may be used to get the status code returned
1385 by Procedure when it completes execution on the target AP, or with
1386 EFI_TIMEOUT if the Procedure fails to complete within the optional
1387 timeout. The implementation will update this variable with
1388 EFI_NOT_READY prior to starting Procedure on the target AP.
1390 @retval EFI_INVALID_PARAMETER CpuNumber not valid
1391 @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
1392 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
1393 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
1394 @retval EFI_SUCCESS The procedure has been successfully scheduled
1398 InternalSmmStartupThisAp (
1399 IN EFI_AP_PROCEDURE2 Procedure
,
1401 IN OUT VOID
*ProcArguments OPTIONAL
,
1402 IN OUT MM_COMPLETION
*Token
,
1403 IN UINTN TimeoutInMicroseconds
,
1404 IN OUT EFI_STATUS
*CpuStatus
1408 Checks whether the input token is the current used token.
1410 @param[in] Token This parameter describes the token that was passed into DispatchProcedure or
1413 @retval TRUE The input token is the current used token.
1414 @retval FALSE The input token is not the current used token.
1422 Checks status of specified AP.
1424 This function checks whether the specified AP has finished the task assigned
1425 by StartupThisAP(), and whether timeout expires.
1427 @param[in] Token This parameter describes the token that was passed into DispatchProcedure or
1430 @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs().
1431 @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired.
1439 Check whether it is an present AP.
1441 @param CpuIndex The AP index which calls this function.
1443 @retval TRUE It's a present AP.
1444 @retval TRUE This is not an AP or it is not present.
1453 Worker function to execute a caller provided function on all enabled APs.
1455 @param[in] Procedure A pointer to the function to be run on
1456 enabled APs of the system.
1457 @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
1458 APs to return from Procedure, either for
1459 blocking or non-blocking mode.
1460 @param[in,out] ProcedureArguments The parameter passed into Procedure for
1462 @param[in,out] Token This is an optional parameter that allows the caller to execute the
1463 procedure in a blocking or non-blocking fashion. If it is NULL the
1464 call is blocking, and the call will not return until the AP has
1465 completed the procedure. If the token is not NULL, the call will
1466 return immediately. The caller can check whether the procedure has
1467 completed with CheckOnProcedure or WaitForProcedure.
1468 @param[in,out] CPUStatus This optional pointer may be used to get the status code returned
1469 by Procedure when it completes execution on the target AP, or with
1470 EFI_TIMEOUT if the Procedure fails to complete within the optional
1471 timeout. The implementation will update this variable with
1472 EFI_NOT_READY prior to starting Procedure on the target AP.
1474 @retval EFI_SUCCESS In blocking mode, all APs have finished before
1475 the timeout expired.
1476 @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
1478 @retval others Failed to Startup all APs.
1482 InternalSmmStartupAllAPs (
1483 IN EFI_AP_PROCEDURE2 Procedure
,
1484 IN UINTN TimeoutInMicroseconds
,
1485 IN OUT VOID
*ProcedureArguments OPTIONAL
,
1486 IN OUT MM_COMPLETION
*Token
,
1487 IN OUT EFI_STATUS
*CPUStatus
1492 Register the SMM Foundation entry point.
1494 @param[in] Procedure A pointer to the code stream to be run on the designated target AP
1495 of the system. Type EFI_AP_PROCEDURE is defined below in Volume 2
1496 with the related definitions of
1497 EFI_MP_SERVICES_PROTOCOL.StartupAllAPs.
1498 If caller may pass a value of NULL to deregister any existing
1500 @param[in,out] ProcedureArguments Allows the caller to pass a list of parameters to the code that is
1501 run by the AP. It is an optional common mailbox between APs and
1502 the caller to share information
1504 @retval EFI_SUCCESS The Procedure has been set successfully.
1505 @retval EFI_INVALID_PARAMETER The Procedure is NULL but ProcedureArguments not NULL.
1509 RegisterStartupProcedure (
1510 IN EFI_AP_PROCEDURE Procedure
,
1511 IN OUT VOID
*ProcedureArguments OPTIONAL
1515 Initialize PackageBsp Info. Processor specified by mPackageFirstThreadIndex[PackageIndex]
1516 will do the package-scope register programming. Set default CpuIndex to (UINT32)-1, which
1517 means not specified yet.
1521 InitPackageFirstThreadIndexInfo (
1526 Allocate buffer for SpinLock and Wrapper function buffer.
1530 InitializeDataForMmMp (
1535 Return whether access to non-SMRAM is restricted.
1537 @retval TRUE Access to non-SMRAM is restricted.
1538 @retval FALSE Access to non-SMRAM is not restricted.
1541 IsRestrictedMemoryAccess (
1546 Choose blocking or non-blocking mode to Wait for all APs.
1548 @param[in] This A pointer to the EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL instance.
1549 @param[in] BlockingMode Blocking or non-blocking mode.
1551 @retval EFI_SUCCESS All APs have arrived SMM mode except SMI disabled APs.
1552 @retval EFI_TIMEOUT There are APs not in SMM mode in given timeout constraint.
1558 IN EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL
*This
,
1559 IN BOOLEAN BlockingMode
1563 Insure when this function returns, no AP will execute normal mode code before entering SMM, except SMI disabled APs.
1567 SmmWaitForApArrival (