Add some `const' qualifiers.
[pintos-anon] / src / userprog / pagedir.c
1 #include "userprog/pagedir.h"
2 #include <stdbool.h>
3 #include <stddef.h>
4 #include <string.h>
5 #include "threads/init.h"
6 #include "threads/mmu.h"
7 #include "threads/palloc.h"
8
9 uint32_t *
10 pagedir_create (void) 
11 {
12   uint32_t *pd = palloc_get (0);
13   memcpy (pd, base_page_dir, PGSIZE);
14   return pd;
15 }
16
17 void
18 pagedir_destroy (uint32_t *pd) 
19 {
20   uint32_t *pde;
21
22   for (pde = pd; pde < pd + pd_no (PHYS_BASE); pde++)
23     if (*pde & PG_P) 
24       {
25         uint32_t *pt = pde_get_pt (*pde);
26         uint32_t *pte;
27         
28         for (pte = pt; pte < pt + PGSIZE / sizeof *pte; pte++)
29           if (*pte & PG_P) 
30             palloc_free (pte_get_page (*pte));
31         palloc_free (pt);
32       }
33   palloc_free (pd);
34 }
35
36 static uint32_t *
37 lookup_page (uint32_t *pd, void *upage, bool create)
38 {
39   uint32_t *pt;
40   uint32_t *pde;
41
42   ASSERT (pd != NULL);
43   ASSERT (upage < PHYS_BASE);
44
45   /* Check for a page table for UPAGE.
46      If one is missing, create one if requested. */
47   pde = pd + pd_no (upage);
48   if (*pde == 0) 
49     {
50       if (create)
51         {
52           pt = palloc_get (PAL_ZERO);
53           if (pt == NULL) 
54             return NULL; 
55       
56           *pde = pde_create (pt);
57         }
58       else
59         return NULL;
60     }
61
62   /* Return the page table entry. */
63   pt = pde_get_pt (*pde);
64   return &pt[pt_no (upage)];
65 }
66
67 bool
68 pagedir_set_page (uint32_t *pd, void *upage, void *kpage,
69                   bool writable) 
70 {
71   uint32_t *pte;
72
73   ASSERT (pg_ofs (kpage) == 0);
74
75   pte = lookup_page (pd, upage, true);
76   if (pte != NULL) 
77     {
78       *pte = pte_create_user (kpage, writable);
79       return true;
80     }
81   else
82     return false;
83 }
84
85 void *
86 pagedir_get_page (uint32_t *pd, const void *upage) 
87 {
88   uint32_t *pte = lookup_page (pd, (void *) upage, false);
89   return pte != NULL && *pte != 0 ? pte_get_page (*pte) : NULL;
90 }
91
92 void
93 pagedir_clear_page (uint32_t *pd, void *upage)
94 {
95   uint32_t *pte = lookup_page (pd, upage, false);
96   if (pte != NULL)
97     *pte = 0;
98 }
99
100 void
101 pagedir_activate (uint32_t *pd) 
102 {
103   if (pd == NULL)
104     pd = base_page_dir;
105   asm volatile ("movl %0,%%cr3" :: "r" (vtop (pd)));
106 }