LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool);\r
BOOLEAN m1GPageTableSupport = FALSE;\r
BOOLEAN mCpuSmmStaticPageTable;\r
-BOOLEAN m5LevelPagingSupport;\r
-X86_ASSEMBLY_PATCH_LABEL gPatch5LevelPagingSupport;\r
\r
/**\r
Disable CET.\r
return FALSE;\r
}\r
\r
-/**\r
- Check if 5-level paging is supported by processor or not.\r
-\r
- @retval TRUE 5-level paging is supported.\r
- @retval FALSE 5-level paging is not supported.\r
-\r
-**/\r
-BOOLEAN\r
-Is5LevelPagingSupport (\r
- VOID\r
- )\r
-{\r
- CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX EcxFlags;\r
-\r
- AsmCpuidEx (\r
- CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS,\r
- CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO,\r
- NULL,\r
- NULL,\r
- &EcxFlags.Uint32,\r
- NULL\r
- );\r
- return (BOOLEAN) (EcxFlags.Bits.FiveLevelPage != 0);\r
-}\r
-\r
/**\r
Set sub-entries number in entry.\r
\r
PhysicalAddressBits = 36;\r
}\r
}\r
+\r
+ //\r
+ // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.\r
+ //\r
+ ASSERT (PhysicalAddressBits <= 52);\r
+ if (PhysicalAddressBits > 48) {\r
+ PhysicalAddressBits = 48;\r
+ }\r
return PhysicalAddressBits;\r
}\r
\r
)\r
{\r
UINT64 PageAddress;\r
- UINTN NumberOfPml5EntriesNeeded;\r
UINTN NumberOfPml4EntriesNeeded;\r
UINTN NumberOfPdpEntriesNeeded;\r
- UINTN IndexOfPml5Entries;\r
UINTN IndexOfPml4Entries;\r
UINTN IndexOfPdpEntries;\r
UINTN IndexOfPageDirectoryEntries;\r
- UINT64 *PageMapLevel5Entry;\r
UINT64 *PageMapLevel4Entry;\r
UINT64 *PageMap;\r
UINT64 *PageDirectoryPointerEntry;\r
UINT64 *PageDirectory1GEntry;\r
UINT64 *PageDirectoryEntry;\r
\r
- //\r
- // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses\r
- // when 5-Level Paging is disabled.\r
- //\r
- ASSERT (mPhysicalAddressBits <= 52);\r
- if (!m5LevelPagingSupport && mPhysicalAddressBits > 48) {\r
- mPhysicalAddressBits = 48;\r
- }\r
-\r
- NumberOfPml5EntriesNeeded = 1;\r
- if (mPhysicalAddressBits > 48) {\r
- NumberOfPml5EntriesNeeded = (UINTN) LShiftU64 (1, mPhysicalAddressBits - 48);\r
- mPhysicalAddressBits = 48;\r
- }\r
-\r
- NumberOfPml4EntriesNeeded = 1;\r
- if (mPhysicalAddressBits > 39) {\r
- NumberOfPml4EntriesNeeded = (UINTN) LShiftU64 (1, mPhysicalAddressBits - 39);\r
- mPhysicalAddressBits = 39;\r
+ if (mPhysicalAddressBits <= 39 ) {\r
+ NumberOfPml4EntriesNeeded = 1;\r
+ NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (mPhysicalAddressBits - 30));\r
+ } else {\r
+ NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (mPhysicalAddressBits - 39));\r
+ NumberOfPdpEntriesNeeded = 512;\r
}\r
\r
- NumberOfPdpEntriesNeeded = 1;\r
- ASSERT (mPhysicalAddressBits > 30);\r
- NumberOfPdpEntriesNeeded = (UINTN) LShiftU64 (1, mPhysicalAddressBits - 30);\r
-\r
//\r
// By architecture only one PageMapLevel4 exists - so lets allocate storage for it.\r
//\r
PageMap = (VOID *) PageTable;\r
\r
PageMapLevel4Entry = PageMap;\r
- PageMapLevel5Entry = NULL;\r
- if (m5LevelPagingSupport) {\r
- //\r
- // By architecture only one PageMapLevel5 exists - so lets allocate storage for it.\r
- //\r
- PageMapLevel5Entry = PageMap;\r
- }\r
PageAddress = 0;\r
-\r
- for ( IndexOfPml5Entries = 0\r
- ; IndexOfPml5Entries < NumberOfPml5EntriesNeeded\r
- ; IndexOfPml5Entries++, PageMapLevel5Entry++) {\r
+ for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {\r
//\r
- // Each PML5 entry points to a page of PML4 entires.\r
- // So lets allocate space for them and fill them in in the IndexOfPml4Entries loop.\r
- // When 5-Level Paging is disabled, below allocation happens only once.\r
+ // Each PML4 entry points to a page of Page Directory Pointer entries.\r
//\r
- if (m5LevelPagingSupport) {\r
- PageMapLevel4Entry = (UINT64 *) ((*PageMapLevel5Entry) & ~mAddressEncMask & gPhyMask);\r
- if (PageMapLevel4Entry == NULL) {\r
- PageMapLevel4Entry = AllocatePageTableMemory (1);\r
- ASSERT(PageMapLevel4Entry != NULL);\r
- ZeroMem (PageMapLevel4Entry, EFI_PAGES_TO_SIZE(1));\r
-\r
- *PageMapLevel5Entry = (UINT64)(UINTN)PageMapLevel4Entry | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
- }\r
- }\r
-\r
- for (IndexOfPml4Entries = 0; IndexOfPml4Entries < (NumberOfPml5EntriesNeeded == 1 ? NumberOfPml4EntriesNeeded : 512); IndexOfPml4Entries++, PageMapLevel4Entry++) {\r
- //\r
- // Each PML4 entry points to a page of Page Directory Pointer entries.\r
- //\r
- PageDirectoryPointerEntry = (UINT64 *) ((*PageMapLevel4Entry) & ~mAddressEncMask & gPhyMask);\r
- if (PageDirectoryPointerEntry == NULL) {\r
- PageDirectoryPointerEntry = AllocatePageTableMemory (1);\r
- ASSERT(PageDirectoryPointerEntry != NULL);\r
- ZeroMem (PageDirectoryPointerEntry, EFI_PAGES_TO_SIZE(1));\r
+ PageDirectoryPointerEntry = (UINT64 *) ((*PageMapLevel4Entry) & ~mAddressEncMask & gPhyMask);\r
+ if (PageDirectoryPointerEntry == NULL) {\r
+ PageDirectoryPointerEntry = AllocatePageTableMemory (1);\r
+ ASSERT(PageDirectoryPointerEntry != NULL);\r
+ ZeroMem (PageDirectoryPointerEntry, EFI_PAGES_TO_SIZE(1));\r
\r
- *PageMapLevel4Entry = (UINT64)(UINTN)PageDirectoryPointerEntry | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
- }\r
+ *PageMapLevel4Entry = (UINT64)(UINTN)PageDirectoryPointerEntry | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
+ }\r
\r
- if (m1GPageTableSupport) {\r
- PageDirectory1GEntry = PageDirectoryPointerEntry;\r
- for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {\r
- if (IndexOfPml4Entries == 0 && IndexOfPageDirectoryEntries < 4) {\r
- //\r
- // Skip the < 4G entries\r
- //\r
- continue;\r
- }\r
+ if (m1GPageTableSupport) {\r
+ PageDirectory1GEntry = PageDirectoryPointerEntry;\r
+ for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {\r
+ if (IndexOfPml4Entries == 0 && IndexOfPageDirectoryEntries < 4) {\r
//\r
- // Fill in the Page Directory entries\r
+ // Skip the < 4G entries\r
//\r
- *PageDirectory1GEntry = PageAddress | mAddressEncMask | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;\r
+ continue;\r
}\r
- } else {\r
- PageAddress = BASE_4GB;\r
- for (IndexOfPdpEntries = 0; IndexOfPdpEntries < (NumberOfPml4EntriesNeeded == 1 ? NumberOfPdpEntriesNeeded : 512); IndexOfPdpEntries++, PageDirectoryPointerEntry++) {\r
- if (IndexOfPml4Entries == 0 && IndexOfPdpEntries < 4) {\r
- //\r
- // Skip the < 4G entries\r
- //\r
- continue;\r
- }\r
+ //\r
+ // Fill in the Page Directory entries\r
+ //\r
+ *PageDirectory1GEntry = PageAddress | mAddressEncMask | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;\r
+ }\r
+ } else {\r
+ PageAddress = BASE_4GB;\r
+ for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {\r
+ if (IndexOfPml4Entries == 0 && IndexOfPdpEntries < 4) {\r
//\r
- // Each Directory Pointer entries points to a page of Page Directory entires.\r
- // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.\r
+ // Skip the < 4G entries\r
//\r
- PageDirectoryEntry = (UINT64 *) ((*PageDirectoryPointerEntry) & ~mAddressEncMask & gPhyMask);\r
- if (PageDirectoryEntry == NULL) {\r
- PageDirectoryEntry = AllocatePageTableMemory (1);\r
- ASSERT(PageDirectoryEntry != NULL);\r
- ZeroMem (PageDirectoryEntry, EFI_PAGES_TO_SIZE(1));\r
+ continue;\r
+ }\r
+ //\r
+ // Each Directory Pointer entries points to a page of Page Directory entires.\r
+ // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.\r
+ //\r
+ PageDirectoryEntry = (UINT64 *) ((*PageDirectoryPointerEntry) & ~mAddressEncMask & gPhyMask);\r
+ if (PageDirectoryEntry == NULL) {\r
+ PageDirectoryEntry = AllocatePageTableMemory (1);\r
+ ASSERT(PageDirectoryEntry != NULL);\r
+ ZeroMem (PageDirectoryEntry, EFI_PAGES_TO_SIZE(1));\r
\r
- //\r
- // Fill in a Page Directory Pointer Entries\r
- //\r
- *PageDirectoryPointerEntry = (UINT64)(UINTN)PageDirectoryEntry | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
- }\r
+ //\r
+ // Fill in a Page Directory Pointer Entries\r
+ //\r
+ *PageDirectoryPointerEntry = (UINT64)(UINTN)PageDirectoryEntry | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
+ }\r
\r
- for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {\r
- //\r
- // Fill in the Page Directory entries\r
- //\r
- *PageDirectoryEntry = PageAddress | mAddressEncMask | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;\r
- }\r
+ for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {\r
+ //\r
+ // Fill in the Page Directory entries\r
+ //\r
+ *PageDirectoryEntry = PageAddress | mAddressEncMask | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;\r
}\r
}\r
}\r
UINTN PageFaultHandlerHookAddress;\r
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;\r
EFI_STATUS Status;\r
- UINT64 *Pml4Entry;\r
- UINT64 *Pml5Entry;\r
\r
//\r
// Initialize spin lock\r
InitializeSpinLock (mPFLock);\r
\r
mCpuSmmStaticPageTable = PcdGetBool (PcdCpuSmmStaticPageTable);\r
- m1GPageTableSupport = Is1GPageSupport ();\r
- m5LevelPagingSupport = Is5LevelPagingSupport ();\r
- mPhysicalAddressBits = CalculateMaximumSupportAddress ();\r
- PatchInstructionX86 (gPatch5LevelPagingSupport, m5LevelPagingSupport, 1);\r
- DEBUG ((DEBUG_INFO, "5LevelPaging Support - %d\n", m5LevelPagingSupport));\r
- DEBUG ((DEBUG_INFO, "1GPageTable Support - %d\n", m1GPageTableSupport));\r
- DEBUG ((DEBUG_INFO, "PcdCpuSmmStaticPageTable - %d\n", mCpuSmmStaticPageTable));\r
- DEBUG ((DEBUG_INFO, "PhysicalAddressBits - %d\n", mPhysicalAddressBits));\r
+ m1GPageTableSupport = Is1GPageSupport ();\r
+ DEBUG ((DEBUG_INFO, "1GPageTableSupport - 0x%x\n", m1GPageTableSupport));\r
+ DEBUG ((DEBUG_INFO, "PcdCpuSmmStaticPageTable - 0x%x\n", mCpuSmmStaticPageTable));\r
+\r
+ mPhysicalAddressBits = CalculateMaximumSupportAddress ();\r
+ DEBUG ((DEBUG_INFO, "PhysicalAddressBits - 0x%x\n", mPhysicalAddressBits));\r
//\r
// Generate PAE page table for the first 4GB memory space\r
//\r
//\r
// Fill Page-Table-Level4 (PML4) entry\r
//\r
- Pml4Entry = (UINT64*)AllocatePageTableMemory (1);\r
- ASSERT (Pml4Entry != NULL);\r
- *Pml4Entry = Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
- ZeroMem (Pml4Entry + 1, EFI_PAGE_SIZE - sizeof (*Pml4Entry));\r
+ PTEntry = (UINT64*)AllocatePageTableMemory (1);\r
+ ASSERT (PTEntry != NULL);\r
+ *PTEntry = Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
+ ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry));\r
\r
//\r
// Set sub-entries number\r
//\r
- SetSubEntriesNum (Pml4Entry, 3);\r
- PTEntry = Pml4Entry;\r
-\r
- if (m5LevelPagingSupport) {\r
- //\r
- // Fill PML5 entry\r
- //\r
- Pml5Entry = (UINT64*)AllocatePageTableMemory (1);\r
- *Pml5Entry = (UINTN) Pml4Entry | mAddressEncMask | PAGE_ATTRIBUTE_BITS;\r
- ZeroMem (Pml5Entry + 1, EFI_PAGE_SIZE - sizeof (*Pml5Entry));\r
- //\r
- // Set sub-entries number\r
- //\r
- SetSubEntriesNum (Pml5Entry, 1);\r
- PTEntry = Pml5Entry;\r
- }\r
+ SetSubEntriesNum (PTEntry, 3);\r
\r
if (mCpuSmmStaticPageTable) {\r
SetStaticPageTable ((UINTN)PTEntry);\r
}\r
\r
//\r
- // Return the address of PML4/PML5 (to set CR3)\r
+ // Return the address of PML4 (to set CR3)\r
//\r
return (UINT32)(UINTN)PTEntry;\r
}\r
VOID\r
)\r
{\r
- UINT64 Pml5Entry;\r
- UINT64 *Pml5;\r
UINT64 *Pml4;\r
UINT64 *Pdpt;\r
UINT64 *Pdt;\r
- UINTN Pml5Index;\r
UINTN Pml4Index;\r
UINTN PdptIndex;\r
UINTN PdtIndex;\r
- UINTN MinPml5;\r
UINTN MinPml4;\r
UINTN MinPdpt;\r
UINTN MinPdt;\r
BOOLEAN PML4EIgnore;\r
BOOLEAN PDPTEIgnore;\r
UINT64 *ReleasePageAddress;\r
- IA32_CR4 Cr4;\r
- BOOLEAN Enable5LevelPaging;\r
\r
Pml4 = NULL;\r
Pdpt = NULL;\r
Pdt = NULL;\r
MinAcc = (UINT64)-1;\r
MinPml4 = (UINTN)-1;\r
- MinPml5 = (UINTN)-1;\r
MinPdpt = (UINTN)-1;\r
MinPdt = (UINTN)-1;\r
Acc = 0;\r
ReleasePageAddress = 0;\r
\r
- Cr4.UintN = AsmReadCr4 ();\r
- Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1);\r
- Pml5 = (UINT64*)(UINTN)(AsmReadCr3 () & gPhyMask);\r
-\r
- if (!Enable5LevelPaging) {\r
- //\r
- // Create one fake PML5 entry for 4-Level Paging\r
- // so that the page table parsing logic only handles 5-Level page structure.\r
- //\r
- Pml5Entry = (UINTN) Pml5 | IA32_PG_P;\r
- Pml5 = &Pml5Entry;\r
- }\r
-\r
//\r
// First, find the leaf entry has the smallest access record value\r
//\r
- for (Pml5Index = 0; Pml5Index < Enable5LevelPaging ? (EFI_PAGE_SIZE / sizeof (*Pml4)) : 1; Pml5Index++) {\r
- if ((Pml5[Pml5Index] & IA32_PG_P) == 0 || (Pml5[Pml5Index] & IA32_PG_PMNT) != 0) {\r
+ Pml4 = (UINT64*)(UINTN)(AsmReadCr3 () & gPhyMask);\r
+ for (Pml4Index = 0; Pml4Index < EFI_PAGE_SIZE / sizeof (*Pml4); Pml4Index++) {\r
+ if ((Pml4[Pml4Index] & IA32_PG_P) == 0 || (Pml4[Pml4Index] & IA32_PG_PMNT) != 0) {\r
//\r
- // If the PML5 entry is not present or is masked, skip it\r
+ // If the PML4 entry is not present or is masked, skip it\r
//\r
continue;\r
}\r
- Pml4 = (UINT64*)(UINTN)(Pml5[Pml5Index] & gPhyMask);\r
- for (Pml4Index = 0; Pml4Index < EFI_PAGE_SIZE / sizeof (*Pml4); Pml4Index++) {\r
- if ((Pml4[Pml4Index] & IA32_PG_P) == 0 || (Pml4[Pml4Index] & IA32_PG_PMNT) != 0) {\r
+ Pdpt = (UINT64*)(UINTN)(Pml4[Pml4Index] & ~mAddressEncMask & gPhyMask);\r
+ PML4EIgnore = FALSE;\r
+ for (PdptIndex = 0; PdptIndex < EFI_PAGE_SIZE / sizeof (*Pdpt); PdptIndex++) {\r
+ if ((Pdpt[PdptIndex] & IA32_PG_P) == 0 || (Pdpt[PdptIndex] & IA32_PG_PMNT) != 0) {\r
//\r
- // If the PML4 entry is not present or is masked, skip it\r
+ // If the PDPT entry is not present or is masked, skip it\r
//\r
- continue;\r
- }\r
- Pdpt = (UINT64*)(UINTN)(Pml4[Pml4Index] & ~mAddressEncMask & gPhyMask);\r
- PML4EIgnore = FALSE;\r
- for (PdptIndex = 0; PdptIndex < EFI_PAGE_SIZE / sizeof (*Pdpt); PdptIndex++) {\r
- if ((Pdpt[PdptIndex] & IA32_PG_P) == 0 || (Pdpt[PdptIndex] & IA32_PG_PMNT) != 0) {\r
+ if ((Pdpt[PdptIndex] & IA32_PG_PMNT) != 0) {\r
//\r
- // If the PDPT entry is not present or is masked, skip it\r
+ // If the PDPT entry is masked, we will ignore checking the PML4 entry\r
//\r
- if ((Pdpt[PdptIndex] & IA32_PG_PMNT) != 0) {\r
+ PML4EIgnore = TRUE;\r
+ }\r
+ continue;\r
+ }\r
+ if ((Pdpt[PdptIndex] & IA32_PG_PS) == 0) {\r
+ //\r
+ // It's not 1-GByte pages entry, it should be a PDPT entry,\r
+ // we will not check PML4 entry more\r
+ //\r
+ PML4EIgnore = TRUE;\r
+ Pdt = (UINT64*)(UINTN)(Pdpt[PdptIndex] & ~mAddressEncMask & gPhyMask);\r
+ PDPTEIgnore = FALSE;\r
+ for (PdtIndex = 0; PdtIndex < EFI_PAGE_SIZE / sizeof(*Pdt); PdtIndex++) {\r
+ if ((Pdt[PdtIndex] & IA32_PG_P) == 0 || (Pdt[PdtIndex] & IA32_PG_PMNT) != 0) {\r
//\r
- // If the PDPT entry is masked, we will ignore checking the PML4 entry\r
+ // If the PD entry is not present or is masked, skip it\r
//\r
- PML4EIgnore = TRUE;\r
- }\r
- continue;\r
- }\r
- if ((Pdpt[PdptIndex] & IA32_PG_PS) == 0) {\r
- //\r
- // It's not 1-GByte pages entry, it should be a PDPT entry,\r
- // we will not check PML4 entry more\r
- //\r
- PML4EIgnore = TRUE;\r
- Pdt = (UINT64*)(UINTN)(Pdpt[PdptIndex] & ~mAddressEncMask & gPhyMask);\r
- PDPTEIgnore = FALSE;\r
- for (PdtIndex = 0; PdtIndex < EFI_PAGE_SIZE / sizeof(*Pdt); PdtIndex++) {\r
- if ((Pdt[PdtIndex] & IA32_PG_P) == 0 || (Pdt[PdtIndex] & IA32_PG_PMNT) != 0) {\r
- //\r
- // If the PD entry is not present or is masked, skip it\r
- //\r
- if ((Pdt[PdtIndex] & IA32_PG_PMNT) != 0) {\r
- //\r
- // If the PD entry is masked, we will not PDPT entry more\r
- //\r
- PDPTEIgnore = TRUE;\r
- }\r
- continue;\r
- }\r
- if ((Pdt[PdtIndex] & IA32_PG_PS) == 0) {\r
+ if ((Pdt[PdtIndex] & IA32_PG_PMNT) != 0) {\r
//\r
- // It's not 2 MByte page table entry, it should be PD entry\r
- // we will find the entry has the smallest access record value\r
+ // If the PD entry is masked, we will not PDPT entry more\r
//\r
PDPTEIgnore = TRUE;\r
- Acc = GetAndUpdateAccNum (Pdt + PdtIndex);\r
- if (Acc < MinAcc) {\r
- //\r
- // If the PD entry has the smallest access record value,\r
- // save the Page address to be released\r
- //\r
- MinAcc = Acc;\r
- MinPml5 = Pml5Index;\r
- MinPml4 = Pml4Index;\r
- MinPdpt = PdptIndex;\r
- MinPdt = PdtIndex;\r
- ReleasePageAddress = Pdt + PdtIndex;\r
- }\r
}\r
+ continue;\r
}\r
- if (!PDPTEIgnore) {\r
+ if ((Pdt[PdtIndex] & IA32_PG_PS) == 0) {\r
//\r
- // If this PDPT entry has no PDT entries pointer to 4 KByte pages,\r
- // it should only has the entries point to 2 MByte Pages\r
+ // It's not 2 MByte page table entry, it should be PD entry\r
+ // we will find the entry has the smallest access record value\r
//\r
- Acc = GetAndUpdateAccNum (Pdpt + PdptIndex);\r
+ PDPTEIgnore = TRUE;\r
+ Acc = GetAndUpdateAccNum (Pdt + PdtIndex);\r
if (Acc < MinAcc) {\r
//\r
- // If the PDPT entry has the smallest access record value,\r
+ // If the PD entry has the smallest access record value,\r
// save the Page address to be released\r
//\r
MinAcc = Acc;\r
- MinPml5 = Pml5Index;\r
MinPml4 = Pml4Index;\r
MinPdpt = PdptIndex;\r
- MinPdt = (UINTN)-1;\r
- ReleasePageAddress = Pdpt + PdptIndex;\r
+ MinPdt = PdtIndex;\r
+ ReleasePageAddress = Pdt + PdtIndex;\r
}\r
}\r
}\r
- }\r
- if (!PML4EIgnore) {\r
- //\r
- // If PML4 entry has no the PDPT entry pointer to 2 MByte pages,\r
- // it should only has the entries point to 1 GByte Pages\r
- //\r
- Acc = GetAndUpdateAccNum (Pml4 + Pml4Index);\r
- if (Acc < MinAcc) {\r
+ if (!PDPTEIgnore) {\r
//\r
- // If the PML4 entry has the smallest access record value,\r
- // save the Page address to be released\r
+ // If this PDPT entry has no PDT entries pointer to 4 KByte pages,\r
+ // it should only has the entries point to 2 MByte Pages\r
//\r
- MinAcc = Acc;\r
- MinPml5 = Pml5Index;\r
- MinPml4 = Pml4Index;\r
- MinPdpt = (UINTN)-1;\r
- MinPdt = (UINTN)-1;\r
- ReleasePageAddress = Pml4 + Pml4Index;\r
+ Acc = GetAndUpdateAccNum (Pdpt + PdptIndex);\r
+ if (Acc < MinAcc) {\r
+ //\r
+ // If the PDPT entry has the smallest access record value,\r
+ // save the Page address to be released\r
+ //\r
+ MinAcc = Acc;\r
+ MinPml4 = Pml4Index;\r
+ MinPdpt = PdptIndex;\r
+ MinPdt = (UINTN)-1;\r
+ ReleasePageAddress = Pdpt + PdptIndex;\r
+ }\r
}\r
}\r
}\r
+ if (!PML4EIgnore) {\r
+ //\r
+ // If PML4 entry has no the PDPT entry pointer to 2 MByte pages,\r
+ // it should only has the entries point to 1 GByte Pages\r
+ //\r
+ Acc = GetAndUpdateAccNum (Pml4 + Pml4Index);\r
+ if (Acc < MinAcc) {\r
+ //\r
+ // If the PML4 entry has the smallest access record value,\r
+ // save the Page address to be released\r
+ //\r
+ MinAcc = Acc;\r
+ MinPml4 = Pml4Index;\r
+ MinPdpt = (UINTN)-1;\r
+ MinPdt = (UINTN)-1;\r
+ ReleasePageAddress = Pml4 + Pml4Index;\r
+ }\r
+ }\r
}\r
//\r
// Make sure one PML4/PDPT/PD entry is selected\r
//\r
// If 4 KByte Page Table is released, check the PDPT entry\r
//\r
- Pml4 = (UINT64 *) (UINTN) (Pml5[MinPml5] & gPhyMask);\r
Pdpt = (UINT64*)(UINTN)(Pml4[MinPml4] & ~mAddressEncMask & gPhyMask);\r
SubEntriesNum = GetSubEntriesNum(Pdpt + MinPdpt);\r
if (SubEntriesNum == 0) {\r
)\r
{\r
UINT64 *PageTable;\r
- UINT64 *PageTableTop;\r
+ UINT64 *Pml4;\r
UINT64 PFAddress;\r
UINTN StartBit;\r
UINTN EndBit;\r
UINTN PageAttribute;\r
EFI_STATUS Status;\r
UINT64 *UpperEntry;\r
- BOOLEAN Enable5LevelPaging;\r
- IA32_CR4 Cr4;\r
\r
//\r
// Set default SMM page attribute\r
PageAttribute = 0;\r
\r
EndBit = 0;\r
- PageTableTop = (UINT64*)(AsmReadCr3 () & gPhyMask);\r
+ Pml4 = (UINT64*)(AsmReadCr3 () & gPhyMask);\r
PFAddress = AsmReadCr2 ();\r
\r
- Cr4.UintN = AsmReadCr4 ();\r
- Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 != 0);\r
-\r
Status = GetPlatformPageTableAttribute (PFAddress, &PageSize, &NumOfPages, &PageAttribute);\r
//\r
// If platform not support page table attribute, set default SMM page attribute\r
}\r
\r
for (Index = 0; Index < NumOfPages; Index++) {\r
- PageTable = PageTableTop;\r
+ PageTable = Pml4;\r
UpperEntry = NULL;\r
- for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > EndBit; StartBit -= 9) {\r
+ for (StartBit = 39; StartBit > EndBit; StartBit -= 9) {\r
PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);\r
if ((PageTable[PTIndex] & IA32_PG_P) == 0) {\r
//\r
UINTN Index2;\r
UINTN Index3;\r
UINTN Index4;\r
- UINTN Index5;\r
UINT64 *L1PageTable;\r
UINT64 *L2PageTable;\r
UINT64 *L3PageTable;\r
UINT64 *L4PageTable;\r
- UINT64 *L5PageTable;\r
BOOLEAN IsSplitted;\r
BOOLEAN PageTableSplitted;\r
BOOLEAN CetEnabled;\r
- IA32_CR4 Cr4;\r
- BOOLEAN Enable5LevelPaging;\r
-\r
- Cr4.UintN = AsmReadCr4 ();\r
- Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1);\r
\r
//\r
// Don't do this if\r
do {\r
DEBUG ((DEBUG_INFO, "Start...\n"));\r
PageTableSplitted = FALSE;\r
- L5PageTable = NULL;\r
- if (Enable5LevelPaging) {\r
- L5PageTable = (UINT64 *)GetPageTableBase ();\r
- SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L5PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
- PageTableSplitted = (PageTableSplitted || IsSplitted);\r
- }\r
\r
- for (Index5 = 0; Index5 < (Enable5LevelPaging ? SIZE_4KB/sizeof(UINT64) : 1); Index5++) {\r
- if (Enable5LevelPaging) {\r
- L4PageTable = (UINT64 *)(UINTN)(L5PageTable[Index5] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
- if (L4PageTable == NULL) {\r
- continue;\r
- }\r
- } else {\r
- L4PageTable = (UINT64 *)GetPageTableBase ();\r
+ L4PageTable = (UINT64 *)GetPageTableBase ();\r
+ SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L4PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
+ PageTableSplitted = (PageTableSplitted || IsSplitted);\r
+\r
+ for (Index4 = 0; Index4 < SIZE_4KB/sizeof(UINT64); Index4++) {\r
+ L3PageTable = (UINT64 *)(UINTN)(L4PageTable[Index4] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
+ if (L3PageTable == NULL) {\r
+ continue;\r
}\r
- SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L4PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
+\r
+ SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L3PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
PageTableSplitted = (PageTableSplitted || IsSplitted);\r
\r
- for (Index4 = 0; Index4 < SIZE_4KB/sizeof(UINT64); Index4++) {\r
- L3PageTable = (UINT64 *)(UINTN)(L4PageTable[Index4] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
- if (L3PageTable == NULL) {\r
+ for (Index3 = 0; Index3 < SIZE_4KB/sizeof(UINT64); Index3++) {\r
+ if ((L3PageTable[Index3] & IA32_PG_PS) != 0) {\r
+ // 1G\r
+ continue;\r
+ }\r
+ L2PageTable = (UINT64 *)(UINTN)(L3PageTable[Index3] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
+ if (L2PageTable == NULL) {\r
continue;\r
}\r
\r
- SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L3PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
+ SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L2PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
PageTableSplitted = (PageTableSplitted || IsSplitted);\r
\r
- for (Index3 = 0; Index3 < SIZE_4KB/sizeof(UINT64); Index3++) {\r
- if ((L3PageTable[Index3] & IA32_PG_PS) != 0) {\r
- // 1G\r
+ for (Index2 = 0; Index2 < SIZE_4KB/sizeof(UINT64); Index2++) {\r
+ if ((L2PageTable[Index2] & IA32_PG_PS) != 0) {\r
+ // 2M\r
continue;\r
}\r
- L2PageTable = (UINT64 *)(UINTN)(L3PageTable[Index3] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
- if (L2PageTable == NULL) {\r
+ L1PageTable = (UINT64 *)(UINTN)(L2PageTable[Index2] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
+ if (L1PageTable == NULL) {\r
continue;\r
}\r
-\r
- SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L2PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
+ SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L1PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
PageTableSplitted = (PageTableSplitted || IsSplitted);\r
-\r
- for (Index2 = 0; Index2 < SIZE_4KB/sizeof(UINT64); Index2++) {\r
- if ((L2PageTable[Index2] & IA32_PG_PS) != 0) {\r
- // 2M\r
- continue;\r
- }\r
- L1PageTable = (UINT64 *)(UINTN)(L2PageTable[Index2] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
- if (L1PageTable == NULL) {\r
- continue;\r
- }\r
- SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L1PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
- PageTableSplitted = (PageTableSplitted || IsSplitted);\r
- }\r
}\r
}\r
}\r