]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / PiSmmCpuDxeSmm.h
1 /** @file
2 Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
3
4 Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #ifndef _CPU_PISMMCPUDXESMM_H_
12 #define _CPU_PISMMCPUDXESMM_H_
13
14 #include <PiSmm.h>
15
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>
24
25 #include <Guid/AcpiS3Context.h>
26 #include <Guid/MemoryAttributesTable.h>
27 #include <Guid/PiSmmMemoryAttributesTable.h>
28 #include <Guid/SmmBaseHob.h>
29
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>
54
55 #include <AcpiCpuData.h>
56 #include <CpuHotPlugData.h>
57
58 #include <Register/Intel/Cpuid.h>
59 #include <Register/Intel/Msr.h>
60
61 #include "CpuService.h"
62 #include "SmmProfile.h"
63
64 //
65 // CET definition
66 //
67 #define CPUID_CET_SS BIT7
68 #define CPUID_CET_IBT BIT20
69
70 #define CR4_CET_ENABLE BIT23
71
72 #define MSR_IA32_S_CET 0x6A2
73 #define MSR_IA32_PL0_SSP 0x6A4
74 #define MSR_IA32_INTERRUPT_SSP_TABLE_ADDR 0x6A8
75
76 typedef union {
77 struct {
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.
83 UINT32 ENDBR_EN : 1;
84 // enable legacy compatibility treatment for indirect call/jmp tracking.
85 UINT32 LEG_IW_EN : 1;
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;
90 UINT32 RSVD : 4;
91 // indirect branch tracking is suppressed.
92 // This bit can be written to 1 only if TRACKER is written as IDLE.
93 UINT32 SUPPRESS : 1;
94 // Value of the endbranch state machine
95 // Values: IDLE (0), WAIT_FOR_ENDBRANCH(1).
96 UINT32 TRACKER : 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;
105 } Bits;
106 UINT64 Uint64;
107 } MSR_IA32_CET;
108
109 //
110 // MSRs required for configuration of SMM Code Access Check
111 //
112 #define EFI_MSR_SMM_MCA_CAP 0x17D
113 #define SMM_CODE_ACCESS_CHK_BIT BIT58
114
115 #define SMM_FEATURE_CONTROL_LOCK_BIT BIT0
116 #define SMM_CODE_CHK_EN_BIT BIT2
117
118 ///
119 /// Page Table Entry
120 ///
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
133
134 #define PAGE_ATTRIBUTE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_U | IA32_PG_RW | IA32_PG_P)
135 //
136 // Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE
137 // X64 PAE PDPTE does not have such restriction
138 //
139 #define IA32_PAE_PDPTE_ATTRIBUTE_BITS (IA32_PG_P)
140
141 #define PAGE_PROGATE_BITS (IA32_PG_NX | PAGE_ATTRIBUTE_BITS)
142
143 #define PAGING_4K_MASK 0xFFF
144 #define PAGING_2M_MASK 0x1FFFFF
145 #define PAGING_1G_MASK 0x3FFFFFFF
146
147 #define PAGING_PAE_INDEX_MASK 0x1FF
148
149 #define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull
150 #define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull
151 #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
152
153 #define SMRR_MAX_ADDRESS BASE_4GB
154
155 typedef enum {
156 PageNone,
157 Page4K,
158 Page2M,
159 Page1G,
160 } PAGE_ATTRIBUTE;
161
162 typedef struct {
163 PAGE_ATTRIBUTE Attribute;
164 UINT64 Length;
165 UINT64 AddressMask;
166 } PAGE_ATTRIBUTE_TABLE;
167
168 //
169 // Size of Task-State Segment defined in IA32 Manual
170 //
171 #define TSS_SIZE 104
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
177
178 #define CR0_WP BIT16
179
180 //
181 // Code select value
182 //
183 #define PROTECT_MODE_CODE_SEGMENT 0x08
184 #define LONG_MODE_CODE_SEGMENT 0x38
185
186 //
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
190 // at least.
191 //
192 #define BACK_BUF_SIZE 0x20
193
194 #define EXCEPTION_VECTOR_NUMBER 0x20
195
196 #define INVALID_APIC_ID 0xFFFFFFFFFFFFFFFFULL
197
198 //
199 // Wrapper used to convert EFI_AP_PROCEDURE2 and EFI_AP_PROCEDURE.
200 //
201 typedef struct {
202 EFI_AP_PROCEDURE Procedure;
203 VOID *ProcedureArgument;
204 } PROCEDURE_WRAPPER;
205
206 #define PROCEDURE_TOKEN_SIGNATURE SIGNATURE_32 ('P', 'R', 'T', 'S')
207
208 typedef struct {
209 UINTN Signature;
210 LIST_ENTRY Link;
211
212 SPIN_LOCK *SpinLock;
213 volatile UINT32 RunningApCount;
214 } PROCEDURE_TOKEN;
215
216 #define PROCEDURE_TOKEN_FROM_LINK(a) CR (a, PROCEDURE_TOKEN, Link, PROCEDURE_TOKEN_SIGNATURE)
217
218 #define TOKEN_BUFFER_SIGNATURE SIGNATURE_32 ('T', 'K', 'B', 'S')
219
220 typedef struct {
221 UINTN Signature;
222 LIST_ENTRY Link;
223
224 UINT8 *Buffer;
225 } TOKEN_BUFFER;
226
227 #define TOKEN_BUFFER_FROM_LINK(a) CR (a, TOKEN_BUFFER, Link, TOKEN_BUFFER_SIGNATURE)
228
229 //
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.
233 //
234 #define SMM_CPU_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('s', 'c', 'p', 'u')
235
236 typedef struct {
237 UINTN Signature;
238
239 EFI_HANDLE SmmCpuHandle;
240
241 EFI_PROCESSOR_INFORMATION *ProcessorInfo;
242 SMM_CPU_OPERATION *Operation;
243 UINTN *CpuSaveStateSize;
244 VOID **CpuSaveState;
245
246 EFI_SMM_RESERVED_SMRAM_REGION SmmReservedSmramRegion[1];
247 EFI_SMM_ENTRY_CONTEXT SmmCoreEntryContext;
248 EFI_SMM_ENTRY_POINT SmmCoreEntry;
249
250 EFI_SMM_CONFIGURATION_PROTOCOL SmmConfiguration;
251
252 PROCEDURE_WRAPPER *ApWrapperFunc;
253 LIST_ENTRY TokenList;
254 LIST_ENTRY *FirstFreeToken;
255 } SMM_CPU_PRIVATE_DATA;
256
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;
264
265 ///
266 /// The mode of the CPU at the time an SMI occurs
267 ///
268 extern UINT8 mSmmSaveStateRegisterLma;
269
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))
275
276 typedef struct {
277 VOID *NextPool;
278 UINTN Offset;
279 UINTN FreePages;
280 } PAGE_TABLE_POOL;
281
282 /**
283 Disable CET.
284 **/
285 VOID
286 EFIAPI
287 DisableCet (
288 VOID
289 );
290
291 /**
292 Enable CET.
293 **/
294 VOID
295 EFIAPI
296 EnableCet (
297 VOID
298 );
299
300 //
301 // SMM CPU Protocol function prototypes.
302 //
303
304 /**
305 Read information from the CPU save state.
306
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.
312
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.
316
317 **/
318 EFI_STATUS
319 EFIAPI
320 SmmReadSaveState (
321 IN CONST EFI_SMM_CPU_PROTOCOL *This,
322 IN UINTN Width,
323 IN EFI_SMM_SAVE_STATE_REGISTER Register,
324 IN UINTN CpuIndex,
325 OUT VOID *Buffer
326 );
327
328 /**
329 Write data to the CPU save state.
330
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.
336
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
340
341 **/
342 EFI_STATUS
343 EFIAPI
344 SmmWriteSaveState (
345 IN CONST EFI_SMM_CPU_PROTOCOL *This,
346 IN UINTN Width,
347 IN EFI_SMM_SAVE_STATE_REGISTER Register,
348 IN UINTN CpuIndex,
349 IN CONST VOID *Buffer
350 );
351
352 /**
353 C function for SMI handler. To change all processor's SMMBase Register.
354
355 **/
356 VOID
357 EFIAPI
358 SmmInitHandler (
359 VOID
360 );
361
362 /**
363 Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init.
364
365 **/
366 VOID
367 ExecuteFirstSmiInit (
368 VOID
369 );
370
371 /**
372 Read a CPU Save State register on the target processor.
373
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.
376
377 This function supports reading a CPU Save State register in SMBase relocation handler.
378
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.
383
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.
387
388 **/
389 EFI_STATUS
390 EFIAPI
391 ReadSaveStateRegister (
392 IN UINTN CpuIndex,
393 IN EFI_SMM_SAVE_STATE_REGISTER Register,
394 IN UINTN Width,
395 OUT VOID *Buffer
396 );
397
398 /**
399 Write value to a CPU Save State register on the target processor.
400
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.
403
404 This function supports writing a CPU Save State register in SMBase relocation handler.
405
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.
410
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.
414
415 **/
416 EFI_STATUS
417 EFIAPI
418 WriteSaveStateRegister (
419 IN UINTN CpuIndex,
420 IN EFI_SMM_SAVE_STATE_REGISTER Register,
421 IN UINTN Width,
422 IN CONST VOID *Buffer
423 );
424
425 extern BOOLEAN mSmmRelocated;
426 extern volatile BOOLEAN *mSmmInitialized;
427 extern UINT32 mBspApicId;
428
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;
439
440 /**
441 Semaphore operation for all processor relocate SMMBase.
442 **/
443 VOID
444 EFIAPI
445 SmmRelocationSemaphoreComplete (
446 VOID
447 );
448
449 ///
450 /// The type of SMM CPU Information
451 ///
452 typedef struct {
453 SPIN_LOCK *Busy;
454 volatile EFI_AP_PROCEDURE2 Procedure;
455 volatile VOID *Parameter;
456 volatile UINT32 *Run;
457 volatile BOOLEAN *Present;
458 PROCEDURE_TOKEN *Token;
459 EFI_STATUS *Status;
460 } SMM_CPU_DATA_BLOCK;
461
462 typedef enum {
463 SmmCpuSyncModeTradition,
464 SmmCpuSyncModeRelaxedAp,
465 SmmCpuSyncModeMax
466 } SMM_CPU_SYNC_MODE;
467
468 typedef struct {
469 //
470 // Pointer to an array. The array should be located immediately after this structure
471 // so that UC cache-ability can be set together.
472 //
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;
485
486 #define SMM_PSD_OFFSET 0xfb00
487
488 ///
489 /// All global semaphores' pointer
490 ///
491 typedef struct {
492 volatile UINT32 *Counter;
493 volatile BOOLEAN *InsideSmm;
494 volatile BOOLEAN *AllCpusInSync;
495 SPIN_LOCK *PFLock;
496 SPIN_LOCK *CodeAccessCheckLock;
497 } SMM_CPU_SEMAPHORE_GLOBAL;
498
499 ///
500 /// All semaphores for each processor
501 ///
502 typedef struct {
503 SPIN_LOCK *Busy;
504 volatile UINT32 *Run;
505 volatile BOOLEAN *Present;
506 SPIN_LOCK *Token;
507 } SMM_CPU_SEMAPHORE_CPU;
508
509 ///
510 /// All semaphores' information
511 ///
512 typedef struct {
513 SMM_CPU_SEMAPHORE_GLOBAL SemaphoreGlobal;
514 SMM_CPU_SEMAPHORE_CPU SemaphoreCpu;
515 } SMM_CPU_SEMAPHORES;
516
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;
536
537 //
538 // Copy of the PcdPteMemoryEncryptionAddressOrMask
539 //
540 extern UINT64 mAddressEncMask;
541
542 /**
543 Create 4G PageTable in SMRAM.
544
545 @param[in] Is32BitPageTable Whether the page table is 32-bit PAE
546 @return PageTable Address
547
548 **/
549 UINT32
550 Gen4GPageTable (
551 IN BOOLEAN Is32BitPageTable
552 );
553
554 /**
555 Initialize global data for MP synchronization.
556
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.
560
561 **/
562 UINT32
563 InitializeMpServiceData (
564 IN VOID *Stacks,
565 IN UINTN StackSize,
566 IN UINTN ShadowStackSize
567 );
568
569 /**
570 Initialize Timer for SMM AP Sync.
571
572 **/
573 VOID
574 InitializeSmmTimer (
575 VOID
576 );
577
578 /**
579 Start Timer for SMM AP Sync.
580
581 **/
582 UINT64
583 EFIAPI
584 StartSyncTimer (
585 VOID
586 );
587
588 /**
589 Check if the SMM AP Sync timer is timeout.
590
591 @param Timer The start timer from the begin.
592
593 **/
594 BOOLEAN
595 EFIAPI
596 IsSyncTimerTimeout (
597 IN UINT64 Timer
598 );
599
600 /**
601 Initialize IDT for SMM Stack Guard.
602
603 **/
604 VOID
605 EFIAPI
606 InitializeIDTSmmStackGuard (
607 VOID
608 );
609
610 /**
611 Initialize IDT IST Field.
612
613 @param[in] ExceptionType Exception type.
614 @param[in] Ist IST value.
615
616 **/
617 VOID
618 EFIAPI
619 InitializeIdtIst (
620 IN EFI_EXCEPTION_TYPE ExceptionType,
621 IN UINT8 Ist
622 );
623
624 /**
625 Initialize Gdt for all processors.
626
627 @param[in] Cr3 CR3 value.
628 @param[out] GdtStepSize The step size for GDT table.
629
630 @return GdtBase for processor 0.
631 GdtBase for processor X is: GdtBase + (GdtStepSize * X)
632 **/
633 VOID *
634 InitGdt (
635 IN UINTN Cr3,
636 OUT UINTN *GdtStepSize
637 );
638
639 /**
640
641 Register the SMM Foundation entry point.
642
643 @param This Pointer to EFI_SMM_CONFIGURATION_PROTOCOL instance
644 @param SmmEntryPoint SMM Foundation EntryPoint
645
646 @retval EFI_SUCCESS Successfully to register SMM foundation entry point
647
648 **/
649 EFI_STATUS
650 EFIAPI
651 RegisterSmmEntry (
652 IN CONST EFI_SMM_CONFIGURATION_PROTOCOL *This,
653 IN EFI_SMM_ENTRY_POINT SmmEntryPoint
654 );
655
656 /**
657 Create PageTable for SMM use.
658
659 @return PageTable Address
660
661 **/
662 UINT32
663 SmmInitPageTable (
664 VOID
665 );
666
667 /**
668 Schedule a procedure to run on the specified CPU.
669
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
673
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
679
680 **/
681 EFI_STATUS
682 EFIAPI
683 SmmStartupThisAp (
684 IN EFI_AP_PROCEDURE Procedure,
685 IN UINTN CpuIndex,
686 IN OUT VOID *ProcArguments OPTIONAL
687 );
688
689 /**
690 Schedule a procedure to run on the specified CPU in a blocking fashion.
691
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
695
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
701
702 **/
703 EFI_STATUS
704 EFIAPI
705 SmmBlockingStartupThisAp (
706 IN EFI_AP_PROCEDURE Procedure,
707 IN UINTN CpuIndex,
708 IN OUT VOID *ProcArguments OPTIONAL
709 );
710
711 /**
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.
714
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.
718
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.
731
732 **/
733 EFI_STATUS
734 SmmSetMemoryAttributes (
735 IN EFI_PHYSICAL_ADDRESS BaseAddress,
736 IN UINT64 Length,
737 IN UINT64 Attributes
738 );
739
740 /**
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.
743
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.
747
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.
760
761 **/
762 EFI_STATUS
763 SmmClearMemoryAttributes (
764 IN EFI_PHYSICAL_ADDRESS BaseAddress,
765 IN UINT64 Length,
766 IN UINT64 Attributes
767 );
768
769 /**
770 Initialize MP synchronization data.
771
772 **/
773 VOID
774 EFIAPI
775 InitializeMpSyncData (
776 VOID
777 );
778
779 /**
780
781 Find out SMRAM information including SMRR base and SMRR size.
782
783 @param SmrrBase SMRR base
784 @param SmrrSize SMRR size
785
786 **/
787 VOID
788 FindSmramInfo (
789 OUT UINT32 *SmrrBase,
790 OUT UINT32 *SmrrSize
791 );
792
793 /**
794 Relocate SmmBases for each processor.
795
796 Execute on first boot and all S3 resumes
797
798 **/
799 VOID
800 EFIAPI
801 SmmRelocateBases (
802 VOID
803 );
804
805 /**
806 Page Fault handler for SMM use.
807
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.
812 **/
813 VOID
814 EFIAPI
815 SmiPFHandler (
816 IN EFI_EXCEPTION_TYPE InterruptType,
817 IN EFI_SYSTEM_CONTEXT SystemContext
818 );
819
820 /**
821 Perform the remaining tasks.
822
823 **/
824 VOID
825 PerformRemainingTasks (
826 VOID
827 );
828
829 /**
830 Perform the pre tasks.
831
832 **/
833 VOID
834 PerformPreTasks (
835 VOID
836 );
837
838 /**
839 Initialize MSR spin lock by MSR index.
840
841 @param MsrIndex MSR index value.
842
843 **/
844 VOID
845 InitMsrSpinLockByIndex (
846 IN UINT32 MsrIndex
847 );
848
849 /**
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.
853
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.
857
858 **/
859 VOID
860 SemaphoreHook (
861 IN UINTN CpuIndex,
862 IN volatile BOOLEAN *RebasedFlag
863 );
864
865 /**
866 Configure SMM Code Access Check feature for all processors.
867 SMM Feature Control MSR will be locked after configuration.
868 **/
869 VOID
870 ConfigSmmCodeAccessCheck (
871 VOID
872 );
873
874 /**
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.
879
880 @param[in] CpuIndex The processor index for the currently
881 executing CPU.
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
887 same mode as SMM.
888
889 @retval The value of the original instruction pointer before it was hooked.
890
891 **/
892 UINT64
893 EFIAPI
894 HookReturnFromSmm (
895 IN UINTN CpuIndex,
896 SMRAM_SAVE_STATE_MAP *CpuState,
897 UINT64 NewInstructionPointer32,
898 UINT64 NewInstructionPointer
899 );
900
901 /**
902 Get the size of the SMI Handler in bytes.
903
904 @retval The size, in bytes, of the SMI Handler.
905
906 **/
907 UINTN
908 EFIAPI
909 GetSmiHandlerSize (
910 VOID
911 );
912
913 /**
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
916 Mode initialization.
917
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.
936 **/
937 VOID
938 EFIAPI
939 InstallSmiHandler (
940 IN UINTN CpuIndex,
941 IN UINT32 SmBase,
942 IN VOID *SmiStack,
943 IN UINTN StackSize,
944 IN UINTN GdtBase,
945 IN UINTN GdtSize,
946 IN UINTN IdtBase,
947 IN UINTN IdtSize,
948 IN UINT32 Cr3
949 );
950
951 /**
952 Search module name by input IP address and output it.
953
954 @param CallerIpAddress Caller instruction pointer.
955
956 **/
957 VOID
958 DumpModuleInfoByIp (
959 IN UINTN CallerIpAddress
960 );
961
962 /**
963 This function sets memory attribute according to MemoryAttributesTable.
964 **/
965 VOID
966 SetMemMapAttributes (
967 VOID
968 );
969
970 /**
971 This function sets UEFI memory attribute according to UEFI memory map.
972 **/
973 VOID
974 SetUefiMemMapAttributes (
975 VOID
976 );
977
978 /**
979 Return if the Address is forbidden as SMM communication buffer.
980
981 @param[in] Address the address to be checked
982
983 @return TRUE The address is forbidden as SMM communication buffer.
984 @return FALSE The address is allowed as SMM communication buffer.
985 **/
986 BOOLEAN
987 IsSmmCommBufferForbiddenAddress (
988 IN UINT64 Address
989 );
990
991 /**
992 This function caches the UEFI memory map information.
993 **/
994 VOID
995 GetUefiMemoryMap (
996 VOID
997 );
998
999 /**
1000 This function sets memory attribute for page table.
1001 **/
1002 VOID
1003 SetPageTableAttributes (
1004 VOID
1005 );
1006
1007 /**
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.
1010
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.
1017
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.
1030
1031 **/
1032 EFI_STATUS
1033 SmmSetMemoryAttributesEx (
1034 IN UINTN PageTableBase,
1035 IN BOOLEAN EnablePML5Paging,
1036 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1037 IN UINT64 Length,
1038 IN UINT64 Attributes,
1039 OUT BOOLEAN *IsSplitted OPTIONAL
1040 );
1041
1042 /**
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.
1045
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.
1052
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.
1065
1066 **/
1067 EFI_STATUS
1068 SmmClearMemoryAttributesEx (
1069 IN UINTN PageTableBase,
1070 IN BOOLEAN EnablePML5Paging,
1071 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1072 IN UINT64 Length,
1073 IN UINT64 Attributes,
1074 OUT BOOLEAN *IsSplitted OPTIONAL
1075 );
1076
1077 /**
1078 This API provides a way to allocate memory for page table.
1079
1080 This API can be called more once to allocate memory for page tables.
1081
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
1085 returned.
1086
1087 @param Pages The number of 4 KB pages to allocate.
1088
1089 @return A pointer to the allocated buffer or NULL if allocation fails.
1090
1091 **/
1092 VOID *
1093 AllocatePageTableMemory (
1094 IN UINTN Pages
1095 );
1096
1097 /**
1098 Allocate pages for code.
1099
1100 @param[in] Pages Number of pages to be allocated.
1101
1102 @return Allocated memory.
1103 **/
1104 VOID *
1105 AllocateCodePages (
1106 IN UINTN Pages
1107 );
1108
1109 /**
1110 Allocate aligned pages for code.
1111
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.
1116
1117 @return Allocated memory.
1118 **/
1119 VOID *
1120 AllocateAlignedCodePages (
1121 IN UINTN Pages,
1122 IN UINTN Alignment
1123 );
1124
1125 //
1126 // S3 related global variable and function prototype.
1127 //
1128
1129 extern BOOLEAN mSmmS3Flag;
1130
1131 /**
1132 Initialize SMM S3 resume state structure used during S3 Resume.
1133
1134 @param[in] Cr3 The base address of the page tables to use in SMM.
1135
1136 **/
1137 VOID
1138 InitSmmS3ResumeState (
1139 IN UINT32 Cr3
1140 );
1141
1142 /**
1143 Get ACPI CPU data.
1144
1145 **/
1146 VOID
1147 GetAcpiCpuData (
1148 VOID
1149 );
1150
1151 /**
1152 Restore SMM Configuration in S3 boot path.
1153
1154 **/
1155 VOID
1156 RestoreSmmConfigurationInS3 (
1157 VOID
1158 );
1159
1160 /**
1161 Get ACPI S3 enable flag.
1162
1163 **/
1164 VOID
1165 GetAcpiS3EnableFlag (
1166 VOID
1167 );
1168
1169 /**
1170 Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.
1171
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.
1175
1176 **/
1177 VOID
1178 TransferApToSafeState (
1179 IN UINTN ApHltLoopCode,
1180 IN UINTN TopOfStack,
1181 IN UINTN NumberToFinishAddress
1182 );
1183
1184 /**
1185 Set ShadowStack memory.
1186
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.
1190
1191 @retval EFI_SUCCESS The shadow stack memory is set.
1192 **/
1193 EFI_STATUS
1194 SetShadowStack (
1195 IN UINTN Cr3,
1196 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1197 IN UINT64 Length
1198 );
1199
1200 /**
1201 Set not present memory.
1202
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.
1206
1207 @retval EFI_SUCCESS The not present memory is set.
1208 **/
1209 EFI_STATUS
1210 SetNotPresentPage (
1211 IN UINTN Cr3,
1212 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1213 IN UINT64 Length
1214 );
1215
1216 /**
1217 Initialize the shadow stack related data structure.
1218
1219 @param CpuIndex The index of CPU.
1220 @param ShadowStack The bottom of the shadow stack for this CPU.
1221 **/
1222 VOID
1223 InitShadowStack (
1224 IN UINTN CpuIndex,
1225 IN VOID *ShadowStack
1226 );
1227
1228 /**
1229 This function set given attributes of the memory region specified by
1230 BaseAddress and Length.
1231
1232 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1233 @param BaseAddress The physical address that is the start address of
1234 a memory region.
1235 @param Length The size in bytes of the memory region.
1236 @param Attributes The bit mask of attributes to set for the memory
1237 region.
1238
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.
1249
1250 **/
1251 EFI_STATUS
1252 EFIAPI
1253 EdkiiSmmSetMemoryAttributes (
1254 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
1255 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1256 IN UINT64 Length,
1257 IN UINT64 Attributes
1258 );
1259
1260 /**
1261 This function clears given attributes of the memory region specified by
1262 BaseAddress and Length.
1263
1264 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1265 @param BaseAddress The physical address that is the start address of
1266 a memory region.
1267 @param Length The size in bytes of the memory region.
1268 @param Attributes The bit mask of attributes to clear for the memory
1269 region.
1270
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.
1281
1282 **/
1283 EFI_STATUS
1284 EFIAPI
1285 EdkiiSmmClearMemoryAttributes (
1286 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
1287 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1288 IN UINT64 Length,
1289 IN UINT64 Attributes
1290 );
1291
1292 /**
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.
1296
1297 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1298 @param BaseAddress The physical address that is the start address of
1299 a memory region.
1300 @param Length The size in bytes of the memory region.
1301 @param Attributes Pointer to attributes returned.
1302
1303 @retval EFI_SUCCESS The attributes got for the memory region.
1304 @retval EFI_INVALID_PARAMETER Length is zero.
1305 Attributes is NULL.
1306 @retval EFI_NO_MAPPING Attributes are not consistent cross the memory
1307 region.
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.
1311
1312 **/
1313 EFI_STATUS
1314 EFIAPI
1315 EdkiiSmmGetMemoryAttributes (
1316 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
1317 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1318 IN UINT64 Length,
1319 IN UINT64 *Attributes
1320 );
1321
1322 /**
1323 This function fixes up the address of the global variable or function
1324 referred in SmmInit assembly files to be the absolute address.
1325 **/
1326 VOID
1327 EFIAPI
1328 PiSmmCpuSmmInitFixupAddress (
1329 );
1330
1331 /**
1332 This function fixes up the address of the global variable or function
1333 referred in SmiEntry assembly files to be the absolute address.
1334 **/
1335 VOID
1336 EFIAPI
1337 PiSmmCpuSmiEntryFixupAddress (
1338 );
1339
1340 /**
1341 This function reads CR2 register when on-demand paging is enabled
1342 for 64 bit and no action for 32 bit.
1343
1344 @param[out] *Cr2 Pointer to variable to hold CR2 register value.
1345 **/
1346 VOID
1347 SaveCr2 (
1348 OUT UINTN *Cr2
1349 );
1350
1351 /**
1352 This function writes into CR2 register when on-demand paging is enabled
1353 for 64 bit and no action for 32 bit.
1354
1355 @param[in] Cr2 Value to write into CR2 register.
1356 **/
1357 VOID
1358 RestoreCr2 (
1359 IN UINTN Cr2
1360 );
1361
1362 /**
1363 Schedule a procedure to run on the specified CPU.
1364
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
1383 member.
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.
1389
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
1395
1396 **/
1397 EFI_STATUS
1398 InternalSmmStartupThisAp (
1399 IN EFI_AP_PROCEDURE2 Procedure,
1400 IN UINTN CpuIndex,
1401 IN OUT VOID *ProcArguments OPTIONAL,
1402 IN OUT MM_COMPLETION *Token,
1403 IN UINTN TimeoutInMicroseconds,
1404 IN OUT EFI_STATUS *CpuStatus
1405 );
1406
1407 /**
1408 Checks whether the input token is the current used token.
1409
1410 @param[in] Token This parameter describes the token that was passed into DispatchProcedure or
1411 BroadcastProcedure.
1412
1413 @retval TRUE The input token is the current used token.
1414 @retval FALSE The input token is not the current used token.
1415 **/
1416 BOOLEAN
1417 IsTokenInUse (
1418 IN SPIN_LOCK *Token
1419 );
1420
1421 /**
1422 Checks status of specified AP.
1423
1424 This function checks whether the specified AP has finished the task assigned
1425 by StartupThisAP(), and whether timeout expires.
1426
1427 @param[in] Token This parameter describes the token that was passed into DispatchProcedure or
1428 BroadcastProcedure.
1429
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.
1432 **/
1433 EFI_STATUS
1434 IsApReady (
1435 IN SPIN_LOCK *Token
1436 );
1437
1438 /**
1439 Check whether it is an present AP.
1440
1441 @param CpuIndex The AP index which calls this function.
1442
1443 @retval TRUE It's a present AP.
1444 @retval TRUE This is not an AP or it is not present.
1445
1446 **/
1447 BOOLEAN
1448 IsPresentAp (
1449 IN UINTN CpuIndex
1450 );
1451
1452 /**
1453 Worker function to execute a caller provided function on all enabled APs.
1454
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
1461 all APs.
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.
1473
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
1477 to all enabled APs.
1478 @retval others Failed to Startup all APs.
1479
1480 **/
1481 EFI_STATUS
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
1488 );
1489
1490 /**
1491
1492 Register the SMM Foundation entry point.
1493
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
1499 startup procedure.
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
1503
1504 @retval EFI_SUCCESS The Procedure has been set successfully.
1505 @retval EFI_INVALID_PARAMETER The Procedure is NULL but ProcedureArguments not NULL.
1506
1507 **/
1508 EFI_STATUS
1509 RegisterStartupProcedure (
1510 IN EFI_AP_PROCEDURE Procedure,
1511 IN OUT VOID *ProcedureArguments OPTIONAL
1512 );
1513
1514 /**
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.
1518
1519 **/
1520 VOID
1521 InitPackageFirstThreadIndexInfo (
1522 VOID
1523 );
1524
1525 /**
1526 Allocate buffer for SpinLock and Wrapper function buffer.
1527
1528 **/
1529 VOID
1530 InitializeDataForMmMp (
1531 VOID
1532 );
1533
1534 /**
1535 Return whether access to non-SMRAM is restricted.
1536
1537 @retval TRUE Access to non-SMRAM is restricted.
1538 @retval FALSE Access to non-SMRAM is not restricted.
1539 **/
1540 BOOLEAN
1541 IsRestrictedMemoryAccess (
1542 VOID
1543 );
1544
1545 /**
1546 Choose blocking or non-blocking mode to Wait for all APs.
1547
1548 @param[in] This A pointer to the EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL instance.
1549 @param[in] BlockingMode Blocking or non-blocking mode.
1550
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.
1553
1554 **/
1555 EFI_STATUS
1556 EFIAPI
1557 SmmCpuRendezvous (
1558 IN EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL *This,
1559 IN BOOLEAN BlockingMode
1560 );
1561
1562 /**
1563 Insure when this function returns, no AP will execute normal mode code before entering SMM, except SMI disabled APs.
1564
1565 **/
1566 VOID
1567 SmmWaitForApArrival (
1568 VOID
1569 );
1570
1571 #endif