| /** @file | |
| Internal header for CpuPageTableLib. | |
| Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #ifndef CPU_PAGE_TABLE_H_ | |
| #define CPU_PAGE_TABLE_H_ | |
| #include <Base.h> | |
| #include <Library/BaseLib.h> | |
| #include <Library/BaseMemoryLib.h> | |
| #include <Library/DebugLib.h> | |
| #include <Library/CpuPageTableLib.h> | |
| #define IA32_PE_BASE_ADDRESS_MASK_40 0xFFFFFFFFFF000ull | |
| #define IA32_PE_BASE_ADDRESS_MASK_39 0xFFFFFFFFFE000ull | |
| #define REGION_LENGTH(l) LShiftU64 (1, (l) * 9 + 3) | |
| #define MAX_PAE_PDPTE_NUM 4 | |
| typedef enum { | |
| Pte = 1, | |
| Pde = 2, | |
| Pdpte = 3, | |
| Pml4 = 4, | |
| Pml5 = 5 | |
| } IA32_PAGE_LEVEL; | |
| typedef struct { | |
| UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory | |
| UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write | |
| UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User | |
| UINT32 Reserved0 : 29; | |
| UINT32 Reserved1 : 31; | |
| UINT32 Nx : 1; // No Execute bit | |
| } IA32_PAGE_COMMON_ENTRY; | |
| /// | |
| /// Format of a non-leaf entry that references a page table entry | |
| /// | |
| typedef union { | |
| struct { | |
| UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory | |
| UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write | |
| UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User | |
| UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching | |
| UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached | |
| UINT32 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) | |
| UINT32 Available0 : 1; // Ignored | |
| UINT32 MustBeZero : 1; // Must Be Zero | |
| UINT32 Available2 : 4; // Ignored | |
| UINT32 PageTableBaseAddressLow : 20; // Page Table Base Address Low | |
| UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High | |
| UINT32 Available3 : 11; // Ignored | |
| UINT32 Nx : 1; // No Execute bit | |
| } Bits; | |
| UINT64 Uint64; | |
| } IA32_PAGE_NON_LEAF_ENTRY; | |
| #define IA32_PNLE_PAGE_TABLE_BASE_ADDRESS(pa) ((pa)->Uint64 & IA32_PE_BASE_ADDRESS_MASK_40) | |
| /// | |
| /// Format of a PML5 Entry (PML5E) that References a PML4 Table | |
| /// | |
| typedef IA32_PAGE_NON_LEAF_ENTRY IA32_PML5E; | |
| /// | |
| /// Format of a PML4 Entry (PML4E) that References a Page-Directory-Pointer Table | |
| /// | |
| typedef IA32_PAGE_NON_LEAF_ENTRY IA32_PML4E; | |
| /// | |
| /// Format of a Page-Directory-Pointer-Table Entry (PDPTE) that References a Page Directory | |
| /// | |
| typedef IA32_PAGE_NON_LEAF_ENTRY IA32_PDPTE; | |
| /// | |
| /// Format of a Page-Directory Entry that References a Page Table | |
| /// | |
| typedef IA32_PAGE_NON_LEAF_ENTRY IA32_PDE; | |
| /// | |
| /// Format of a leaf entry that Maps a 1-Gbyte or 2-MByte Page | |
| /// | |
| typedef union { | |
| struct { | |
| UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory | |
| UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write | |
| UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User | |
| UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching | |
| UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached | |
| UINT32 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) | |
| UINT32 Dirty : 1; // 0 = Not dirty, 1 = Dirty (set by CPU) | |
| UINT32 MustBeOne : 1; // Page Size. Must Be One | |
| UINT32 Global : 1; // 0 = Not global, 1 = Global (if CR4.PGE = 1) | |
| UINT32 Available1 : 3; // Ignored | |
| UINT32 Pat : 1; // PAT | |
| UINT32 PageTableBaseAddressLow : 19; // Page Table Base Address Low | |
| UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High | |
| UINT32 Available3 : 7; // Ignored | |
| UINT32 ProtectionKey : 4; // Protection key | |
| UINT32 Nx : 1; // No Execute bit | |
| } Bits; | |
| UINT64 Uint64; | |
| } IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE; | |
| #define IA32_PLEB_PAGE_TABLE_BASE_ADDRESS(pa) ((pa)->Uint64 & IA32_PE_BASE_ADDRESS_MASK_39) | |
| /// | |
| /// Format of a Page-Directory Entry that Maps a 2-MByte Page | |
| /// | |
| typedef IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE IA32_PDE_2M; | |
| /// | |
| /// Format of a Page-Directory-Pointer-Table Entry (PDPTE) that Maps a 1-GByte Page | |
| /// | |
| typedef IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE IA32_PDPTE_1G; | |
| /// | |
| /// Format of a Page-Table Entry that Maps a 4-KByte Page | |
| /// | |
| typedef union { | |
| struct { | |
| UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory | |
| UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write | |
| UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User | |
| UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching | |
| UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached | |
| UINT32 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) | |
| UINT32 Dirty : 1; // 0 = Not dirty, 1 = Dirty (set by CPU) | |
| UINT32 Pat : 1; // PAT | |
| UINT32 Global : 1; // 0 = Not global, 1 = Global (if CR4.PGE = 1) | |
| UINT32 Available1 : 3; // Ignored | |
| UINT32 PageTableBaseAddressLow : 20; // Page Table Base Address Low | |
| UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High | |
| UINT32 Available3 : 7; // Ignored | |
| UINT32 ProtectionKey : 4; // Protection key | |
| UINT32 Nx : 1; // No Execute bit | |
| } Bits; | |
| UINT64 Uint64; | |
| } IA32_PTE_4K; | |
| #define IA32_PTE4K_PAGE_TABLE_BASE_ADDRESS(pa) ((pa)->Uint64 & IA32_PE_BASE_ADDRESS_MASK_40) | |
| /// | |
| /// Format of a Page-Directory-Pointer-Table Entry (PDPTE) that References a Page Directory (32bit PAE specific) | |
| /// | |
| typedef union { | |
| struct { | |
| UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory | |
| UINT32 MustBeZero : 2; // Must Be Zero | |
| UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching | |
| UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached | |
| UINT32 MustBeZero2 : 4; // Must Be Zero | |
| UINT32 Available : 3; // Ignored | |
| UINT32 PageTableBaseAddressLow : 20; // Page Table Base Address Low | |
| UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High | |
| UINT32 MustBeZero3 : 12; // Must Be Zero | |
| } Bits; | |
| UINT64 Uint64; | |
| } IA32_PDPTE_PAE; | |
| typedef union { | |
| IA32_PAGE_NON_LEAF_ENTRY Pnle; // To access Pml5, Pml4, Pdpte and Pde. | |
| IA32_PML5E Pml5; | |
| IA32_PML4E Pml4; | |
| IA32_PDPTE Pdpte; | |
| IA32_PDE Pde; | |
| IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE PleB; // to access Pdpte1G and Pde2M. | |
| IA32_PDPTE_1G Pdpte1G; | |
| IA32_PDE_2M Pde2M; | |
| IA32_PTE_4K Pte4K; | |
| IA32_PDPTE_PAE PdptePae; | |
| IA32_PAGE_COMMON_ENTRY Pce; // To access all common bits in above entries. | |
| UINT64 Uint64; | |
| UINTN Uintn; | |
| } IA32_PAGING_ENTRY; | |
| /** | |
| Return TRUE when the page table entry is a leaf entry that points to the physical address memory. | |
| Return FALSE when the page table entry is a non-leaf entry that points to the page table entries. | |
| @param[in] PagingEntry Pointer to the page table entry. | |
| @param[in] Level Page level where the page table entry resides in. | |
| @retval TRUE It's a leaf entry. | |
| @retval FALSE It's a non-leaf entry. | |
| **/ | |
| BOOLEAN | |
| IsPle ( | |
| IN IA32_PAGING_ENTRY *PagingEntry, | |
| IN UINTN Level | |
| ); | |
| /** | |
| Return the attribute of a 2M/1G page table entry. | |
| @param[in] PleB Pointer to a 2M/1G page table entry. | |
| @param[in] ParentMapAttribute Pointer to the parent attribute. | |
| @return Attribute of the 2M/1G page table entry. | |
| **/ | |
| UINT64 | |
| PageTableLibGetPleBMapAttribute ( | |
| IN IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE *PleB, | |
| IN IA32_MAP_ATTRIBUTE *ParentMapAttribute | |
| ); | |
| /** | |
| Return the attribute of a non-leaf page table entry. | |
| @param[in] Pnle Pointer to a non-leaf page table entry. | |
| @param[in] ParentMapAttribute Pointer to the parent attribute. | |
| @return Attribute of the non-leaf page table entry. | |
| **/ | |
| UINT64 | |
| PageTableLibGetPnleMapAttribute ( | |
| IN IA32_PAGE_NON_LEAF_ENTRY *Pnle, | |
| IN IA32_MAP_ATTRIBUTE *ParentMapAttribute | |
| ); | |
| #endif |