Loading [MathJax]/jax/output/HTML-CSS/config.js
CS350 COS
COS
All Data Structures Files Functions Variables Typedefs Macros
pmap.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include <sys/kconfig.h>
#include <sys/kassert.h>
#include <sys/kdebug.h>
#include <sys/kmem.h>
#include <machine/amd64.h>
#include <machine/amd64op.h>
#include <machine/mp.h>
#include <machine/pmap.h>
Include dependency graph for pmap.c:

Go to the source code of this file.

Functions

void PMap_Init ()
 
void PMap_InitAP ()
 
ASPMap_NewAS ()
 
void PMap_DestroyAS (AS *space)
 
ASPMap_CurrentAS ()
 
void PMap_LoadAS (AS *space)
 
static PageTablePMapAllocPageTable ()
 
uintptr_t PMap_Translate (AS *space, uintptr_t va)
 
static void PMapLookupEntry (AS *space, uint64_t va, PageEntry **entry, int size)
 
bool PMap_Map (AS *as, uint64_t phys, uint64_t virt, uint64_t pages, uint64_t flags)
 
bool PMap_Unmap (AS *as, uint64_t va, uint64_t pages)
 
bool PMap_AllocMap (AS *as, uint64_t virt, uint64_t len, uint64_t flags)
 
void PMap_SystemLookup (uint64_t va, PageEntry **entry, int size)
 
bool PMap_SystemLMap (uint64_t phys, uint64_t virt, uint64_t lpages, uint64_t flags)
 
bool PMap_SystemMap (uint64_t phys, uint64_t virt, uint64_t pages, uint64_t flags)
 
bool PMap_SystemUnmap (uint64_t virt, uint64_t pages)
 
static uint64_t AddrFromIJKL (uint64_t i, uint64_t j, uint64_t k, uint64_t l)
 
void PMap_DumpFull (AS *space)
 
static void Debug_PMapDumpFull (int argc, const char *argv[])
 
 REGISTER_DBGCMD (pmapdumpfull, "Dump memory mappings", Debug_PMapDumpFull)
 
void PMap_Dump (AS *space)
 
static void Debug_PMapDump (int argc, const char *argv[])
 
 REGISTER_DBGCMD (pmapdump, "Dump memory mappings", Debug_PMapDump)
 

Variables

AS systemAS
 
AScurrentAS [MAX_CPUS]
 

Function Documentation

◆ AddrFromIJKL()

static uint64_t AddrFromIJKL ( uint64_t  i,
uint64_t  j,
uint64_t  k,
uint64_t  l 
)
static

Definition at line 546 of file pmap.c.

547{
548 return (i << 39) | (j << HUGE_PGSHIFT) | (k << LARGE_PGSHIFT) | (l << PGSHIFT);
549}
#define PGSHIFT
Definition: amd64.h:20
#define HUGE_PGSHIFT
Definition: amd64.h:28
#define LARGE_PGSHIFT
Definition: amd64.h:24
Here is the caller graph for this function:

◆ Debug_PMapDump()

static void Debug_PMapDump ( int  argc,
const char *  argv[] 
)
static

Definition at line 669 of file pmap.c.

670{
672}
#define THISCPU
Definition: mp.h:21
AS * currentAS[MAX_CPUS]
Definition: pmap.c:16
void PMap_Dump(AS *space)
Definition: pmap.c:616
Here is the call graph for this function:

◆ Debug_PMapDumpFull()

static void Debug_PMapDumpFull ( int  argc,
const char *  argv[] 
)
static

Definition at line 608 of file pmap.c.

609{
611}
void PMap_DumpFull(AS *space)
Definition: pmap.c:552
Here is the call graph for this function:

◆ PMap_AllocMap()

bool PMap_AllocMap ( AS as,
uint64_t  virt,
uint64_t  len,
uint64_t  flags 
)

PMap_AllocMap –

Map a virtual mapping in an address space and back it by newly allocated memory.

