]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
UefiCpuPkg/PiSmmCpuDxeSmm: Enable MM MP Protocol
[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 - 2019, 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
29 #include <Library/BaseLib.h>
30 #include <Library/IoLib.h>
31 #include <Library/TimerLib.h>
32 #include <Library/SynchronizationLib.h>
33 #include <Library/DebugLib.h>
34 #include <Library/BaseMemoryLib.h>
35 #include <Library/PcdLib.h>
36 #include <Library/MtrrLib.h>
37 #include <Library/SmmCpuPlatformHookLib.h>
38 #include <Library/SmmServicesTableLib.h>
39 #include <Library/MemoryAllocationLib.h>
40 #include <Library/UefiBootServicesTableLib.h>
41 #include <Library/UefiRuntimeServicesTableLib.h>
42 #include <Library/DebugAgentLib.h>
43 #include <Library/UefiLib.h>
44 #include <Library/HobLib.h>
45 #include <Library/LocalApicLib.h>
46 #include <Library/UefiCpuLib.h>
47 #include <Library/CpuExceptionHandlerLib.h>
48 #include <Library/ReportStatusCodeLib.h>
49 #include <Library/SmmCpuFeaturesLib.h>
50 #include <Library/PeCoffGetEntryPointLib.h>
51 #include <Library/RegisterCpuFeaturesLib.h>
52
53 #include <AcpiCpuData.h>
54 #include <CpuHotPlugData.h>
55
56 #include <Register/Cpuid.h>
57 #include <Register/Msr.h>
58
59 #include "CpuService.h"
60 #include "SmmProfile.h"
61
62 //
63 // CET definition
64 //
65 #define CPUID_CET_SS BIT7
66 #define CPUID_CET_IBT BIT20
67
68 #define CR4_CET_ENABLE BIT23
69
70 #define MSR_IA32_S_CET 0x6A2
71 #define MSR_IA32_PL0_SSP 0x6A4
72 #define MSR_IA32_INTERRUPT_SSP_TABLE_ADDR 0x6A8
73
74 typedef union {
75 struct {
76 // enable shadow stacks
77 UINT32 SH_STK_ENP:1;
78 // enable the WRSS{D,Q}W instructions.
79 UINT32 WR_SHSTK_EN:1;
80 // enable tracking of indirect call/jmp targets to be ENDBRANCH instruction.
81 UINT32 ENDBR_EN:1;
82 // enable legacy compatibility treatment for indirect call/jmp tracking.
83 UINT32 LEG_IW_EN:1;
84 // enable use of no-track prefix on indirect call/jmp.
85 UINT32 NO_TRACK_EN:1;
86 // disable suppression of CET indirect branch tracking on legacy compatibility.
87 UINT32 SUPPRESS_DIS:1;
88 UINT32 RSVD:4;
89 // indirect branch tracking is suppressed.
90 // This bit can be written to 1 only if TRACKER is written as IDLE.
91 UINT32 SUPPRESS:1;
92 // Value of the endbranch state machine
93 // Values: IDLE (0), WAIT_FOR_ENDBRANCH(1).
94 UINT32 TRACKER:1;
95 // linear address of a bitmap in memory indicating valid
96 // pages as target of CALL/JMP_indirect that do not land on ENDBRANCH when CET is enabled
97 // and not suppressed. Valid when ENDBR_EN is 1. Must be machine canonical when written on
98 // parts that support 64 bit mode. On parts that do not support 64 bit mode, the bits 63:32 are
99 // reserved and must be 0. This value is extended by 12 bits at the low end to form the base address
100 // (this automatically aligns the address on a 4-Kbyte boundary).
101 UINT32 EB_LEG_BITMAP_BASE_low:12;
102 UINT32 EB_LEG_BITMAP_BASE_high:32;
103 } Bits;
104 UINT64 Uint64;
105 } MSR_IA32_CET;
106
107 //
108 // MSRs required for configuration of SMM Code Access Check
109 //
110 #define EFI_MSR_SMM_MCA_CAP 0x17D
111 #define SMM_CODE_ACCESS_CHK_BIT BIT58
112
113 #define SMM_FEATURE_CONTROL_LOCK_BIT BIT0
114 #define SMM_CODE_CHK_EN_BIT BIT2
115
116 ///
117 /// Page Table Entry
118 ///
119 #define IA32_PG_P BIT0
120 #define IA32_PG_RW BIT1
121 #define IA32_PG_U BIT2
122 #define IA32_PG_WT BIT3
123 #define IA32_PG_CD BIT4
124 #define IA32_PG_A BIT5
125 #define IA32_PG_D BIT6
126 #define IA32_PG_PS BIT7
127 #define IA32_PG_PAT_2M BIT12
128 #define IA32_PG_PAT_4K IA32_PG_PS
129 #define IA32_PG_PMNT BIT62
130 #define IA32_PG_NX BIT63
131
132 #define PAGE_ATTRIBUTE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_U | IA32_PG_RW | IA32_PG_P)
133 //
134 // Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE
135 // X64 PAE PDPTE does not have such restriction
136 //
137 #define IA32_PAE_PDPTE_ATTRIBUTE_BITS (IA32_PG_P)
138
139 #define PAGE_PROGATE_BITS (IA32_PG_NX | PAGE_ATTRIBUTE_BITS)
140
141 #define PAGING_4K_MASK 0xFFF
142 #define PAGING_2M_MASK 0x1FFFFF
143 #define PAGING_1G_MASK 0x3FFFFFFF
144
145 #define PAGING_PAE_INDEX_MASK 0x1FF
146
147 #define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull
148 #define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull
149 #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
150
151 #define SMRR_MAX_ADDRESS BASE_4GB
152
153 typedef enum {
154 PageNone,
155 Page4K,
156 Page2M,
157 Page1G,
158 } PAGE_ATTRIBUTE;
159
160 typedef struct {
161 PAGE_ATTRIBUTE Attribute;
162 UINT64 Length;
163 UINT64 AddressMask;
164 } PAGE_ATTRIBUTE_TABLE;
165
166 //
167 // Size of Task-State Segment defined in IA32 Manual
168 //
169 #define TSS_SIZE 104
170 #define EXCEPTION_TSS_SIZE (TSS_SIZE + 4) // Add 4 bytes SSP
171 #define TSS_X64_IST1_OFFSET 36
172 #define TSS_IA32_CR3_OFFSET 28
173 #define TSS_IA32_ESP_OFFSET 56
174 #define TSS_IA32_SSP_OFFSET 104
175
176 #define CR0_WP BIT16
177
178 //
179 // Code select value
180 //
181 #define PROTECT_MODE_CODE_SEGMENT 0x08
182 #define LONG_MODE_CODE_SEGMENT 0x38
183
184 //
185 // The size 0x20 must be bigger than
186 // the size of template code of SmmInit. Currently,
187 // the size of SmmInit requires the 0x16 Bytes buffer
188 // at least.
189 //
190 #define BACK_BUF_SIZE 0x20
191
192 #define EXCEPTION_VECTOR_NUMBER 0x20
193
194 #define INVALID_APIC_ID 0xFFFFFFFFFFFFFFFFULL
195
196 typedef UINT32 SMM_CPU_ARRIVAL_EXCEPTIONS;
197 #define ARRIVAL_EXCEPTION_BLOCKED 0x1
198 #define ARRIVAL_EXCEPTION_DELAYED 0x2
199 #define ARRIVAL_EXCEPTION_SMI_DISABLED 0x4
200
201 //
202 // Wrapper used to convert EFI_AP_PROCEDURE2 and EFI_AP_PROCEDURE.
203 //
204 typedef struct {
205 EFI_AP_PROCEDURE Procedure;
206 VOID *ProcedureArgument;
207 } PROCEDURE_WRAPPER;
208
209 #define PROCEDURE_TOKEN_SIGNATURE SIGNATURE_32 ('P', 'R', 'T', 'S')
210
211 typedef struct {
212 UINTN Signature;
213 LIST_ENTRY Link;
214
215 SPIN_LOCK *ProcedureToken;
216 } PROCEDURE_TOKEN;
217
218 #define PROCEDURE_TOKEN_FROM_LINK(a) CR (a, PROCEDURE_TOKEN, Link, PROCEDURE_TOKEN_SIGNATURE)
219
220 //
221 // Private structure for the SMM CPU module that is stored in DXE Runtime memory
222 // Contains the SMM Configuration Protocols that is produced.
223 // Contains a mix of DXE and SMM contents. All the fields must be used properly.
224 //
225 #define SMM_CPU_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('s', 'c', 'p', 'u')
226
227 typedef struct {
228 UINTN Signature;
229
230 EFI_HANDLE SmmCpuHandle;
231
232 EFI_PROCESSOR_INFORMATION *ProcessorInfo;
233 SMM_CPU_OPERATION *Operation;
234 UINTN *CpuSaveStateSize;
235 VOID **CpuSaveState;
236
237 EFI_SMM_RESERVED_SMRAM_REGION SmmReservedSmramRegion[1];
238 EFI_SMM_ENTRY_CONTEXT SmmCoreEntryContext;
239 EFI_SMM_ENTRY_POINT SmmCoreEntry;
240
241 EFI_SMM_CONFIGURATION_PROTOCOL SmmConfiguration;
242
243 PROCEDURE_WRAPPER *ApWrapperFunc;
244 LIST_ENTRY TokenList;
245
246 } SMM_CPU_PRIVATE_DATA;
247
248 extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate;
249 extern CPU_HOT_PLUG_DATA mCpuHotPlugData;
250 extern UINTN mMaxNumberOfCpus;
251 extern UINTN mNumberOfCpus;
252 extern EFI_SMM_CPU_PROTOCOL mSmmCpu;
253 extern EFI_MM_MP_PROTOCOL mSmmMp;
254
255 ///
256 /// The mode of the CPU at the time an SMI occurs
257 ///
258 extern UINT8 mSmmSaveStateRegisterLma;
259
260 //
261 // SMM CPU Protocol function prototypes.
262 //
263
264 /**
265 Read information from the CPU save state.
266
267 @param This EFI_SMM_CPU_PROTOCOL instance
268 @param Width The number of bytes to read from the CPU save state.
269 @param Register Specifies the CPU register to read form the save state.
270 @param CpuIndex Specifies the zero-based index of the CPU save state
271 @param Buffer Upon return, this holds the CPU register value read from the save state.
272
273 @retval EFI_SUCCESS The register was read from Save State
274 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
275 @retval EFI_INVALID_PARAMTER This or Buffer is NULL.
276
277 **/
278 EFI_STATUS
279 EFIAPI
280 SmmReadSaveState (
281 IN CONST EFI_SMM_CPU_PROTOCOL *This,
282 IN UINTN Width,
283 IN EFI_SMM_SAVE_STATE_REGISTER Register,
284 IN UINTN CpuIndex,
285 OUT VOID *Buffer
286 );
287
288 /**
289 Write data to the CPU save state.
290
291 @param This EFI_SMM_CPU_PROTOCOL instance
292 @param Width The number of bytes to read from the CPU save state.
293 @param Register Specifies the CPU register to write to the save state.
294 @param CpuIndex Specifies the zero-based index of the CPU save state
295 @param Buffer Upon entry, this holds the new CPU register value.
296
297 @retval EFI_SUCCESS The register was written from Save State
298 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
299 @retval EFI_INVALID_PARAMTER ProcessorIndex or Width is not correct
300
301 **/
302 EFI_STATUS
303 EFIAPI
304 SmmWriteSaveState (
305 IN CONST EFI_SMM_CPU_PROTOCOL *This,
306 IN UINTN Width,
307 IN EFI_SMM_SAVE_STATE_REGISTER Register,
308 IN UINTN CpuIndex,
309 IN CONST VOID *Buffer
310 );
311
312 /**
313 Read a CPU Save State register on the target processor.
314
315 This function abstracts the differences that whether the CPU Save State register is in the
316 IA32 CPU Save State Map or X64 CPU Save State Map.
317
318 This function supports reading a CPU Save State register in SMBase relocation handler.
319
320 @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
321 @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
322 @param[in] Width The number of bytes to read from the CPU save state.
323 @param[out] Buffer Upon return, this holds the CPU register value read from the save state.
324
325 @retval EFI_SUCCESS The register was read from Save State.
326 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
327 @retval EFI_INVALID_PARAMTER This or Buffer is NULL.
328
329 **/
330 EFI_STATUS
331 EFIAPI
332 ReadSaveStateRegister (
333 IN UINTN CpuIndex,
334 IN EFI_SMM_SAVE_STATE_REGISTER Register,
335 IN UINTN Width,
336 OUT VOID *Buffer
337 );
338
339 /**
340 Write value to a CPU Save State register on the target processor.
341
342 This function abstracts the differences that whether the CPU Save State register is in the
343 IA32 CPU Save State Map or X64 CPU Save State Map.
344
345 This function supports writing a CPU Save State register in SMBase relocation handler.
346
347 @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
348 @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
349 @param[in] Width The number of bytes to read from the CPU save state.
350 @param[in] Buffer Upon entry, this holds the new CPU register value.
351
352 @retval EFI_SUCCESS The register was written to Save State.
353 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
354 @retval EFI_INVALID_PARAMTER ProcessorIndex or Width is not correct.
355
356 **/
357 EFI_STATUS
358 EFIAPI
359 WriteSaveStateRegister (
360 IN UINTN CpuIndex,
361 IN EFI_SMM_SAVE_STATE_REGISTER Register,
362 IN UINTN Width,
363 IN CONST VOID *Buffer
364 );
365
366 extern CONST UINT8 gcSmmInitTemplate[];
367 extern CONST UINT16 gcSmmInitSize;
368 X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr0;
369 extern UINT32 mSmmCr0;
370 X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr3;
371 extern UINT32 mSmmCr4;
372 X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr4;
373 X86_ASSEMBLY_PATCH_LABEL gPatchSmmInitStack;
374 X86_ASSEMBLY_PATCH_LABEL mPatchCetSupported;
375 extern BOOLEAN mCetSupported;
376
377 /**
378 Semaphore operation for all processor relocate SMMBase.
379 **/
380 VOID
381 EFIAPI
382 SmmRelocationSemaphoreComplete (
383 VOID
384 );
385
386 ///
387 /// The type of SMM CPU Information
388 ///
389 typedef struct {
390 SPIN_LOCK *Busy;
391 volatile EFI_AP_PROCEDURE2 Procedure;
392 volatile VOID *Parameter;
393 volatile UINT32 *Run;
394 volatile BOOLEAN *Present;
395 SPIN_LOCK *Token;
396 EFI_STATUS *Status;
397 } SMM_CPU_DATA_BLOCK;
398
399 typedef enum {
400 SmmCpuSyncModeTradition,
401 SmmCpuSyncModeRelaxedAp,
402 SmmCpuSyncModeMax
403 } SMM_CPU_SYNC_MODE;
404
405 typedef struct {
406 //
407 // Pointer to an array. The array should be located immediately after this structure
408 // so that UC cache-ability can be set together.
409 //
410 SMM_CPU_DATA_BLOCK *CpuData;
411 volatile UINT32 *Counter;
412 volatile UINT32 BspIndex;
413 volatile BOOLEAN *InsideSmm;
414 volatile BOOLEAN *AllCpusInSync;
415 volatile SMM_CPU_SYNC_MODE EffectiveSyncMode;
416 volatile BOOLEAN SwitchBsp;
417 volatile BOOLEAN *CandidateBsp;
418 EFI_AP_PROCEDURE StartupProcedure;
419 VOID *StartupProcArgs;
420 } SMM_DISPATCHER_MP_SYNC_DATA;
421
422 #define SMM_PSD_OFFSET 0xfb00
423
424 ///
425 /// All global semaphores' pointer
426 ///
427 typedef struct {
428 volatile UINT32 *Counter;
429 volatile BOOLEAN *InsideSmm;
430 volatile BOOLEAN *AllCpusInSync;
431 SPIN_LOCK *PFLock;
432 SPIN_LOCK *CodeAccessCheckLock;
433 } SMM_CPU_SEMAPHORE_GLOBAL;
434
435 ///
436 /// All semaphores for each processor
437 ///
438 typedef struct {
439 SPIN_LOCK *Busy;
440 volatile UINT32 *Run;
441 volatile BOOLEAN *Present;
442 SPIN_LOCK *Token;
443 } SMM_CPU_SEMAPHORE_CPU;
444
445 ///
446 /// All semaphores' information
447 ///
448 typedef struct {
449 SMM_CPU_SEMAPHORE_GLOBAL SemaphoreGlobal;
450 SMM_CPU_SEMAPHORE_CPU SemaphoreCpu;
451 } SMM_CPU_SEMAPHORES;
452
453 extern IA32_DESCRIPTOR gcSmiGdtr;
454 extern EFI_PHYSICAL_ADDRESS mGdtBuffer;
455 extern UINTN mGdtBufferSize;
456 extern IA32_DESCRIPTOR gcSmiIdtr;
457 extern VOID *gcSmiIdtrPtr;
458 extern UINT64 gPhyMask;
459 extern SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData;
460 extern UINTN mSmmStackArrayBase;
461 extern UINTN mSmmStackArrayEnd;
462 extern UINTN mSmmStackSize;
463 extern EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService;
464 extern IA32_DESCRIPTOR gcSmiInitGdtr;
465 extern SMM_CPU_SEMAPHORES mSmmCpuSemaphores;
466 extern UINTN mSemaphoreSize;
467 extern SPIN_LOCK *mPFLock;
468 extern SPIN_LOCK *mConfigSmmCodeAccessCheckLock;
469 extern EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges;
470 extern UINTN mSmmCpuSmramRangeCount;
471 extern UINT8 mPhysicalAddressBits;
472
473 //
474 // Copy of the PcdPteMemoryEncryptionAddressOrMask
475 //
476 extern UINT64 mAddressEncMask;
477
478 /**
479 Create 4G PageTable in SMRAM.
480
481 @param[in] Is32BitPageTable Whether the page table is 32-bit PAE
482 @return PageTable Address
483
484 **/
485 UINT32
486 Gen4GPageTable (
487 IN BOOLEAN Is32BitPageTable
488 );
489
490
491 /**
492 Initialize global data for MP synchronization.
493
494 @param Stacks Base address of SMI stack buffer for all processors.
495 @param StackSize Stack size for each processor in SMM.
496 @param ShadowStackSize Shadow Stack size for each processor in SMM.
497
498 **/
499 UINT32
500 InitializeMpServiceData (
501 IN VOID *Stacks,
502 IN UINTN StackSize,
503 IN UINTN ShadowStackSize
504 );
505
506 /**
507 Initialize Timer for SMM AP Sync.
508
509 **/
510 VOID
511 InitializeSmmTimer (
512 VOID
513 );
514
515 /**
516 Start Timer for SMM AP Sync.
517
518 **/
519 UINT64
520 EFIAPI
521 StartSyncTimer (
522 VOID
523 );
524
525 /**
526 Check if the SMM AP Sync timer is timeout.
527
528 @param Timer The start timer from the begin.
529
530 **/
531 BOOLEAN
532 EFIAPI
533 IsSyncTimerTimeout (
534 IN UINT64 Timer
535 );
536
537 /**
538 Initialize IDT for SMM Stack Guard.
539
540 **/
541 VOID
542 EFIAPI
543 InitializeIDTSmmStackGuard (
544 VOID
545 );
546
547 /**
548 Initialize Gdt for all processors.
549
550 @param[in] Cr3 CR3 value.
551 @param[out] GdtStepSize The step size for GDT table.
552
553 @return GdtBase for processor 0.
554 GdtBase for processor X is: GdtBase + (GdtStepSize * X)
555 **/
556 VOID *
557 InitGdt (
558 IN UINTN Cr3,
559 OUT UINTN *GdtStepSize
560 );
561
562 /**
563
564 Register the SMM Foundation entry point.
565
566 @param This Pointer to EFI_SMM_CONFIGURATION_PROTOCOL instance
567 @param SmmEntryPoint SMM Foundation EntryPoint
568
569 @retval EFI_SUCCESS Successfully to register SMM foundation entry point
570
571 **/
572 EFI_STATUS
573 EFIAPI
574 RegisterSmmEntry (
575 IN CONST EFI_SMM_CONFIGURATION_PROTOCOL *This,
576 IN EFI_SMM_ENTRY_POINT SmmEntryPoint
577 );
578
579 /**
580 Create PageTable for SMM use.
581
582 @return PageTable Address
583
584 **/
585 UINT32
586 SmmInitPageTable (
587 VOID
588 );
589
590 /**
591 Schedule a procedure to run on the specified CPU.
592
593 @param Procedure The address of the procedure to run
594 @param CpuIndex Target CPU number
595 @param ProcArguments The parameter to pass to the procedure
596
597 @retval EFI_INVALID_PARAMETER CpuNumber not valid
598 @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
599 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
600 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
601 @retval EFI_SUCCESS - The procedure has been successfully scheduled
602
603 **/
604 EFI_STATUS
605 EFIAPI
606 SmmStartupThisAp (
607 IN EFI_AP_PROCEDURE Procedure,
608 IN UINTN CpuIndex,
609 IN OUT VOID *ProcArguments OPTIONAL
610 );
611
612 /**
613 Schedule a procedure to run on the specified CPU in a blocking fashion.
614
615 @param Procedure The address of the procedure to run
616 @param CpuIndex Target CPU Index
617 @param ProcArguments The parameter to pass to the procedure
618
619 @retval EFI_INVALID_PARAMETER CpuNumber not valid
620 @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
621 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
622 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
623 @retval EFI_SUCCESS The procedure has been successfully scheduled
624
625 **/
626 EFI_STATUS
627 EFIAPI
628 SmmBlockingStartupThisAp (
629 IN EFI_AP_PROCEDURE Procedure,
630 IN UINTN CpuIndex,
631 IN OUT VOID *ProcArguments OPTIONAL
632 );
633
634 /**
635 This function sets the attributes for the memory region specified by BaseAddress and
636 Length from their current attributes to the attributes specified by Attributes.
637
638 @param[in] BaseAddress The physical address that is the start address of a memory region.
639 @param[in] Length The size in bytes of the memory region.
640 @param[in] Attributes The bit mask of attributes to set for the memory region.
641
642 @retval EFI_SUCCESS The attributes were set for the memory region.
643 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
644 BaseAddress and Length cannot be modified.
645 @retval EFI_INVALID_PARAMETER Length is zero.
646 Attributes specified an illegal combination of attributes that
647 cannot be set together.
648 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
649 the memory resource range.
650 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
651 resource range specified by BaseAddress and Length.
652 The bit mask of attributes is not support for the memory resource
653 range specified by BaseAddress and Length.
654
655 **/
656 EFI_STATUS
657 EFIAPI
658 SmmSetMemoryAttributes (
659 IN EFI_PHYSICAL_ADDRESS BaseAddress,
660 IN UINT64 Length,
661 IN UINT64 Attributes
662 );
663
664 /**
665 This function clears the attributes for the memory region specified by BaseAddress and
666 Length from their current attributes to the attributes specified by Attributes.
667
668 @param[in] BaseAddress The physical address that is the start address of a memory region.
669 @param[in] Length The size in bytes of the memory region.
670 @param[in] Attributes The bit mask of attributes to clear for the memory region.
671
672 @retval EFI_SUCCESS The attributes were cleared for the memory region.
673 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
674 BaseAddress and Length cannot be modified.
675 @retval EFI_INVALID_PARAMETER Length is zero.
676 Attributes specified an illegal combination of attributes that
677 cannot be set together.
678 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
679 the memory resource range.
680 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
681 resource range specified by BaseAddress and Length.
682 The bit mask of attributes is not support for the memory resource
683 range specified by BaseAddress and Length.
684
685 **/
686 EFI_STATUS
687 EFIAPI
688 SmmClearMemoryAttributes (
689 IN EFI_PHYSICAL_ADDRESS BaseAddress,
690 IN UINT64 Length,
691 IN UINT64 Attributes
692 );
693
694 /**
695 Initialize MP synchronization data.
696
697 **/
698 VOID
699 EFIAPI
700 InitializeMpSyncData (
701 VOID
702 );
703
704 /**
705
706 Find out SMRAM information including SMRR base and SMRR size.
707
708 @param SmrrBase SMRR base
709 @param SmrrSize SMRR size
710
711 **/
712 VOID
713 FindSmramInfo (
714 OUT UINT32 *SmrrBase,
715 OUT UINT32 *SmrrSize
716 );
717
718 /**
719 Relocate SmmBases for each processor.
720
721 Execute on first boot and all S3 resumes
722
723 **/
724 VOID
725 EFIAPI
726 SmmRelocateBases (
727 VOID
728 );
729
730 /**
731 Page Fault handler for SMM use.
732
733 @param InterruptType Defines the type of interrupt or exception that
734 occurred on the processor.This parameter is processor architecture specific.
735 @param SystemContext A pointer to the processor context when
736 the interrupt occurred on the processor.
737 **/
738 VOID
739 EFIAPI
740 SmiPFHandler (
741 IN EFI_EXCEPTION_TYPE InterruptType,
742 IN EFI_SYSTEM_CONTEXT SystemContext
743 );
744
745 /**
746 Perform the remaining tasks.
747
748 **/
749 VOID
750 PerformRemainingTasks (
751 VOID
752 );
753
754 /**
755 Perform the pre tasks.
756
757 **/
758 VOID
759 PerformPreTasks (
760 VOID
761 );
762
763 /**
764 Initialize MSR spin lock by MSR index.
765
766 @param MsrIndex MSR index value.
767
768 **/
769 VOID
770 InitMsrSpinLockByIndex (
771 IN UINT32 MsrIndex
772 );
773
774 /**
775 Hook return address of SMM Save State so that semaphore code
776 can be executed immediately after AP exits SMM to indicate to
777 the BSP that an AP has exited SMM after SMBASE relocation.
778
779 @param[in] CpuIndex The processor index.
780 @param[in] RebasedFlag A pointer to a flag that is set to TRUE
781 immediately after AP exits SMM.
782
783 **/
784 VOID
785 SemaphoreHook (
786 IN UINTN CpuIndex,
787 IN volatile BOOLEAN *RebasedFlag
788 );
789
790 /**
791 Configure SMM Code Access Check feature for all processors.
792 SMM Feature Control MSR will be locked after configuration.
793 **/
794 VOID
795 ConfigSmmCodeAccessCheck (
796 VOID
797 );
798
799 /**
800 Hook the code executed immediately after an RSM instruction on the currently
801 executing CPU. The mode of code executed immediately after RSM must be
802 detected, and the appropriate hook must be selected. Always clear the auto
803 HALT restart flag if it is set.
804
805 @param[in] CpuIndex The processor index for the currently
806 executing CPU.
807 @param[in] CpuState Pointer to SMRAM Save State Map for the
808 currently executing CPU.
809 @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to
810 32-bit mode from 64-bit SMM.
811 @param[in] NewInstructionPointer Instruction pointer to use if resuming to
812 same mode as SMM.
813
814 @retval The value of the original instruction pointer before it was hooked.
815
816 **/
817 UINT64
818 EFIAPI
819 HookReturnFromSmm (
820 IN UINTN CpuIndex,
821 SMRAM_SAVE_STATE_MAP *CpuState,
822 UINT64 NewInstructionPointer32,
823 UINT64 NewInstructionPointer
824 );
825
826 /**
827 Get the size of the SMI Handler in bytes.
828
829 @retval The size, in bytes, of the SMI Handler.
830
831 **/
832 UINTN
833 EFIAPI
834 GetSmiHandlerSize (
835 VOID
836 );
837
838 /**
839 Install the SMI handler for the CPU specified by CpuIndex. This function
840 is called by the CPU that was elected as monarch during System Management
841 Mode initialization.
842
843 @param[in] CpuIndex The index of the CPU to install the custom SMI handler.
844 The value must be between 0 and the NumberOfCpus field
845 in the System Management System Table (SMST).
846 @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex.
847 @param[in] SmiStack The stack to use when an SMI is processed by the
848 the CPU specified by CpuIndex.
849 @param[in] StackSize The size, in bytes, if the stack used when an SMI is
850 processed by the CPU specified by CpuIndex.
851 @param[in] GdtBase The base address of the GDT to use when an SMI is
852 processed by the CPU specified by CpuIndex.
853 @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is
854 processed by the CPU specified by CpuIndex.
855 @param[in] IdtBase The base address of the IDT to use when an SMI is
856 processed by the CPU specified by CpuIndex.
857 @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is
858 processed by the CPU specified by CpuIndex.
859 @param[in] Cr3 The base address of the page tables to use when an SMI
860 is processed by the CPU specified by CpuIndex.
861 **/
862 VOID
863 EFIAPI
864 InstallSmiHandler (
865 IN UINTN CpuIndex,
866 IN UINT32 SmBase,
867 IN VOID *SmiStack,
868 IN UINTN StackSize,
869 IN UINTN GdtBase,
870 IN UINTN GdtSize,
871 IN UINTN IdtBase,
872 IN UINTN IdtSize,
873 IN UINT32 Cr3
874 );
875
876 /**
877 Search module name by input IP address and output it.
878
879 @param CallerIpAddress Caller instruction pointer.
880
881 **/
882 VOID
883 DumpModuleInfoByIp (
884 IN UINTN CallerIpAddress
885 );
886
887 /**
888 This function sets memory attribute according to MemoryAttributesTable.
889 **/
890 VOID
891 SetMemMapAttributes (
892 VOID
893 );
894
895 /**
896 This function sets UEFI memory attribute according to UEFI memory map.
897 **/
898 VOID
899 SetUefiMemMapAttributes (
900 VOID
901 );
902
903 /**
904 Return if the Address is forbidden as SMM communication buffer.
905
906 @param[in] Address the address to be checked
907
908 @return TRUE The address is forbidden as SMM communication buffer.
909 @return FALSE The address is allowed as SMM communication buffer.
910 **/
911 BOOLEAN
912 IsSmmCommBufferForbiddenAddress (
913 IN UINT64 Address
914 );
915
916 /**
917 This function caches the UEFI memory map information.
918 **/
919 VOID
920 GetUefiMemoryMap (
921 VOID
922 );
923
924 /**
925 This function sets memory attribute for page table.
926 **/
927 VOID
928 SetPageTableAttributes (
929 VOID
930 );
931
932 /**
933 Return page table base.
934
935 @return page table base.
936 **/
937 UINTN
938 GetPageTableBase (
939 VOID
940 );
941
942 /**
943 This function sets the attributes for the memory region specified by BaseAddress and
944 Length from their current attributes to the attributes specified by Attributes.
945
946 @param[in] BaseAddress The physical address that is the start address of a memory region.
947 @param[in] Length The size in bytes of the memory region.
948 @param[in] Attributes The bit mask of attributes to set for the memory region.
949 @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted.
950
951 @retval EFI_SUCCESS The attributes were set for the memory region.
952 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
953 BaseAddress and Length cannot be modified.
954 @retval EFI_INVALID_PARAMETER Length is zero.
955 Attributes specified an illegal combination of attributes that
956 cannot be set together.
957 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
958 the memory resource range.
959 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
960 resource range specified by BaseAddress and Length.
961 The bit mask of attributes is not support for the memory resource
962 range specified by BaseAddress and Length.
963
964 **/
965 EFI_STATUS
966 EFIAPI
967 SmmSetMemoryAttributesEx (
968 IN EFI_PHYSICAL_ADDRESS BaseAddress,
969 IN UINT64 Length,
970 IN UINT64 Attributes,
971 OUT BOOLEAN *IsSplitted OPTIONAL
972 );
973
974 /**
975 This function clears the attributes for the memory region specified by BaseAddress and
976 Length from their current attributes to the attributes specified by Attributes.
977
978 @param[in] BaseAddress The physical address that is the start address of a memory region.
979 @param[in] Length The size in bytes of the memory region.
980 @param[in] Attributes The bit mask of attributes to clear for the memory region.
981 @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted.
982
983 @retval EFI_SUCCESS The attributes were cleared for the memory region.
984 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
985 BaseAddress and Length cannot be modified.
986 @retval EFI_INVALID_PARAMETER Length is zero.
987 Attributes specified an illegal combination of attributes that
988 cannot be set together.
989 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
990 the memory resource range.
991 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
992 resource range specified by BaseAddress and Length.
993 The bit mask of attributes is not support for the memory resource
994 range specified by BaseAddress and Length.
995
996 **/
997 EFI_STATUS
998 EFIAPI
999 SmmClearMemoryAttributesEx (
1000 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1001 IN UINT64 Length,
1002 IN UINT64 Attributes,
1003 OUT BOOLEAN *IsSplitted OPTIONAL
1004 );
1005
1006 /**
1007 This API provides a way to allocate memory for page table.
1008
1009 This API can be called more once to allocate memory for page tables.
1010
1011 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
1012 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
1013 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
1014 returned.
1015
1016 @param Pages The number of 4 KB pages to allocate.
1017
1018 @return A pointer to the allocated buffer or NULL if allocation fails.
1019
1020 **/
1021 VOID *
1022 AllocatePageTableMemory (
1023 IN UINTN Pages
1024 );
1025
1026 /**
1027 Allocate pages for code.
1028
1029 @param[in] Pages Number of pages to be allocated.
1030
1031 @return Allocated memory.
1032 **/
1033 VOID *
1034 AllocateCodePages (
1035 IN UINTN Pages
1036 );
1037
1038 /**
1039 Allocate aligned pages for code.
1040
1041 @param[in] Pages Number of pages to be allocated.
1042 @param[in] Alignment The requested alignment of the allocation.
1043 Must be a power of two.
1044 If Alignment is zero, then byte alignment is used.
1045
1046 @return Allocated memory.
1047 **/
1048 VOID *
1049 AllocateAlignedCodePages (
1050 IN UINTN Pages,
1051 IN UINTN Alignment
1052 );
1053
1054
1055 //
1056 // S3 related global variable and function prototype.
1057 //
1058
1059 extern BOOLEAN mSmmS3Flag;
1060
1061 /**
1062 Initialize SMM S3 resume state structure used during S3 Resume.
1063
1064 @param[in] Cr3 The base address of the page tables to use in SMM.
1065
1066 **/
1067 VOID
1068 InitSmmS3ResumeState (
1069 IN UINT32 Cr3
1070 );
1071
1072 /**
1073 Get ACPI CPU data.
1074
1075 **/
1076 VOID
1077 GetAcpiCpuData (
1078 VOID
1079 );
1080
1081 /**
1082 Restore SMM Configuration in S3 boot path.
1083
1084 **/
1085 VOID
1086 RestoreSmmConfigurationInS3 (
1087 VOID
1088 );
1089
1090 /**
1091 Get ACPI S3 enable flag.
1092
1093 **/
1094 VOID
1095 GetAcpiS3EnableFlag (
1096 VOID
1097 );
1098
1099 /**
1100 Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.
1101
1102 @param[in] ApHltLoopCode The address of the safe hlt-loop function.
1103 @param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode.
1104 @param[in] NumberToFinishAddress Address of Semaphore of APs finish count.
1105
1106 **/
1107 VOID
1108 TransferApToSafeState (
1109 IN UINTN ApHltLoopCode,
1110 IN UINTN TopOfStack,
1111 IN UINTN NumberToFinishAddress
1112 );
1113
1114 /**
1115 Set ShadowStack memory.
1116
1117 @param[in] Cr3 The page table base address.
1118 @param[in] BaseAddress The physical address that is the start address of a memory region.
1119 @param[in] Length The size in bytes of the memory region.
1120
1121 @retval EFI_SUCCESS The shadow stack memory is set.
1122 **/
1123 EFI_STATUS
1124 SetShadowStack (
1125 IN UINTN Cr3,
1126 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1127 IN UINT64 Length
1128 );
1129
1130 /**
1131 Set not present memory.
1132
1133 @param[in] Cr3 The page table base address.
1134 @param[in] BaseAddress The physical address that is the start address of a memory region.
1135 @param[in] Length The size in bytes of the memory region.
1136
1137 @retval EFI_SUCCESS The not present memory is set.
1138 **/
1139 EFI_STATUS
1140 SetNotPresentPage (
1141 IN UINTN Cr3,
1142 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1143 IN UINT64 Length
1144 );
1145
1146 /**
1147 Initialize the shadow stack related data structure.
1148
1149 @param CpuIndex The index of CPU.
1150 @param ShadowStack The bottom of the shadow stack for this CPU.
1151 **/
1152 VOID
1153 InitShadowStack (
1154 IN UINTN CpuIndex,
1155 IN VOID *ShadowStack
1156 );
1157
1158 /**
1159 This function set given attributes of the memory region specified by
1160 BaseAddress and Length.
1161
1162 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1163 @param BaseAddress The physical address that is the start address of
1164 a memory region.
1165 @param Length The size in bytes of the memory region.
1166 @param Attributes The bit mask of attributes to set for the memory
1167 region.
1168
1169 @retval EFI_SUCCESS The attributes were set for the memory region.
1170 @retval EFI_INVALID_PARAMETER Length is zero.
1171 Attributes specified an illegal combination of
1172 attributes that cannot be set together.
1173 @retval EFI_UNSUPPORTED The processor does not support one or more
1174 bytes of the memory resource range specified
1175 by BaseAddress and Length.
1176 The bit mask of attributes is not supported for
1177 the memory resource range specified by
1178 BaseAddress and Length.
1179
1180 **/
1181 EFI_STATUS
1182 EFIAPI
1183 EdkiiSmmSetMemoryAttributes (
1184 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
1185 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1186 IN UINT64 Length,
1187 IN UINT64 Attributes
1188 );
1189
1190 /**
1191 This function clears given attributes of the memory region specified by
1192 BaseAddress and Length.
1193
1194 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1195 @param BaseAddress The physical address that is the start address of
1196 a memory region.
1197 @param Length The size in bytes of the memory region.
1198 @param Attributes The bit mask of attributes to clear for the memory
1199 region.
1200
1201 @retval EFI_SUCCESS The attributes were cleared for the memory region.
1202 @retval EFI_INVALID_PARAMETER Length is zero.
1203 Attributes specified an illegal combination of
1204 attributes that cannot be cleared together.
1205 @retval EFI_UNSUPPORTED The processor does not support one or more
1206 bytes of the memory resource range specified
1207 by BaseAddress and Length.
1208 The bit mask of attributes is not supported for
1209 the memory resource range specified by
1210 BaseAddress and Length.
1211
1212 **/
1213 EFI_STATUS
1214 EFIAPI
1215 EdkiiSmmClearMemoryAttributes (
1216 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
1217 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1218 IN UINT64 Length,
1219 IN UINT64 Attributes
1220 );
1221
1222 /**
1223 This function retrieves the attributes of the memory region specified by
1224 BaseAddress and Length. If different attributes are got from different part
1225 of the memory region, EFI_NO_MAPPING will be returned.
1226
1227 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1228 @param BaseAddress The physical address that is the start address of
1229 a memory region.
1230 @param Length The size in bytes of the memory region.
1231 @param Attributes Pointer to attributes returned.
1232
1233 @retval EFI_SUCCESS The attributes got for the memory region.
1234 @retval EFI_INVALID_PARAMETER Length is zero.
1235 Attributes is NULL.
1236 @retval EFI_NO_MAPPING Attributes are not consistent cross the memory
1237 region.
1238 @retval EFI_UNSUPPORTED The processor does not support one or more
1239 bytes of the memory resource range specified
1240 by BaseAddress and Length.
1241
1242 **/
1243 EFI_STATUS
1244 EFIAPI
1245 EdkiiSmmGetMemoryAttributes (
1246 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
1247 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1248 IN UINT64 Length,
1249 IN UINT64 *Attributes
1250 );
1251
1252 /**
1253 This function fixes up the address of the global variable or function
1254 referred in SmmInit assembly files to be the absoute address.
1255 **/
1256 VOID
1257 EFIAPI
1258 PiSmmCpuSmmInitFixupAddress (
1259 );
1260
1261 /**
1262 This function fixes up the address of the global variable or function
1263 referred in SmiEntry assembly files to be the absoute address.
1264 **/
1265 VOID
1266 EFIAPI
1267 PiSmmCpuSmiEntryFixupAddress (
1268 );
1269
1270 /**
1271 This function reads CR2 register when on-demand paging is enabled
1272 for 64 bit and no action for 32 bit.
1273
1274 @param[out] *Cr2 Pointer to variable to hold CR2 register value.
1275 **/
1276 VOID
1277 SaveCr2 (
1278 OUT UINTN *Cr2
1279 );
1280
1281 /**
1282 This function writes into CR2 register when on-demand paging is enabled
1283 for 64 bit and no action for 32 bit.
1284
1285 @param[in] Cr2 Value to write into CR2 register.
1286 **/
1287 VOID
1288 RestoreCr2 (
1289 IN UINTN Cr2
1290 );
1291
1292 /**
1293 Schedule a procedure to run on the specified CPU.
1294
1295 @param[in] Procedure The address of the procedure to run
1296 @param[in] CpuIndex Target CPU Index
1297 @param[in,out] ProcArguments The parameter to pass to the procedure
1298 @param[in,out] Token This is an optional parameter that allows the caller to execute the
1299 procedure in a blocking or non-blocking fashion. If it is NULL the
1300 call is blocking, and the call will not return until the AP has
1301 completed the procedure. If the token is not NULL, the call will
1302 return immediately. The caller can check whether the procedure has
1303 completed with CheckOnProcedure or WaitForProcedure.
1304 @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for the APs to finish
1305 execution of Procedure, either for blocking or non-blocking mode.
1306 Zero means infinity. If the timeout expires before all APs return
1307 from Procedure, then Procedure on the failed APs is terminated. If
1308 the timeout expires in blocking mode, the call returns EFI_TIMEOUT.
1309 If the timeout expires in non-blocking mode, the timeout determined
1310 can be through CheckOnProcedure or WaitForProcedure.
1311 Note that timeout support is optional. Whether an implementation
1312 supports this feature can be determined via the Attributes data
1313 member.
1314 @param[in,out] CPUStatus This optional pointer may be used to get the status code returned
1315 by Procedure when it completes execution on the target AP, or with
1316 EFI_TIMEOUT if the Procedure fails to complete within the optional
1317 timeout. The implementation will update this variable with
1318 EFI_NOT_READY prior to starting Procedure on the target AP.
1319
1320 @retval EFI_INVALID_PARAMETER CpuNumber not valid
1321 @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
1322 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
1323 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
1324 @retval EFI_SUCCESS The procedure has been successfully scheduled
1325
1326 **/
1327 EFI_STATUS
1328 InternalSmmStartupThisAp (
1329 IN EFI_AP_PROCEDURE2 Procedure,
1330 IN UINTN CpuIndex,
1331 IN OUT VOID *ProcArguments OPTIONAL,
1332 IN MM_COMPLETION *Token,
1333 IN UINTN TimeoutInMicroseconds,
1334 IN OUT EFI_STATUS *CpuStatus
1335 );
1336
1337 /**
1338 Checks whether the input token is the current used token.
1339
1340 @param[in] Token This parameter describes the token that was passed into DispatchProcedure or
1341 BroadcastProcedure.
1342
1343 @retval TRUE The input token is the current used token.
1344 @retval FALSE The input token is not the current used token.
1345 **/
1346 BOOLEAN
1347 IsTokenInUse (
1348 IN SPIN_LOCK *Token
1349 );
1350
1351 /**
1352 Checks status of specified AP.
1353
1354 This function checks whether the specified AP has finished the task assigned
1355 by StartupThisAP(), and whether timeout expires.
1356
1357 @param[in] Token This parameter describes the token that was passed into DispatchProcedure or
1358 BroadcastProcedure.
1359
1360 @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs().
1361 @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired.
1362 **/
1363 EFI_STATUS
1364 IsApReady (
1365 IN SPIN_LOCK *Token
1366 );
1367
1368 /**
1369 Check whether it is an present AP.
1370
1371 @param CpuIndex The AP index which calls this function.
1372
1373 @retval TRUE It's a present AP.
1374 @retval TRUE This is not an AP or it is not present.
1375
1376 **/
1377 BOOLEAN
1378 IsPresentAp (
1379 IN UINTN CpuIndex
1380 );
1381
1382 /**
1383 Worker function to execute a caller provided function on all enabled APs.
1384
1385 @param[in] Procedure A pointer to the function to be run on
1386 enabled APs of the system.
1387 @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
1388 APs to return from Procedure, either for
1389 blocking or non-blocking mode.
1390 @param[in,out] ProcedureArgument The parameter passed into Procedure for
1391 all APs.
1392 @param[in,out] Token This is an optional parameter that allows the caller to execute the
1393 procedure in a blocking or non-blocking fashion. If it is NULL the
1394 call is blocking, and the call will not return until the AP has
1395 completed the procedure. If the token is not NULL, the call will
1396 return immediately. The caller can check whether the procedure has
1397 completed with CheckOnProcedure or WaitForProcedure.
1398 @param[in,out] CPUStatus This optional pointer may be used to get the status code returned
1399 by Procedure when it completes execution on the target AP, or with
1400 EFI_TIMEOUT if the Procedure fails to complete within the optional
1401 timeout. The implementation will update this variable with
1402 EFI_NOT_READY prior to starting Procedure on the target AP.
1403
1404 @retval EFI_SUCCESS In blocking mode, all APs have finished before
1405 the timeout expired.
1406 @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
1407 to all enabled APs.
1408 @retval others Failed to Startup all APs.
1409
1410 **/
1411 EFI_STATUS
1412 InternalSmmStartupAllAPs (
1413 IN EFI_AP_PROCEDURE2 Procedure,
1414 IN UINTN TimeoutInMicroseconds,
1415 IN OUT VOID *ProcedureArguments OPTIONAL,
1416 IN OUT MM_COMPLETION *Token,
1417 IN OUT EFI_STATUS *CPUStatus
1418 );
1419
1420 /**
1421
1422 Register the SMM Foundation entry point.
1423
1424 @param[in] Procedure A pointer to the code stream to be run on the designated target AP
1425 of the system. Type EFI_AP_PROCEDURE is defined below in Volume 2
1426 with the related definitions of
1427 EFI_MP_SERVICES_PROTOCOL.StartupAllAPs.
1428 If caller may pass a value of NULL to deregister any existing
1429 startup procedure.
1430 @param[in,out] ProcedureArguments Allows the caller to pass a list of parameters to the code that is
1431 run by the AP. It is an optional common mailbox between APs and
1432 the caller to share information
1433
1434 @retval EFI_SUCCESS The Procedure has been set successfully.
1435 @retval EFI_INVALID_PARAMETER The Procedure is NULL but ProcedureArguments not NULL.
1436
1437 **/
1438 EFI_STATUS
1439 RegisterStartupProcedure (
1440 IN EFI_AP_PROCEDURE Procedure,
1441 IN VOID *ProcedureArguments OPTIONAL
1442 );
1443
1444 /**
1445 Allocate buffer for SpinLock and Wrapper function buffer.
1446
1447 **/
1448 VOID
1449 InitializeDataForMmMp (
1450 VOID
1451 );
1452
1453 #endif