1 | /** @file
|
---|
2 | Internal header for CpuPageTableLib.
|
---|
3 |
|
---|
4 | Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>
|
---|
5 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
6 |
|
---|
7 | **/
|
---|
8 |
|
---|
9 | #ifndef CPU_PAGE_TABLE_H_
|
---|
10 | #define CPU_PAGE_TABLE_H_
|
---|
11 |
|
---|
12 | #include <Base.h>
|
---|
13 | #include <Library/BaseLib.h>
|
---|
14 | #include <Library/BaseMemoryLib.h>
|
---|
15 | #include <Library/DebugLib.h>
|
---|
16 | #include <Library/CpuPageTableLib.h>
|
---|
17 |
|
---|
18 | #define IA32_PE_BASE_ADDRESS_MASK_40 0xFFFFFFFFFF000ull
|
---|
19 | #define IA32_PE_BASE_ADDRESS_MASK_39 0xFFFFFFFFFE000ull
|
---|
20 |
|
---|
21 | #define REGION_LENGTH(l) LShiftU64 (1, (l) * 9 + 3)
|
---|
22 |
|
---|
23 | #define MAX_PAE_PDPTE_NUM 4
|
---|
24 |
|
---|
25 | typedef enum {
|
---|
26 | Pte = 1,
|
---|
27 | Pde = 2,
|
---|
28 | Pdpte = 3,
|
---|
29 | Pml4 = 4,
|
---|
30 | Pml5 = 5
|
---|
31 | } IA32_PAGE_LEVEL;
|
---|
32 |
|
---|
33 | typedef struct {
|
---|
34 | UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory
|
---|
35 | UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write
|
---|
36 | UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User
|
---|
37 | UINT32 Reserved0 : 29;
|
---|
38 | UINT32 Reserved1 : 31;
|
---|
39 | UINT32 Nx : 1; // No Execute bit
|
---|
40 | } IA32_PAGE_COMMON_ENTRY;
|
---|
41 |
|
---|
42 | ///
|
---|
43 | /// Format of a non-leaf entry that references a page table entry
|
---|
44 | ///
|
---|
45 | typedef union {
|
---|
46 | struct {
|
---|
47 | UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory
|
---|
48 | UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write
|
---|
49 | UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User
|
---|
50 | UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching
|
---|
51 | UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached
|
---|
52 | UINT32 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)
|
---|
53 | UINT32 Available0 : 1; // Ignored
|
---|
54 | UINT32 MustBeZero : 1; // Must Be Zero
|
---|
55 | UINT32 Available2 : 4; // Ignored
|
---|
56 | UINT32 PageTableBaseAddressLow : 20; // Page Table Base Address Low
|
---|
57 |
|
---|
58 | UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High
|
---|
59 | UINT32 Available3 : 11; // Ignored
|
---|
60 | UINT32 Nx : 1; // No Execute bit
|
---|
61 | } Bits;
|
---|
62 | UINT64 Uint64;
|
---|
63 | } IA32_PAGE_NON_LEAF_ENTRY;
|
---|
64 |
|
---|
65 | #define IA32_PNLE_PAGE_TABLE_BASE_ADDRESS(pa) ((pa)->Uint64 & IA32_PE_BASE_ADDRESS_MASK_40)
|
---|
66 |
|
---|
67 | ///
|
---|
68 | /// Format of a PML5 Entry (PML5E) that References a PML4 Table
|
---|
69 | ///
|
---|
70 | typedef IA32_PAGE_NON_LEAF_ENTRY IA32_PML5E;
|
---|
71 |
|
---|
72 | ///
|
---|
73 | /// Format of a PML4 Entry (PML4E) that References a Page-Directory-Pointer Table
|
---|
74 | ///
|
---|
75 | typedef IA32_PAGE_NON_LEAF_ENTRY IA32_PML4E;
|
---|
76 |
|
---|
77 | ///
|
---|
78 | /// Format of a Page-Directory-Pointer-Table Entry (PDPTE) that References a Page Directory
|
---|
79 | ///
|
---|
80 | typedef IA32_PAGE_NON_LEAF_ENTRY IA32_PDPTE;
|
---|
81 |
|
---|
82 | ///
|
---|
83 | /// Format of a Page-Directory Entry that References a Page Table
|
---|
84 | ///
|
---|
85 | typedef IA32_PAGE_NON_LEAF_ENTRY IA32_PDE;
|
---|
86 |
|
---|
87 | ///
|
---|
88 | /// Format of a leaf entry that Maps a 1-Gbyte or 2-MByte Page
|
---|
89 | ///
|
---|
90 | typedef union {
|
---|
91 | struct {
|
---|
92 | UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory
|
---|
93 | UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write
|
---|
94 | UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User
|
---|
95 | UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching
|
---|
96 | UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached
|
---|
97 | UINT32 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)
|
---|
98 | UINT32 Dirty : 1; // 0 = Not dirty, 1 = Dirty (set by CPU)
|
---|
99 | UINT32 MustBeOne : 1; // Page Size. Must Be One
|
---|
100 | UINT32 Global : 1; // 0 = Not global, 1 = Global (if CR4.PGE = 1)
|
---|
101 | UINT32 Available1 : 3; // Ignored
|
---|
102 | UINT32 Pat : 1; // PAT
|
---|
103 | UINT32 PageTableBaseAddressLow : 19; // Page Table Base Address Low
|
---|
104 |
|
---|
105 | UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High
|
---|
106 | UINT32 Available3 : 7; // Ignored
|
---|
107 | UINT32 ProtectionKey : 4; // Protection key
|
---|
108 | UINT32 Nx : 1; // No Execute bit
|
---|
109 | } Bits;
|
---|
110 | UINT64 Uint64;
|
---|
111 | } IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE;
|
---|
112 | #define IA32_PLEB_PAGE_TABLE_BASE_ADDRESS(pa) ((pa)->Uint64 & IA32_PE_BASE_ADDRESS_MASK_39)
|
---|
113 |
|
---|
114 | ///
|
---|
115 | /// Format of a Page-Directory Entry that Maps a 2-MByte Page
|
---|
116 | ///
|
---|
117 | typedef IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE IA32_PDE_2M;
|
---|
118 |
|
---|
119 | ///
|
---|
120 | /// Format of a Page-Directory-Pointer-Table Entry (PDPTE) that Maps a 1-GByte Page
|
---|
121 | ///
|
---|
122 | typedef IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE IA32_PDPTE_1G;
|
---|
123 |
|
---|
124 | ///
|
---|
125 | /// Format of a Page-Table Entry that Maps a 4-KByte Page
|
---|
126 | ///
|
---|
127 | typedef union {
|
---|
128 | struct {
|
---|
129 | UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory
|
---|
130 | UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write
|
---|
131 | UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User
|
---|
132 | UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching
|
---|
133 | UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached
|
---|
134 | UINT32 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)
|
---|
135 | UINT32 Dirty : 1; // 0 = Not dirty, 1 = Dirty (set by CPU)
|
---|
136 | UINT32 Pat : 1; // PAT
|
---|
137 | UINT32 Global : 1; // 0 = Not global, 1 = Global (if CR4.PGE = 1)
|
---|
138 | UINT32 Available1 : 3; // Ignored
|
---|
139 | UINT32 PageTableBaseAddressLow : 20; // Page Table Base Address Low
|
---|
140 |
|
---|
141 | UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High
|
---|
142 | UINT32 Available3 : 7; // Ignored
|
---|
143 | UINT32 ProtectionKey : 4; // Protection key
|
---|
144 | UINT32 Nx : 1; // No Execute bit
|
---|
145 | } Bits;
|
---|
146 | UINT64 Uint64;
|
---|
147 | } IA32_PTE_4K;
|
---|
148 | #define IA32_PTE4K_PAGE_TABLE_BASE_ADDRESS(pa) ((pa)->Uint64 & IA32_PE_BASE_ADDRESS_MASK_40)
|
---|
149 |
|
---|
150 | ///
|
---|
151 | /// Format of a Page-Directory-Pointer-Table Entry (PDPTE) that References a Page Directory (32bit PAE specific)
|
---|
152 | ///
|
---|
153 | typedef union {
|
---|
154 | struct {
|
---|
155 | UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory
|
---|
156 | UINT32 MustBeZero : 2; // Must Be Zero
|
---|
157 | UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching
|
---|
158 | UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached
|
---|
159 | UINT32 MustBeZero2 : 4; // Must Be Zero
|
---|
160 | UINT32 Available : 3; // Ignored
|
---|
161 | UINT32 PageTableBaseAddressLow : 20; // Page Table Base Address Low
|
---|
162 |
|
---|
163 | UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High
|
---|
164 | UINT32 MustBeZero3 : 12; // Must Be Zero
|
---|
165 | } Bits;
|
---|
166 | UINT64 Uint64;
|
---|
167 | } IA32_PDPTE_PAE;
|
---|
168 |
|
---|
169 | typedef union {
|
---|
170 | IA32_PAGE_NON_LEAF_ENTRY Pnle; // To access Pml5, Pml4, Pdpte and Pde.
|
---|
171 | IA32_PML5E Pml5;
|
---|
172 | IA32_PML4E Pml4;
|
---|
173 | IA32_PDPTE Pdpte;
|
---|
174 | IA32_PDE Pde;
|
---|
175 |
|
---|
176 | IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE PleB; // to access Pdpte1G and Pde2M.
|
---|
177 | IA32_PDPTE_1G Pdpte1G;
|
---|
178 | IA32_PDE_2M Pde2M;
|
---|
179 |
|
---|
180 | IA32_PTE_4K Pte4K;
|
---|
181 |
|
---|
182 | IA32_PDPTE_PAE PdptePae;
|
---|
183 | IA32_PAGE_COMMON_ENTRY Pce; // To access all common bits in above entries.
|
---|
184 |
|
---|
185 | UINT64 Uint64;
|
---|
186 | UINTN Uintn;
|
---|
187 | } IA32_PAGING_ENTRY;
|
---|
188 |
|
---|
189 | /**
|
---|
190 | Return TRUE when the page table entry is a leaf entry that points to the physical address memory.
|
---|
191 | Return FALSE when the page table entry is a non-leaf entry that points to the page table entries.
|
---|
192 |
|
---|
193 | @param[in] PagingEntry Pointer to the page table entry.
|
---|
194 | @param[in] Level Page level where the page table entry resides in.
|
---|
195 |
|
---|
196 | @retval TRUE It's a leaf entry.
|
---|
197 | @retval FALSE It's a non-leaf entry.
|
---|
198 | **/
|
---|
199 | BOOLEAN
|
---|
200 | IsPle (
|
---|
201 | IN IA32_PAGING_ENTRY *PagingEntry,
|
---|
202 | IN UINTN Level
|
---|
203 | );
|
---|
204 |
|
---|
205 | /**
|
---|
206 | Return the attribute of a 2M/1G page table entry.
|
---|
207 |
|
---|
208 | @param[in] PleB Pointer to a 2M/1G page table entry.
|
---|
209 | @param[in] ParentMapAttribute Pointer to the parent attribute.
|
---|
210 |
|
---|
211 | @return Attribute of the 2M/1G page table entry.
|
---|
212 | **/
|
---|
213 | UINT64
|
---|
214 | PageTableLibGetPleBMapAttribute (
|
---|
215 | IN IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE *PleB,
|
---|
216 | IN IA32_MAP_ATTRIBUTE *ParentMapAttribute
|
---|
217 | );
|
---|
218 |
|
---|
219 | /**
|
---|
220 | Return the attribute of a non-leaf page table entry.
|
---|
221 |
|
---|
222 | @param[in] Pnle Pointer to a non-leaf page table entry.
|
---|
223 | @param[in] ParentMapAttribute Pointer to the parent attribute.
|
---|
224 |
|
---|
225 | @return Attribute of the non-leaf page table entry.
|
---|
226 | **/
|
---|
227 | UINT64
|
---|
228 | PageTableLibGetPnleMapAttribute (
|
---|
229 | IN IA32_PAGE_NON_LEAF_ENTRY *Pnle,
|
---|
230 | IN IA32_MAP_ATTRIBUTE *ParentMapAttribute
|
---|
231 | );
|
---|
232 |
|
---|
233 | #endif
|
---|