rewrite the device subsystem interfaces (#48)
[lunaix-os.git] / lunaix-os / arch / x86 / includes / asm / pagetable.h
1 #ifndef __LUNAIX_ARCH_PAGETABLE_H
2 #define __LUNAIX_ARCH_PAGETABLE_H
3
4 #include <lunaix/types.h>
5 #include <lunaix/compiler.h>
6
7 /* ******** Page Table Manipulation ******** */
8
9 #ifdef CONFIG_ARCH_X86_64
10
11 #include "variants/pt_def64.h"
12
13 #else
14
15 #include "variants/pt_def32.h"
16
17 #endif
18
19 /* General mask to get page offset of a LnT huge page */
20
21 #define L0T_MASK            ( L0T_SIZE - 1 )
22 #define L1T_MASK            ( L1T_SIZE - 1 )
23 #define L2T_MASK            ( L2T_SIZE - 1 )
24 #define L3T_MASK            ( L3T_SIZE - 1 )
25 #define LFT_MASK            ( LFT_SIZE - 1 )
26
27 /* Masks to get index of a LnTE */
28
29 #define L0T_INDEX_MASK      ( VMS_MASK ^ L0T_MASK )
30 #define L1T_INDEX_MASK      ( L0T_MASK ^ L1T_MASK )
31 #define L2T_INDEX_MASK      ( L1T_MASK ^ L2T_MASK )
32 #define L3T_INDEX_MASK      ( L2T_MASK ^ L3T_MASK )
33 #define LFT_INDEX_MASK      ( L3T_MASK ^ LFT_MASK )
34
35 #define PAGE_SHIFT          _PAGE_BASE_SHIFT
36 #define PAGE_SIZE           _PAGE_BASE_SIZE
37 #define PAGE_MASK           _PAGE_BASE_MASK
38
39 #define LEVEL_SHIFT         _PAGE_LEVEL_SHIFT
40 #define LEVEL_SIZE          _PAGE_LEVEL_SIZE
41 #define LEVEL_MASK          _PAGE_LEVEL_MASK
42
43 // max PTEs number
44 #define MAX_PTEN            _PAGE_LEVEL_SIZE
45
46 // max translation level supported
47 #define MAX_LEVEL           _PTW_LEVEL
48
49 typedef struct __pte pte_t;
50
51
52 #define _PTE_PPFN_MASK          ( (~PAGE_MASK & PMS_MASK))
53 #define _PTE_PROT_MASK          ( ~_PTE_PPFN_MASK )
54
55 #define KERNEL_PAGE             ( _PTE_P )
56 #define KERNEL_EXEC             ( KERNEL_PAGE | _PTE_X )
57 #define KERNEL_DATA             ( KERNEL_PAGE | _PTE_W | _PTE_NX )
58 #define KERNEL_RDONLY           ( KERNEL_PAGE | _PTE_NX )
59 #define KERNEL_ROEXEC           ( KERNEL_PAGE | _PTE_X  )
60 #define KERNEL_PGTAB            ( KERNEL_PAGE | _PTE_W )
61 #define KERNEL_DEFAULT            KERNEL_PGTAB
62
63 #define USER_PAGE               ( _PTE_P | _PTE_U )
64 #define USER_EXEC               ( USER_PAGE | _PTE_X )
65 #define USER_DATA               ( USER_PAGE | _PTE_W | _PTE_NX )
66 #define USER_RDONLY             ( USER_PAGE | _PTE_NX )
67 #define USER_ROEXEC             ( USER_PAGE | _PTE_X  )
68 #define USER_PGTAB              ( USER_PAGE | _PTE_W )
69 #define USER_DEFAULT              USER_PGTAB
70
71 #define SELF_MAP                ( KERNEL_PGTAB | _PTE_WT | _PTE_CD )
72
73 #define __mkpte_from(pte_val)   ((pte_t){ .val = (pte_val) })
74
75 #define null_pte                ( __mkpte_from(0) )
76 #define guard_pte               ( __mkpte_from(__MEMGUARD) )
77 #define pte_val(pte)            ( pte.val )
78
79
80 static inline bool
81 pte_isguardian(pte_t pte)
82 {
83     return pte.val == __MEMGUARD;
84 }
85
86 static inline pte_t
87 mkpte_prot(pte_attr_t prot)
88 {
89     pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
90     return __mkpte_from(attrs);
91 }
92
93 static inline pte_t
94 mkpte(ptr_t paddr, pte_attr_t prot)
95 {
96     pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
97     return __mkpte_from((paddr & ~_PAGE_BASE_MASK) | attrs);
98 }
99
100 static inline pte_t
101 mkpte_root(ptr_t paddr, pte_attr_t prot)
102 {
103     pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
104     return __mkpte_from((paddr & ~_PAGE_BASE_MASK) | attrs);
105 }
106
107 static inline pte_t
108 mkpte_raw(unsigned long pte_val)
109 {
110     return __mkpte_from(pte_val);
111 }
112
113 static inline pte_t
114 pte_setpaddr(pte_t pte, ptr_t paddr)
115 {
116     return __mkpte_from((pte.val & _PTE_PROT_MASK) | (paddr & ~_PTE_PROT_MASK));
117 }
118
119 static inline pte_t
120 pte_setppfn(pte_t pte, pfn_t ppfn)
121 {
122     return pte_setpaddr(pte, ppfn * PAGE_SIZE);
123 }
124
125 static inline ptr_t
126 pte_paddr(pte_t pte)
127 {
128     return __paddr(pte.val) & ~_PTE_PROT_MASK;
129 }
130
131 static inline pfn_t
132 pte_ppfn(pte_t pte)
133 {
134     return pte_paddr(pte) >> _PAGE_BASE_SHIFT;
135 }
136
137 static inline pte_t
138 pte_setprot(pte_t pte, ptr_t prot)
139 {
140     return __mkpte_from((pte.val & ~_PTE_PROT_MASK) | (prot & _PTE_PROT_MASK));
141 }
142
143 static inline pte_attr_t
144 pte_prot(pte_t pte)
145 {
146     return (pte.val & _PTE_PROT_MASK);
147 }
148
149 static inline bool
150 pte_isnull(pte_t pte)
151 {
152     return !pte.val;
153 }
154
155 static inline pte_t
156 pte_mkhuge(pte_t pte) 
157 {
158     return __mkpte_from(pte.val | _PTE_PS);
159 }
160
161 static inline pte_t
162 pte_mkvolatile(pte_t pte) 
163 {
164     return __mkpte_from(pte.val | _PTE_WT | _PTE_CD);
165 }
166
167 static inline pte_t
168 pte_mkroot(pte_t pte) 
169 {
170     return __mkpte_from(pte.val & ~_PTE_PS);
171 }
172
173 static inline pte_t
174 pte_usepat(pte_t pte) 
175 {
176     return __mkpte_from(pte.val | _PTE_PAT);
177 }
178
179 static inline bool
180 pte_huge(pte_t pte) 
181 {
182     return !!(pte.val & _PTE_PS);
183 }
184
185 static inline pte_t
186 pte_mkloaded(pte_t pte) 
187 {
188     return __mkpte_from(pte.val | _PTE_P);
189 }
190
191 static inline pte_t
192 pte_mkunloaded(pte_t pte) 
193 {
194     return __mkpte_from(pte.val & ~_PTE_P);
195 }
196
197 static inline bool
198 pte_isloaded(pte_t pte) 
199 {
200     return !!(pte.val & _PTE_P);
201 }
202
203 static inline pte_t
204 pte_mkwprotect(pte_t pte) 
205 {
206     return __mkpte_from(pte.val & ~_PTE_W);
207 }
208
209 static inline pte_t
210 pte_mkwritable(pte_t pte) 
211 {
212     return __mkpte_from(pte.val | _PTE_W);
213 }
214
215 static inline bool
216 pte_iswprotect(pte_t pte) 
217 {
218     return !(pte.val & _PTE_W);
219 }
220
221 static inline pte_t
222 pte_mkuser(pte_t pte) 
223 {
224     return __mkpte_from(pte.val | _PTE_U);
225 }
226
227 static inline pte_t
228 pte_mkkernel(pte_t pte) 
229 {
230     return __mkpte_from(pte.val & ~_PTE_U);
231 }
232
233 static inline bool
234 pte_allow_user(pte_t pte) 
235 {
236     return !!(pte.val & _PTE_U);
237 }
238
239 static inline pte_t
240 pte_mkexec(pte_t pte)
241 {
242     return __mkpte_from(pte.val & ~_PTE_NX);
243 }
244
245 static inline pte_t
246 pte_mknonexec(pte_t pte)
247 {
248     return __mkpte_from(pte.val | _PTE_NX);
249 }
250
251 static inline bool
252 pte_isexec(pte_t pte)
253 {
254     return !(pte.val & _PTE_NX);
255 }
256
257 static inline pte_t
258 pte_mkuntouch(pte_t pte) 
259 {
260     return __mkpte_from(pte.val & ~_PTE_A);
261 }
262
263 static inline bool
264 pte_istouched(pte_t pte) 
265 {
266     return !!(pte.val & _PTE_A);
267 }
268
269 static inline pte_t
270 pte_mkclean(pte_t pte) 
271 {
272     return __mkpte_from(pte.val & ~_PTE_D);
273 }
274
275 static inline bool
276 pte_dirty(pte_t pte) 
277 {
278     return !!(pte.val & _PTE_D);
279 }
280
281 static inline void
282 set_pte(pte_t* ptep, pte_t pte)
283 {
284     ptep->val = pte.val;
285 }
286
287 static inline pte_t
288 pte_at(pte_t* ptep) {
289     return *ptep;
290 }
291
292 pte_t
293 translate_vmr_prot(unsigned int vmr_prot, pte_t pte);
294
295 #endif /* __LUNAIX_ARCH_PAGETABLE_H */