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