Parameters
[in]asAddress space.
[in]virtVirtual address.
[in]pagesPages to map in.
[in]flagsFlags to apply to the mapping.
Return values
trueOn success
falseOn failure

Definition at line 423 of file pmap.c.

424{
425 int i;
426 uint64_t pages = (len + PGSIZE - 1) / PGSIZE;
427 PageEntry *entry;
428
429 ASSERT((virt & PGMASK) == 0);
430
431 for (i = 0; i < pages; i++) {
432 uint64_t va = virt + PGSIZE * i;
433 PMapLookupEntry(as, va, &entry, PGSIZE);
434 if (!entry) {
435 kprintf("Map failed to allocate memory!\n");
436 return false;
437 }
438
439 if ((*entry & PTE_P) != PTE_P) {
440 void *pg = PAlloc_AllocPage();
441 *entry = (uint64_t)DMVA2PA(pg) | PTE_P | PTE_U | flags;
442 }
443 }
444
445 return true;
446}
#define PTE_P
Definition: amd64.h:35
#define PTE_U
Definition: amd64.h:37
uint64_t PageEntry
Definition: amd64.h:52
#define PGMASK
Definition: amd64.h:22
#define ASSERT(_x)
Definition: kassert.h:8
int kprintf(const char *fmt,...)
Definition: printf.c:210
void * PAlloc_AllocPage()
Definition: palloc.c:188
#define PGSIZE
Definition: malloc.c:21
uint64_t len
Definition: multiboot.h:2
static void PMapLookupEntry(AS *space, uint64_t va, PageEntry **entry, int size)
Definition: pmap.c:278
#define DMVA2PA(dmva)
Definition: pmap.h:47
unsigned long uint64_t
Definition: types.h:13
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMap_CurrentAS()

AS * PMap_CurrentAS ( )

PMap_CurrentAS –

Get the current address space on this CPU.

Returns
Current address space.

Definition at line 168 of file pmap.c.

169{
170 return currentAS[THISCPU()];
171}

◆ PMap_DestroyAS()

void PMap_DestroyAS ( AS space)

PMap_DestroyAS –

Destroys an address space and releases the physical pages.

Parameters
[in]spaceAddress space to destroy.

Definition at line 116 of file pmap.c.

117{
118 // Only free the userspace portion (bottom half)
119 for (int i = 0; i < PAGETABLE_ENTRIES / 2; i++)
120 {
121 PageEntry pte = space->root->entries[i];
122 if (pte & PTE_P) {
123 // Remove sub-pages
124 PageTable *tbl2 = (PageTable *)DMPA2VA(pte & PGNUMMASK);
125 for (int j = 0; j < PAGETABLE_ENTRIES; j++) {
126 PageEntry pte2 = tbl2->entries[j];
127 if (pte2 & PTE_P) {
128 PageTable *tbl3 = (PageTable *)DMPA2VA(pte2 & PGNUMMASK);
129 for (int k = 0; k < PAGETABLE_ENTRIES; k++) {
130 PageEntry pte3 = tbl3->entries[k];
131 if (pte3 & PTE_P) {
132 ASSERT((pte3 & PTE_PS) == 0); // XXX: Large pages not supported
133 PageTable *tbl4 = (PageTable *)DMPA2VA(pte3 & PGNUMMASK);
134 for (int l = 0; l < PAGETABLE_ENTRIES; l++) {
135 PageEntry pte4 = tbl4->entries[l];
136 if (pte4 & PTE_P) {
137 // Free userspace page
138 PAlloc_Release((void *)DMPA2VA(pte4 & PGNUMMASK));
139 }
140 }
141
142 // Free 3rd level page table page
143 PAlloc_Release((void *)DMPA2VA(pte3 & PGNUMMASK));
144 }
145 }
146
147 // Free 2nd level page table page
148 PAlloc_Release((void *)DMPA2VA(pte2 & PGNUMMASK));
149 }
150 }
151
152 // Free page table page
153 PAlloc_Release((void *)DMPA2VA(pte & PGNUMMASK));
154 }
155 }
156
157 PAlloc_Release(space);
158}
PageEntry entries[PAGETABLE_ENTRIES]
Definition: amd64.h:55
#define PGNUMMASK
Definition: amd64.h:15
#define PTE_PS
Definition: amd64.h:42
#define PAGETABLE_ENTRIES
Definition: amd64.h:50
void PAlloc_Release(void *pg)
Definition: palloc.c:265
PageTable * root
Definition: pmap.h:53
#define DMPA2VA(pa)
Definition: pmap.h:48
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMap_Dump()

