A Total Overhaul on the Lunaix's Virtual Memory Model (#26)
[lunaix-os.git] / lunaix-os / arch / generic / includes / sys / mm / pagetable.h
1 /**
2  * @file pagetable.h
3  * @author Lunaixsky (lunaxisky@qq.com)
4  * @brief Generic (skeleton) definition for pagetable.h
5  * @version 0.1
6  * @date 2024-02-18
7  * 
8  * @copyright Copyright (c) 2024
9  * 
10  */
11
12 #ifndef __LUNAIX_ARCH_PAGETABLE_H
13 #define __LUNAIX_ARCH_PAGETABLE_H
14
15 #include <lunaix/types.h>
16 #include <lunaix/compiler.h>
17
18 /* ******** Page Table Manipulation ******** */
19
20 // Levels of page table to traverse for a single page walk
21 #define _PTW_LEVEL          2
22
23 #define _PAGE_BASE_SHIFT    12
24 #define _PAGE_BASE_SIZE     ( 1UL << _PAGE_BASE_SHIFT )
25 #define _PAGE_BASE_MASK     ( _PAGE_BASE_SIZE - 1)
26
27 #define _PAGE_LEVEL_SHIFT   10
28 #define _PAGE_LEVEL_SIZE    ( 1UL << _PAGE_LEVEL_SHIFT )
29 #define _PAGE_LEVEL_MASK    ( _PAGE_LEVEL_SIZE - 1 )
30 #define _PAGE_Ln_SIZE(n)    ( 1UL << (_PAGE_BASE_SHIFT + _PAGE_LEVEL_SHIFT * (_PTW_LEVEL - (n) - 1)) )
31
32 // Note: we set VMS_SIZE = VMS_MASK as it is impossible
33 //       to express 4Gi in 32bit unsigned integer
34
35 #define VMS_MASK            ( -1UL )
36 #define VMS_SIZE            VMS_MASK
37
38 /* General size of a LnT huge page */
39
40 #define L0T_SIZE            _PAGE_Ln_SIZE(0)
41 #define L1T_SIZE            _PAGE_Ln_SIZE(1)
42 #define L2T_SIZE            _PAGE_Ln_SIZE(1)
43 #define L3T_SIZE            _PAGE_Ln_SIZE(1)
44 #define LFT_SIZE            _PAGE_Ln_SIZE(1)
45
46 /* General mask to get page offset of a LnT huge page */
47
48 #define L0T_MASK            ( L0T_SIZE - 1 )
49 #define L1T_MASK            ( L1T_SIZE - 1 )
50 #define L2T_MASK            ( L2T_SIZE - 1 )
51 #define L3T_MASK            ( L3T_SIZE - 1 )
52 #define LFT_MASK            ( LFT_SIZE - 1 )
53
54 /* Masks to get index of a LnTE */
55
56 #define L0T_INDEX_MASK      ( VMS_MASK ^ L0T_MASK )
57 #define L1T_INDEX_MASK      ( L0T_MASK ^ L1T_MASK )
58 #define L2T_INDEX_MASK      ( L1T_MASK ^ L2T_MASK )
59 #define L3T_INDEX_MASK      ( L2T_MASK ^ L3T_MASK )
60 #define LFT_INDEX_MASK      ( L3T_MASK ^ LFT_MASK )
61
62 #define PAGE_SHIFT          _PAGE_BASE_SHIFT
63 #define PAGE_SIZE           _PAGE_BASE_SIZE
64 #define PAGE_MASK           _PAGE_BASE_MASK
65
66 #define LEVEL_SHIFT         _PAGE_LEVEL_SHIFT
67 #define LEVEL_SIZE          _PAGE_LEVEL_SIZE
68 #define LEVEL_MASK          _PAGE_LEVEL_MASK
69
70 // max PTEs number
71 #define MAX_PTEN            _PAGE_LEVEL_SIZE
72
73 // max translation level supported
74 #define MAX_LEVEL           _PTW_LEVEL
75
76
77 /* ******** PTE Manipulation ******** */
78
79 struct __pte {
80     unsigned int val;
81 } align(4);
82
83 #ifndef pte_t
84 typedef struct __pte pte_t;
85 #endif
86
87 typedef unsigned int pfn_t;
88 typedef unsigned int pte_attr_t;
89
90 #define _PTE_P                  (0)
91 #define _PTE_W                  (0)
92 #define _PTE_U                  (0)
93 #define _PTE_A                  (0)
94 #define _PTE_D                  (0)
95 #define _PTE_X                  (0)
96 #define _PTE_R                  (0)
97
98 #define _PTE_PROT_MASK          ( _PTE_W | _PTE_U | _PTE_X )
99
100 #define KERNEL_PAGE             ( _PTE_P )
101 #define KERNEL_EXEC             ( KERNEL_PAGE | _PTE_X )
102 #define KERNEL_DATA             ( KERNEL_PAGE | _PTE_W  )
103 #define KERNEL_RDONLY           ( KERNEL_PAGE )
104
105 #define USER_PAGE               ( _PTE_P | _PTE_U )
106 #define USER_EXEC               ( USER_PAGE | _PTE_X )
107 #define USER_DATA               ( USER_PAGE | _PTE_W )
108 #define USER_RDONLY             ( USER_PAGE )
109
110 #define SELF_MAP                ( KERNEL_DATA | _PTE_WT | _PTE_CD )
111
112 #define __mkpte_from(pte_val)   ((pte_t){ .val = (pte_val) })
113 #define __MEMGUARD               0xdeadc0deUL
114
115 #define null_pte                ( __mkpte_from(0) )
116 #define guard_pte               ( __mkpte_from(__MEMGUARD) )
117 #define pte_val(pte)            ( pte.val )
118
119
120 static inline bool
121 pte_isguardian(pte_t pte)
122 {
123     return pte.val == __MEMGUARD;
124 }
125
126 static inline pte_t
127 mkpte_prot(pte_attr_t prot)
128 {
129     return null_pte;
130 }
131
132 static inline pte_t
133 mkpte(ptr_t paddr, pte_attr_t prot)
134 {
135     return null_pte;
136 }
137
138 static inline pte_t
139 mkpte_root(ptr_t paddr, pte_attr_t prot)
140 {
141     return null_pte;
142 }
143
144 static inline pte_t
145 mkpte_raw(unsigned long pte_val)
146 {
147     return null_pte;
148 }
149
150 static inline pte_t
151 pte_setpaddr(pte_t pte, ptr_t paddr)
152 {
153     return pte;
154 }
155
156 static inline ptr_t
157 pte_paddr(pte_t pte)
158 {
159     return 0;
160 }
161
162 static inline pte_t
163 pte_setprot(pte_t pte, ptr_t prot)
164 {
165     return pte;
166 }
167
168 static inline pte_attr_t
169 pte_prot(pte_t pte)
170 {
171     return 0;
172 }
173
174 static inline bool
175 pte_isnull(pte_t pte)
176 {
177     return !pte.val;
178 }
179
180 static inline pte_t
181 pte_mkhuge(pte_t pte) 
182 {
183     return pte;
184 }
185
186 static inline pte_t
187 pte_mkvolatile(pte_t pte) 
188 {
189     return pte;
190 }
191
192 static inline pte_t
193 pte_mkroot(pte_t pte) 
194 {
195     return pte;
196 }
197
198 static inline pte_t
199 pte_usepat(pte_t pte) 
200 {
201     return pte;
202 }
203
204 static inline bool
205 pte_huge(pte_t pte) 
206 {
207     return false;
208 }
209
210 static inline pte_t
211 pte_mkloaded(pte_t pte) 
212 {
213     return pte;
214 }
215
216 static inline pte_t
217 pte_mkunloaded(pte_t pte) 
218 {
219     return pte;
220 }
221
222 static inline bool
223 pte_isloaded(pte_t pte) 
224 {
225     return false;
226 }
227
228 static inline pte_t
229 pte_mkwprotect(pte_t pte) 
230 {
231     return pte;
232 }
233
234 static inline pte_t
235 pte_mkwritable(pte_t pte) 
236 {
237     return pte;
238 }
239
240 static inline bool
241 pte_iswprotect(pte_t pte) 
242 {
243     return false;
244 }
245
246 static inline pte_t
247 pte_mkuser(pte_t pte) 
248 {
249     return pte;
250 }
251
252 static inline pte_t
253 pte_mkkernel(pte_t pte) 
254 {
255     return pte;
256 }
257
258 static inline bool
259 pte_allow_user(pte_t pte) 
260 {
261     return false;
262 }
263
264 static inline pte_t
265 pte_mkexec(pte_t pte)
266 {
267     return pte;
268 }
269
270 static inline pte_t
271 pte_mknonexec(pte_t pte)
272 {
273     return pte;
274 }
275
276 static inline bool
277 pte_isexec(pte_t pte)
278 {
279     return false;
280 }
281
282 static inline pte_t
283 pte_mkuntouch(pte_t pte) 
284 {
285     return pte;
286 }
287
288 static inline bool
289 pte_istouched(pte_t pte) 
290 {
291     return false;
292 }
293
294 static inline pte_t
295 pte_mkclean(pte_t pte) 
296 {
297     return pte;
298 }
299
300 static inline bool
301 pte_dirty(pte_t pte) 
302 {
303     return false;
304 }
305
306 static inline void
307 set_pte(pte_t* ptep, pte_t pte)
308 {
309     ptep->val = pte.val;
310 }
311
312 static inline pte_t
313 pte_at(pte_t* ptep) {
314     return *ptep;
315 }
316
317
318 #endif /* __LUNAIX_ARCH_PAGETABLE_H */