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