VOID\r
);\r
\r
+/**\r
+ Get page table base address and the depth of the page table.\r
+\r
+ @param[out] Base Page table base address.\r
+ @param[out] FiveLevels TRUE means 5 level paging. FALSE means 4 level paging.\r
+**/\r
+VOID\r
+GetPageTable (\r
+ OUT UINTN *Base,\r
+ OUT BOOLEAN *FiveLevels OPTIONAL\r
+ )\r
+{\r
+ *Base = ((mInternalCr3 == 0) ?\r
+ (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64) :\r
+ mInternalCr3);\r
+ if (FiveLevels != NULL) {\r
+ *FiveLevels = FALSE;\r
+ }\r
+}\r
+\r
/**\r
Create PageTable for SMM use.\r
\r
UINT64 *L1PageTable;\r
UINT64 *L2PageTable;\r
UINT64 *L3PageTable;\r
+ UINTN PageTableBase;\r
BOOLEAN IsSplitted;\r
BOOLEAN PageTableSplitted;\r
BOOLEAN CetEnabled;\r
DEBUG ((DEBUG_INFO, "Start...\n"));\r
PageTableSplitted = FALSE;\r
\r
- L3PageTable = (UINT64 *)GetPageTableBase ();\r
+ GetPageTable (&PageTableBase, NULL);\r
+ L3PageTable = (UINT64 *)PageTableBase;\r
\r
- SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L3PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
+ SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)PageTableBase, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
PageTableSplitted = (PageTableSplitted || IsSplitted);\r
\r
for (Index3 = 0; Index3 < 4; Index3++) {\r
extern UINTN mNumberOfCpus;\r
extern EFI_SMM_CPU_PROTOCOL mSmmCpu;\r
extern EFI_MM_MP_PROTOCOL mSmmMp;\r
+extern UINTN mInternalCr3;\r
\r
///\r
/// The mode of the CPU at the time an SMI occurs\r
);\r
\r
/**\r
- Return page table base.\r
+ Get page table base address and the depth of the page table.\r
\r
- @return page table base.\r
+ @param[out] Base Page table base address.\r
+ @param[out] FiveLevels TRUE means 5 level paging. FALSE means 4 level paging.\r
**/\r
-UINTN\r
-GetPageTableBase (\r
- VOID\r
+VOID\r
+GetPageTable (\r
+ OUT UINTN *Base,\r
+ OUT BOOLEAN *FiveLevels OPTIONAL\r
);\r
\r
/**\r
mInternalCr3 = Cr3;\r
}\r
\r
-/**\r
- Return page table base.\r
-\r
- @return page table base.\r
-**/\r
-UINTN\r
-GetPageTableBase (\r
- VOID\r
- )\r
-{\r
- if (mInternalCr3 != 0) {\r
- return mInternalCr3;\r
- }\r
- return (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64);\r
-}\r
-\r
/**\r
Return length according to page attributes.\r
\r
UINT64 *L3PageTable;\r
UINT64 *L4PageTable;\r
UINT64 *L5PageTable;\r
- IA32_CR4 Cr4;\r
+ UINTN PageTableBase;\r
BOOLEAN Enable5LevelPaging;\r
\r
+ GetPageTable (&PageTableBase, &Enable5LevelPaging);\r
+\r
Index5 = ((UINTN)RShiftU64 (Address, 48)) & PAGING_PAE_INDEX_MASK;\r
Index4 = ((UINTN)RShiftU64 (Address, 39)) & PAGING_PAE_INDEX_MASK;\r
Index3 = ((UINTN)Address >> 30) & PAGING_PAE_INDEX_MASK;\r
Index2 = ((UINTN)Address >> 21) & PAGING_PAE_INDEX_MASK;\r
Index1 = ((UINTN)Address >> 12) & PAGING_PAE_INDEX_MASK;\r
\r
- Cr4.UintN = AsmReadCr4 ();\r
- Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1);\r
-\r
if (sizeof(UINTN) == sizeof(UINT64)) {\r
if (Enable5LevelPaging) {\r
- L5PageTable = (UINT64 *)GetPageTableBase ();\r
+ L5PageTable = (UINT64 *)PageTableBase;\r
if (L5PageTable[Index5] == 0) {\r
*PageAttribute = PageNone;\r
return NULL;\r
\r
L4PageTable = (UINT64 *)(UINTN)(L5PageTable[Index5] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
} else {\r
- L4PageTable = (UINT64 *)GetPageTableBase ();\r
+ L4PageTable = (UINT64 *)PageTableBase;\r
}\r
if (L4PageTable[Index4] == 0) {\r
*PageAttribute = PageNone;\r
\r
L3PageTable = (UINT64 *)(UINTN)(L4PageTable[Index4] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
} else {\r
- L3PageTable = (UINT64 *)GetPageTableBase ();\r
+ L3PageTable = (UINT64 *)PageTableBase;\r
}\r
if (L3PageTable[Index3] == 0) {\r
*PageAttribute = PageNone;\r
}\r
}\r
\r
+/**\r
+ Get page table base address and the depth of the page table.\r
+\r
+ @param[out] Base Page table base address.\r
+ @param[out] FiveLevels TRUE means 5 level paging. FALSE means 4 level paging.\r
+**/\r
+VOID\r
+GetPageTable (\r
+ OUT UINTN *Base,\r
+ OUT BOOLEAN *FiveLevels OPTIONAL\r
+ )\r
+{\r
+ IA32_CR4 Cr4;\r
+\r
+ if (mInternalCr3 == 0) {\r
+ *Base = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;\r
+ if (FiveLevels != NULL) {\r
+ Cr4.UintN = AsmReadCr4 ();\r
+ *FiveLevels = (BOOLEAN)(Cr4.Bits.LA57 == 1);\r
+ }\r
+ return;\r
+ }\r
+\r
+ *Base = mInternalCr3;\r
+ if (FiveLevels != NULL) {\r
+ *FiveLevels = m5LevelPagingNeeded;\r
+ }\r
+}\r
+\r
/**\r
Set sub-entries number in entry.\r
\r
UINT64 *L3PageTable;\r
UINT64 *L4PageTable;\r
UINT64 *L5PageTable;\r
+ UINTN PageTableBase;\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 mark page table memory as read-only if\r
// - no restriction on access to non-SMRAM memory; or\r
DEBUG ((DEBUG_INFO, "Start...\n"));\r
PageTableSplitted = FALSE;\r
L5PageTable = NULL;\r
+\r
+ GetPageTable (&PageTableBase, &Enable5LevelPaging);\r
+\r
if (Enable5LevelPaging) {\r
- L5PageTable = (UINT64 *)GetPageTableBase ();\r
- SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L5PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
+ L5PageTable = (UINT64 *)PageTableBase;\r
+ SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)PageTableBase, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
PageTableSplitted = (PageTableSplitted || IsSplitted);\r
}\r
\r
continue;\r
}\r
} else {\r
- L4PageTable = (UINT64 *)GetPageTableBase ();\r
+ L4PageTable = (UINT64 *)PageTableBase;\r
}\r
SmmSetMemoryAttributesEx ((EFI_PHYSICAL_ADDRESS)(UINTN)L4PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
PageTableSplitted = (PageTableSplitted || IsSplitted);\r