Fixed user_mem_check()
[akaros.git] / kern / include / pmap.h
1 /* See COPYRIGHT for copyright information. */
2
3 #ifndef ROS_KERN_PMAP_H
4 #define ROS_KERN_PMAP_H
5 #ifndef ROS_KERNEL
6 # error "This is a ROS kernel header; user programs should not #include it"
7 #endif
8
9 #include <ros/memlayout.h>
10 #include <sys/queue.h>
11 #include <multiboot.h>
12 #include <atomic.h>
13 #include <process.h>
14 #include <assert.h>
15 #include <page_alloc.h>
16 #include <multiboot.h>
17
18 /* This macro takes a kernel virtual address -- an address that points above
19  * KERNBASE, where the machine's maximum 256MB of physical memory is mapped --
20  * and returns the corresponding physical address.  It panics if you pass it a
21  * non-kernel virtual address.
22  */
23 #define PADDR(kva)                                              \
24 ({                                                              \
25         physaddr_t __m_kva = (physaddr_t) (kva);                \
26         if (__m_kva < KERNBASE)                                 \
27                 panic("PADDR called with invalid kva %08lx", __m_kva);\
28         __m_kva - KERNBASE;                                     \
29 })
30
31 /* This macro takes a physical address and returns the corresponding kernel
32  * virtual address.  It warns if you pass an invalid physical address. */
33 #define KADDR(pa)                                               \
34 ({                                                              \
35         physaddr_t __m_pa = (pa);                               \
36         size_t __m_ppn = PPN(__m_pa);                           \
37         if (__m_ppn >= npages)                                  \
38                 warn("KADDR called with invalid pa %08lx", __m_pa);\
39         (void*TRUSTED) (__m_pa + KERNBASE);                             \
40 })
41
42 extern char (SNT bootstacktop)[], (SNT bootstack)[];
43
44 // List of pysical pages
45 extern volatile uint32_t pages_lock;
46 extern page_t SLOCKED(&pages_lock) * SREADONLY COUNT(npages) pages;
47
48 extern physaddr_t boot_cr3;
49 extern pde_t *COUNT(NPDENTRIES) boot_pgdir;
50
51 extern char*BND(end, maxaddrpa_ptr + IVY_KERNBASE) boot_freemem;
52
53 void    multiboot_detect_memory(multiboot_info_t *COUNT(1) mbi);
54 void    multiboot_print_memory_map(multiboot_info_t *COUNT(1) mbi);
55 bool    enable_pse(void);
56 void    vm_init(void);
57
58 void    page_init(void);
59 void    page_check(void);
60 int         page_insert(pde_t *COUNT(NPDENTRIES) pgdir, page_t *pp, void *SNT va, int perm);
61 void*COUNT(PGSIZE) page_insert_in_range(pde_t *COUNT(NPDENTRIES) pgdir, page_t *pp, 
62                              void *SNT vab, void *SNT vae, int perm);
63 void    page_remove(pde_t *COUNT(NPDENTRIES) pgdir, void *SNT va);
64 page_t*COUNT(1) page_lookup(pde_t SSOMELOCK*COUNT(NPDENTRIES) pgdir, void *SNT va, pte_t **pte_store);
65 error_t pagetable_remove(pde_t *COUNT(NPDENTRIES) pgdir, void *SNT va);
66 void    page_decref(page_t *COUNT(1) pp);
67
68 void setup_default_mtrrs(barrier_t* smp_barrier);
69 void    tlb_invalidate(pde_t *COUNT(NPDENTRIES) pgdir, void *SNT va);
70 void tlb_flush_global(void);
71
72 void * (DALLOC(len) user_mem_check) (env_t *env, const void *DANGEROUS va,
73                                      size_t len, int perm);
74
75 void * (DALLOC(len) user_mem_assert)(env_t *env, const void *DANGEROUS va,
76                                      size_t len, int perm);
77
78 size_t user_mem_strlcpy(env_t *env, char *NT COUNT(len - 1),
79                         const char *DANGEROUS va, size_t len, int perm);
80
81 error_t
82 memcpy_from_user(env_t* env, void* COUNT(len) dest,
83                  const void *DANGEROUS va, size_t len);
84                  
85 pte_t *pgdir_walk(pde_t *COUNT(NPDENTRIES) pgdir, const void *SNT va, int create);
86 int get_va_perms(pde_t *pgdir, const void *SNT va);
87
88 static inline page_t *SAFE ppn2page(size_t ppn)
89 {
90         if( ppn >= npages )
91                 warn("ppn2page called with ppn (%08u) larger than npages", ppn);
92         return &(pages[ppn]);
93 }
94
95 static inline ppn_t page2ppn(page_t *pp)
96 {
97         return pp - pages;
98 }
99
100 static inline physaddr_t page2pa(page_t *pp)
101 {
102         return page2ppn(pp) << PGSHIFT;
103 }
104
105 static inline page_t*COUNT(1) pa2page(physaddr_t pa)
106 {
107         if (PPN(pa) >= npages)
108                 warn("pa2page called with pa (0x%08x) larger than npages", pa);
109         return &pages[PPN(pa)];
110 }
111
112 static inline void*COUNT(PGSIZE) page2kva(page_t *pp)
113 {
114         return KADDR(page2pa(pp));
115 }
116
117 static inline void*COUNT(PGSIZE) ppn2kva(size_t pp)
118 {
119         return page2kva(ppn2page(pp));
120 }
121
122 static inline page_t* kva2page(void* addr) 
123 {
124         return pa2page(PADDR(addr));
125 }
126
127 #endif /* !ROS_KERN_PMAP_H */