TianoCore EDK2 master
Loading...
Searching...
No Matches
S3Resume.c
Go to the documentation of this file.
1
14#include <PiPei.h>
15
16#include <Guid/AcpiS3Context.h>
19#include <Guid/EndOfS3Resume.h>
20#include <Guid/S3SmmInitDone.h>
21#include <Ppi/S3Resume2.h>
22#include <Ppi/SmmAccess.h>
24#include <Ppi/EndOfPeiPhase.h>
26#include <Ppi/MpServices2.h>
27
28#include <Library/DebugLib.h>
29#include <Library/BaseLib.h>
32#include <Library/HobLib.h>
35#include <Library/IoLib.h>
38#include <Library/PcdLib.h>
42#include <Library/MtrrLib.h>
43
44#include <Library/HobLib.h>
45#include <Library/LockBoxLib.h>
47
55#define STACK_ALIGN_DOWN(Ptr) \
56 ((UINTN)(Ptr) & ~(UINTN)(CPU_STACK_ALIGNMENT - 1))
57
58#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
59
60#pragma pack(1)
61typedef union {
62 struct {
63 UINT32 LimitLow : 16;
64 UINT32 BaseLow : 16;
65 UINT32 BaseMid : 8;
66 UINT32 Type : 4;
67 UINT32 System : 1;
68 UINT32 Dpl : 2;
69 UINT32 Present : 1;
70 UINT32 LimitHigh : 4;
71 UINT32 Software : 1;
72 UINT32 Reserved : 1;
73 UINT32 DefaultSize : 1;
74 UINT32 Granularity : 1;
75 UINT32 BaseHigh : 8;
76 } Bits;
77 UINT64 Uint64;
78} IA32_GDT;
79
80//
81// Page-Map Level-4 Offset (PML4) and
82// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
83//
84typedef union {
85 struct {
86 UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory
87 UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write
88 UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User
89 UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching
90 UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached
91 UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)
92 UINT64 Reserved : 1; // Reserved
93 UINT64 MustBeZero : 2; // Must Be Zero
94 UINT64 Available : 3; // Available for use by system software
95 UINT64 PageTableBaseAddress : 40; // Page Table Base Address
96 UINT64 AvabilableHigh : 11; // Available for use by system software
97 UINT64 Nx : 1; // No Execute bit
98 } Bits;
99 UINT64 Uint64;
101
102//
103// Page Table Entry 2MB
104//
105typedef union {
106 struct {
107 UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory
108 UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write
109 UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User
110 UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching
111 UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached
112 UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)
113 UINT64 Dirty : 1; // 0 = Not Dirty, 1 = written by processor on access to page
114 UINT64 MustBe1 : 1; // Must be 1
115 UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
116 UINT64 Available : 3; // Available for use by system software
117 UINT64 PAT : 1; //
118 UINT64 MustBeZero : 8; // Must be zero;
119 UINT64 PageTableBaseAddress : 31; // Page Table Base Address
120 UINT64 AvabilableHigh : 11; // Available for use by system software
121 UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution
122 } Bits;
123 UINT64 Uint64;
125
126//
127// Page Table Entry 1GB
128//
129typedef union {
130 struct {
131 UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory
132 UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write
133 UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User
134 UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching
135 UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached
136 UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)
137 UINT64 Dirty : 1; // 0 = Not Dirty, 1 = written by processor on access to page
138 UINT64 MustBe1 : 1; // Must be 1
139 UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
140 UINT64 Available : 3; // Available for use by system software
141 UINT64 PAT : 1; //
142 UINT64 MustBeZero : 17; // Must be zero;
143 UINT64 PageTableBaseAddress : 22; // Page Table Base Address
144 UINT64 AvabilableHigh : 11; // Available for use by system software
145 UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution
146 } Bits;
147 UINT64 Uint64;
149
150//
151// Define two type of smm communicate headers.
152// One for 32 bits PEI + 64 bits DXE, the other for 32 bits PEI + 32 bits DXE case.
153//
154typedef struct {
155 EFI_GUID HeaderGuid;
156 UINT32 MessageLength;
157 UINT8 Data[1];
159
160typedef struct {
161 EFI_GUID HeaderGuid;
162 UINT64 MessageLength;
163 UINT8 Data[1];
165
166#pragma pack()
167
168//
169// Function prototypes
170//
171
178typedef
179VOID
180(EFIAPI *ASM_TRANSFER_CONTROL)(
181 IN UINT32 S3WakingVector,
182 IN UINT32 AcpiLowMemoryBase
183 );
184
217EFIAPI
220 );
221
228VOID
229EFIAPI
231 IN UINT16 SelectorValue
232 );
233
234//
235// Globals
236//
238
239EFI_PEI_PPI_DESCRIPTOR mPpiList = {
240 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
241 &gEfiPeiS3Resume2PpiGuid,
242 &mS3ResumePpi
243};
244
245EFI_PEI_PPI_DESCRIPTOR mPpiListPostScriptTable = {
246 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
247 &gPeiPostScriptTablePpiGuid,
248 0
249};
250
251EFI_PEI_PPI_DESCRIPTOR mPpiListEndOfPeiTable = {
252 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
253 &gEfiEndOfPeiSignalPpiGuid,
254 0
255};
256
257EFI_PEI_PPI_DESCRIPTOR mPpiListS3SmmInitDoneTable = {
258 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
259 &gEdkiiS3SmmInitDoneGuid,
260 0
261};
262
263EFI_PEI_PPI_DESCRIPTOR mPpiListEndOfS3ResumeTable = {
264 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
265 &gEdkiiEndOfS3ResumeGuid,
266 0
267};
268
269//
270// Global Descriptor Table (GDT)
271//
273 /* selector { Global Segment Descriptor } */
274 /* 0x00 */ {
275 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
276 },
277 /* 0x08 */ {
278 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
279 },
280 /* 0x10 */ {
281 { 0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0 }
282 },
283 /* 0x18 */ {
284 { 0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0 }
285 },
286 /* 0x20 */ {
287 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
288 },
289 /* 0x28 */ {
290 { 0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 0, 1, 0 }
291 },
292 /* 0x30 */ {
293 { 0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 0, 1, 0 }
294 },
295 /* 0x38 */ {
296 { 0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0 }
297 },
298 /* 0x40 */ {
299 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
300 },
301};
302
303#define DATA_SEGEMENT_SELECTOR 0x18
304
305//
306// IA32 Gdt register
307//
308GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR mGdt = {
309 sizeof (mGdtEntries) - 1,
310 (UINTN)mGdtEntries
311};
312
321BOOLEAN
323 IN ACPI_S3_CONTEXT *AcpiS3Context
324 )
325{
327
328 Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)((UINTN)(AcpiS3Context->AcpiFacsTable));
329 if ((Facs == NULL) ||
331 ((Facs->FirmwareWakingVector == 0) && (Facs->XFirmwareWakingVector == 0)))
332 {
333 // Something wrong with FACS
334 return FALSE;
335 }
336
337 if (Facs->XFirmwareWakingVector != 0) {
339 ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) &&
340 ((Facs->OspmFlags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0))
341 {
342 // Both BIOS and OS wants 64bit vector
343 ASSERT ((FeaturePcdGet (PcdDxeIplSwitchToLongMode)) || (sizeof (UINTN) == sizeof (UINT64)));
344 return TRUE;
345 }
346 }
347
348 return FALSE;
349}
350
357VOID
359 IN EFI_GUID *HandlerType
360 )
361{
362 EFI_STATUS Status;
363 EFI_PEI_SMM_COMMUNICATION_PPI *SmmCommunicationPpi;
364 UINTN CommSize;
367 VOID *CommBuffer;
368
369 DEBUG ((DEBUG_INFO, "Signal %g to SMM - Enter\n", HandlerType));
370
371 //
372 // This buffer consumed in DXE phase, so base on DXE mode to prepare communicate buffer.
373 // Detect whether DXE is 64 bits mode.
374 // if (sizeof(UINTN) == sizeof(UINT64), PEI already 64 bits, assume DXE also 64 bits.
375 // or (FeaturePcdGet (PcdDxeIplSwitchToLongMode)), DXE will switch to 64 bits.
376 //
377 if ((sizeof (UINTN) == sizeof (UINT64)) || (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
378 CommBuffer = &Header64;
379 Header64.MessageLength = 0;
380 CommSize = OFFSET_OF (SMM_COMMUNICATE_HEADER_64, Data);
381 } else {
382 CommBuffer = &Header32;
383 Header32.MessageLength = 0;
384 CommSize = OFFSET_OF (SMM_COMMUNICATE_HEADER_32, Data);
385 }
386
387 CopyGuid (CommBuffer, HandlerType);
388
389 Status = PeiServicesLocatePpi (
390 &gEfiPeiSmmCommunicationPpiGuid,
391 0,
392 NULL,
393 (VOID **)&SmmCommunicationPpi
394 );
395 if (EFI_ERROR (Status)) {
396 DEBUG ((DEBUG_ERROR, "Locate Smm Communicate Ppi failed (%r)!\n", Status));
397 return;
398 }
399
400 Status = SmmCommunicationPpi->Communicate (
401 SmmCommunicationPpi,
402 (VOID *)CommBuffer,
403 &CommSize
404 );
405 if (EFI_ERROR (Status)) {
406 DEBUG ((DEBUG_ERROR, "SmmCommunicationPpi->Communicate return failure (%r)!\n", Status));
407 }
408
409 DEBUG ((DEBUG_INFO, "Signal %g to SMM - Exit (%r)\n", HandlerType, Status));
410 return;
411}
412
420VOID
421EFIAPI
423 IN ACPI_S3_CONTEXT *AcpiS3Context,
424 IN PEI_S3_RESUME_STATE *PeiS3ResumeState
425 )
426{
427 EFI_STATUS Status;
430 UINTN TempStackTop;
431 UINTN TempStack[0x10];
432
433 //
434 // Restore IDT
435 //
436 AsmWriteIdtr (&PeiS3ResumeState->Idtr);
437
438 if (PeiS3ResumeState->ReturnStatus != EFI_SUCCESS) {
439 //
440 // Report Status code that boot script execution is failed
441 //
443 EFI_ERROR_CODE | EFI_ERROR_MINOR,
444 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR)
445 );
446 }
447
448 //
449 // NOTE: Because Debug Timer interrupt and system interrupts will be disabled
450 // in BootScriptExecuteDxe, the rest code in S3ResumeBootOs() cannot be halted
451 // by soft debugger.
452 //
453
454 PERF_INMODULE_END ("ScriptExec");
455
456 //
457 // Install BootScriptDonePpi
458 //
459 PERF_INMODULE_BEGIN ("BootScriptDonePpi");
460
461 Status = PeiServicesInstallPpi (&mPpiListPostScriptTable);
462 ASSERT_EFI_ERROR (Status);
463
464 PERF_INMODULE_END ("BootScriptDonePpi");
465
466 //
467 // Get ACPI Table Address
468 //
469 Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)((UINTN)(AcpiS3Context->AcpiFacsTable));
470
471 if ((Facs == NULL) ||
473 ((Facs->FirmwareWakingVector == 0) && (Facs->XFirmwareWakingVector == 0)))
474 {
475 //
476 // Report Status code that no valid vector is found
477 //
479 EFI_ERROR_CODE | EFI_ERROR_MAJOR,
480 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR)
481 );
482 CpuDeadLoop ();
483 return;
484 }
485
486 //
487 // Install EndOfPeiPpi
488 //
489 PERF_INMODULE_BEGIN ("EndOfPeiPpi");
490
491 Status = PeiServicesInstallPpi (&mPpiListEndOfPeiTable);
492 ASSERT_EFI_ERROR (Status);
493
494 PERF_INMODULE_END ("EndOfPeiPpi");
495
496 PERF_INMODULE_BEGIN ("EndOfS3Resume");
497
498 DEBUG ((DEBUG_INFO, "Signal EndOfS3Resume\n"));
499
500 //
501 // Install EndOfS3Resume.
502 //
503 Status = PeiServicesInstallPpi (&mPpiListEndOfS3ResumeTable);
504 ASSERT_EFI_ERROR (Status);
505
506 //
507 // Signal EndOfS3Resume to SMM.
508 //
509 SignalToSmmByCommunication (&gEdkiiEndOfS3ResumeGuid);
510
511 PERF_INMODULE_END ("EndOfS3Resume");
512
513 //
514 // report status code on S3 resume
515 //
516 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE);
517
518 AsmTransferControl = (ASM_TRANSFER_CONTROL)(UINTN)PeiS3ResumeState->AsmTransferControl;
519 if (Facs->XFirmwareWakingVector != 0) {
520 //
521 // Switch to native waking vector
522 //
523 TempStackTop = (UINTN)&TempStack + sizeof (TempStack);
524 DEBUG ((
525 DEBUG_INFO,
526 "%a() Stack Base: 0x%x, Stack Size: 0x%x\n",
527 __func__,
528 TempStackTop,
529 sizeof (TempStack)
530 ));
532 ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) &&
533 ((Facs->OspmFlags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0))
534 {
535 //
536 // X64 long mode waking vector
537 //
538 DEBUG ((DEBUG_INFO, "Transfer from PEI to 64bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));
539 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
540 //
541 // 32bit PEI calls to 64bit OS S3 waking vector
542 //
544 0x38,
545 Facs->XFirmwareWakingVector,
546 0,
547 0,
548 (UINT64)(UINTN)TempStackTop
549 );
550 } else {
551 if (sizeof (UINTN) == sizeof (UINT64)) {
552 //
553 // 64bit PEI calls to 64bit OS S3 waking vector
554 //
556 (SWITCH_STACK_ENTRY_POINT)(UINTN)Facs->XFirmwareWakingVector,
557 NULL,
558 NULL,
559 (VOID *)(UINTN)TempStackTop
560 );
561 } else {
562 //
563 // Report Status code that no valid waking vector is found.
564 // Note: 32bit PEI + 32bit DXE firmware calling to 64bit OS S3 waking vector is an invalid configuration.
565 //
567 EFI_ERROR_CODE | EFI_ERROR_MAJOR,
568 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR)
569 );
570 DEBUG ((DEBUG_ERROR, "Unsupported for 32bit DXE transfer to 64bit OS waking vector!\r\n"));
571 ASSERT (FALSE);
572 CpuDeadLoop ();
573 return;
574 }
575 }
576 } else {
577 //
578 // IA32 protected mode waking vector (Page disabled)
579 //
580 DEBUG ((DEBUG_INFO, "Transfer to 32bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));
581 if (sizeof (UINTN) == sizeof (UINT64)) {
582 //
583 // 64bit PEI calls to 32bit OS S3 waking vector
584 //
586 0x10,
587 (UINT32)Facs->XFirmwareWakingVector,
588 0,
589 0,
590 (UINT32)TempStackTop
591 );
592 } else {
593 //
594 // 32bit PEI calls to 32bit OS S3 waking vector
595 //
597 (SWITCH_STACK_ENTRY_POINT)(UINTN)Facs->XFirmwareWakingVector,
598 NULL,
599 NULL,
600 (VOID *)(UINTN)TempStackTop
601 );
602 }
603 }
604 } else {
605 //
606 // 16bit Realmode waking vector
607 //
608 DEBUG ((DEBUG_INFO, "Transfer to 16bit OS waking vector - %x\r\n", (UINTN)Facs->FirmwareWakingVector));
609 AsmTransferControl (Facs->FirmwareWakingVector, 0x0);
610 }
611
612 //
613 // Report Status code the failure of S3Resume
614 //
616 EFI_ERROR_CODE | EFI_ERROR_MAJOR,
617 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR)
618 );
619
620 //
621 // Never run to here
622 //
623 CpuDeadLoop ();
624}
625
633VOID
635 IN UINTN S3NvsPageTableAddress,
636 IN BOOLEAN Build4GPageTableOnly
637 )
638{
639 if ((FeaturePcdGet (PcdDxeIplSwitchToLongMode)) || (sizeof (UINTN) == sizeof (UINT64))) {
640 UINT32 RegEax;
641 UINT32 RegEdx;
642 UINT8 PhysicalAddressBits;
643 EFI_PHYSICAL_ADDRESS PageAddress;
644 UINTN IndexOfPml4Entries;
645 UINTN IndexOfPdpEntries;
646 UINTN IndexOfPageDirectoryEntries;
647 UINT32 NumberOfPml4EntriesNeeded;
648 UINT32 NumberOfPdpEntriesNeeded;
649 PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
651 PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
652 PAGE_TABLE_ENTRY *PageDirectoryEntry;
653 VOID *Hob;
654 BOOLEAN Page1GSupport;
655 PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
656 UINT64 AddressEncMask;
657
658 //
659 // Make sure AddressEncMask is contained to smallest supported address field
660 //
661 AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
662
663 //
664 // NOTE: We have to ASSUME the page table generation format, because we do not know whole page table information.
665 // The whole page table is too large to be saved in SMRAM.
666 //
667 // The assumption is : whole page table is allocated in CONTINUOUS memory and CR3 points to TOP page.
668 //
669 DEBUG ((DEBUG_INFO, "S3NvsPageTableAddress - %x (%x)\n", (UINTN)S3NvsPageTableAddress, (UINTN)Build4GPageTableOnly));
670
671 //
672 // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
673 //
674 PageMap = (PAGE_MAP_AND_DIRECTORY_POINTER *)S3NvsPageTableAddress;
675 S3NvsPageTableAddress += SIZE_4KB;
676
677 Page1GSupport = FALSE;
678 if (PcdGetBool (PcdUse1GPageTable)) {
679 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
680 if (RegEax >= 0x80000001) {
681 AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
682 if ((RegEdx & BIT26) != 0) {
683 Page1GSupport = TRUE;
684 }
685 }
686 }
687
688 //
689 // Get physical address bits supported.
690 //
691 Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
692 if (Hob != NULL) {
693 PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
694 } else {
695 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
696 if (RegEax >= 0x80000008) {
697 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
698 PhysicalAddressBits = (UINT8)RegEax;
699 } else {
700 PhysicalAddressBits = 36;
701 }
702 }
703
704 //
705 // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
706 //
707 ASSERT (PhysicalAddressBits <= 52);
708 if (PhysicalAddressBits > 48) {
709 PhysicalAddressBits = 48;
710 }
711
712 //
713 // NOTE: In order to save time to create full page table, we just create 4G page table by default.
714 // And let PF handler in BootScript driver to create more on request.
715 //
716 if (Build4GPageTableOnly) {
717 PhysicalAddressBits = 32;
718 ZeroMem (PageMap, EFI_PAGES_TO_SIZE (2));
719 }
720
721 //
722 // Calculate the table entries needed.
723 //
724 if (PhysicalAddressBits <= 39) {
725 NumberOfPml4EntriesNeeded = 1;
726 NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
727 } else {
728 NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));
729 NumberOfPdpEntriesNeeded = 512;
730 }
731
732 PageMapLevel4Entry = PageMap;
733 PageAddress = 0;
734 for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {
735 //
736 // Each PML4 entry points to a page of Page Directory Pointer entires.
737 // So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
738 //
739 PageDirectoryPointerEntry = (PAGE_MAP_AND_DIRECTORY_POINTER *)S3NvsPageTableAddress;
740 S3NvsPageTableAddress += SIZE_4KB;
741
742 //
743 // Make a PML4 Entry
744 //
745 PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask;
746 PageMapLevel4Entry->Bits.ReadWrite = 1;
747 PageMapLevel4Entry->Bits.Present = 1;
748
749 if (Page1GSupport) {
750 PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry;
751
752 for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
753 //
754 // Fill in the Page Directory entries
755 //
756 PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | AddressEncMask;
757 PageDirectory1GEntry->Bits.ReadWrite = 1;
758 PageDirectory1GEntry->Bits.Present = 1;
759 PageDirectory1GEntry->Bits.MustBe1 = 1;
760 }
761 } else {
762 for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
763 //
764 // Each Directory Pointer entries points to a page of Page Directory entires.
765 // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
766 //
767 PageDirectoryEntry = (PAGE_TABLE_ENTRY *)S3NvsPageTableAddress;
768 S3NvsPageTableAddress += SIZE_4KB;
769
770 //
771 // Fill in a Page Directory Pointer Entries
772 //
773 PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask;
774 PageDirectoryPointerEntry->Bits.ReadWrite = 1;
775 PageDirectoryPointerEntry->Bits.Present = 1;
776
777 for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
778 //
779 // Fill in the Page Directory entries
780 //
781 PageDirectoryEntry->Uint64 = (UINT64)PageAddress | AddressEncMask;
782 PageDirectoryEntry->Bits.ReadWrite = 1;
783 PageDirectoryEntry->Bits.Present = 1;
784 PageDirectoryEntry->Bits.MustBe1 = 1;
785 }
786 }
787 }
788 }
789
790 return;
791 } else {
792 //
793 // If DXE is running 32-bit mode, no need to establish page table.
794 //
795 return;
796 }
797}
798
808VOID
809EFIAPI
811 IN ACPI_S3_CONTEXT *AcpiS3Context,
812 IN BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable
813 )
814{
815 EFI_STATUS Status;
816 PEI_SMM_ACCESS_PPI *SmmAccess;
817 UINTN Index;
818 VOID *GuidHob;
819 PEI_S3_RESUME_STATE *PeiS3ResumeState;
820 BOOLEAN InterruptStatus;
821
822 DEBUG ((DEBUG_INFO, "S3ResumeExecuteBootScript()\n"));
823
824 //
825 // Attempt to use content from SMRAM first
826 //
827 GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);
828 if (GuidHob != NULL) {
829 //
830 // Last step for SMM - send SMI for initialization
831 //
832
833 //
834 // Send SMI to APs
835 //
837 //
838 // Send SMI to BSP
839 //
841
842 Status = PeiServicesLocatePpi (
843 &gPeiSmmAccessPpiGuid,
844 0,
845 NULL,
846 (VOID **)&SmmAccess
847 );
848 if (!EFI_ERROR (Status)) {
849 DEBUG ((DEBUG_INFO, "Close all SMRAM regions before executing boot script\n"));
850
851 for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
852 Status = SmmAccess->Close ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);
853 }
854
855 DEBUG ((DEBUG_INFO, "Lock all SMRAM regions before executing boot script\n"));
856
857 for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
858 Status = SmmAccess->Lock ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);
859 }
860 }
861
862 DEBUG ((DEBUG_INFO, "Signal S3SmmInitDone\n"));
863 //
864 // Install S3SmmInitDone PPI.
865 //
866 Status = PeiServicesInstallPpi (&mPpiListS3SmmInitDoneTable);
867 ASSERT_EFI_ERROR (Status);
868 //
869 // Signal S3SmmInitDone to SMM.
870 //
871 SignalToSmmByCommunication (&gEdkiiS3SmmInitDoneGuid);
872 }
873
874 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
875 AsmWriteCr3 ((UINTN)AcpiS3Context->S3NvsPageTableAddress);
876 }
877
878 InterruptStatus = SaveAndDisableInterrupts ();
879 //
880 // Need to make sure the GDT is loaded with values that support long mode and real mode.
881 //
882 AsmWriteGdtr (&mGdt);
883 //
884 // update segment selectors per the new GDT.
885 //
886 AsmSetDataSelectors (DATA_SEGEMENT_SELECTOR);
887 //
888 // Restore interrupt state.
889 //
890 SetInterruptState (InterruptStatus);
891
892 //
893 // Prepare data for return back
894 //
895 PeiS3ResumeState = AllocatePool (sizeof (*PeiS3ResumeState));
896 if (PeiS3ResumeState == NULL) {
898 EFI_ERROR_CODE | EFI_ERROR_MAJOR,
899 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_FAILED)
900 );
901 ASSERT (FALSE);
902 }
903
904 DEBUG ((DEBUG_INFO, "PeiS3ResumeState - %x\r\n", PeiS3ResumeState));
905 PeiS3ResumeState->ReturnCs = 0x10;
906 PeiS3ResumeState->ReturnEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)S3ResumeBootOs;
907 PeiS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status);
908 //
909 // Save IDT
910 //
911 AsmReadIdtr (&PeiS3ResumeState->Idtr);
912
913 //
914 // Report Status Code to indicate S3 boot script execution
915 //
916 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_BOOT_SCRIPT);
917
918 PERF_INMODULE_BEGIN ("ScriptExec");
919
920 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
921 //
922 // X64 S3 Resume
923 //
924 DEBUG ((DEBUG_INFO, "Enable X64 and transfer control to Standalone Boot Script Executor\r\n"));
925
926 //
927 // Switch to long mode to complete resume.
928 //
930 0x38,
931 EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint,
932 (UINT64)(UINTN)AcpiS3Context,
933 (UINT64)(UINTN)PeiS3ResumeState,
934 (UINT64)(UINTN)(AcpiS3Context->BootScriptStackBase + AcpiS3Context->BootScriptStackSize)
935 );
936 } else {
937 //
938 // IA32 S3 Resume
939 //
940 DEBUG ((DEBUG_INFO, "transfer control to Standalone Boot Script Executor\r\n"));
942 (SWITCH_STACK_ENTRY_POINT)(UINTN)EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint,
943 (VOID *)AcpiS3Context,
944 (VOID *)PeiS3ResumeState,
945 (VOID *)(UINTN)(AcpiS3Context->BootScriptStackBase + AcpiS3Context->BootScriptStackSize)
946 );
947 }
948
949 //
950 // Never run to here
951 //
952 CpuDeadLoop ();
953}
954
960VOID
961EFIAPI
963 IN VOID *MtrrTable
964 )
965{
966 MtrrSetAllMtrrs (MtrrTable);
967}
968
1001EFIAPI
1004 )
1005{
1006 EFI_STATUS Status;
1007 PEI_SMM_ACCESS_PPI *SmmAccess;
1008 UINTN Index;
1009 ACPI_S3_CONTEXT *AcpiS3Context;
1010 EFI_PHYSICAL_ADDRESS TempEfiBootScriptExecutorVariable;
1011 EFI_PHYSICAL_ADDRESS TempAcpiS3Context;
1012 BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable;
1013 UINTN VarSize;
1014 EFI_SMRAM_DESCRIPTOR *SmramDescriptor;
1015 SMM_S3_RESUME_STATE *SmmS3ResumeState;
1016 VOID *GuidHob;
1017 BOOLEAN Build4GPageTableOnly;
1018 BOOLEAN InterruptStatus;
1019 IA32_CR0 Cr0;
1020 EDKII_PEI_MP_SERVICES2_PPI *MpService2Ppi;
1021 MTRR_SETTINGS MtrrTable;
1022
1023 TempAcpiS3Context = 0;
1024 TempEfiBootScriptExecutorVariable = 0;
1025
1026 DEBUG ((DEBUG_INFO, "Enter S3 PEIM\r\n"));
1027
1028 VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
1029 Status = RestoreLockBox (
1030 &gEfiAcpiVariableGuid,
1031 &TempAcpiS3Context,
1032 &VarSize
1033 );
1034 ASSERT_EFI_ERROR (Status);
1035
1036 Status = RestoreLockBox (
1037 &gEfiAcpiS3ContextGuid,
1038 NULL,
1039 NULL
1040 );
1041 ASSERT_EFI_ERROR (Status);
1042
1043 AcpiS3Context = (ACPI_S3_CONTEXT *)(UINTN)TempAcpiS3Context;
1044 ASSERT (AcpiS3Context != NULL);
1045
1046 VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
1047 Status = RestoreLockBox (
1048 &gEfiBootScriptExecutorVariableGuid,
1049 &TempEfiBootScriptExecutorVariable,
1050 &VarSize
1051 );
1052 ASSERT_EFI_ERROR (Status);
1053
1054 Status = RestoreLockBox (
1055 &gEfiBootScriptExecutorContextGuid,
1056 NULL,
1057 NULL
1058 );
1059 ASSERT_EFI_ERROR (Status);
1060
1061 EfiBootScriptExecutorVariable = (BOOT_SCRIPT_EXECUTOR_VARIABLE *)(UINTN)TempEfiBootScriptExecutorVariable;
1062 ASSERT (EfiBootScriptExecutorVariable != NULL);
1063
1064 DEBUG ((DEBUG_INFO, "AcpiS3Context = %x\n", AcpiS3Context));
1065 DEBUG ((DEBUG_INFO, "Waking Vector = %x\n", ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)((UINTN)(AcpiS3Context->AcpiFacsTable)))->FirmwareWakingVector));
1066 DEBUG ((DEBUG_INFO, "AcpiS3Context->AcpiFacsTable = %x\n", AcpiS3Context->AcpiFacsTable));
1067 DEBUG ((DEBUG_INFO, "AcpiS3Context->IdtrProfile = %x\n", AcpiS3Context->IdtrProfile));
1068 DEBUG ((DEBUG_INFO, "AcpiS3Context->S3NvsPageTableAddress = %x\n", AcpiS3Context->S3NvsPageTableAddress));
1069 DEBUG ((DEBUG_INFO, "AcpiS3Context->S3DebugBufferAddress = %x\n", AcpiS3Context->S3DebugBufferAddress));
1070 DEBUG ((DEBUG_INFO, "AcpiS3Context->BootScriptStackBase = %x\n", AcpiS3Context->BootScriptStackBase));
1071 DEBUG ((DEBUG_INFO, "AcpiS3Context->BootScriptStackSize = %x\n", AcpiS3Context->BootScriptStackSize));
1072 DEBUG ((DEBUG_INFO, "EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = %x\n", EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint));
1073
1074 //
1075 // Additional step for BootScript integrity - we only handle BootScript and BootScriptExecutor.
1076 // Script dispatch image and context (parameter) are handled by platform.
1077 // We just use restore all lock box in place, no need restore one by one.
1078 //
1079 Status = RestoreAllLockBoxInPlace ();
1080 ASSERT_EFI_ERROR (Status);
1081 if (EFI_ERROR (Status)) {
1082 // Something wrong
1083 CpuDeadLoop ();
1084 }
1085
1086 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
1087 //
1088 // Need reconstruct page table here, since we do not trust ACPINvs.
1089 //
1090 if (IsLongModeWakingVector (AcpiS3Context)) {
1091 Build4GPageTableOnly = FALSE;
1092 } else {
1093 Build4GPageTableOnly = TRUE;
1094 }
1095
1096 RestoreS3PageTables ((UINTN)AcpiS3Context->S3NvsPageTableAddress, Build4GPageTableOnly);
1097 }
1098
1099 //
1100 // Attempt to use content from SMRAM first
1101 //
1102 GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);
1103 if (GuidHob != NULL) {
1104 Status = PeiServicesLocatePpi (
1105 &gPeiSmmAccessPpiGuid,
1106 0,
1107 NULL,
1108 (VOID **)&SmmAccess
1109 );
1110 for (Index = 0; !EFI_ERROR (Status); Index++) {
1111 Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);
1112 }
1113
1114 //
1115 // Get MP Services2 Ppi to pass it to Smm S3.
1116 //
1117 Status = PeiServicesLocatePpi (
1118 &gEdkiiPeiMpServices2PpiGuid,
1119 0,
1120 NULL,
1121 (VOID **)&MpService2Ppi
1122 );
1123 ASSERT_EFI_ERROR (Status);
1124
1125 //
1126 // Restore MTRR setting
1127 //
1128 VarSize = sizeof (MTRR_SETTINGS);
1129 Status = RestoreLockBox (
1130 &gEdkiiS3MtrrSettingGuid,
1131 &MtrrTable,
1132 &VarSize
1133 );
1134 ASSERT_EFI_ERROR (Status);
1135
1136 //
1137 // Sync up the MTRR values for all processors.
1138 //
1139 Status = MpService2Ppi->StartupAllCPUs (
1140 MpService2Ppi,
1142 0,
1143 (VOID *)&MtrrTable
1144 );
1145 ASSERT_EFI_ERROR (Status);
1146
1147 SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *)GET_GUID_HOB_DATA (GuidHob);
1148 SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart;
1149
1150 SmmS3ResumeState->ReturnCs = AsmReadCs ();
1151 SmmS3ResumeState->ReturnEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)S3ResumeExecuteBootScript;
1152 SmmS3ResumeState->ReturnContext1 = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context;
1153 SmmS3ResumeState->ReturnContext2 = (EFI_PHYSICAL_ADDRESS)(UINTN)EfiBootScriptExecutorVariable;
1154 SmmS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status);
1155
1156 DEBUG ((DEBUG_INFO, "SMM S3 Signature = %x\n", SmmS3ResumeState->Signature));
1157 DEBUG ((DEBUG_INFO, "SMM S3 Stack Base = %x\n", SmmS3ResumeState->SmmS3StackBase));
1158 DEBUG ((DEBUG_INFO, "SMM S3 Stack Size = %x\n", SmmS3ResumeState->SmmS3StackSize));
1159 DEBUG ((DEBUG_INFO, "SMM S3 Resume Entry Point = %x\n", SmmS3ResumeState->SmmS3ResumeEntryPoint));
1160 DEBUG ((DEBUG_INFO, "SMM S3 CR0 = %x\n", SmmS3ResumeState->SmmS3Cr0));
1161 DEBUG ((DEBUG_INFO, "SMM S3 CR3 = %x\n", SmmS3ResumeState->SmmS3Cr3));
1162 DEBUG ((DEBUG_INFO, "SMM S3 CR4 = %x\n", SmmS3ResumeState->SmmS3Cr4));
1163 DEBUG ((DEBUG_INFO, "SMM S3 Return CS = %x\n", SmmS3ResumeState->ReturnCs));
1164 DEBUG ((DEBUG_INFO, "SMM S3 Return Entry Point = %x\n", SmmS3ResumeState->ReturnEntryPoint));
1165 DEBUG ((DEBUG_INFO, "SMM S3 Return Context1 = %x\n", SmmS3ResumeState->ReturnContext1));
1166 DEBUG ((DEBUG_INFO, "SMM S3 Return Context2 = %x\n", SmmS3ResumeState->ReturnContext2));
1167 DEBUG ((DEBUG_INFO, "SMM S3 Return Stack Pointer = %x\n", SmmS3ResumeState->ReturnStackPointer));
1168 DEBUG ((DEBUG_INFO, "SMM S3 Smst = %x\n", SmmS3ResumeState->Smst));
1169
1170 //
1171 // 64bit PEI and 32bit DXE is not a supported combination.
1172 //
1173 if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) {
1174 ASSERT (sizeof (UINTN) == sizeof (UINT32));
1175 }
1176
1177 //
1178 // Directly do the switch stack when PEI and SMM env run in the same execution mode.
1179 //
1180 if (((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) && (sizeof (UINTN) == sizeof (UINT32))) ||
1181 ((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) && (sizeof (UINTN) == sizeof (UINT64))))
1182 {
1183 SwitchStack (
1184 (SWITCH_STACK_ENTRY_POINT)(UINTN)SmmS3ResumeState->SmmS3ResumeEntryPoint,
1185 (VOID *)AcpiS3Context,
1186 0,
1187 (VOID *)(UINTN)(SmmS3ResumeState->SmmS3StackBase + SmmS3ResumeState->SmmS3StackSize)
1188 );
1189 }
1190
1191 if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) {
1192 //
1193 // Switch to long mode to complete resume.
1194 //
1195
1196 InterruptStatus = SaveAndDisableInterrupts ();
1197 //
1198 // Need to make sure the GDT is loaded with values that support long mode and real mode.
1199 //
1200 AsmWriteGdtr (&mGdt);
1201 //
1202 // update segment selectors per the new GDT.
1203 //
1204 AsmSetDataSelectors (DATA_SEGEMENT_SELECTOR);
1205 //
1206 // Restore interrupt state.
1207 //
1208 SetInterruptState (InterruptStatus);
1209
1210 Cr0.UintN = AsmReadCr0 ();
1211 if (Cr0.Bits.PG != 0) {
1212 //
1213 // We're in 32-bit mode, with paging enabled. We can't set CR3 to
1214 // the 64-bit page tables without first disabling paging.
1215 //
1216 Cr0.Bits.PG = 0;
1217 AsmWriteCr0 (Cr0.UintN);
1218 }
1219
1220 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
1221 AsmWriteCr3 ((UINTN)SmmS3ResumeState->SmmS3Cr3);
1222 }
1223
1224 //
1225 // Disable interrupt of Debug timer, since IDT table cannot work in long mode.
1226 // NOTE: On x64 platforms, because DisablePaging64() will disable interrupts,
1227 // the code in S3ResumeExecuteBootScript() cannot be halted by soft debugger.
1228 //
1230
1232 0x38,
1233 SmmS3ResumeState->SmmS3ResumeEntryPoint,
1234 (UINT64)(UINTN)AcpiS3Context,
1235 0,
1236 SmmS3ResumeState->SmmS3StackBase + SmmS3ResumeState->SmmS3StackSize
1237 );
1238 }
1239 }
1240
1241 S3ResumeExecuteBootScript (AcpiS3Context, EfiBootScriptExecutorVariable);
1242 return EFI_SUCCESS;
1243}
1244
1257EFIAPI
1259 IN EFI_PEI_FILE_HANDLE FileHandle,
1260 IN CONST EFI_PEI_SERVICES **PeiServices
1261 )
1262{
1263 EFI_STATUS Status;
1264
1265 //
1266 // Install S3 Resume Ppi
1267 //
1268 Status = (**PeiServices).InstallPpi (PeiServices, &mPpiList);
1269 ASSERT_EFI_ERROR (Status);
1270
1271 return EFI_SUCCESS;
1272}
UINT64 UINTN
#define EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
Definition: Acpi40.h:1180
#define EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION
Definition: Acpi40.h:238
#define EFI_ACPI_4_0_OSPM_64BIT_WAKE__F
Definition: Acpi40.h:251
CONST EFI_PEI_SERVICES **EFIAPI GetPeiServicesTablePointer(VOID)
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
Definition: HobLib.c:142
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
BOOLEAN EFIAPI SetInterruptState(IN BOOLEAN InterruptState)
Definition: Cpu.c:48
BOOLEAN EFIAPI SaveAndDisableInterrupts(VOID)
Definition: Cpu.c:21
VOID EFIAPI SwitchStack(IN SWITCH_STACK_ENTRY_POINT EntryPoint, IN VOID *Context1 OPTIONAL, IN VOID *Context2 OPTIONAL, IN VOID *NewStack,...)
Definition: SwitchStack.c:42
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
VOID(EFIAPI * SWITCH_STACK_ENTRY_POINT)(IN VOID *Context1 OPTIONAL, IN VOID *Context2 OPTIONAL)
Definition: BaseLib.h:5019
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
BOOLEAN EFIAPI SaveAndSetDebugTimerInterrupt(IN BOOLEAN EnableStatus)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
UINTN EFIAPI AsmWriteCr3(UINTN Cr3)
UINTN EFIAPI AsmReadCr0(VOID)
UINTN EFIAPI AsmWriteCr0(UINTN Cr0)
UINT16 EFIAPI AsmReadCs(VOID)
VOID EFIAPI SendSmiIpi(IN UINT32 ApicId)
Definition: BaseXApicLib.c:427
UINT32 EFIAPI GetApicId(VOID)
Definition: BaseXApicLib.c:337
VOID EFIAPI SendSmiIpiAllExcludingSelf(VOID)
Definition: BaseXApicLib.c:446
RETURN_STATUS EFIAPI RestoreLockBox(IN GUID *Guid, IN VOID *Buffer OPTIONAL, IN OUT UINTN *Length OPTIONAL)
RETURN_STATUS EFIAPI RestoreAllLockBoxInPlace(VOID)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define REPORT_STATUS_CODE(Type, Value)
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuId.c:36
MTRR_SETTINGS *EFIAPI MtrrSetAllMtrrs(IN MTRR_SETTINGS *MtrrSetting)
Definition: MtrrLib.c:2908
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
#define PERF_INMODULE_BEGIN(MeasurementString)
#define PERF_INMODULE_END(MeasurementString)
VOID(EFIAPI * EFI_AP_PROCEDURE)(IN OUT VOID *Buffer)
Definition: PiMultiPhase.h:198
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
#define EFI_ERROR_MINOR
Definition: PiStatusCode.h:58
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:43
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI PeimS3ResumeEntryPoint(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
Definition: S3Resume.c:1258
VOID EFIAPI LoadMtrrData(IN VOID *MtrrTable)
Definition: S3Resume.c:962
VOID(EFIAPI * ASM_TRANSFER_CONTROL)(IN UINT32 S3WakingVector, IN UINT32 AcpiLowMemoryBase)
Definition: S3Resume.c:180
VOID SignalToSmmByCommunication(IN EFI_GUID *HandlerType)
Definition: S3Resume.c:358
#define STACK_ALIGN_DOWN(Ptr)
Definition: S3Resume.c:55
EFI_STATUS EFIAPI S3RestoreConfig2(IN EFI_PEI_S3_RESUME2_PPI *This)
Definition: S3Resume.c:1002
BOOLEAN IsLongModeWakingVector(IN ACPI_S3_CONTEXT *AcpiS3Context)
Definition: S3Resume.c:322
VOID EFIAPI S3ResumeBootOs(IN ACPI_S3_CONTEXT *AcpiS3Context, IN PEI_S3_RESUME_STATE *PeiS3ResumeState)
Definition: S3Resume.c:422
VOID RestoreS3PageTables(IN UINTN S3NvsPageTableAddress, IN BOOLEAN Build4GPageTableOnly)
Definition: S3Resume.c:634
VOID EFIAPI S3ResumeExecuteBootScript(IN ACPI_S3_CONTEXT *AcpiS3Context, IN BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable)
Definition: S3Resume.c:810
VOID EFIAPI AsmSetDataSelectors(IN UINT16 SelectorValue)
VOID AsmTransferControl(IN UINT32 S3WakingVector, IN UINT32 AcpiLowMemoryBase)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
VOID EFIAPI AsmDisablePaging64(IN UINT16 Cs, IN UINT32 EntryPoint, IN UINT32 Context1 OPTIONAL, IN UINT32 Context2 OPTIONAL, IN UINT32 NewStack)
VOID EFIAPI AsmEnablePaging64(IN UINT16 Cs, IN UINT64 EntryPoint, IN UINT64 Context1 OPTIONAL, IN UINT64 Context2 OPTIONAL, IN UINT64 NewStack)
VOID EFIAPI AsmReadIdtr(OUT IA32_DESCRIPTOR *Idtr)
Definition: X86ReadIdtr.c:24
VOID EFIAPI AsmWriteGdtr(IN CONST IA32_DESCRIPTOR *Gdtr)
VOID EFIAPI AsmWriteIdtr(IN CONST IA32_DESCRIPTOR *Idtr)
EFI_PHYSICAL_ADDRESS CpuStart
Definition: PiMultiPhase.h:127
Definition: Base.h:213