Support partial contexts
[akaros.git] / kern / arch / riscv / pmap.c
index 54c80af..72e5406 100644 (file)
@@ -15,9 +15,9 @@
 #include <kmalloc.h>
 #include <page_alloc.h>
 
-pde_t* boot_pgdir;             // Virtual address of boot time page directory
+#warning "convert pgdir* to pgdir_t"
+pgdir_t* boot_pgdir;           // Virtual address of boot time page directory
 physaddr_t boot_cr3;           // Physical address of boot time page directory
-page_t* pages = NULL;          // Virtual address of physical page array
 
 // --------------------------------------------------------------
 // Set up initial memory mappings and turn on MMU.
@@ -47,24 +47,24 @@ vm_init(void)
 // This is boot_pgdir_walk, but using page_alloc() instead of boot_alloc().
 // Unlike boot_pgdir_walk, pgdir_walk can fail.
 pte_t*
-pgdir_walk(pde_t *pgdir, const void *SNT va, int create)
+pgdir_walk(pgdir_t *pgdir, const void *va, int create)
 {
-  pte_t* ppte[NPTLEVELS];
-       pte_t* pt[NPTLEVELS];
+       pte_t* ppte;
+       pte_t* pt;
 
-       pt[0] = pgdir;
+       pt = pgdir;
        for(int i = 0; i < NPTLEVELS-1; i++)
        {
-         // this code relies upon the fact that all page tables are the same size
-         uintptr_t idx = (uintptr_t)va >> (L1PGSHIFT - i*(L1PGSHIFT-L2PGSHIFT));
+               // this code relies upon the fact that all page tables are the same size
+               uintptr_t idx = (uintptr_t)va >> (L1PGSHIFT - i*(L1PGSHIFT-L2PGSHIFT));
                idx = idx & (NPTENTRIES-1);
 
-               ppte[i] = &pt[i][idx];
+               ppte = &pt[idx];
 
-               if(*ppte[i] & PTE_E)
-                       return ppte[i];
+               if(*ppte & PTE_E)
+                       return ppte;
 
-       if(!(*ppte[i] & PTE_T))
+               if(!(*ppte & PTE_T))
                {
                        if(!create)
                                return NULL;
@@ -74,20 +74,20 @@ pgdir_walk(pde_t *pgdir, const void *SNT va, int create)
                                return NULL;
                        memset(page2kva(new_table), 0, PGSIZE);
 
-                       *ppte[i] = PTD(page2pa(new_table));
+                       *ppte = PTD(page2pa(new_table));
                }
 
-               pt[i+1] = (pte_t*)KADDR(PTD_ADDR(*ppte[i]));
+               pt = (pte_t*)KADDR(PTD_ADDR(*ppte));
        }
 
        uintptr_t idx = (uintptr_t)va >> (L1PGSHIFT - (NPTLEVELS-1)*(L1PGSHIFT-L2PGSHIFT));
        idx = idx & (NPTENTRIES-1);
-  return &pt[NPTLEVELS-1][idx];
+  return &pt[idx];
 }
 
 /* Returns the effective permissions for PTE_U, PTE_W, and PTE_P on a given
  * virtual address. */
-int get_va_perms(pde_t *pgdir, const void *SNT va)
+int get_va_perms(pgdir_t *pgdir, const void *va)
 {
        pte_t* pte = pgdir_walk(pgdir, va, 0);
        return pte == NULL ? 0 : (*pte & (PTE_PERM | PTE_E));
@@ -98,7 +98,32 @@ page_check(void)
 {
 }
 
-void* mmio_alloc(physaddr_t pa, size_t size)
+int arch_pgdir_setup(pgdir_t boot_copy, pgdir_t *new_pd)
 {
-       return NULL;
+       pte_t *kpt = kpage_alloc_addr();
+       if (!kpt)
+               return -ENOMEM;
+       memcpy(kpt, (pte_t*)boot_copy, PGSIZE);
+
+       /* TODO: VPT/UVPT mappings */
+
+       *new_pd = (pgdir_t)kpt;
+       return 0;
+}
+
+physaddr_t arch_pgdir_get_cr3(pgdir_t pd)
+{
+       return PADDR((pte_t*)pd);
+}
+
+void arch_pgdir_clear(pgdir_t *pd)
+{
+       *pd = 0;
+}
+
+/* Returns the page shift of the largest jumbo supported */
+int arch_max_jumbo_page_shift(void)
+{
+       #warning "What jumbo page sizes does RISC support?"
+       return PGSHIFT;
 }