Added struct proc pointer to base of the executable args block
[akaros.git] / kern / arch / riscv / pmap_ops.h
1 /* Copyright (c) 2015 Google Inc.
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Arch-specific operations for page tables and PTEs */
6
7 #pragma once
8
9 static inline bool pte_walk_okay(pte_t pte)
10 {
11         return pte ? TRUE : FALSE;
12 }
13
14 /* PTE states:
15  *  - present: the PTE is involved in a valid page table walk, with the physaddr
16  *  part pointing to a physical page.
17  *
18  *      - mapped: the PTE is involved in some sort of mapping, e.g. a VMR.  We're
19  *      storing something in the PTE, but it is isn't necessarily present and
20  *      pointing to an actual physical page.  All present are mapped, but not vice
21  *      versa.  Mapped could also include paged-out, if we support that later.
22  *
23  *      - unmapped: completely unused. (0 value) */
24 static inline bool pte_is_present(pte_t pte)
25 {
26         return *(kpte_t*)pte & PTE_P ? TRUE : FALSE;
27 }
28
29 static inline bool pte_is_unmapped(pte_t pte)
30 {
31         return PAGE_UNMAPPED(*(kpte_t*)pte);
32 }
33
34 static inline bool pte_is_mapped(pte_t pte)
35 {
36         return !PAGE_UNMAPPED(*(kpte_t*)pte);
37 }
38
39 static inline bool pte_is_paged_out(pte_t pte)
40 {
41         return PAGE_PAGED_OUT(*(kpte_t*)pte);
42 }
43
44 static inline bool pte_is_dirty(pte_t pte)
45 {
46         return *(kpte_t*)pte & PTE_D ? TRUE : FALSE;
47 }
48
49 static inline bool pte_is_accessed(pte_t pte)
50 {
51         return *(kpte_t*)pte & PTE_A ? TRUE : FALSE;
52 }
53
54 /* Used in debugging code - want something better involving the walk */
55 static inline bool pte_is_jumbo(pte_t pte)
56 {
57         return *(kpte_t*)pte & PTE_PS ? TRUE : FALSE;
58 }
59
60 static inline physaddr_t pte_get_paddr(pte_t pte)
61 {
62         return PTE_ADDR(*(kpte_t*)pte);
63 }
64
65 /* Returns the PTE in an unsigned long, for debugging mostly. */
66 static inline unsigned long pte_print(pte_t pte)
67 {
68         return *(kpte_t*)pte;
69 }
70
71 static inline void pte_write(pte_t pte, physaddr_t pa, int settings)
72 {
73         *(kpte_t*)pte = PTE(pa2ppn(pa), settings);
74 }
75
76 static inline void pte_clear_present(pte_t pte)
77 {
78         *(kpte_t*)pte &= ~PTE_P;
79 }
80
81 static inline void pte_clear(pte_t pte)
82 {
83         *(kpte_t*)pte = 0;
84 }
85
86 /* These are used by memcpy_*_user, but are very dangerous (and possibly used
87  * incorrectly there).  These aren't the overall perms for a VA.  For U and W,
88  * we need the intersection of the PTEs along the walk and not just the last
89  * one.  It just so happens that the W is only cleared on the last PTE, so the
90  * check works for that.  But if there was a page under ULIM that wasn't U due
91  * to an intermediate PTE, we'd miss that. */
92 static inline bool pte_has_perm_ur(pte_t pte)
93 {
94         return *(kpte_t*)pte & PTE_USER_RO ? TRUE : FALSE;
95 }
96
97 static inline bool pte_has_perm_urw(pte_t pte)
98 {
99         return *(kpte_t*)pte & PTE_USER_RW ? TRUE : FALSE;
100 }
101
102 /* Settings includes protection (maskable via PTE_PROT) and other bits, such as
103  * jumbo, dirty, accessed, etc.  Whatever this returns can get fed back to
104  * replace_settings or pte_write.
105  *
106  * Arch-indep settings include: PTE_PERM (U, W, P, etc), PTE_D, PTE_A, PTE_PS.
107  * Other OSs (x86) may include others. */
108 static inline int pte_get_settings(pte_t pte)
109 {
110         return *(kpte_t*)pte & PTE_PERM;
111 }
112
113 static inline void pte_replace_perm(pte_t pte, int perm)
114 {
115         *(kpte_t*)pte = (*(kpte_t*)pte & ~PTE_PERM) | perm;
116 }