void PMap_Dump ( AS space)

Definition at line 616 of file pmap.c.

617{
618 int i = 0;
619 int j = 0;
620 int k = 0;
621 int l = 0;
622 PageTable *root = space->root;
623
624 kprintf("%-18s %-18s %-5s\n", "Virtual", "Physical PTE", "Flags");
625 for (i = 0; i < PAGETABLE_ENTRIES/2; i++) {
626 PageEntry pte = root->entries[i];
627 PageTable *l1 = (PageTable *)DMPA2VA(pte & PGNUMMASK);
628
629 if (!(pte & PTE_P))
630 continue;
631
632 for (j = 0; j < PAGETABLE_ENTRIES; j++) {
633 PageEntry pte2 = l1->entries[j];
634 PageTable *l2 = (PageTable *)DMPA2VA(pte2 & PGNUMMASK);
635
636 if (!(pte2 & PTE_P))
637 continue;
638
639 for (k = 0; k < PAGETABLE_ENTRIES; k++) {
640 PageEntry pte3 = l2->entries[k];
641 PageTable *l3 = (PageTable *)DMPA2VA(pte3 & PGNUMMASK);
642
643 if (!(pte3 & PTE_P))
644 continue;
645
646 if ((pte3 & PTE_PS) == 0) {
647 for (l = 0; l < PAGETABLE_ENTRIES; l++) {
648 PageEntry pte4 = l3->entries[l];
649
650 if (pte4 & PTE_P)
651 kprintf("0x%016llx: 0x%016llx P%c%c%c%c%c\n",
652 AddrFromIJKL(i, j, k, l),
653 (uint64_t)pte4,
654 (pte4 & PTE_W) ? 'W' : ' ',
655 (pte4 & PTE_NX) ? ' ' : 'X',
656 (pte4 & PTE_U) ? 'U' : ' ',
657 (pte4 & PTE_A) ? 'A' : ' ',
658 (pte4 & PTE_D) ? 'D' : ' ');
659 }
660 }
661 }
662 }
663 }
664
665 return;
666}
#define PTE_W
Definition: amd64.h:36
#define PTE_NX
Definition: amd64.h:48
#define PTE_D
Definition: amd64.h:41
#define PTE_A
Definition: amd64.h:40
static uint64_t AddrFromIJKL(uint64_t i, uint64_t j, uint64_t k, uint64_t l)
Definition: pmap.c:546
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMap_DumpFull()

void PMap_DumpFull ( AS space)

Definition at line 552 of file pmap.c.

