smp_call wait / backend work
[akaros.git] / kern / 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 <inc/memlayout.h>
10 #include <inc/assert.h>
11 #include <inc/multiboot.h>
12 #include <kern/atomic.h>
13 #include <kern/env.h>
14
15 /* This macro takes a kernel virtual address -- an address that points above
16  * KERNBASE, where the machine's maximum 256MB of physical memory is mapped --
17  * and returns the corresponding physical address.  It panics if you pass it a
18  * non-kernel virtual address.
19  */
20 #define PADDR(kva)                                              \
21 ({                                                              \
22         physaddr_t __m_kva = (physaddr_t) (kva);                \
23         if (__m_kva < KERNBASE)                                 \
24                 panic("PADDR called with invalid kva %08lx", __m_kva);\
25         __m_kva - KERNBASE;                                     \
26 })
27
28 /* This macro takes a physical address and returns the corresponding kernel
29  * virtual address.  It warns if you pass an invalid physical address. */
30 #define KADDR(pa)                                               \
31 ({                                                              \
32         physaddr_t __m_pa = (pa);                               \
33         uint32_t __m_ppn = PPN(__m_pa);                         \
34         if (__m_ppn >= npage)                                   \
35                 warn("KADDR called with invalid pa %08lx", __m_pa);\
36         (void*) (__m_pa + KERNBASE);                            \
37 })
38
39
40
41 extern char bootstacktop[], bootstack[];
42
43 extern page_t *pages;
44 extern size_t npage;
45
46 extern physaddr_t boot_cr3;
47 extern pde_t *boot_pgdir;
48
49 extern segdesc_t (COUNT(SEG_COUNT) gdt)[];
50 extern pseudodesc_t gdt_pd;
51
52 void    i386_detect_memory(multiboot_info_t *mbi);
53 void    i386_print_memory_map(multiboot_info_t *mbi);
54 bool    enable_pse(void);
55 void    i386_vm_init(void);
56
57 void    page_init(void);
58 void    page_check(void);
59 int     page_alloc(page_t **pp_store);
60 void    page_free(page_t *pp);
61 int     page_insert(pde_t *pgdir, page_t *pp, void *va, int perm);
62 void    page_remove(pde_t *pgdir, void *va);
63 page_t *page_lookup(pde_t *pgdir, void *va, pte_t **pte_store);
64 void    page_decref(page_t *pp);
65
66 void setup_default_mtrrs(barrier_t* smp_barrier);
67 void    tlb_invalidate(pde_t *pgdir, void *va);
68 void tlb_flush_global(void);
69
70 void *COUNT(len)
71 user_mem_check(env_t *env, const void *DANGEROUS va, size_t len, int perm);
72
73 void *COUNT(len)
74 user_mem_assert(env_t *env, const void *DANGEROUS va, size_t len, int perm);
75
76 static inline void cache_flush(void)
77 {
78         wbinvd();
79 }
80
81 static inline void cacheline_flush(void* addr)
82 {
83         clflush((uintptr_t*)addr);
84 }
85
86 static inline ppn_t page2ppn(page_t *pp)
87 {
88         return pp - pages;
89 }
90
91 static inline physaddr_t page2pa(page_t *pp)
92 {
93         return page2ppn(pp) << PGSHIFT;
94 }
95
96 static inline page_t* pa2page(physaddr_t pa)
97 {
98         if (PPN(pa) >= npage)
99                 warn("pa2page called with pa larger than npage");
100         return &pages[PPN(pa)];
101 }
102
103 static inline void* page2kva(page_t *pp)
104 {
105         return KADDR(page2pa(pp));
106 }
107
108 pte_t *pgdir_walk(pde_t *pgdir, const void *va, int create);
109
110 #endif /* !ROS_KERN_PMAP_H */