Merge branch 'master' into isa/arm64
[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
62 #define USER_PAGE               ( _PTE_P | _PTE_U )
63 #define USER_EXEC               ( USER_PAGE | _PTE_X )
64 #define USER_DATA               ( USER_PAGE | _PTE_W | _PTE_NX )
65 #define USER_RDONLY             ( USER_PAGE | _PTE_NX )
66 #define USER_ROEXEC             ( USER_PAGE | _PTE_X  )
67 #define USER_PGTAB              ( USER_PAGE | _PTE_W )
68 #define USER_DEFAULT              USER_PGTAB
69
70 #define SELF_MAP                ( KERNEL_PGTAB | _PTE_WT | _PTE_CD )
71
72 #define __mkpte_from(pte_val)   ((pte_t){ .val = (pte_val) })
73
74 #define null_pte                ( __mkpte_from(0) )
75 #define guard_pte               ( __mkpte_from(__MEMGUARD) )
76 #define pte_val(pte)            ( pte.val )
77
78
79 static inline bool
80 pte_isguardian(pte_t pte)
81 {
82     return pte.val == __MEMGUARD;
83 }
84
85 static inline pte_t
86 mkpte_prot(pte_attr_t prot)
87 {
88     pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
89     return __mkpte_from(attrs);
90 }
91
92 static inline pte_t
93 mkpte(ptr_t paddr, pte_attr_t prot)
94 {
95     pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
96     return __mkpte_from((paddr & ~_PAGE_BASE_MASK) | attrs);
97 }
98
99 static inline pte_t
100 mkpte_root(ptr_t paddr, pte_attr_t prot)
101 {
102     pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
103     return __mkpte_from((paddr & ~_PAGE_BASE_MASK) | attrs);
104 }
105
106 static inline pte_t
107 mkpte_raw(unsigned long pte_val)
108 {
109     return __mkpte_from(pte_val);
110 }
111
112 static inline pte_t
113 pte_setpaddr(pte_t pte, ptr_t paddr)
114 {
115     return __mkpte_from((pte.val & _PTE_PROT_MASK) | (paddr & ~_PTE_PROT_MASK));
116 }
117
118 static inline pte_t
119 pte_setppfn(pte_t pte, pfn_t ppfn)
120 {
121     return pte_setpaddr(pte, ppfn * PAGE_SIZE);
122 }
123
124 static inline ptr_t
125 pte_paddr(pte_t pte)
126 {
127     return __paddr(pte.val) & ~_PTE_PROT_MASK;
128 }
129
130 static inline pfn_t
131 pte_ppfn(pte_t pte)
132 {
133     return pte_paddr(pte) >> _PAGE_BASE_SHIFT;
134 }
135
136 static inline pte_t
137 pte_setprot(pte_t pte, ptr_t prot)
138 {
139     return __mkpte_from((pte.val & ~_PTE_PROT_MASK) | (prot & _PTE_PROT_MASK));
140 }
141
142 static inline pte_attr_t
143 pte_prot(pte_t pte)
144 {
145     return (pte.val & _PTE_PROT_MASK);
146 }
147
148 static inline bool
149 pte_isnull(pte_t pte)
150 {
151     return !pte.val;
152 }
153
154 static inline pte_t
155 pte_mkhuge(pte_t pte) 
156 {
157     return __mkpte_from(pte.val | _PTE_PS);
158 }
159
160 static inline pte_t
161 pte_mkvolatile(pte_t pte) 
162 {
163     return __mkpte_from(pte.val | _PTE_WT | _PTE_CD);
164 }
165
166 static inline pte_t
167 pte_mkroot(pte_t pte) 
168 {
169     return __mkpte_from(pte.val & ~_PTE_PS);
170 }
171
172 static inline pte_t
173 pte_usepat(pte_t pte) 
174 {
175     return __mkpte_from(pte.val | _PTE_PAT);
176 }
177
178 static inline bool
179 pte_huge(pte_t pte) 
180 {
181     return !!(pte.val & _PTE_PS);
182 }
183
184 static inline pte_t
185 pte_mkloaded(pte_t pte) 
186 {
187     return __mkpte_from(pte.val | _PTE_P);
188 }
189
190 static inline pte_t
191 pte_mkunloaded(pte_t pte) 
192 {
193     return __mkpte_from(pte.val & ~_PTE_P);
194 }
195
196 static inline bool
197 pte_isloaded(pte_t pte) 
198 {
199     return !!(pte.val & _PTE_P);
200 }
201
202 static inline pte_t
203 pte_mkwprotect(pte_t pte) 
204 {
205     return __mkpte_from(pte.val & ~_PTE_W);
206 }
207
208 static inline pte_t
209 pte_mkwritable(pte_t pte) 
210 {
211     return __mkpte_from(pte.val | _PTE_W);
212 }
213
214 static inline bool
215 pte_iswprotect(pte_t pte) 
216 {
217     return !(pte.val & _PTE_W);
218 }
219
220 static inline pte_t
221 pte_mkuser(pte_t pte) 
222 {
223     return __mkpte_from(pte.val | _PTE_U);
224 }
225
226 static inline pte_t
227 pte_mkkernel(pte_t pte) 
228 {
229     return __mkpte_from(pte.val & ~_PTE_U);
230 }
231
232 static inline bool
233 pte_allow_user(pte_t pte) 
234 {
235     return !!(pte.val & _PTE_U);
236 }
237
238 static inline pte_t
239 pte_mkexec(pte_t pte)
240 {
241     return __mkpte_from(pte.val & ~_PTE_NX);
242 }
243
244 static inline pte_t
245 pte_mknonexec(pte_t pte)
246 {
247     return __mkpte_from(pte.val | _PTE_NX);
248 }
249
250 static inline bool
251 pte_isexec(pte_t pte)
252 {
253     return !(pte.val & _PTE_NX);
254 }
255
256 static inline pte_t
257 pte_mkuntouch(pte_t pte) 
258 {
259     return __mkpte_from(pte.val & ~_PTE_A);
260 }
261
262 static inline bool
263 pte_istouched(pte_t pte) 
264 {
265     return !!(pte.val & _PTE_A);
266 }
267
268 static inline pte_t
269 pte_mkclean(pte_t pte) 
270 {
271     return __mkpte_from(pte.val & ~_PTE_D);
272 }
273
274 static inline bool
275 pte_dirty(pte_t pte) 
276 {
277     return !!(pte.val & _PTE_D);
278 }
279
280 static inline void
281 set_pte(pte_t* ptep, pte_t pte)
282 {
283     ptep->val = pte.val;
284 }
285
286 static inline pte_t
287 pte_at(pte_t* ptep) {
288     return *ptep;
289 }
290
291 pte_t
292 translate_vmr_prot(unsigned int vmr_prot, pte_t pte);
293
294 #endif /* __LUNAIX_ARCH_PAGETABLE_H */