553{
554 int i = 0;
555 int j = 0;
556 int k = 0;
557 int l = 0;
558 PageTable *root = space->root;
559
560 kprintf("Root: %016llx\n", (uint64_t)space->root);
561
562 for (i = 0; i < PAGETABLE_ENTRIES; i++) {
563 PageEntry pte = root->entries[i];
564 PageTable *l1 = (PageTable *)DMPA2VA(pte & PGNUMMASK);
565
566 if (!(pte & PTE_P))
567 continue;
568
569 kprintf("Level 1: %016llx\n", (uint64_t)pte);
570
571 for (j = 0; j < PAGETABLE_ENTRIES; j++) {
572 PageEntry pte2 = l1->entries[j];
573 PageTable *l2 = (PageTable *)DMPA2VA(pte2 & PGNUMMASK);
574
575 if (!(pte2 & PTE_P))
576 continue;
577
578 kprintf("Level 2: %016llx\n", (uint64_t)pte2);
579
580 for (k = 0; k < PAGETABLE_ENTRIES; k++) {
581 PageEntry pte3 = l2->entries[k];
582 PageTable *l3 = (PageTable *)DMPA2VA(pte3 & PGNUMMASK);
583
584 if (!(pte3 & PTE_P))
585 continue;
586
587 kprintf("Level 3: %016llx:%016llx\n",
588 AddrFromIJKL(i, j, k, 0),
589 (uint64_t)pte3);
590
591 if ((pte3 & PTE_PS) == 0) {
592 for (l = 0; l < PAGETABLE_ENTRIES; l++) {
593 PageEntry pte4 = l3->entries[l];
594
595 kprintf("Level 4: %016llx:%016llx\n",
596 AddrFromIJKL(i, j, k, l),
597 (uint64_t)pte4);
598 }
599 }
600 }
601 }
602 }
603
604 return;
605}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMap_Init()

void PMap_Init ( )

Definition at line 19 of file pmap.c.

20{
21 int i, j;
22
23 kprintf("Initializing PMAP ... ");
24
25 // Setup global state
26 for (i = 0; i < MAX_CPUS; i++) {
27 currentAS[i] = 0;
28 }
29
30 // Allocate system page table
34 if (!systemAS.root)
35 PANIC("Cannot allocate system page table");
36
37 for (i = 0; i < PAGETABLE_ENTRIES / 2; i++)
38 systemAS.root->entries[i] = 0;
39
40 for (i = PAGETABLE_ENTRIES / 2; i < PAGETABLE_ENTRIES; i++) {
41 PageTable *pgtbl = PAlloc_AllocPage();
42 PageEntry pte = DMVA2PA((uint64_t)pgtbl) | PTE_W | PTE_P;
43 if (!pgtbl)
44 PANIC("Not enough memory!");
45
46 systemAS.root->entries[i] = pte;
47
48 for (j = 0; j < PAGETABLE_ENTRIES; j++) {
49 pgtbl->entries[j] = 0;
50 }
51 }
52
53 // Setup system mappings
55 3*512, 0); // 3GB RWX
56 PMap_SystemLMap(0xC0000000, MEM_DIRECTMAP_BASE + 0xC0000000,
57 512, PTE_NX|PTE_PCD); // 1GB RW + PCD
58 PMap_SystemLMap(0x100000000, MEM_DIRECTMAP_BASE + 0x100000000,
59 60*512, 0); // 60GB RWX
60
62
63 kprintf("Done!\n");
64}
#define PTE_PCD
Definition: amd64.h:39
#define PANIC
Definition: kassert.h:18
#define MAX_CPUS
Definition: kconfig.h:8
bool PMap_SystemLMap(uint64_t phys, uint64_t virt, uint64_t lpages, uint64_t flags)
Definition: pmap.c:480
AS systemAS
Definition: pmap.c:15
void PMap_LoadAS(AS *space)
Definition: pmap.c:182
uint64_t mappings
Definition: pmap.h:55
uint64_t tables
Definition: pmap.h:54
#define MEM_DIRECTMAP_BASE
Definition: pmap.h:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMap_InitAP()

void PMap_InitAP ( )

Definition at line 67 of file pmap.c.

68{
70}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMap_LoadAS()

void PMap_LoadAS ( AS space)

PMap_LoadAS –

Load an address space into the CPU. Reloads the CR3 register in x86-64 that points the physical page tables and flushes the TLB entries.

Parameters
[in]spaceAddress space to load.

Definition at line 182 of file pmap.c.

183{
184 write_cr3(DMVA2PA((uint64_t)space->root));
185 currentAS[THISCPU()] = space;
186}
static INLINE void write_cr3(uint64_t val)
Definition: amd64op.h:166
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMap_Map()

