LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool);\r
BOOLEAN m1GPageTableSupport = FALSE;\r
BOOLEAN mCpuSmmRestrictedMemoryAccess;\r
-BOOLEAN m5LevelPagingSupport;\r
-X86_ASSEMBLY_PATCH_LABEL gPatch5LevelPagingSupport;\r
+BOOLEAN m5LevelPagingNeeded;\r
+X86_ASSEMBLY_PATCH_LABEL gPatch5LevelPagingNeeded;\r
\r
/**\r
Disable CET.\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
+ The routine returns TRUE when CPU supports it (CPUID[7,0].ECX.BIT[16] is set) and\r
+ the max physical address bits is bigger than 48. Because 4-level paging can support\r
+ to address physical address up to 2^48 - 1, there is no need to enable 5-level paging\r
+ with max physical address bits <= 48.\r
\r
+ @retval TRUE 5-level paging enabling is needed.\r
+ @retval FALSE 5-level paging enabling is not needed.\r
**/\r
BOOLEAN\r
-Is5LevelPagingSupport (\r
+Is5LevelPagingNeeded (\r
VOID\r
)\r
{\r
- CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX EcxFlags;\r
+ CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;\r
+ CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX ExtFeatureEcx;\r
+ UINT32 MaxExtendedFunctionId;\r
\r
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunctionId, NULL, NULL, NULL);\r
+ if (MaxExtendedFunctionId >= CPUID_VIR_PHY_ADDRESS_SIZE) {\r
+ AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL);\r
+ } else {\r
+ VirPhyAddressSize.Bits.PhysicalAddressBits = 36;\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
+ NULL, NULL, &ExtFeatureEcx.Uint32, NULL\r
);\r
- return (BOOLEAN) (EcxFlags.Bits.FiveLevelPage != 0);\r
+ DEBUG ((\r
+ DEBUG_INFO, "PhysicalAddressBits = %d, 5LPageTable = %d.\n",\r
+ VirPhyAddressSize.Bits.PhysicalAddressBits, ExtFeatureEcx.Bits.FiveLevelPage\r
+ ));\r
+\r
+ if (VirPhyAddressSize.Bits.PhysicalAddressBits > 4 * 9 + 12) {\r
+ ASSERT (ExtFeatureEcx.Bits.FiveLevelPage == 1);\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
}\r
\r
/**\r
// when 5-Level Paging is disabled.\r
//\r
ASSERT (mPhysicalAddressBits <= 52);\r
- if (!m5LevelPagingSupport && mPhysicalAddressBits > 48) {\r
+ if (!m5LevelPagingNeeded && mPhysicalAddressBits > 48) {\r
mPhysicalAddressBits = 48;\r
}\r
\r
\r
PageMapLevel4Entry = PageMap;\r
PageMapLevel5Entry = NULL;\r
- if (m5LevelPagingSupport) {\r
+ if (m5LevelPagingNeeded) {\r
//\r
// By architecture only one PageMapLevel5 exists - so lets allocate storage for it.\r
//\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
//\r
- if (m5LevelPagingSupport) {\r
+ if (m5LevelPagingNeeded) {\r
PageMapLevel4Entry = (UINT64 *) ((*PageMapLevel5Entry) & ~mAddressEncMask & gPhyMask);\r
if (PageMapLevel4Entry == NULL) {\r
PageMapLevel4Entry = AllocatePageTableMemory (1);\r
\r
mCpuSmmRestrictedMemoryAccess = PcdGetBool (PcdCpuSmmRestrictedMemoryAccess);\r
m1GPageTableSupport = Is1GPageSupport ();\r
- m5LevelPagingSupport = Is5LevelPagingSupport ();\r
+ m5LevelPagingNeeded = Is5LevelPagingNeeded ();\r
mPhysicalAddressBits = CalculateMaximumSupportAddress ();\r
- PatchInstructionX86 (gPatch5LevelPagingSupport, m5LevelPagingSupport, 1);\r
- DEBUG ((DEBUG_INFO, "5LevelPaging Support - %d\n", m5LevelPagingSupport));\r
+ PatchInstructionX86 (gPatch5LevelPagingNeeded, m5LevelPagingNeeded, 1);\r
+ DEBUG ((DEBUG_INFO, "5LevelPaging Needed - %d\n", m5LevelPagingNeeded));\r
DEBUG ((DEBUG_INFO, "1GPageTable Support - %d\n", m1GPageTableSupport));\r
DEBUG ((DEBUG_INFO, "PcdCpuSmmRestrictedMemoryAccess - %d\n", mCpuSmmRestrictedMemoryAccess));\r
DEBUG ((DEBUG_INFO, "PhysicalAddressBits - %d\n", mPhysicalAddressBits));\r
SetSubEntriesNum (Pml4Entry, 3);\r
PTEntry = Pml4Entry;\r
\r
- if (m5LevelPagingSupport) {\r
+ if (m5LevelPagingNeeded) {\r
//\r
// Fill PML5 entry\r
//\r