Changes pde_t* -> pgdir_t
[akaros.git] / kern / src / pmap.c
index d4ba124..cb8351f 100644 (file)
@@ -33,15 +33,16 @@ uintptr_t boot_freelimit = 0;
 
 static size_t sizeof_mboot_mmentry(struct multiboot_mmap_entry *entry)
 {
-       /* Careful - addr + len is a uint64 (need to cast down for 32 bit) */
-       return (size_t)(entry->addr + entry->len);
+       /* Careful - len is a uint64 (need to cast down for 32 bit) */
+       return (size_t)(entry->len);
 }
 
 static void adjust_max_pmem(struct multiboot_mmap_entry *entry, void *data)
 {
        if (entry->type != MULTIBOOT_MEMORY_AVAILABLE)
                return;
-       max_pmem = MAX(max_pmem, sizeof_mboot_mmentry(entry));
+       /* Careful - addr + len is a uint64 (need to cast down for 32 bit) */
+       max_pmem = MAX(max_pmem, (size_t)(entry->addr + entry->len));
 }
 
 /**
@@ -131,7 +132,7 @@ static void boot_alloc_init(void)
                boot_freelimit = boot_zone_end;
        } else {
                boot_freemem = end_kva;
-               boot_freelimit = max_paddr;
+               boot_freelimit = max_paddr + KERNBASE;
        }
        printd("boot_zone: %p, paddr base: 0x%llx, paddr len: 0x%llx\n", boot_zone,
               boot_zone ? boot_zone->addr : 0,
@@ -151,8 +152,13 @@ void *boot_alloc(size_t amt, size_t align)
                boot_alloc_init();
        boot_freemem = ROUNDUP(boot_freemem, align);
        retval = boot_freemem;
-       if (boot_freemem + amt > boot_freelimit)
+       if (boot_freemem + amt > boot_freelimit){
+               printk("boot_alloc: boot_freemem is 0x%x\n", boot_freemem);
+               printk("boot_alloc: amt is %d\n", amt);
+               printk("boot_freelimit is 0x%x\n", boot_freelimit);
+               printk("boot_freemem + amt is > boot_freelimit\n");
                panic("Out of memory in boot alloc, you fool!\n");
+       }
        boot_freemem += amt;
        printd("boot alloc from %p to %p\n", retval, boot_freemem);
        /* multiboot info probably won't ever conflict with our boot alloc */
@@ -203,20 +209,21 @@ void *boot_zalloc(size_t amt, size_t align)
  *                   into which the page should be inserted
  *
  */
-int page_insert(pde_t *pgdir, struct page *page, void *va, int perm) 
+int page_insert(pgdir_t pgdir, struct page *page, void *va, int perm) 
 {
-       pte_t* pte = pgdir_walk(pgdir, va, 1);
-       if (!pte)
+       pte_t pte = pgdir_walk(pgdir, va, 1);
+       if (!pte_walk_okay(pte))
                return -ENOMEM;
        /* Two things here:  First, we need to up the ref count of the page we want
         * to insert in case it is already mapped at va.  In that case we don't want
         * page_remove to ultimately free it, and then for us to continue as if pp
         * wasn't freed. (moral = up the ref asap) */
        kref_get(&page->pg_kref, 1);
-       /* Careful, page remove handles the cases where the page is PAGED_OUT. */
-       if (!PAGE_UNMAPPED(*pte))
+       /* Careful, page remove handles the cases where the page is PAGED_OUT and
+        * any other state. (TODO: review all other states, maybe rm only for P) */
+       if (pte_is_mapped(pte))
                page_remove(pgdir, va);
-       *pte = PTE(page2ppn(page), PTE_P | perm);
+       pte_write(pte, page2pa(page), PTE_P | perm);
        return 0;
 }
 
@@ -237,14 +244,14 @@ int page_insert(pde_t *pgdir, struct page *page, void *va, int perm)
  * @return PAGE the page mapped at virtual address 'va'
  * @return NULL No mapping exists at virtual address 'va', or it's paged out
  */
-page_t *page_lookup(pde_t *pgdir, void *va, pte_t **pte_store)
+page_t *page_lookup(pgdir_t pgdir, void *va, pte_t *pte_store)
 {
-       pte_t* pte = pgdir_walk(pgdir, va, 0);
-       if (!pte || !PAGE_PRESENT(*pte))
+       pte_t pte = pgdir_walk(pgdir, va, 0);
+       if (!pte_walk_okay(pte) || !pte_is_present(pte))
                return 0;
        if (pte_store)
                *pte_store = pte;
-       return pa2page(PTE_ADDR(*pte));
+       return pa2page(pte_get_paddr(pte));
 }
 
 /**
@@ -269,27 +276,27 @@ page_t *page_lookup(pde_t *pgdir, void *va, pte_t **pte_store)
  * TODO: consider deprecating this, or at least changing how it works with TLBs.
  * Might want to have the caller need to manage the TLB.  Also note it is used
  * in env_user_mem_free, minus the walk. */
-void page_remove(pde_t *pgdir, void *va)
+void page_remove(pgdir_t pgdir, void *va)
 {
-       pte_t *pte;
+       pte_t pte;
        page_t *page;
 
        pte = pgdir_walk(pgdir,va,0);
-       if (!pte || PAGE_UNMAPPED(*pte))
+       if (!pte_walk_okay(pte) || pte_is_unmapped(pte))
                return;
 
-       if (PAGE_PRESENT(*pte)) {
+       if (pte_is_present(pte)) {
                /* TODO: (TLB) need to do a shootdown, inval sucks.  And might want to
                 * manage the TLB / free pages differently. (like by the caller).
                 * Careful about the proc/memory lock here. */
-               page = ppn2page(PTE2PPN(*pte));
-               *pte = 0;
+               page = pa2page(pte_get_paddr(pte));
+               pte_clear(pte);
                tlb_invalidate(pgdir, va);
                page_decref(page);
-       } else if (PAGE_PAGED_OUT(*pte)) {
+       } else if (pte_is_paged_out(pte)) {
                /* TODO: (SWAP) need to free this from the swap */
                panic("Swapping not supported!");
-               *pte = 0;
+               pte_clear(pte);
        }
 }
 
@@ -304,7 +311,7 @@ void page_remove(pde_t *pgdir, void *va)
  * @param va    the virtual address associated with the tlb entry
  *              we are trying to invalidate
  */
-void tlb_invalidate(pde_t *pgdir, void *va)
+void tlb_invalidate(pgdir_t pgdir, void *va)
 {
        // Flush the entry only if we're modifying the current address space.
        // For now, there is only one address space, so always invalidate.
@@ -327,3 +334,25 @@ bool regions_collide_unsafe(uintptr_t start1, uintptr_t end1,
                return TRUE;
        }
 }
+
+void print_free_mem(void)
+{
+       static uint8_t *bm = 0;
+       /* racy, but this is debugging code */
+       if (!bm)
+               bm = kzmalloc((max_nr_pages + 1) / 8, 0);
+
+       long x = 0;
+       for (int i = 0; i < max_nr_pages; i++) {
+               if (page_is_free(i)) {
+                       x++;
+                       SET_BITMASK_BIT(bm, i);
+               } else {
+                       if (GET_BITMASK_BIT(bm, i)) {
+                               print_pageinfo(ppn2page(i));
+                               CLR_BITMASK_BIT(bm, i);
+                       }
+               }
+       }
+       printk("Nr Free pages: %lld\n", x);
+}