]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmmCr4" with PatchInstructionX86()
[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 - 2018, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
6
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 #ifndef _CPU_PISMMCPUDXESMM_H_
18 #define _CPU_PISMMCPUDXESMM_H_
19
20 #include <PiSmm.h>
21
22 #include <Protocol/MpService.h>
23 #include <Protocol/SmmConfiguration.h>
24 #include <Protocol/SmmCpu.h>
25 #include <Protocol/SmmAccess2.h>
26 #include <Protocol/SmmReadyToLock.h>
27 #include <Protocol/SmmCpuService.h>
28 #include <Protocol/SmmMemoryAttribute.h>
29
30 #include <Guid/AcpiS3Context.h>
31 #include <Guid/PiSmmMemoryAttributesTable.h>
32
33 #include <Library/BaseLib.h>
34 #include <Library/IoLib.h>
35 #include <Library/TimerLib.h>
36 #include <Library/SynchronizationLib.h>
37 #include <Library/DebugLib.h>
38 #include <Library/BaseMemoryLib.h>
39 #include <Library/PcdLib.h>
40 #include <Library/CacheMaintenanceLib.h>
41 #include <Library/MtrrLib.h>
42 #include <Library/SmmCpuPlatformHookLib.h>
43 #include <Library/SmmServicesTableLib.h>
44 #include <Library/MemoryAllocationLib.h>
45 #include <Library/UefiBootServicesTableLib.h>
46 #include <Library/UefiRuntimeServicesTableLib.h>
47 #include <Library/DebugAgentLib.h>
48 #include <Library/HobLib.h>
49 #include <Library/LocalApicLib.h>
50 #include <Library/UefiCpuLib.h>
51 #include <Library/CpuExceptionHandlerLib.h>
52 #include <Library/ReportStatusCodeLib.h>
53 #include <Library/SmmCpuFeaturesLib.h>
54 #include <Library/PeCoffGetEntryPointLib.h>
55
56 #include <AcpiCpuData.h>
57 #include <CpuHotPlugData.h>
58
59 #include <Register/Cpuid.h>
60 #include <Register/Msr.h>
61
62 #include "CpuService.h"
63 #include "SmmProfile.h"
64
65 //
66 // MSRs required for configuration of SMM Code Access Check
67 //
68 #define EFI_MSR_SMM_MCA_CAP 0x17D
69 #define SMM_CODE_ACCESS_CHK_BIT BIT58
70
71 #define SMM_FEATURE_CONTROL_LOCK_BIT BIT0
72 #define SMM_CODE_CHK_EN_BIT BIT2
73
74 ///
75 /// Page Table Entry
76 ///
77 #define IA32_PG_P BIT0
78 #define IA32_PG_RW BIT1
79 #define IA32_PG_U BIT2
80 #define IA32_PG_WT BIT3
81 #define IA32_PG_CD BIT4
82 #define IA32_PG_A BIT5
83 #define IA32_PG_D BIT6
84 #define IA32_PG_PS BIT7
85 #define IA32_PG_PAT_2M BIT12
86 #define IA32_PG_PAT_4K IA32_PG_PS
87 #define IA32_PG_PMNT BIT62
88 #define IA32_PG_NX BIT63
89
90 #define PAGE_ATTRIBUTE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_U | IA32_PG_RW | IA32_PG_P)
91 //
92 // Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE
93 // X64 PAE PDPTE does not have such restriction
94 //
95 #define IA32_PAE_PDPTE_ATTRIBUTE_BITS (IA32_PG_P)
96
97 #define PAGE_PROGATE_BITS (IA32_PG_NX | PAGE_ATTRIBUTE_BITS)
98
99 #define PAGING_4K_MASK 0xFFF
100 #define PAGING_2M_MASK 0x1FFFFF
101 #define PAGING_1G_MASK 0x3FFFFFFF
102
103 #define PAGING_PAE_INDEX_MASK 0x1FF
104
105 #define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull
106 #define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull
107 #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
108
109 #define SMRR_MAX_ADDRESS BASE_4GB
110
111 typedef enum {
112 PageNone,
113 Page4K,
114 Page2M,
115 Page1G,
116 } PAGE_ATTRIBUTE;
117
118 typedef struct {
119 PAGE_ATTRIBUTE Attribute;
120 UINT64 Length;
121 UINT64 AddressMask;
122 } PAGE_ATTRIBUTE_TABLE;
123
124 //
125 // Size of Task-State Segment defined in IA32 Manual
126 //
127 #define TSS_SIZE 104
128 #define TSS_X64_IST1_OFFSET 36
129 #define TSS_IA32_CR3_OFFSET 28
130 #define TSS_IA32_ESP_OFFSET 56
131
132 #define CR0_WP BIT16
133
134 //
135 // Code select value
136 //
137 #define PROTECT_MODE_CODE_SEGMENT 0x08
138 #define LONG_MODE_CODE_SEGMENT 0x38
139
140 //
141 // The size 0x20 must be bigger than
142 // the size of template code of SmmInit. Currently,
143 // the size of SmmInit requires the 0x16 Bytes buffer
144 // at least.
145 //
146 #define BACK_BUF_SIZE 0x20
147
148 #define EXCEPTION_VECTOR_NUMBER 0x20
149
150 #define INVALID_APIC_ID 0xFFFFFFFFFFFFFFFFULL
151
152 typedef UINT32 SMM_CPU_ARRIVAL_EXCEPTIONS;
153 #define ARRIVAL_EXCEPTION_BLOCKED 0x1
154 #define ARRIVAL_EXCEPTION_DELAYED 0x2
155 #define ARRIVAL_EXCEPTION_SMI_DISABLED 0x4
156
157 //
158 // Private structure for the SMM CPU module that is stored in DXE Runtime memory
159 // Contains the SMM Configuration Protocols that is produced.
160 // Contains a mix of DXE and SMM contents. All the fields must be used properly.
161 //
162 #define SMM_CPU_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('s', 'c', 'p', 'u')
163
164 typedef struct {
165 UINTN Signature;
166
167 EFI_HANDLE SmmCpuHandle;
168
169 EFI_PROCESSOR_INFORMATION *ProcessorInfo;
170 SMM_CPU_OPERATION *Operation;
171 UINTN *CpuSaveStateSize;
172 VOID **CpuSaveState;
173
174 EFI_SMM_RESERVED_SMRAM_REGION SmmReservedSmramRegion[1];
175 EFI_SMM_ENTRY_CONTEXT SmmCoreEntryContext;
176 EFI_SMM_ENTRY_POINT SmmCoreEntry;
177
178 EFI_SMM_CONFIGURATION_PROTOCOL SmmConfiguration;
179 } SMM_CPU_PRIVATE_DATA;
180
181 extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate;
182 extern CPU_HOT_PLUG_DATA mCpuHotPlugData;
183 extern UINTN mMaxNumberOfCpus;
184 extern UINTN mNumberOfCpus;
185 extern EFI_SMM_CPU_PROTOCOL mSmmCpu;
186
187 ///
188 /// The mode of the CPU at the time an SMI occurs
189 ///
190 extern UINT8 mSmmSaveStateRegisterLma;
191
192 //
193 // SMM CPU Protocol function prototypes.
194 //
195
196 /**
197 Read information from the CPU save state.
198
199 @param This EFI_SMM_CPU_PROTOCOL instance
200 @param Width The number of bytes to read from the CPU save state.
201 @param Register Specifies the CPU register to read form the save state.
202 @param CpuIndex Specifies the zero-based index of the CPU save state
203 @param Buffer Upon return, this holds the CPU register value read from the save state.
204
205 @retval EFI_SUCCESS The register was read from Save State
206 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
207 @retval EFI_INVALID_PARAMTER This or Buffer is NULL.
208
209 **/
210 EFI_STATUS
211 EFIAPI
212 SmmReadSaveState (
213 IN CONST EFI_SMM_CPU_PROTOCOL *This,
214 IN UINTN Width,
215 IN EFI_SMM_SAVE_STATE_REGISTER Register,
216 IN UINTN CpuIndex,
217 OUT VOID *Buffer
218 );
219
220 /**
221 Write data to the CPU save state.
222
223 @param This EFI_SMM_CPU_PROTOCOL instance
224 @param Width The number of bytes to read from the CPU save state.
225 @param Register Specifies the CPU register to write to the save state.
226 @param CpuIndex Specifies the zero-based index of the CPU save state
227 @param Buffer Upon entry, this holds the new CPU register value.
228
229 @retval EFI_SUCCESS The register was written from Save State
230 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
231 @retval EFI_INVALID_PARAMTER ProcessorIndex or Width is not correct
232
233 **/
234 EFI_STATUS
235 EFIAPI
236 SmmWriteSaveState (
237 IN CONST EFI_SMM_CPU_PROTOCOL *This,
238 IN UINTN Width,
239 IN EFI_SMM_SAVE_STATE_REGISTER Register,
240 IN UINTN CpuIndex,
241 IN CONST VOID *Buffer
242 );
243
244 /**
245 Read a CPU Save State register on the target processor.
246
247 This function abstracts the differences that whether the CPU Save State register is in the
248 IA32 CPU Save State Map or X64 CPU Save State Map.
249
250 This function supports reading a CPU Save State register in SMBase relocation handler.
251
252 @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
253 @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
254 @param[in] Width The number of bytes to read from the CPU save state.
255 @param[out] Buffer Upon return, this holds the CPU register value read from the save state.
256
257 @retval EFI_SUCCESS The register was read from Save State.
258 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
259 @retval EFI_INVALID_PARAMTER This or Buffer is NULL.
260
261 **/
262 EFI_STATUS
263 EFIAPI
264 ReadSaveStateRegister (
265 IN UINTN CpuIndex,
266 IN EFI_SMM_SAVE_STATE_REGISTER Register,
267 IN UINTN Width,
268 OUT VOID *Buffer
269 );
270
271 /**
272 Write value to a CPU Save State register on the target processor.
273
274 This function abstracts the differences that whether the CPU Save State register is in the
275 IA32 CPU Save State Map or X64 CPU Save State Map.
276
277 This function supports writing a CPU Save State register in SMBase relocation handler.
278
279 @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
280 @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
281 @param[in] Width The number of bytes to read from the CPU save state.
282 @param[in] Buffer Upon entry, this holds the new CPU register value.
283
284 @retval EFI_SUCCESS The register was written to Save State.
285 @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
286 @retval EFI_INVALID_PARAMTER ProcessorIndex or Width is not correct.
287
288 **/
289 EFI_STATUS
290 EFIAPI
291 WriteSaveStateRegister (
292 IN UINTN CpuIndex,
293 IN EFI_SMM_SAVE_STATE_REGISTER Register,
294 IN UINTN Width,
295 IN CONST VOID *Buffer
296 );
297
298 //
299 //
300 //
301 typedef struct {
302 UINT32 Offset;
303 UINT16 Segment;
304 UINT16 Reserved;
305 } IA32_FAR_ADDRESS;
306
307 extern IA32_FAR_ADDRESS gSmmJmpAddr;
308
309 extern CONST UINT8 gcSmmInitTemplate[];
310 extern CONST UINT16 gcSmmInitSize;
311 extern UINT32 gSmmCr0;
312 X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr3;
313 extern UINT32 mSmmCr4;
314 X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr4;
315 extern UINTN gSmmInitStack;
316
317 /**
318 Semaphore operation for all processor relocate SMMBase.
319 **/
320 VOID
321 EFIAPI
322 SmmRelocationSemaphoreComplete (
323 VOID
324 );
325
326 ///
327 /// The type of SMM CPU Information
328 ///
329 typedef struct {
330 SPIN_LOCK *Busy;
331 volatile EFI_AP_PROCEDURE Procedure;
332 volatile VOID *Parameter;
333 volatile UINT32 *Run;
334 volatile BOOLEAN *Present;
335 } SMM_CPU_DATA_BLOCK;
336
337 typedef enum {
338 SmmCpuSyncModeTradition,
339 SmmCpuSyncModeRelaxedAp,
340 SmmCpuSyncModeMax
341 } SMM_CPU_SYNC_MODE;
342
343 typedef struct {
344 //
345 // Pointer to an array. The array should be located immediately after this structure
346 // so that UC cache-ability can be set together.
347 //
348 SMM_CPU_DATA_BLOCK *CpuData;
349 volatile UINT32 *Counter;
350 volatile UINT32 BspIndex;
351 volatile BOOLEAN *InsideSmm;
352 volatile BOOLEAN *AllCpusInSync;
353 volatile SMM_CPU_SYNC_MODE EffectiveSyncMode;
354 volatile BOOLEAN SwitchBsp;
355 volatile BOOLEAN *CandidateBsp;
356 } SMM_DISPATCHER_MP_SYNC_DATA;
357
358 #define MSR_SPIN_LOCK_INIT_NUM 15
359
360 typedef struct {
361 SPIN_LOCK *SpinLock;
362 UINT32 MsrIndex;
363 } MP_MSR_LOCK;
364
365 #define SMM_PSD_OFFSET 0xfb00
366
367 ///
368 /// All global semaphores' pointer
369 ///
370 typedef struct {
371 volatile UINT32 *Counter;
372 volatile BOOLEAN *InsideSmm;
373 volatile BOOLEAN *AllCpusInSync;
374 SPIN_LOCK *PFLock;
375 SPIN_LOCK *CodeAccessCheckLock;
376 SPIN_LOCK *MemoryMappedLock;
377 } SMM_CPU_SEMAPHORE_GLOBAL;
378
379 ///
380 /// All semaphores for each processor
381 ///
382 typedef struct {
383 SPIN_LOCK *Busy;
384 volatile UINT32 *Run;
385 volatile BOOLEAN *Present;
386 } SMM_CPU_SEMAPHORE_CPU;
387
388 ///
389 /// All MSRs semaphores' pointer and counter
390 ///
391 typedef struct {
392 SPIN_LOCK *Msr;
393 UINTN AvailableCounter;
394 } SMM_CPU_SEMAPHORE_MSR;
395
396 ///
397 /// All semaphores' information
398 ///
399 typedef struct {
400 SMM_CPU_SEMAPHORE_GLOBAL SemaphoreGlobal;
401 SMM_CPU_SEMAPHORE_CPU SemaphoreCpu;
402 SMM_CPU_SEMAPHORE_MSR SemaphoreMsr;
403 } SMM_CPU_SEMAPHORES;
404
405 extern IA32_DESCRIPTOR gcSmiGdtr;
406 extern EFI_PHYSICAL_ADDRESS mGdtBuffer;
407 extern UINTN mGdtBufferSize;
408 extern IA32_DESCRIPTOR gcSmiIdtr;
409 extern VOID *gcSmiIdtrPtr;
410 extern UINT64 gPhyMask;
411 extern SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData;
412 extern UINTN mSmmStackArrayBase;
413 extern UINTN mSmmStackArrayEnd;
414 extern UINTN mSmmStackSize;
415 extern EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService;
416 extern IA32_DESCRIPTOR gcSmiInitGdtr;
417 extern SMM_CPU_SEMAPHORES mSmmCpuSemaphores;
418 extern UINTN mSemaphoreSize;
419 extern SPIN_LOCK *mPFLock;
420 extern SPIN_LOCK *mConfigSmmCodeAccessCheckLock;
421 extern SPIN_LOCK *mMemoryMappedLock;
422 extern EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges;
423 extern UINTN mSmmCpuSmramRangeCount;
424 extern UINT8 mPhysicalAddressBits;
425
426 //
427 // Copy of the PcdPteMemoryEncryptionAddressOrMask
428 //
429 extern UINT64 mAddressEncMask;
430
431 /**
432 Create 4G PageTable in SMRAM.
433
434 @param[in] Is32BitPageTable Whether the page table is 32-bit PAE
435 @return PageTable Address
436
437 **/
438 UINT32
439 Gen4GPageTable (
440 IN BOOLEAN Is32BitPageTable
441 );
442
443
444 /**
445 Initialize global data for MP synchronization.
446
447 @param Stacks Base address of SMI stack buffer for all processors.
448 @param StackSize Stack size for each processor in SMM.
449
450 **/
451 UINT32
452 InitializeMpServiceData (
453 IN VOID *Stacks,
454 IN UINTN StackSize
455 );
456
457 /**
458 Initialize Timer for SMM AP Sync.
459
460 **/
461 VOID
462 InitializeSmmTimer (
463 VOID
464 );
465
466 /**
467 Start Timer for SMM AP Sync.
468
469 **/
470 UINT64
471 EFIAPI
472 StartSyncTimer (
473 VOID
474 );
475
476 /**
477 Check if the SMM AP Sync timer is timeout.
478
479 @param Timer The start timer from the begin.
480
481 **/
482 BOOLEAN
483 EFIAPI
484 IsSyncTimerTimeout (
485 IN UINT64 Timer
486 );
487
488 /**
489 Initialize IDT for SMM Stack Guard.
490
491 **/
492 VOID
493 EFIAPI
494 InitializeIDTSmmStackGuard (
495 VOID
496 );
497
498 /**
499 Initialize Gdt for all processors.
500
501 @param[in] Cr3 CR3 value.
502 @param[out] GdtStepSize The step size for GDT table.
503
504 @return GdtBase for processor 0.
505 GdtBase for processor X is: GdtBase + (GdtStepSize * X)
506 **/
507 VOID *
508 InitGdt (
509 IN UINTN Cr3,
510 OUT UINTN *GdtStepSize
511 );
512
513 /**
514
515 Register the SMM Foundation entry point.
516
517 @param This Pointer to EFI_SMM_CONFIGURATION_PROTOCOL instance
518 @param SmmEntryPoint SMM Foundation EntryPoint
519
520 @retval EFI_SUCCESS Successfully to register SMM foundation entry point
521
522 **/
523 EFI_STATUS
524 EFIAPI
525 RegisterSmmEntry (
526 IN CONST EFI_SMM_CONFIGURATION_PROTOCOL *This,
527 IN EFI_SMM_ENTRY_POINT SmmEntryPoint
528 );
529
530 /**
531 Create PageTable for SMM use.
532
533 @return PageTable Address
534
535 **/
536 UINT32
537 SmmInitPageTable (
538 VOID
539 );
540
541 /**
542 Schedule a procedure to run on the specified CPU.
543
544 @param Procedure The address of the procedure to run
545 @param CpuIndex Target CPU number
546 @param ProcArguments The parameter to pass to the procedure
547
548 @retval EFI_INVALID_PARAMETER CpuNumber not valid
549 @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
550 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
551 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
552 @retval EFI_SUCCESS - The procedure has been successfully scheduled
553
554 **/
555 EFI_STATUS
556 EFIAPI
557 SmmStartupThisAp (
558 IN EFI_AP_PROCEDURE Procedure,
559 IN UINTN CpuIndex,
560 IN OUT VOID *ProcArguments OPTIONAL
561 );
562
563 /**
564 Schedule a procedure to run on the specified CPU in a blocking fashion.
565
566 @param Procedure The address of the procedure to run
567 @param CpuIndex Target CPU Index
568 @param ProcArguments The parameter to pass to the procedure
569
570 @retval EFI_INVALID_PARAMETER CpuNumber not valid
571 @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
572 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
573 @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
574 @retval EFI_SUCCESS The procedure has been successfully scheduled
575
576 **/
577 EFI_STATUS
578 EFIAPI
579 SmmBlockingStartupThisAp (
580 IN EFI_AP_PROCEDURE Procedure,
581 IN UINTN CpuIndex,
582 IN OUT VOID *ProcArguments OPTIONAL
583 );
584
585 /**
586 This function sets the attributes for the memory region specified by BaseAddress and
587 Length from their current attributes to the attributes specified by Attributes.
588
589 @param[in] BaseAddress The physical address that is the start address of a memory region.
590 @param[in] Length The size in bytes of the memory region.
591 @param[in] Attributes The bit mask of attributes to set for the memory region.
592
593 @retval EFI_SUCCESS The attributes were set for the memory region.
594 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
595 BaseAddress and Length cannot be modified.
596 @retval EFI_INVALID_PARAMETER Length is zero.
597 Attributes specified an illegal combination of attributes that
598 cannot be set together.
599 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
600 the memory resource range.
601 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
602 resource range specified by BaseAddress and Length.
603 The bit mask of attributes is not support for the memory resource
604 range specified by BaseAddress and Length.
605
606 **/
607 EFI_STATUS
608 EFIAPI
609 SmmSetMemoryAttributes (
610 IN EFI_PHYSICAL_ADDRESS BaseAddress,
611 IN UINT64 Length,
612 IN UINT64 Attributes
613 );
614
615 /**
616 This function clears the attributes for the memory region specified by BaseAddress and
617 Length from their current attributes to the attributes specified by Attributes.
618
619 @param[in] BaseAddress The physical address that is the start address of a memory region.
620 @param[in] Length The size in bytes of the memory region.
621 @param[in] Attributes The bit mask of attributes to clear for the memory region.
622
623 @retval EFI_SUCCESS The attributes were cleared for the memory region.
624 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
625 BaseAddress and Length cannot be modified.
626 @retval EFI_INVALID_PARAMETER Length is zero.
627 Attributes specified an illegal combination of attributes that
628 cannot be set together.
629 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
630 the memory resource range.
631 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
632 resource range specified by BaseAddress and Length.
633 The bit mask of attributes is not support for the memory resource
634 range specified by BaseAddress and Length.
635
636 **/
637 EFI_STATUS
638 EFIAPI
639 SmmClearMemoryAttributes (
640 IN EFI_PHYSICAL_ADDRESS BaseAddress,
641 IN UINT64 Length,
642 IN UINT64 Attributes
643 );
644
645 /**
646 Initialize MP synchronization data.
647
648 **/
649 VOID
650 EFIAPI
651 InitializeMpSyncData (
652 VOID
653 );
654
655 /**
656
657 Find out SMRAM information including SMRR base and SMRR size.
658
659 @param SmrrBase SMRR base
660 @param SmrrSize SMRR size
661
662 **/
663 VOID
664 FindSmramInfo (
665 OUT UINT32 *SmrrBase,
666 OUT UINT32 *SmrrSize
667 );
668
669 /**
670 Relocate SmmBases for each processor.
671
672 Execute on first boot and all S3 resumes
673
674 **/
675 VOID
676 EFIAPI
677 SmmRelocateBases (
678 VOID
679 );
680
681 /**
682 Page Fault handler for SMM use.
683
684 @param InterruptType Defines the type of interrupt or exception that
685 occurred on the processor.This parameter is processor architecture specific.
686 @param SystemContext A pointer to the processor context when
687 the interrupt occurred on the processor.
688 **/
689 VOID
690 EFIAPI
691 SmiPFHandler (
692 IN EFI_EXCEPTION_TYPE InterruptType,
693 IN EFI_SYSTEM_CONTEXT SystemContext
694 );
695
696 /**
697 Perform the remaining tasks.
698
699 **/
700 VOID
701 PerformRemainingTasks (
702 VOID
703 );
704
705 /**
706 Perform the pre tasks.
707
708 **/
709 VOID
710 PerformPreTasks (
711 VOID
712 );
713
714 /**
715 Initialize MSR spin lock by MSR index.
716
717 @param MsrIndex MSR index value.
718
719 **/
720 VOID
721 InitMsrSpinLockByIndex (
722 IN UINT32 MsrIndex
723 );
724
725 /**
726 Hook return address of SMM Save State so that semaphore code
727 can be executed immediately after AP exits SMM to indicate to
728 the BSP that an AP has exited SMM after SMBASE relocation.
729
730 @param[in] CpuIndex The processor index.
731 @param[in] RebasedFlag A pointer to a flag that is set to TRUE
732 immediately after AP exits SMM.
733
734 **/
735 VOID
736 SemaphoreHook (
737 IN UINTN CpuIndex,
738 IN volatile BOOLEAN *RebasedFlag
739 );
740
741 /**
742 Configure SMM Code Access Check feature for all processors.
743 SMM Feature Control MSR will be locked after configuration.
744 **/
745 VOID
746 ConfigSmmCodeAccessCheck (
747 VOID
748 );
749
750 /**
751 Hook the code executed immediately after an RSM instruction on the currently
752 executing CPU. The mode of code executed immediately after RSM must be
753 detected, and the appropriate hook must be selected. Always clear the auto
754 HALT restart flag if it is set.
755
756 @param[in] CpuIndex The processor index for the currently
757 executing CPU.
758 @param[in] CpuState Pointer to SMRAM Save State Map for the
759 currently executing CPU.
760 @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to
761 32-bit mode from 64-bit SMM.
762 @param[in] NewInstructionPointer Instruction pointer to use if resuming to
763 same mode as SMM.
764
765 @retval The value of the original instruction pointer before it was hooked.
766
767 **/
768 UINT64
769 EFIAPI
770 HookReturnFromSmm (
771 IN UINTN CpuIndex,
772 SMRAM_SAVE_STATE_MAP *CpuState,
773 UINT64 NewInstructionPointer32,
774 UINT64 NewInstructionPointer
775 );
776
777 /**
778 Get the size of the SMI Handler in bytes.
779
780 @retval The size, in bytes, of the SMI Handler.
781
782 **/
783 UINTN
784 EFIAPI
785 GetSmiHandlerSize (
786 VOID
787 );
788
789 /**
790 Install the SMI handler for the CPU specified by CpuIndex. This function
791 is called by the CPU that was elected as monarch during System Management
792 Mode initialization.
793
794 @param[in] CpuIndex The index of the CPU to install the custom SMI handler.
795 The value must be between 0 and the NumberOfCpus field
796 in the System Management System Table (SMST).
797 @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex.
798 @param[in] SmiStack The stack to use when an SMI is processed by the
799 the CPU specified by CpuIndex.
800 @param[in] StackSize The size, in bytes, if the stack used when an SMI is
801 processed by the CPU specified by CpuIndex.
802 @param[in] GdtBase The base address of the GDT to use when an SMI is
803 processed by the CPU specified by CpuIndex.
804 @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is
805 processed by the CPU specified by CpuIndex.
806 @param[in] IdtBase The base address of the IDT to use when an SMI is
807 processed by the CPU specified by CpuIndex.
808 @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is
809 processed by the CPU specified by CpuIndex.
810 @param[in] Cr3 The base address of the page tables to use when an SMI
811 is processed by the CPU specified by CpuIndex.
812 **/
813 VOID
814 EFIAPI
815 InstallSmiHandler (
816 IN UINTN CpuIndex,
817 IN UINT32 SmBase,
818 IN VOID *SmiStack,
819 IN UINTN StackSize,
820 IN UINTN GdtBase,
821 IN UINTN GdtSize,
822 IN UINTN IdtBase,
823 IN UINTN IdtSize,
824 IN UINT32 Cr3
825 );
826
827 /**
828 Search module name by input IP address and output it.
829
830 @param CallerIpAddress Caller instruction pointer.
831
832 **/
833 VOID
834 DumpModuleInfoByIp (
835 IN UINTN CallerIpAddress
836 );
837
838 /**
839 This function sets memory attribute according to MemoryAttributesTable.
840 **/
841 VOID
842 SetMemMapAttributes (
843 VOID
844 );
845
846 /**
847 This function sets UEFI memory attribute according to UEFI memory map.
848 **/
849 VOID
850 SetUefiMemMapAttributes (
851 VOID
852 );
853
854 /**
855 Return if the Address is forbidden as SMM communication buffer.
856
857 @param[in] Address the address to be checked
858
859 @return TRUE The address is forbidden as SMM communication buffer.
860 @return FALSE The address is allowed as SMM communication buffer.
861 **/
862 BOOLEAN
863 IsSmmCommBufferForbiddenAddress (
864 IN UINT64 Address
865 );
866
867 /**
868 This function caches the UEFI memory map information.
869 **/
870 VOID
871 GetUefiMemoryMap (
872 VOID
873 );
874
875 /**
876 This function sets memory attribute for page table.
877 **/
878 VOID
879 SetPageTableAttributes (
880 VOID
881 );
882
883 /**
884 Return page table base.
885
886 @return page table base.
887 **/
888 UINTN
889 GetPageTableBase (
890 VOID
891 );
892
893 /**
894 This function sets the attributes for the memory region specified by BaseAddress and
895 Length from their current attributes to the attributes specified by Attributes.
896
897 @param[in] BaseAddress The physical address that is the start address of a memory region.
898 @param[in] Length The size in bytes of the memory region.
899 @param[in] Attributes The bit mask of attributes to set for the memory region.
900 @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted.
901
902 @retval EFI_SUCCESS The attributes were set for the memory region.
903 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
904 BaseAddress and Length cannot be modified.
905 @retval EFI_INVALID_PARAMETER Length is zero.
906 Attributes specified an illegal combination of attributes that
907 cannot be set together.
908 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
909 the memory resource range.
910 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
911 resource range specified by BaseAddress and Length.
912 The bit mask of attributes is not support for the memory resource
913 range specified by BaseAddress and Length.
914
915 **/
916 EFI_STATUS
917 EFIAPI
918 SmmSetMemoryAttributesEx (
919 IN EFI_PHYSICAL_ADDRESS BaseAddress,
920 IN UINT64 Length,
921 IN UINT64 Attributes,
922 OUT BOOLEAN *IsSplitted OPTIONAL
923 );
924
925 /**
926 This function clears the attributes for the memory region specified by BaseAddress and
927 Length from their current attributes to the attributes specified by Attributes.
928
929 @param[in] BaseAddress The physical address that is the start address of a memory region.
930 @param[in] Length The size in bytes of the memory region.
931 @param[in] Attributes The bit mask of attributes to clear for the memory region.
932 @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted.
933
934 @retval EFI_SUCCESS The attributes were cleared for the memory region.
935 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
936 BaseAddress and Length cannot be modified.
937 @retval EFI_INVALID_PARAMETER Length is zero.
938 Attributes specified an illegal combination of attributes that
939 cannot be set together.
940 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
941 the memory resource range.
942 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
943 resource range specified by BaseAddress and Length.
944 The bit mask of attributes is not support for the memory resource
945 range specified by BaseAddress and Length.
946
947 **/
948 EFI_STATUS
949 EFIAPI
950 SmmClearMemoryAttributesEx (
951 IN EFI_PHYSICAL_ADDRESS BaseAddress,
952 IN UINT64 Length,
953 IN UINT64 Attributes,
954 OUT BOOLEAN *IsSplitted OPTIONAL
955 );
956
957 /**
958 This API provides a way to allocate memory for page table.
959
960 This API can be called more once to allocate memory for page tables.
961
962 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
963 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
964 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
965 returned.
966
967 @param Pages The number of 4 KB pages to allocate.
968
969 @return A pointer to the allocated buffer or NULL if allocation fails.
970
971 **/
972 VOID *
973 AllocatePageTableMemory (
974 IN UINTN Pages
975 );
976
977 /**
978 Allocate pages for code.
979
980 @param[in] Pages Number of pages to be allocated.
981
982 @return Allocated memory.
983 **/
984 VOID *
985 AllocateCodePages (
986 IN UINTN Pages
987 );
988
989 /**
990 Allocate aligned pages for code.
991
992 @param[in] Pages Number of pages to be allocated.
993 @param[in] Alignment The requested alignment of the allocation.
994 Must be a power of two.
995 If Alignment is zero, then byte alignment is used.
996
997 @return Allocated memory.
998 **/
999 VOID *
1000 AllocateAlignedCodePages (
1001 IN UINTN Pages,
1002 IN UINTN Alignment
1003 );
1004
1005
1006 //
1007 // S3 related global variable and function prototype.
1008 //
1009
1010 extern BOOLEAN mSmmS3Flag;
1011
1012 /**
1013 Initialize SMM S3 resume state structure used during S3 Resume.
1014
1015 @param[in] Cr3 The base address of the page tables to use in SMM.
1016
1017 **/
1018 VOID
1019 InitSmmS3ResumeState (
1020 IN UINT32 Cr3
1021 );
1022
1023 /**
1024 Get ACPI CPU data.
1025
1026 **/
1027 VOID
1028 GetAcpiCpuData (
1029 VOID
1030 );
1031
1032 /**
1033 Restore SMM Configuration in S3 boot path.
1034
1035 **/
1036 VOID
1037 RestoreSmmConfigurationInS3 (
1038 VOID
1039 );
1040
1041 /**
1042 Get ACPI S3 enable flag.
1043
1044 **/
1045 VOID
1046 GetAcpiS3EnableFlag (
1047 VOID
1048 );
1049
1050 /**
1051 Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.
1052
1053 @param[in] ApHltLoopCode The address of the safe hlt-loop function.
1054 @param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode.
1055 @param[in] NumberToFinishAddress Address of Semaphore of APs finish count.
1056
1057 **/
1058 VOID
1059 TransferApToSafeState (
1060 IN UINTN ApHltLoopCode,
1061 IN UINTN TopOfStack,
1062 IN UINTN NumberToFinishAddress
1063 );
1064
1065 /**
1066 This function set given attributes of the memory region specified by
1067 BaseAddress and Length.
1068
1069 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1070 @param BaseAddress The physical address that is the start address of
1071 a memory region.
1072 @param Length The size in bytes of the memory region.
1073 @param Attributes The bit mask of attributes to set for the memory
1074 region.
1075
1076 @retval EFI_SUCCESS The attributes were set for the memory region.
1077 @retval EFI_INVALID_PARAMETER Length is zero.
1078 Attributes specified an illegal combination of
1079 attributes that cannot be set together.
1080 @retval EFI_UNSUPPORTED The processor does not support one or more
1081 bytes of the memory resource range specified
1082 by BaseAddress and Length.
1083 The bit mask of attributes is not supported for
1084 the memory resource range specified by
1085 BaseAddress and Length.
1086
1087 **/
1088 EFI_STATUS
1089 EFIAPI
1090 EdkiiSmmSetMemoryAttributes (
1091 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
1092 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1093 IN UINT64 Length,
1094 IN UINT64 Attributes
1095 );
1096
1097 /**
1098 This function clears given attributes of the memory region specified by
1099 BaseAddress and Length.
1100
1101 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1102 @param BaseAddress The physical address that is the start address of
1103 a memory region.
1104 @param Length The size in bytes of the memory region.
1105 @param Attributes The bit mask of attributes to clear for the memory
1106 region.
1107
1108 @retval EFI_SUCCESS The attributes were cleared for the memory region.
1109 @retval EFI_INVALID_PARAMETER Length is zero.
1110 Attributes specified an illegal combination of
1111 attributes that cannot be cleared together.
1112 @retval EFI_UNSUPPORTED The processor does not support one or more
1113 bytes of the memory resource range specified
1114 by BaseAddress and Length.
1115 The bit mask of attributes is not supported for
1116 the memory resource range specified by
1117 BaseAddress and Length.
1118
1119 **/
1120 EFI_STATUS
1121 EFIAPI
1122 EdkiiSmmClearMemoryAttributes (
1123 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
1124 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1125 IN UINT64 Length,
1126 IN UINT64 Attributes
1127 );
1128
1129 /**
1130 This function retrieves the attributes of the memory region specified by
1131 BaseAddress and Length. If different attributes are got from different part
1132 of the memory region, EFI_NO_MAPPING will be returned.
1133
1134 @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
1135 @param BaseAddress The physical address that is the start address of
1136 a memory region.
1137 @param Length The size in bytes of the memory region.
1138 @param Attributes Pointer to attributes returned.
1139
1140 @retval EFI_SUCCESS The attributes got for the memory region.
1141 @retval EFI_INVALID_PARAMETER Length is zero.
1142 Attributes is NULL.
1143 @retval EFI_NO_MAPPING Attributes are not consistent cross the memory
1144 region.
1145 @retval EFI_UNSUPPORTED The processor does not support one or more
1146 bytes of the memory resource range specified
1147 by BaseAddress and Length.
1148
1149 **/
1150 EFI_STATUS
1151 EFIAPI
1152 EdkiiSmmGetMemoryAttributes (
1153 IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
1154 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1155 IN UINT64 Length,
1156 IN UINT64 *Attributes
1157 );
1158
1159 /**
1160 This function fixes up the address of the global variable or function
1161 referred in SmmInit assembly files to be the absoute address.
1162 **/
1163 VOID
1164 EFIAPI
1165 PiSmmCpuSmmInitFixupAddress (
1166 );
1167
1168 /**
1169 This function fixes up the address of the global variable or function
1170 referred in SmiEntry assembly files to be the absoute address.
1171 **/
1172 VOID
1173 EFIAPI
1174 PiSmmCpuSmiEntryFixupAddress (
1175 );
1176
1177 #endif