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