bool PMap_Map ( AS as,
uint64_t  phys,
uint64_t  virt,
uint64_t  pages,
uint64_t  flags 
)

PMap_Map –

Map a physical to virtual mapping in an address space.

Parameters
[in]asAddress space.
[in]physPhysical address.
[in]virtVirtual address.
[in]pagesPages to map in.
[in]flagsFlags to apply to the mapping.
Return values
trueOn success
falseOn failure

Definition at line 355 of file pmap.c.

356{
357 int i;
358 PageEntry *entry;
359
360 for (i = 0; i < pages; i++) {
361 uint64_t va = virt + PGSIZE * i;
362 PMapLookupEntry(as, va, &entry, PGSIZE);
363 if (!entry) {
364 kprintf("Map failed to allocate memory!\n");
365 return false;
366 }
367
368 *entry = (phys + PGSIZE * i) | PTE_P | PTE_W | PTE_U | flags;
369 }
370
371 return true;
372}
Here is the call graph for this function:

◆ PMap_NewAS()

AS * PMap_NewAS ( )

PMap_NewAS –

Create a new address space.

Returns
Newly created address space.

Definition at line 80 of file pmap.c.

81{
82 int i;
83 AS *as = PAlloc_AllocPage();
84
85 if (!as)
86 return NULL;
87
88 as->root = PAlloc_AllocPage();
89 as->tables = 1;
90 as->mappings = 0;
91
92 if (!as->root) {
94 return NULL;
95 }
96
97 for (i = 0; i < PAGETABLE_ENTRIES / 2; i++)
98 {
99 as->root->entries[i] = 0;
100 }
101 for (i = PAGETABLE_ENTRIES / 2; i < PAGETABLE_ENTRIES; i++) {
102 as->root->entries[i] = systemAS.root->entries[i];
103 }
104
105 return as;
106}
Definition: pmap.h:52
#define NULL
Definition: stddef.h:6
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMap_SystemLMap()

bool PMap_SystemLMap ( uint64_t  phys,
uint64_t  virt,
uint64_t  lpages,
uint64_t  flags 
)

PMap_SystemLMap –

Map a range of large (2MB) physical pages to virtual pages in the kernel address space that is shared by all processes.

Parameters
[in]physPhysical address.
[in]virtVirtual address.
[in]lpagesLarge pages to map in.
[in]flagsFlags to apply to the mapping.
Return values
trueOn success
falseOn failure

Definition at line 480 of file pmap.c.

481{
482 int i;
483 PageEntry *entry;
484
485 for (i = 0; i < lpages; i++) {
486 uint64_t va = virt + LARGE_PGSIZE * i;
488 if (!entry) {
489 kprintf("SystemLMap failed to allocate memory!\n");
490 return false;
491 }
492
493 *entry = (phys + LARGE_PGSIZE * i) | PTE_P | PTE_W | PTE_PS | flags;
494 }
495
496 return true;
497}
#define LARGE_PGSIZE
Definition: amd64.h:25
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMap_SystemLookup()

void PMap_SystemLookup ( uint64_t  va,
PageEntry **  entry,
int  size 
)

PMap_SystemLookup –

Lookup a kernel virtual address in a page table and return a pointer to the page entry. This function allocates page tables as necessary to fill in the 4-level heirarchy.

Parameters
[in]vaVirtual address to lookup.
[out]entryPointer will point to the PageEntry.
[in]sizePage size we want to use.

Definition at line 460 of file pmap.c.

461{
462 PMapLookupEntry(&systemAS, va, entry, size);
463}
uint32_t size
Definition: multiboot.h:0
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMap_SystemMap()

bool PMap_SystemMap ( uint64_t  phys,
uint64_t  virt,
uint64_t  pages,
uint64_t  flags 
)

PMap_SystemLMap –

Map a range of physical pages to virtual pages in the kernel address space that is shared by all processes.

