1 /* See COPYRIGHT for copyright information. */
16 #include <page_alloc.h>
18 #warning "convert pgdir* to pgdir_t"
19 pgdir_t* boot_pgdir; // Virtual address of boot time page directory
20 physaddr_t boot_cr3; // Physical address of boot time page directory
22 // --------------------------------------------------------------
23 // Set up initial memory mappings and turn on MMU.
24 // --------------------------------------------------------------
29 // we already set up our page tables before jumping
30 // into the kernel, so there's not much going on here
32 extern pte_t l1pt[NPTENTRIES];
34 boot_cr3 = PADDR(boot_pgdir);
37 // Given 'pgdir', a pointer to a page directory, pgdir_walk returns
38 // a pointer to the page table entry (PTE) for linear address 'va'.
39 // This requires walking the two-level page table structure.
41 // If the relevant page table doesn't exist in the page directory, then:
42 // - If create == 0, pgdir_walk returns NULL.
43 // - Otherwise, pgdir_walk tries to allocate a new page table
44 // with page_alloc. If this fails, pgdir_walk returns NULL.
45 // - Otherwise, pgdir_walk returns a pointer into the new page table.
47 // This is boot_pgdir_walk, but using page_alloc() instead of boot_alloc().
48 // Unlike boot_pgdir_walk, pgdir_walk can fail.
50 pgdir_walk(pgdir_t *pgdir, const void *va, int create)
56 for(int i = 0; i < NPTLEVELS-1; i++)
58 // this code relies upon the fact that all page tables are the same size
59 uintptr_t idx = (uintptr_t)va >> (L1PGSHIFT - i*(L1PGSHIFT-L2PGSHIFT));
60 idx = idx & (NPTENTRIES-1);
73 if(kpage_alloc(&new_table))
75 memset(page2kva(new_table), 0, PGSIZE);
77 *ppte = PTD(page2pa(new_table));
80 pt = (pte_t*)KADDR(PTD_ADDR(*ppte));
83 uintptr_t idx = (uintptr_t)va >> (L1PGSHIFT - (NPTLEVELS-1)*(L1PGSHIFT-L2PGSHIFT));
84 idx = idx & (NPTENTRIES-1);
88 /* Returns the effective permissions for PTE_U, PTE_W, and PTE_P on a given
90 int get_va_perms(pgdir_t *pgdir, const void *va)
92 pte_t* pte = pgdir_walk(pgdir, va, 0);
93 return pte == NULL ? 0 : (*pte & (PTE_PERM | PTE_E));
101 uintptr_t gva2gpa(struct proc *p, uintptr_t cr3, uintptr_t gva)
103 panic("Unimplemented");
107 int arch_pgdir_setup(pgdir_t boot_copy, pgdir_t *new_pd)
109 pte_t *kpt = kpage_alloc_addr();
112 memcpy(kpt, (pte_t*)boot_copy, PGSIZE);
114 /* TODO: VPT/UVPT mappings */
116 *new_pd = (pgdir_t)kpt;
120 physaddr_t arch_pgdir_get_cr3(pgdir_t pd)
122 return PADDR((pte_t*)pd);
125 void arch_pgdir_clear(pgdir_t *pd)
130 /* Returns the page shift of the largest jumbo supported */
131 int arch_max_jumbo_page_shift(void)
133 #warning "What jumbo page sizes does RISC support?"