52 RscHob.Raw = HobStart;
53 MemHob.Raw = HobStart;
60 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
64 if ((RscHob.ResourceDescriptor->
ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
72 EFI_HOB_TYPE_MEMORY_ALLOCATION,
83 MemHob.Raw = GET_NEXT_HOB (MemHob);
89 RscHob.Raw = GET_NEXT_HOB (RscHob);
93 DEBUG ((DEBUG_INFO,
"Clearing first 4K-page!\r\n"));
112 return ((
PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) != 0);
133 if (RegEax >= 0x80000001) {
135 if ((RegEdx & BIT20) != 0) {
167 PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0 ||
168 PcdGet32 (PcdImageProtectionPolicy) != 0);
183 if ((MsrRegisters & BIT11) == 0) {
184 MsrRegisters |= BIT11;
218 if ((StackBase >= Address) && (StackBase < (Address + Size))) {
224 if ((Address < StackBase + StackSize) && ((Address + Size) > StackBase)) {
230 if ((Address < GhcbBase + GhcbSize) && ((Address + Size) > GhcbBase)) {
267 PoolPages = ((PoolPages - 1) / PAGE_TABLE_POOL_UNIT_PAGES + 1) *
268 PAGE_TABLE_POOL_UNIT_PAGES;
270 if (Buffer ==
NULL) {
271 DEBUG ((DEBUG_ERROR,
"ERROR: Out of aligned pages\r\n"));
278 if (mPageTablePool ==
NULL) {
279 mPageTablePool = Buffer;
280 mPageTablePool->NextPool = mPageTablePool;
283 mPageTablePool->NextPool = Buffer;
284 mPageTablePool = Buffer;
290 mPageTablePool->FreePages = PoolPages - 1;
327 if ((mPageTablePool ==
NULL) ||
328 (Pages > mPageTablePool->FreePages))
335 Buffer = (UINT8 *)mPageTablePool + mPageTablePool->Offset;
338 mPageTablePool->FreePages -= Pages;
357 IN OUT UINT64 *PageEntry2M,
365 UINTN IndexOfPageTableEntries;
367 UINT64 AddressEncMask;
372 AddressEncMask =
PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
375 ASSERT (PageTableEntry !=
NULL);
380 *PageEntry2M = (UINT64)(
UINTN)PageTableEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW;
382 PhysicalAddress4K = PhysicalAddress;
383 for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512; IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB) {
387 PageTableEntry->Uint64 = (UINT64)PhysicalAddress4K;
396 || (PhysicalAddress4K < GhcbBase)
397 || (PhysicalAddress4K >= GhcbBase + GhcbSize)
398 || (((PhysicalAddress4K - GhcbBase) & SIZE_4KB) != 0))
400 PageTableEntry->Uint64 |= AddressEncMask;
403 PageTableEntry->Bits.ReadWrite = 1;
406 (
PcdGetBool (PcdCpuStackGuard) && (PhysicalAddress4K == StackBase)))
408 PageTableEntry->Bits.Present = 0;
410 PageTableEntry->Bits.Present = 1;
414 && (PhysicalAddress4K >= StackBase)
415 && (PhysicalAddress4K < StackBase + StackSize))
420 PageTableEntry->Bits.Nx = 1;
439 IN OUT UINT64 *PageEntry1G,
447 UINTN IndexOfPageDirectoryEntries;
449 UINT64 AddressEncMask;
454 AddressEncMask =
PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
457 ASSERT (PageDirectoryEntry !=
NULL);
462 *PageEntry1G = (UINT64)(
UINTN)PageDirectoryEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW;
464 PhysicalAddress2M = PhysicalAddress;
465 for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) {
466 if (
ToSplitPageTable (PhysicalAddress2M, SIZE_2MB, StackBase, StackSize, GhcbBase, GhcbSize)) {
470 Split2MPageTo4K (PhysicalAddress2M, (UINT64 *)PageDirectoryEntry, StackBase, StackSize, GhcbBase, GhcbSize);
475 PageDirectoryEntry->Uint64 = (UINT64)PhysicalAddress2M | AddressEncMask;
476 PageDirectoryEntry->Bits.ReadWrite = 1;
477 PageDirectoryEntry->Bits.Present = 1;
478 PageDirectoryEntry->Bits.MustBe1 = 1;
495 IN BOOLEAN Level4Paging
500 UINT64 AddressEncMask;
503 UINT64 *NewPageTable;
511 ASSERT (PageTableBase != 0);
518 Address = Address & PAGE_TABLE_POOL_ALIGN_MASK;
520 LevelShift[1] = PAGING_L1_ADDRESS_SHIFT;
521 LevelShift[2] = PAGING_L2_ADDRESS_SHIFT;
522 LevelShift[3] = PAGING_L3_ADDRESS_SHIFT;
523 LevelShift[4] = PAGING_L4_ADDRESS_SHIFT;
525 LevelMask[1] = PAGING_4K_ADDRESS_MASK_64;
526 LevelMask[2] = PAGING_2M_ADDRESS_MASK_64;
527 LevelMask[3] = PAGING_1G_ADDRESS_MASK_64;
528 LevelMask[4] = PAGING_1G_ADDRESS_MASK_64;
530 LevelSize[1] = SIZE_4KB;
531 LevelSize[2] = SIZE_2MB;
532 LevelSize[3] = SIZE_1GB;
533 LevelSize[4] = SIZE_512GB;
535 AddressEncMask =
PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &
536 PAGING_1G_ADDRESS_MASK_64;
537 PageTable = (UINT64 *)(
UINTN)PageTableBase;
538 PoolUnitSize = PAGE_TABLE_POOL_UNIT_SIZE;
540 for (Level = (Level4Paging) ? 4 : 3; Level > 0; --Level) {
542 Index &= PAGING_PAE_INDEX_MASK;
544 PageAttr = PageTable[Index];
545 if ((PageAttr & IA32_PG_PS) == 0) {
549 PageTable = (UINT64 *)(
UINTN)(PageAttr & ~AddressEncMask &
550 PAGING_4K_ADDRESS_MASK_64);
554 if (PoolUnitSize >= LevelSize[Level]) {
559 if ((PageAttr & IA32_PG_RW) != 0) {
560 while (PoolUnitSize > 0) {
566 ASSERT (Index < EFI_PAGE_SIZE/
sizeof (UINT64));
568 PageTable[Index] &= ~(UINT64)IA32_PG_RW;
569 PoolUnitSize -= LevelSize[Level];
583 ASSERT (NewPageTable !=
NULL);
585 PhysicalAddress = PageAttr & LevelMask[Level];
587 EntryIndex < EFI_PAGE_SIZE/
sizeof (UINT64);
590 NewPageTable[EntryIndex] = PhysicalAddress | AddressEncMask |
591 IA32_PG_P | IA32_PG_RW;
593 NewPageTable[EntryIndex] |= IA32_PG_PS;
596 PhysicalAddress += LevelSize[Level - 1];
599 PageTable[Index] = (UINT64)(
UINTN)NewPageTable | AddressEncMask |
600 IA32_PG_P | IA32_PG_RW;
601 PageTable = NewPageTable;
616 IN BOOLEAN Level4Paging
624 if (mPageTablePool ==
NULL) {
633 HeadPool = mPageTablePool;
644 while (PoolSize > 0) {
646 Address += PAGE_TABLE_POOL_UNIT_SIZE;
647 PoolSize -= PAGE_TABLE_POOL_UNIT_SIZE;
650 Pool = Pool->NextPool;
651 }
while (Pool != HeadPool);
682 UINT8 PhysicalAddressBits;
684 UINTN IndexOfPml5Entries;
685 UINTN IndexOfPml4Entries;
686 UINTN IndexOfPdpEntries;
687 UINTN IndexOfPageDirectoryEntries;
688 UINT32 NumberOfPml5EntriesNeeded;
689 UINT32 NumberOfPml4EntriesNeeded;
690 UINT32 NumberOfPdpEntriesNeeded;
697 UINTN BigPageAddress;
699 BOOLEAN Page5LevelEnabled;
700 BOOLEAN Page1GSupport;
702 UINT64 AddressEncMask;
708 PageMapLevel5Entry =
NULL;
713 AddressEncMask =
PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
715 Page1GSupport =
FALSE;
718 if (RegEax >= 0x80000001) {
720 if ((RegEdx & BIT26) != 0) {
721 Page1GSupport =
TRUE;
731 PhysicalAddressBits = ((
EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
734 if (RegEax >= 0x80000008) {
736 PhysicalAddressBits = (UINT8)RegEax;
738 PhysicalAddressBits = 36;
742 if (
sizeof (
UINTN) ==
sizeof (UINT64)) {
747 Page5LevelEnabled = (Cr4.Bits.LA57 != 0);
748 if (Page5LevelEnabled) {
755 Page5LevelEnabled =
FALSE;
766 Page5LevelEnabled =
TRUE;
771 DEBUG ((DEBUG_INFO,
"AddressBits=%u 5LevelPaging=%u 1GPage=%u\n", PhysicalAddressBits, Page5LevelEnabled, Page1GSupport));
778 ASSERT (PhysicalAddressBits <= 52);
779 if (!Page5LevelEnabled && (PhysicalAddressBits > 48)) {
780 PhysicalAddressBits = 48;
786 NumberOfPml5EntriesNeeded = 1;
787 if (PhysicalAddressBits > 48) {
788 NumberOfPml5EntriesNeeded = (UINT32)
LShiftU64 (1, PhysicalAddressBits - 48);
789 PhysicalAddressBits = 48;
792 NumberOfPml4EntriesNeeded = 1;
793 if (PhysicalAddressBits > 39) {
794 NumberOfPml4EntriesNeeded = (UINT32)
LShiftU64 (1, PhysicalAddressBits - 39);
795 PhysicalAddressBits = 39;
798 NumberOfPdpEntriesNeeded = 1;
799 ASSERT (PhysicalAddressBits > 30);
800 NumberOfPdpEntriesNeeded = (UINT32)
LShiftU64 (1, PhysicalAddressBits - 30);
805 if (!Page1GSupport) {
806 TotalPagesNum = ((NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1) * NumberOfPml5EntriesNeeded + 1;
808 TotalPagesNum = (NumberOfPml4EntriesNeeded + 1) * NumberOfPml5EntriesNeeded + 1;
814 if (!Page5LevelEnabled) {
820 "Pml5=%u Pml4=%u Pdp=%u TotalPage=%Lu\n",
821 NumberOfPml5EntriesNeeded,
822 NumberOfPml4EntriesNeeded,
823 NumberOfPdpEntriesNeeded,
824 (UINT64)TotalPagesNum
828 ASSERT (BigPageAddress != 0);
833 PageMap = (VOID *)BigPageAddress;
834 if (Page5LevelEnabled) {
838 PageMapLevel5Entry = PageMap;
839 BigPageAddress += SIZE_4KB;
844 for ( IndexOfPml5Entries = 0
845 ; IndexOfPml5Entries < NumberOfPml5EntriesNeeded
846 ; IndexOfPml5Entries++)
853 PageMapLevel4Entry = (VOID *)BigPageAddress;
854 BigPageAddress += SIZE_4KB;
856 if (Page5LevelEnabled) {
860 PageMapLevel5Entry->Uint64 = (UINT64)(
UINTN)PageMapLevel4Entry | AddressEncMask;
861 PageMapLevel5Entry->Bits.ReadWrite = 1;
862 PageMapLevel5Entry->Bits.Present = 1;
863 PageMapLevel5Entry++;
866 for ( IndexOfPml4Entries = 0
867 ; IndexOfPml4Entries < (NumberOfPml5EntriesNeeded == 1 ? NumberOfPml4EntriesNeeded : 512)
868 ; IndexOfPml4Entries++, PageMapLevel4Entry++)
874 PageDirectoryPointerEntry = (VOID *)BigPageAddress;
875 BigPageAddress += SIZE_4KB;
880 PageMapLevel4Entry->Uint64 = (UINT64)(
UINTN)PageDirectoryPointerEntry | AddressEncMask;
881 PageMapLevel4Entry->Bits.ReadWrite = 1;
882 PageMapLevel4Entry->Bits.Present = 1;
885 PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry;
887 for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
888 if (
ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSize, GhcbBase, GhcbSize)) {
889 Split1GPageTo2M (PageAddress, (UINT64 *)PageDirectory1GEntry, StackBase, StackSize, GhcbBase, GhcbSize);
894 PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | AddressEncMask;
895 PageDirectory1GEntry->Bits.ReadWrite = 1;
896 PageDirectory1GEntry->Bits.Present = 1;
897 PageDirectory1GEntry->Bits.MustBe1 = 1;
901 for ( IndexOfPdpEntries = 0
902 ; IndexOfPdpEntries < (NumberOfPml4EntriesNeeded == 1 ? NumberOfPdpEntriesNeeded : 512)
903 ; IndexOfPdpEntries++, PageDirectoryPointerEntry++)
909 PageDirectoryEntry = (VOID *)BigPageAddress;
910 BigPageAddress += SIZE_4KB;
915 PageDirectoryPointerEntry->Uint64 = (UINT64)(
UINTN)PageDirectoryEntry | AddressEncMask;
916 PageDirectoryPointerEntry->Bits.ReadWrite = 1;
917 PageDirectoryPointerEntry->Bits.Present = 1;
919 for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
920 if (
ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSize, GhcbBase, GhcbSize)) {
924 Split2MPageTo4K (PageAddress, (UINT64 *)PageDirectoryEntry, StackBase, StackSize, GhcbBase, GhcbSize);
929 PageDirectoryEntry->Uint64 = (UINT64)PageAddress | AddressEncMask;
930 PageDirectoryEntry->Bits.ReadWrite = 1;
931 PageDirectoryEntry->Bits.Present = 1;
932 PageDirectoryEntry->Bits.MustBe1 = 1;
950 if (Page5LevelEnabled) {
973 return (
UINTN)PageMap;
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT32 EFIAPI AsmCpuidEx(IN UINT32 Index, IN UINT32 SubIndex, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
UINTN EFIAPI AsmWriteCr4(UINTN Cr4)
UINTN EFIAPI AsmReadCr0(VOID)
UINTN EFIAPI AsmWriteCr0(UINTN Cr0)
UINT64 EFIAPI AsmWriteMsr64(IN UINT32 Index, IN UINT64 Value)
UINTN EFIAPI AsmReadCr4(VOID)
BOOLEAN ToSplitPageTable(IN EFI_PHYSICAL_ADDRESS Address, IN UINTN Size, IN EFI_PHYSICAL_ADDRESS StackBase, IN UINTN StackSize, IN EFI_PHYSICAL_ADDRESS GhcbBase, IN UINTN GhcbSize)
VOID Split2MPageTo4K(IN EFI_PHYSICAL_ADDRESS PhysicalAddress, IN OUT UINT64 *PageEntry2M, IN EFI_PHYSICAL_ADDRESS StackBase, IN UINTN StackSize, IN EFI_PHYSICAL_ADDRESS GhcbBase, IN UINTN GhcbSize)
BOOLEAN IsExecuteDisableBitAvailable(VOID)
BOOLEAN IsEnableNonExecNeeded(VOID)
VOID ClearFirst4KPage(IN VOID *HobStart)
VOID EnablePageTableProtection(IN UINTN PageTableBase, IN BOOLEAN Level4Paging)
VOID * AllocatePageTableMemory(IN UINTN Pages)
UINTN CreateIdentityMappingPageTables(IN EFI_PHYSICAL_ADDRESS StackBase, IN UINTN StackSize, IN EFI_PHYSICAL_ADDRESS GhcbBase, IN UINTN GhcbSize)
VOID Split1GPageTo2M(IN EFI_PHYSICAL_ADDRESS PhysicalAddress, IN OUT UINT64 *PageEntry1G, IN EFI_PHYSICAL_ADDRESS StackBase, IN UINTN StackSize, IN EFI_PHYSICAL_ADDRESS GhcbBase, IN UINTN GhcbSize)
BOOLEAN InitializePageTablePool(IN UINTN PoolPages)
BOOLEAN IsNullDetectionEnabled(VOID)
VOID SetPageTablePoolReadOnly(IN UINTN PageTableBase, IN EFI_PHYSICAL_ADDRESS Address, IN BOOLEAN Level4Paging)
VOID EnableExecuteDisableBit(VOID)
#define DEBUG(Expression)
#define CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS
#define CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
#define PcdGet64(TokenName)
#define PcdGet8(TokenName)
#define PcdGet32(TokenName)
#define PcdGetBool(TokenName)
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
EFI_PHYSICAL_ADDRESS MemoryBaseAddress
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor
EFI_PHYSICAL_ADDRESS PhysicalStart
EFI_RESOURCE_TYPE ResourceType
struct CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX::@709 Bits