Parameters
[in]physPhysical address.
[in]virtVirtual address.
[in]pagesPages to map in.
[in]flagsFlags to apply to the mapping.
Return values
trueOn success
falseOn failure

Definition at line 514 of file pmap.c.

515{
516 int i;
517 PageEntry *entry;
518
519 for (i = 0; i < pages; i++) {
520 uint64_t va = virt + PGSIZE * i;
521 PMapLookupEntry(&systemAS, va, &entry, PGSIZE);
522 if (!entry) {
523 kprintf("SystemMap failed to allocate memory!\n");
524 return false;
525 }
526
527 *entry = (phys + PGSIZE * i) | PTE_P | PTE_W | flags;
528 }
529
530 return true;
531}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMap_SystemUnmap()

bool PMap_SystemUnmap ( uint64_t  virt,
uint64_t  pages 
)

PMap_SystemUnmap –

We do not currently use this!

Definition at line 539 of file pmap.c.

540{
542 return false;
543}
#define NOT_IMPLEMENTED()
Definition: kassert.h:13

◆ PMap_Translate()

uintptr_t PMap_Translate ( AS space,
uintptr_t  va 
)

PMap_Translate –

Translates a virtual address to physical address for a given address space.

Parameters
[in]spaceAddress space we wish to lookup a mapping in.
[in]vaVirtual address we wish to translate.

Definition at line 220 of file pmap.c.

221{
222 int i,j,k,l;
223 PageTable *table = space->root;
224 PageEntry pte;
225 PageEntry *entry;
226
227 i = (va >> (HUGE_PGSHIFT + PGIDXSHIFT)) & PGIDXMASK;
228 j = (va >> HUGE_PGSHIFT) & PGIDXMASK;
229 k = (va >> LARGE_PGSHIFT) & PGIDXMASK;
230 l = (va >> PGSHIFT) & PGIDXMASK;
231
232 pte = table->entries[i];
233 if (pte == 0) {
234 ASSERT(pte);
235 return 0;
236 }
237 table = (PageTable *)DMPA2VA(pte & PGNUMMASK);
238
239 pte = table->entries[j];
240 // XXX: Support 1GB pages
241 if (pte == 0) {
242 ASSERT(pte);
243 return 0;
244 }
245 table = (PageTable *)DMPA2VA(pte & PGNUMMASK);
246
247 pte = table->entries[k];
248 if ((pte & PTE_PS) == PTE_PS) {
249 // Handle 2MB pages
250 entry = &table->entries[k];
251 return (*entry & ~(LARGE_PGMASK | PTE_NX)) + (va & LARGE_PGMASK);
252 }
253 if (pte == 0) {
254 ASSERT(pte);
255 return 0;
256 }
257 table = (PageTable *)DMPA2VA(pte & PGNUMMASK);
258
259 // Handle 4KB pages
260 entry = &table->entries[l];
261
262 return (*entry & ~(PGMASK | PTE_NX)) + (va & PGMASK);
263}
#define PGIDXSHIFT
Definition: amd64.h:17
#define LARGE_PGMASK
Definition: amd64.h:26
#define PGIDXMASK
Definition: amd64.h:18
Here is the caller graph for this function:

◆ PMap_Unmap()

bool PMap_Unmap ( AS as,
uint64_t  va,
uint64_t  pages 
)

PMap_Unmap –

Unmap a range of addresses.

Parameters
[in]asAddress space.
[in]vaVirtual address.
[in]pagesPages to map in.
Return values
trueOn success
falseOn failure

Definition at line 387 of file pmap.c.

388{
389 int i;
390 PageEntry *entry;
391
392 for (i = 0; i < pages; i++) {
393 uint64_t vai = va + PGSIZE * i;
394 PMapLookupEntry(as, vai, &entry, PGSIZE);
395 if (!entry) {
396 kprintf("Unmap tried to allocate memory!\n");
397 return false;
398 }
399
401
402 *entry = 0;
403 }
404
405 return true;
406}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMapAllocPageTable()

