if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
InitializeIDTSmmStackGuard ();\r
}\r
- return Gen4GPageTable (0);\r
+ return Gen4GPageTable (0, TRUE);\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- mSmmS3ResumeState->SmmS3Cr3 = Gen4GPageTable (0);\r
+ mSmmS3ResumeState->SmmS3Cr3 = Gen4GPageTable (0, TRUE);\r
\r
return ;\r
}\r
Create 4G PageTable in SMRAM.\r
\r
@param ExtraPages Additional page numbers besides for 4G memory\r
+ @param Is32BitPageTable Whether the page table is 32-bit PAE\r
@return PageTable Address\r
\r
**/\r
UINT32\r
Gen4GPageTable (\r
- IN UINTN ExtraPages\r
+ IN UINTN ExtraPages,\r
+ IN BOOLEAN Is32BitPageTable\r
)\r
{\r
VOID *PageTable;\r
// Set Page Directory Pointers\r
//\r
for (Index = 0; Index < 4; Index++) {\r
- Pte[Index] = (UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1) + IA32_PG_P;\r
+ Pte[Index] = (UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1) + (Is32BitPageTable ? IA32_PAE_PDPTE_ATTRIBUTE_BITS : PAGE_ATTRIBUTE_BITS);\r
}\r
Pte += EFI_PAGE_SIZE / sizeof (*Pte);\r
\r
// Fill in Page Directory Entries\r
//\r
for (Index = 0; Index < EFI_PAGE_SIZE * 4 / sizeof (*Pte); Index++) {\r
- Pte[Index] = (Index << 21) + IA32_PG_PS + IA32_PG_RW + IA32_PG_P;\r
+ Pte[Index] = (Index << 21) | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;\r
}\r
\r
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
Pdpte = (UINT64*)PageTable;\r
for (PageIndex = Low2MBoundary; PageIndex <= High2MBoundary; PageIndex += SIZE_2MB) {\r
Pte = (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~(EFI_PAGE_SIZE - 1));\r
- Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages + IA32_PG_RW + IA32_PG_P;\r
+ Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | PAGE_ATTRIBUTE_BITS;\r
//\r
// Fill in Page Table Entries\r
//\r
GuardPage = 0;\r
}\r
} else {\r
- Pte[Index] = PageAddress + IA32_PG_RW + IA32_PG_P;\r
+ Pte[Index] = PageAddress | PAGE_ATTRIBUTE_BITS;\r
}\r
PageAddress+= EFI_PAGE_SIZE;\r
}\r
NewPageTable[Index] |= (UINT64)(Index << EFI_PAGE_SHIFT);\r
}\r
\r
- PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | IA32_PG_P;\r
+ PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | PAGE_ATTRIBUTE_BITS;\r
}\r
\r
ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
///\r
#define IA32_PG_P BIT0\r
#define IA32_PG_RW BIT1\r
+#define IA32_PG_U BIT2\r
#define IA32_PG_WT BIT3\r
#define IA32_PG_CD BIT4\r
#define IA32_PG_A BIT5\r
+#define IA32_PG_D BIT6\r
#define IA32_PG_PS BIT7\r
#define IA32_PG_PAT_2M BIT12\r
#define IA32_PG_PAT_4K IA32_PG_PS\r
#define IA32_PG_PMNT BIT62\r
#define IA32_PG_NX BIT63\r
\r
+#define PAGE_ATTRIBUTE_BITS (IA32_PG_RW | IA32_PG_P)\r
+//\r
+// Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE\r
+// X64 PAE PDPTE does not have such restriction\r
+//\r
+#define IA32_PAE_PDPTE_ATTRIBUTE_BITS (IA32_PG_P)\r
+\r
//\r
// Size of Task-State Segment defined in IA32 Manual\r
//\r
Create 4G PageTable in SMRAM.\r
\r
@param ExtraPages Additional page numbers besides for 4G memory\r
+ @param Is32BitPageTable Whether the page table is 32-bit PAE\r
@return PageTable Address\r
\r
**/\r
UINT32\r
Gen4GPageTable (\r
- IN UINTN ExtraPages\r
+ IN UINTN ExtraPages,\r
+ IN BOOLEAN Is32BitPageTable\r
);\r
\r
\r
\r
// Split it\r
for (Level4 = 0; Level4 < SIZE_4KB / sizeof(*Pt); Level4++) {\r
- Pt[Level4] = Address + ((Level4 << 12) | IA32_PG_RW | IA32_PG_P);\r
+ Pt[Level4] = Address + ((Level4 << 12) | PAGE_ATTRIBUTE_BITS);\r
} // end for PT\r
- *Pte = (UINTN)Pt | IA32_PG_RW | IA32_PG_P;\r
+ *Pte = (UINTN)Pt | PAGE_ATTRIBUTE_BITS;\r
} // end if IsAddressSplit\r
} // end for PTE\r
} // end for PDE\r
//\r
// Patch to remove Present flag and RW flag\r
//\r
- *Pte = *Pte & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P));\r
+ *Pte = *Pte & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);\r
}\r
if (Nx && mXdSupported) {\r
*Pte = *Pte | IA32_PG_NX;\r
}\r
for (Level4 = 0; Level4 < SIZE_4KB / sizeof(*Pt); Level4++, Pt++) {\r
if (!IsAddressValid (Address, &Nx)) {\r
- *Pt = *Pt & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P));\r
+ *Pt = *Pt & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);\r
}\r
if (Nx && mXdSupported) {\r
*Pt = *Pt | IA32_PG_NX;\r
//\r
PageTable[PTIndex] = (PFAddress & ~((1ull << 21) - 1));\r
PageTable[PTIndex] |= (UINT64)IA32_PG_PS;\r
- PageTable[PTIndex] |= (UINT64)(IA32_PG_RW | IA32_PG_P);\r
+ PageTable[PTIndex] |= (UINT64)PAGE_ATTRIBUTE_BITS;\r
if ((ErrorCode & IA32_PF_EC_ID) != 0) {\r
PageTable[PTIndex] &= ~IA32_PG_NX;\r
}\r
// Set new entry\r
//\r
PageTable[PTIndex] = (PFAddress & ~((1ull << 12) - 1));\r
- PageTable[PTIndex] |= (UINT64)(IA32_PG_RW | IA32_PG_P);\r
+ PageTable[PTIndex] |= (UINT64)PAGE_ATTRIBUTE_BITS;\r
if ((ErrorCode & IA32_PF_EC_ID) != 0) {\r
PageTable[PTIndex] &= ~IA32_PG_NX;\r
}\r
//\r
// Generate PAE page table for the first 4GB memory space\r
//\r
- Pages = Gen4GPageTable (PAGE_TABLE_PAGES + 1);\r
+ Pages = Gen4GPageTable (PAGE_TABLE_PAGES + 1, FALSE);\r
\r
//\r
// Set IA32_PG_PMNT bit to mask this entry\r
// Fill Page-Table-Level4 (PML4) entry\r
//\r
PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (PAGE_TABLE_PAGES + 1));\r
- *PTEntry = Pages + IA32_PG_P;\r
+ *PTEntry = Pages + PAGE_ATTRIBUTE_BITS;\r
ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry));\r
//\r
// Set sub-entries number\r
//\r
// If the entry is not present, allocate one page from page pool for it\r
//\r
- PageTable[PTIndex] = AllocPage () | IA32_PG_RW | IA32_PG_P;\r
+ PageTable[PTIndex] = AllocPage () | PAGE_ATTRIBUTE_BITS;\r
} else {\r
//\r
// Save the upper entry address\r
// Fill the new entry\r
//\r
PageTable[PTIndex] = (PFAddress & gPhyMask & ~((1ull << EndBit) - 1)) |\r
- PageAttribute | IA32_PG_A | IA32_PG_RW | IA32_PG_P;\r
+ PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS;\r
if (UpperEntry != NULL) {\r
SetSubEntriesNum (UpperEntry, GetSubEntriesNum (UpperEntry) + 1);\r
}\r
//\r
// Generate PAE page table for the first 4GB memory space\r
//\r
- Pages = Gen4GPageTable (1);\r
+ Pages = Gen4GPageTable (1, FALSE);\r
\r
//\r
// Fill Page-Table-Level4 (PML4) entry\r
//\r
PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (1));\r
- *PTEntry = Pages + IA32_PG_P;\r
+ *PTEntry = Pages | PAGE_ATTRIBUTE_BITS;\r
ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry));\r
\r
//\r
//\r
// Link & Record the current uplink\r
//\r
- *Uplink = Address | IA32_PG_P | IA32_PG_RW;\r
+ *Uplink = Address | PAGE_ATTRIBUTE_BITS;\r
mPFPageUplink[mPFPageIndex] = Uplink;\r
\r
mPFPageIndex = (mPFPageIndex + 1) % MAX_PF_PAGE_COUNT;\r
// PTE\r
PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);\r
for (Index = 0; Index < 512; Index++) {\r
- PageTable[Index] = Address | IA32_PG_RW | IA32_PG_P;\r
+ PageTable[Index] = Address | PAGE_ATTRIBUTE_BITS;\r
if (!IsAddressValid (Address, &Nx)) {\r
- PageTable[Index] = PageTable[Index] & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P));\r
+ PageTable[Index] = PageTable[Index] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);\r
}\r
if (Nx && mXdSupported) {\r
PageTable[Index] = PageTable[Index] | IA32_PG_NX;\r
//\r
// Patch to remove present flag and rw flag.\r
//\r
- PageTable[PTIndex] = PageTable[PTIndex] & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P));\r
+ PageTable[PTIndex] = PageTable[PTIndex] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);\r
}\r
//\r
// Set XD bit to 1\r
//\r
// Add present flag or clear XD flag to make page fault handler succeed.\r
//\r
- PageTable[PTIndex] |= (UINT64)(IA32_PG_RW | IA32_PG_P);\r
+ PageTable[PTIndex] |= (UINT64)(PAGE_ATTRIBUTE_BITS);\r
if ((ErrorCode & IA32_PF_EC_ID) != 0) {\r
//\r
// If page fault is caused by instruction fetch, clear XD bit in the entry.\r