- return (UINT32)(UINTN)PageTable;\r
-}\r
-\r
-/**\r
- Set memory cache ability.\r
-\r
- @param PageTable PageTable Address\r
- @param Address Memory Address to change cache ability\r
- @param Cacheability Cache ability to set\r
-\r
-**/\r
-VOID\r
-SetCacheability (\r
- IN UINT64 *PageTable,\r
- IN UINTN Address,\r
- IN UINT8 Cacheability\r
- )\r
-{\r
- UINTN PTIndex;\r
- VOID *NewPageTableAddress;\r
- UINT64 *NewPageTable;\r
- UINTN Index;\r
-\r
- ASSERT ((Address & EFI_PAGE_MASK) == 0);\r
-\r
- if (sizeof (UINTN) == sizeof (UINT64)) {\r
- PTIndex = (UINTN)RShiftU64 (Address, 39) & 0x1ff;\r
- ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);\r
- }\r
-\r
- PTIndex = (UINTN)RShiftU64 (Address, 30) & 0x1ff;\r
- ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);\r
-\r
- //\r
- // A perfect implementation should check the original cacheability with the\r
- // one being set, and break a 2M page entry into pieces only when they\r
- // disagreed.\r
- //\r
- PTIndex = (UINTN)RShiftU64 (Address, 21) & 0x1ff;\r
- if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {\r
- //\r
- // Allocate a page from SMRAM\r
- //\r
- NewPageTableAddress = AllocatePageTableMemory (1);\r
- ASSERT (NewPageTableAddress != NULL);\r
+ if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) {\r
+ Pte = (UINT64*)(UINTN)(Pdpte[0] & ~mAddressEncMask & ~(EFI_PAGE_SIZE - 1));\r
+ if ((Pte[0] & IA32_PG_PS) == 0) {\r
+ // 4K-page entries are already mapped. Just hide the first one anyway.\r
+ Pte = (UINT64*)(UINTN)(Pte[0] & ~mAddressEncMask & ~(EFI_PAGE_SIZE - 1));\r
+ Pte[0] &= ~(UINT64)IA32_PG_P; // Hide page 0\r
+ } else {\r
+ // Create 4K-page entries\r
+ Pages = (UINTN)AllocatePageTableMemory (1);\r
+ ASSERT (Pages != 0);\r