static PageTable * PMapAllocPageTable ( )
static

PMapAllocPageTable –

Allocates and initializes a page table.

Returns
Newly created PageTable.

Definition at line 196 of file pmap.c.

197{
198 int i;
199 PageTable *pgtbl = PAlloc_AllocPage();
200
201 if (!pgtbl)
202 return 0;
203
204 for (i = 0; i < PAGETABLE_ENTRIES; i++) {
205 pgtbl->entries[i] = 0;
206 }
207
208 return pgtbl;
209}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PMapLookupEntry()

static void PMapLookupEntry ( AS space,
uint64_t  va,
PageEntry **  entry,
int  size 
)
static

PMapLookupEntry –

Lookup a virtual address in a page table and return a pointer to the page entry. This function allocates page tables as necessary to fill in the 4-level heirarchy.

Parameters
[in]spaceAddress space to search.
[in]vaVirtual address to lookup.
[out]entryPointer will point to the PageEntry.
[in]sizePage size we want to use.

Definition at line 278 of file pmap.c.

279{
280 int i,j,k,l;
281 PageTable *table = space->root;
282 PageEntry pte;
283
284 i = (va >> (HUGE_PGSHIFT + PGIDXSHIFT)) & PGIDXMASK;
285 j = (va >> HUGE_PGSHIFT) & PGIDXMASK;
286 k = (va >> LARGE_PGSHIFT) & PGIDXMASK;
287 l = (va >> PGSHIFT) & PGIDXMASK;
288
289 *entry = NULL;
290
291 pte = table->entries[i];
292 if (pte == 0) {
293 PageTable *newtable = PMapAllocPageTable();
294 if (!newtable)
295 return;
296
297 pte = DMVA2PA((uint64_t)newtable) | PTE_P | PTE_W | PTE_U;
298 table->entries[i] = pte;
299 }
300 table = (PageTable *)DMPA2VA(pte & PGNUMMASK);
301
302 pte = table->entries[j];
303 if (size == HUGE_PGSIZE) {
304 // Handle 1GB pages
305 *entry = &table->entries[j];
306 return;
307 }
308 if (pte == 0) {
309 PageTable *newtable = PMapAllocPageTable();
310 if (!newtable)
311 return;
312
313 pte = DMVA2PA((uint64_t)newtable) | PTE_P | PTE_W | PTE_U;
314 table->entries[j] = pte;
315 }
316 table = (PageTable *)DMPA2VA(pte & PGNUMMASK);
317
318 pte = table->entries[k];
319 if (size == LARGE_PGSIZE) {
320 // Handle 2MB pages
321 *entry = &table->entries[k];
322 return;
323 }
324 if (pte == 0) {
325 PageTable *newtable = PMapAllocPageTable();
326 if (!newtable)
327 return;
328
329 pte = DMVA2PA((uint64_t)newtable) | PTE_P | PTE_W | PTE_U;
330 table->entries[k] = pte;
331 }
332 table = (PageTable *)DMPA2VA(pte & PGNUMMASK);
333
334 // Handle 4KB pages
335 ASSERT(size == PGSIZE);
336 *entry = &table->entries[l];
337 return;
338}
#define HUGE_PGSIZE
Definition: amd64.h:29
static PageTable * PMapAllocPageTable()
Definition: pmap.c:196
Here is the call graph for this function:
Here is the caller graph for this function:

◆ REGISTER_DBGCMD() [1/2]

REGISTER_DBGCMD ( pmapdump  ,
"Dump memory mappings"  ,
Debug_PMapDump   
)

◆ REGISTER_DBGCMD() [2/2]

REGISTER_DBGCMD ( pmapdumpfull  ,
"Dump memory mappings"  ,
Debug_PMapDumpFull   
)

Variable Documentation

◆ currentAS

AS* currentAS[MAX_CPUS]

Definition at line 16 of file pmap.c.

◆ systemAS

AS systemAS

Definition at line 15 of file pmap.c.