My Project
Loading...
Searching...
No Matches
pfn.c
Go to the documentation of this file.
1/*++
2
3Module Name:
4
5 pfn.c
6
7Purpose:
8
9 This translation unit contains the implementation of the PFN Database (covers physical memory map init)
10
11Author:
12
13 slep (Matanel) 2025.
14
15Revision History:
16 DD/MM/YY
17
18
19 17/10/2025 - Revised Physical Memory from a simple bitmap to a PFN database.
20
21
22--*/
23
24#include "../../includes/mm.h"
25#include "../../includes/mg.h"
26#include "../../assert.h"
27#include "../../includes/me.h"
28
32
33static
34uint64_t
35MiGetTotalMemory (
36 const BOOT_INFO* boot_info
37)
38
39/*++
40
41 Routine description:
42
43 Calculates the highest address of USABLE physical memory in the system.
44
45 Arguments:
46
47 [IN] Pointer to BOOT_INFO struct, obtained from UEFI.
48
49 Return Values:
50
51 Highest Usable Address in physical memory (total amount of usable RAM)
52
53 DO NOTE: The function will return the max address that is usable in the system, which might leave MMIO holes above, these will NOT be added into the PFN DB.
54
55--*/
56
57{
58 uint64_t highest_addr = 0;
59 size_t entry_count = boot_info->MapSize / boot_info->DescriptorSize;
60 PEFI_MEMORY_DESCRIPTOR desc = boot_info->MemoryMap;
61
62 for (size_t i = 0; i < entry_count; i++) {
63 // FILTER: Only look at usable RAM or memory we might reclaim.
64 // Ignore Reserved, Unusable, and MemoryMappedIO.
65 // TODO Other types...
66 if (desc->Type == EfiConventionalMemory)
67 {
68 uint64_t region_end = desc->PhysicalStart + (desc->NumberOfPages * PhysicalFrameSize);
69 if (region_end > highest_addr) highest_addr = region_end;
70 }
71
72 desc = (PEFI_MEMORY_DESCRIPTOR)((uint8_t*)desc + boot_info->DescriptorSize);
73 }
74
75 return highest_addr;
76}
77
78static
79void
80MiReservePhysRange(
81 uint64_t phys_start,
82 uint64_t length
83)
84
85{
86 uint64_t first = phys_start / PhysicalFrameSize;
87 uint64_t pages = (length + PhysicalFrameSize - 1) / PhysicalFrameSize;
88 for (uint64_t i = 0; i < pages; ++i) {
89 uint64_t idx = first + i;
90 if (idx >= PfnDatabase.TotalPageCount) continue;
91 PPFN_ENTRY e = &PfnDatabase.PfnEntries[idx];
92 e->RefCount = 1;
96 }
97}
98
101 IN PBOOT_INFO BootInfo
102)
103
104/*++
105
106 Routine description:
107
108 Initializes the global PFN database.
109
110 Arguments:
111
112 [IN] Pointer to BOOT_INFO struct, obtained from UEFI.
113
114 Return Values:
115
116 MTSTATUS Status Code.
117
118--*/
119
120{
121 // First of all, before creating the PFN Database
122 // we would need the amount of total RAM, divide that by each physical frame size
123 // to allocate the amount of PFN_ENTRY(ies) needed.
124 uint64_t totalRam = MiGetTotalMemory(BootInfo);
125 if (!totalRam) return MT_NO_MEMORY;
126
127 uint64_t totalPfnEntries = totalRam / PhysicalFrameSize;
128
129 // The amount of PFN Entries needed times the sizeof the struct, gives us the amount in bytes.
130 uint64_t neededRam = totalPfnEntries * sizeof(PFN_ENTRY);
131 assert((neededRam) < INT32_MAX, "Needed Ram DB is insanely huge");
132
133 // Now, we need to find a suitable memory region to hold the PFN Entries in.
134 PEFI_MEMORY_DESCRIPTOR desc = BootInfo->MemoryMap;
135 size_t entryCount = BootInfo->MapSize / BootInfo->DescriptorSize;
136 uint64_t pfnEntriesPhys = 0;
137
138 // Loop over all memory.
139 for (size_t i = 0; i < entryCount; i++) {
140 if (desc->Type == EfiConventionalMemory) {
141 // This physical region size is the number of pages in it times frame size.
142 uint64_t regionSize = desc->NumberOfPages * PhysicalFrameSize;
143
144 if (regionSize >= neededRam) {
145 // This region can hold the PFN database entries.
146 pfnEntriesPhys = desc->PhysicalStart;
147 break;
148 }
149 }
150 // Advance to the next UEFI memory descriptor in the map.
151 desc = (PEFI_MEMORY_DESCRIPTOR)((uint8_t*)desc + BootInfo->DescriptorSize);
152 }
153
154 // Verify we found a suitable region.
155 if (!pfnEntriesPhys) return MT_NOT_FOUND;
156
157 // Convert the address to our virtual offsetable.
158 uint64_t pfnEntriesVirt = pfnEntriesPhys + PhysicalMemoryOffset;
159
160 // Initialize the doubly linked lists.
161 InitializeListHead(&PfnDatabase.FreePageList.ListEntry);
162 InitializeListHead(&PfnDatabase.BadPageList.ListEntry);
163 InitializeListHead(&PfnDatabase.StandbyPageList.ListEntry);
164 InitializeListHead(&PfnDatabase.ZeroedPageList.ListEntry);
165 InitializeListHead(&PfnDatabase.ModifiedPageList.ListEntry);
166
167 // Map the whole region, acquire its PTE for each 4KiB.
168 uint64_t neededPages = (neededRam + VirtualPageSize - 1) / VirtualPageSize;
169
170 for (uint64_t i = 0; i < neededPages; i++) {
171 PMMPTE pte = MiGetPtePointer(pfnEntriesVirt);
172 if (!pte) return MT_GENERAL_FAILURE;
173 MI_WRITE_PTE(pte, pfnEntriesVirt, pfnEntriesPhys, PAGE_PRESENT | PAGE_RW);
174 pfnEntriesVirt += VirtualPageSize;
175 pfnEntriesPhys += VirtualPageSize;
176 }
177
178 // Set the pointer.
179 uint64_t pfn_region_phys = pfnEntriesPhys - (neededPages * VirtualPageSize);
180 PfnDatabase.PfnEntries = (PPFN_ENTRY)(uintptr_t)(pfn_region_phys + PhysicalMemoryOffset);
181
182 // Zero the region.
183 kmemset(PfnDatabase.PfnEntries, 0, neededPages * VirtualPageSize);
184
185 // Initialize counts.
186 PfnDatabase.TotalPageCount = totalPfnEntries;
187 PfnDatabase.AvailablePages = 0;
188 PfnDatabase.TotalReserved = 0;
189
190 PfnDatabase.FreePageList.Count = 0;
191 PfnDatabase.BadPageList.Count = 0;
192 PfnDatabase.StandbyPageList.Count = 0;
193 PfnDatabase.ZeroedPageList.Count = 0;
194 PfnDatabase.ModifiedPageList.Count = 0;
195
196 // Initialize locks
197 PfnDatabase.PfnDatabaseLock.locked = 0;
198 PfnDatabase.BadPageList.PfnListLock.locked = 0;
199 PfnDatabase.StandbyPageList.PfnListLock.locked = 0;
200 PfnDatabase.ZeroedPageList.PfnListLock.locked = 0;
201 PfnDatabase.FreePageList.PfnListLock.locked = 0;
202 PfnDatabase.ModifiedPageList.PfnListLock.locked = 0;
203
204 // Reserve the PFN Array in the PFN List.
205 MiReservePhysRange(pfn_region_phys, neededPages * VirtualPageSize);
206
207 // We can interact with the entries, begin filling the PFN DB.
208 PAGE_INDEX lastPfnIdx = 0;
209 desc = BootInfo->MemoryMap; // reset desc to original pointer
210 for (size_t i = 0; i < entryCount; i++) {
211 uint64_t regionStart = desc->PhysicalStart;
212 uint64_t regionPages = desc->NumberOfPages;
213
214 // For each 4KiB page in the physical region of pages
215 for (uint64_t p = 0; p < regionPages; p++) {
216 // The physical address is calculated by taking the (regionStart (physical address of region base) plus the current increment) times the frame size.
217 uint64_t physAddr = regionStart + p * PhysicalFrameSize;
218
219 uint64_t currentPfnIndex = (physAddr / PhysicalFrameSize);
220
221 // UEFI Memory maps arent sorted in order, we could get address 0x100000 at one iteration, and address 0x2000 at the next iteration.
222 // We guard it with a simple if statement.
223 if (currentPfnIndex > lastPfnIdx) {
224 lastPfnIdx = currentPfnIndex;
225 }
226
227 if (currentPfnIndex >= PfnDatabase.TotalPageCount) {
228 // out of range physical address, we skip.
229 continue;
230 }
231
232 PPFN_ENTRY entry = &PfnDatabase.PfnEntries[currentPfnIndex];
233
234 // If this page is inside the PFN-array region we just reserved, skip adding it to db.
235 if (desc->Type == EfiConventionalMemory) {
236 if (physAddr >= pfn_region_phys && physAddr < pfn_region_phys + neededPages * VirtualPageSize) {
237 continue; // Do not touch this entry, it was set by MiReservePhysRange
238 }
239 }
240
241 // Initialize the PFN Entry.
242 entry->RefCount = 0;
243
244 switch (desc->Type) {
246 entry->State = PfnStateFree;
247 entry->Flags = PFN_FLAG_NONE;
248
249 // Add to free list.
250 InsertTailList(&PfnDatabase.FreePageList.ListEntry, &entry->Descriptor.ListEntry);
251 // Increment the free page list count.
252 InterlockedIncrementU64(&PfnDatabase.FreePageList.Count);
253 InterlockedIncrementU64(&PfnDatabase.AvailablePages);
254 break;
257 case EfiLoaderCode:
258 case EfiLoaderData:
262 case EfiACPIMemoryNVS:
263 // Mark pages used by firmware, loader, or kernel as active.
264 // these will not be returned by the page allocator.
265 entry->State = PfnStateActive;
266 entry->Flags = PFN_FLAG_NONE;
267 entry->Descriptor.Mapping.PteAddress = NULL;
268 entry->Descriptor.Mapping.Vad = NULL; // No VAD for these.
269 entry->RefCount = 1; // Set reference count to 1, so allocator will not get confused.
270 InterlockedIncrementU64(&PfnDatabase.TotalReserved);
271 break;
272 //case EfiACPIReclaimMemory TODO RECLAIMABLE.
273 default:
274 // If its not conventional memory, or one of the runtime/loader/boot/reserved, it is bad memory.
275 entry->State = PfnStateBad;
276 entry->Flags = PFN_FLAG_NONE;
277
278 // Add to free list and increment count.
279 InsertTailList(&PfnDatabase.BadPageList.ListEntry, &entry->Descriptor.ListEntry);
280 InterlockedIncrementU64(&PfnDatabase.BadPageList.Count);
281 break;
282 }
283 }
284 desc = (PEFI_MEMORY_DESCRIPTOR)((uint8_t*)desc + BootInfo->DescriptorSize);
285 }
286
287 // Set the global state as initialized.
289 MmHighestPfn = lastPfnIdx;
290 return MT_SUCCESS;
291}
292
293static
295MiReleaseAnyPage(
296 IN PDOUBLY_LINKED_LIST ListEntry
297)
298
299/*++
300
301 Routine description:
302
303 Attempts to retrieve a PFN Entry from the ListEntry given.
304
305 Arguments:
306
307 [IN] Pointer to ListEntry of PFN_LIST.
308
309 Return Values:
310
311 Pointer of PFN_ENTRY, NULL on failure.
312
313--*/
314
315{
316 PDOUBLY_LINKED_LIST pListEntry = RemoveHeadList(ListEntry);
317 if (!pListEntry) return NULL;
318
319 // Return the PFN_ENTRY of this ListEntry.
320 PPFN_ENTRY pPfnEntry = CONTAINING_RECORD(pListEntry, PFN_ENTRY, Descriptor.ListEntry);
321 return pPfnEntry;
322}
323
326 IN PFN_STATE ListType
327)
328
329/*++
330
331 Routine description:
332
333 Retrieves a physical page from the PFN Database.
334
335 Arguments:
336
337 [IN] enum _PFN_STATE Type. (e.g PfnStateZeroed is guranteed to return a zeroed physical page)
338
339 Return Values:
340
341 PFN Index of the page, otherwise PFN_ERROR on failure.
342
343 Notes:
344
345 The PFN index given, does not return an actively mapped PFN (that is mapped to a VA), other functions must set its mapping.
346
347--*/
348
349{
350 // Declarations
351 IRQL oldIrql;
352 IRQL DbIrql;
353 PPFN_ENTRY pfn = NULL;
354 PFN_STATE oldState; // To know if we need to zero
355
356 // Acquire global PFN DB lock.
357 MsAcquireSpinlock(&PfnDatabase.PfnDatabaseLock, &DbIrql);
358
359 // 1. Try ZeroedPageList
360 MsAcquireSpinlock(&PfnDatabase.ZeroedPageList.PfnListLock, &oldIrql);
361 pfn = MiReleaseAnyPage(&PfnDatabase.ZeroedPageList.ListEntry);
362 MsReleaseSpinlock(&PfnDatabase.ZeroedPageList.PfnListLock, oldIrql);
363 if (pfn) {
364 InterlockedDecrementU64(&PfnDatabase.ZeroedPageList.Count);
365 oldState = PfnStateZeroed;
366 goto found;
367 }
368
369 // 2. Try FreePageList
370 MsAcquireSpinlock(&PfnDatabase.FreePageList.PfnListLock, &oldIrql);
371 pfn = MiReleaseAnyPage(&PfnDatabase.FreePageList.ListEntry);
372 MsReleaseSpinlock(&PfnDatabase.FreePageList.PfnListLock, oldIrql);
373 if (pfn) {
374 InterlockedDecrementU64(&PfnDatabase.FreePageList.Count);
375 oldState = PfnStateFree;
376 goto found;
377 }
378
379 // 3. Try StandbyPageList
380 MsAcquireSpinlock(&PfnDatabase.StandbyPageList.PfnListLock, &oldIrql);
381 pfn = MiReleaseAnyPage(&PfnDatabase.StandbyPageList.ListEntry);
382 MsReleaseSpinlock(&PfnDatabase.StandbyPageList.PfnListLock, oldIrql);
383 if (pfn) {
384 InterlockedDecrementU64(&PfnDatabase.StandbyPageList.Count);
385 oldState = PfnStateStandby;
386 goto found;
387 }
388
389 // 4. All lists are empty
390 // TODO: Paging (flush modified list to disk, give a page from there.)
391 // Release Global Lock
392 MsReleaseSpinlock(&PfnDatabase.PfnDatabaseLock, DbIrql);
393 return (uint64_t)-1;
394
395found:
396 // Claim while locked.
397 assert((pfn->RefCount) == 0);
399 // Set final metadata: now "owned" by the caller.
400 pfn->RefCount = 1;
401
402 // Release Global Lock
403 MsReleaseSpinlock(&PfnDatabase.PfnDatabaseLock, DbIrql);
404 // Decrement total available pages
405 InterlockedDecrementU64(&PfnDatabase.AvailablePages);
406
407 uint64_t pfnIndex = PPFN_TO_INDEX(pfn);
408
409 // If caller wants a zeroed page, but we didn't get one, zero it now.
410 if (ListType == PfnStateZeroed && oldState != PfnStateZeroed) {
411 IRQL hyperIrql;
412 uint8_t* va = MiMapPageInHyperspace(pfnIndex, &hyperIrql);
413 kmemset(va, 0, VirtualPageSize);
414 MiUnmapHyperSpaceMap(hyperIrql);
415 }
416
417 return pfnIndex;
418}
419
420void
422 IN PAGE_INDEX PfnIndex
423)
424
425/*++
426
427 Routine description:
428
429 Releases a physical page back to the memory manager
430
431 Arguments:
432
433 [IN] PAGE_INDEX Index of the PFN given by MiRequestPhysicalPage
434
435 Return Values:
436
437 None.
438
439--*/
440
441{
442 // First, access the PFN in the database to determine its staistics.
443 PPFN_ENTRY pfn = INDEX_TO_PPFN(PfnIndex);
444
445 assert((pfn->RefCount) > 0, "Refcount is 0 while releasing. Double Free");
446
447 if (InterlockedDecrementU32(&pfn->RefCount) == 0) {
448 // This is the last reference to the page, store it back in the list.
449 if (pfn->State == PfnStateActive) {
450 // Clear mapping info.
451 pfn->Descriptor.Mapping.Vad = NULL;
452 if (pfn->Descriptor.Mapping.PteAddress != NULL &&
454 // Dirty bit is set, we throw it back to the modified page list.
455 IRQL oldIrql;
456 pfn->State = PfnStateModified;
457 MsAcquireSpinlock(&PfnDatabase.ModifiedPageList.PfnListLock, &oldIrql);
458 // TODO SET FILE OFFSET PAGING
459 InsertTailList(&PfnDatabase.ModifiedPageList.ListEntry, &pfn->Descriptor.ListEntry);
460
461 // Increment the counters
462 InterlockedIncrementU64(&PfnDatabase.ModifiedPageList.Count);
463 InterlockedIncrementU64(&PfnDatabase.AvailablePages);
464
465 MsReleaseSpinlock(&PfnDatabase.ModifiedPageList.PfnListLock, oldIrql);
466 }
467 else {
468 // Dirty bit is not set, we throw it to the standby list.
469 IRQL oldIrql;
470 pfn->State = PfnStateStandby;
471 MsAcquireSpinlock(&PfnDatabase.StandbyPageList.PfnListLock, &oldIrql);
472 // TODO SET FILE OFFSET PAGING
473 InsertTailList(&PfnDatabase.StandbyPageList.ListEntry, &pfn->Descriptor.ListEntry);
474
475 // Increment the counters
476 InterlockedIncrementU64(&PfnDatabase.StandbyPageList.Count);
477 InterlockedIncrementU64(&PfnDatabase.AvailablePages);
478
479 MsReleaseSpinlock(&PfnDatabase.StandbyPageList.PfnListLock, oldIrql);
480 }
481 }
482 }
483}
484
485void
487 PPFN_ENTRY pfn
488)
489
490// Link a specified PPFN_ENTRY from its PfnDb list.
491
492{
493 IRQL oldIrql;
494 SPINLOCK* lock = NULL;
495 volatile uint64_t* count = NULL;
496
497 /* Determine which list this PFN is on and pick the corresponding lock/count */
498 switch (pfn->State) {
499 case PfnStateFree:
500 lock = &PfnDatabase.FreePageList.PfnListLock;
501 count = &PfnDatabase.FreePageList.Count;
502 break;
503 case PfnStateZeroed:
504 lock = &PfnDatabase.ZeroedPageList.PfnListLock;
505 count = &PfnDatabase.ZeroedPageList.Count;
506 break;
507 case PfnStateStandby:
508 lock = &PfnDatabase.StandbyPageList.PfnListLock;
509 count = &PfnDatabase.StandbyPageList.Count;
510 break;
511 default:
512 /* Active/Modified/Bad pages are handled elsewhere */
513 return;
514 }
515
516 MsAcquireSpinlock(lock, &oldIrql);
517
518 /*
519 * Guard: if the entry isn't linked (both pointers NULL) then nothing to do.
520 * This avoids calling RemoveEntryList on an unlinked node.
521 */
522 if (pfn->Descriptor.ListEntry.Flink == NULL &&
523 pfn->Descriptor.ListEntry.Blink == NULL) {
524 MsReleaseSpinlock(lock, oldIrql);
525 return;
526 }
527
528 /* Remove this node from whatever list it currently sits on. */
530
531 /* Clear the entry's links to mark it as unlinked (like RemoveHeadList does). */
533
534 /* Update list and global counts while holding the lock. */
536 InterlockedDecrementU64(&PfnDatabase.AvailablePages);
537
538 MsReleaseSpinlock(lock, oldIrql);
539}
#define IN
Definition annotations.h:7
#define assert(...)
Definition assert.h:57
FORCEINLINE uint64_t InterlockedIncrementU64(volatile uint64_t *target)
Definition atomic.h:119
FORCEINLINE uint32_t InterlockedDecrementU32(volatile uint32_t *target)
Definition atomic.h:116
FORCEINLINE uint64_t InterlockedDecrementU64(volatile uint64_t *target)
Definition atomic.h:122
struct _DOUBLY_LINKED_LIST * PDOUBLY_LINKED_LIST
enum _IRQL IRQL
#define EfiRuntimeServicesData
Definition efi.h:91
struct _BOOT_INFO * PBOOT_INFO
#define EfiBootServicesCode
Definition efi.h:88
#define EfiLoaderData
Definition efi.h:87
#define EfiACPIMemoryNVS
Definition efi.h:95
#define EfiLoaderCode
Definition efi.h:86
#define EfiBootServicesData
Definition efi.h:89
struct _BOOT_INFO BOOT_INFO
struct _EFI_MEMORY_DESCRIPTOR * PEFI_MEMORY_DESCRIPTOR
#define EfiConventionalMemory
Definition efi.h:92
#define EfiRuntimeServicesCode
Definition efi.h:90
#define EfiReservedMemoryType
Definition efi.h:85
void * MiMapPageInHyperspace(IN uint64_t PfnIndex, OUT PIRQL OldIrql)
Definition hypermap.c:33
void MiUnmapHyperSpaceMap(IN IRQL OldIrql)
Definition hypermap.c:83
#define CONTAINING_RECORD(ptr, type, member)
Definition macros.h:11
PMMPTE MiGetPtePointer(IN uintptr_t va)
Definition map.c:76
@ PAGE_RW
Definition mm.h:272
@ PAGE_PRESENT
Definition mm.h:268
#define PhysicalFrameSize
Definition mm.h:54
@ PfnStateTransition
Definition mm.h:244
@ PfnStateFree
Definition mm.h:242
@ PfnStateZeroed
Definition mm.h:243
@ PfnStateModified
Definition mm.h:241
@ PfnStateActive
Definition mm.h:239
@ PfnStateStandby
Definition mm.h:240
@ PfnStateBad
Definition mm.h:245
enum _PFN_STATE PFN_STATE
#define PPFN_TO_INDEX(PPFN)
Definition mm.h:116
struct _MMPTE * PMMPTE
struct _MM_PFN_DATABASE MM_PFN_DATABASE
struct _PFN_ENTRY PFN_ENTRY
uint64_t PAGE_INDEX
Definition mm.h:232
FORCEINLINE void * kmemset(void *dest, int64_t val, uint64_t len)
Definition mm.h:540
#define PhysicalMemoryOffset
Definition mm.h:56
#define VirtualPageSize
Definition mm.h:53
#define INDEX_TO_PPFN(Index)
Definition mm.h:62
#define MI_WRITE_PTE(_PtePointer, _Va, _Pa, _Flags)
Definition mm.h:90
struct _PFN_ENTRY * PPFN_ENTRY
@ PFN_FLAG_NONE
Definition mm.h:250
FORCEINLINE PDOUBLY_LINKED_LIST RemoveHeadList(PDOUBLY_LINKED_LIST Head)
Definition ms.h:215
FORCEINLINE void InitializeListHead(PDOUBLY_LINKED_LIST Head)
Definition ms.h:166
FORCEINLINE void InsertTailList(PDOUBLY_LINKED_LIST Head, PDOUBLY_LINKED_LIST Entry)
Definition ms.h:179
struct _SPINLOCK SPINLOCK
FORCEINLINE void RemoveEntryList(PDOUBLY_LINKED_LIST Entry)
Definition ms.h:240
#define MT_NO_MEMORY
Definition mtstatus.h:42
#define MT_SUCCESS
Definition mtstatus.h:22
#define MT_GENERAL_FAILURE
Definition mtstatus.h:31
int32_t MTSTATUS
Definition mtstatus.h:12
#define MT_NOT_FOUND
Definition mtstatus.h:30
PAGE_INDEX MiRequestPhysicalPage(IN PFN_STATE ListType)
Definition pfn.c:325
PAGE_INDEX MmHighestPfn
Definition pfn.c:31
void MiUnlinkPageFromList(PPFN_ENTRY pfn)
Definition pfn.c:486
void MiReleasePhysicalPage(IN PAGE_INDEX PfnIndex)
Definition pfn.c:421
bool MmPfnDatabaseInitialized
Definition pfn.c:30
MM_PFN_DATABASE PfnDatabase
Definition pfn.c:29
MTSTATUS MiInitializePfnDatabase(IN PBOOT_INFO BootInfo)
Definition pfn.c:100
void MsAcquireSpinlock(IN PSPINLOCK lock, IN PIRQL OldIrql)
Definition spinlock.c:13
void MsReleaseSpinlock(IN PSPINLOCK lock, IN IRQL OldIrql)
Definition spinlock.c:45
EFI_MEMORY_DESCRIPTOR * MemoryMap
Definition efi.h:54
size_t DescriptorSize
Definition efi.h:56
size_t MapSize
Definition efi.h:55
struct _DOUBLY_LINKED_LIST * Blink
Definition core.h:28
struct _DOUBLY_LINKED_LIST * Flink
Definition core.h:29
uint32_t Type
Definition efi.h:34
uint64_t NumberOfPages
Definition efi.h:38
uint64_t PhysicalStart
Definition efi.h:36
struct _MMPTE::@172372265215056352375070220246156106027174106113::@200357034104227323320222006243127050212100105247 Hard
uint64_t Dirty
Definition mm.h:398
union _PFN_ENTRY::@217024126340164016372152071216274230164113211246 Descriptor
volatile uint32_t RefCount
Definition mm.h:429
struct _PFN_ENTRY::@217024126340164016372152071216274230164113211246::@301110335271023021153236134322146064331241142124 Mapping
uint8_t State
Definition mm.h:430
PMMPTE PteAddress
Definition mm.h:441
struct _MMVAD * Vad
Definition mm.h:440
struct _DOUBLY_LINKED_LIST ListEntry
Definition mm.h:436
uint8_t Flags
Definition mm.h:431