1 #ifndef __LUNAIX_ARCH_PAGETABLE_H
2 #define __LUNAIX_ARCH_PAGETABLE_H
4 #include <lunaix/types.h>
5 #include <lunaix/compiler.h>
7 /* ******** Page Table Manipulation ******** */
9 #ifdef CONFIG_ARCH_X86_64
11 #include "variants/pt_def64.h"
15 #include "variants/pt_def32.h"
19 /* General mask to get page offset of a LnT huge page */
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 )
27 /* Masks to get index of a LnTE */
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 )
35 #define PAGE_SHIFT _PAGE_BASE_SHIFT
36 #define PAGE_SIZE _PAGE_BASE_SIZE
37 #define PAGE_MASK _PAGE_BASE_MASK
39 #define LEVEL_SHIFT _PAGE_LEVEL_SHIFT
40 #define LEVEL_SIZE _PAGE_LEVEL_SIZE
41 #define LEVEL_MASK _PAGE_LEVEL_MASK
44 #define MAX_PTEN _PAGE_LEVEL_SIZE
46 // max translation level supported
47 #define MAX_LEVEL _PTW_LEVEL
49 typedef struct __pte pte_t;
52 #define _PTE_PPFN_MASK ( (~PAGE_MASK & PMS_MASK))
53 #define _PTE_PROT_MASK ( ~_PTE_PPFN_MASK )
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
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
71 #define SELF_MAP ( KERNEL_PGTAB | _PTE_WT | _PTE_CD )
73 #define __mkpte_from(pte_val) ((pte_t){ .val = (pte_val) })
75 #define null_pte ( __mkpte_from(0) )
76 #define guard_pte ( __mkpte_from(__MEMGUARD) )
77 #define pte_val(pte) ( pte.val )
81 pte_isguardian(pte_t pte)
83 return pte.val == __MEMGUARD;
87 mkpte_prot(pte_attr_t prot)
89 pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
90 return __mkpte_from(attrs);
94 mkpte(ptr_t paddr, pte_attr_t prot)
96 pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
97 return __mkpte_from((paddr & ~_PAGE_BASE_MASK) | attrs);
101 mkpte_root(ptr_t paddr, pte_attr_t prot)
103 pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
104 return __mkpte_from((paddr & ~_PAGE_BASE_MASK) | attrs);
108 mkpte_raw(unsigned long pte_val)
110 return __mkpte_from(pte_val);
114 pte_setpaddr(pte_t pte, ptr_t paddr)
116 return __mkpte_from((pte.val & _PTE_PROT_MASK) | (paddr & ~_PTE_PROT_MASK));
120 pte_setppfn(pte_t pte, pfn_t ppfn)
122 return pte_setpaddr(pte, ppfn * PAGE_SIZE);
128 return __paddr(pte.val) & ~_PTE_PROT_MASK;
134 return pte_paddr(pte) >> _PAGE_BASE_SHIFT;
138 pte_setprot(pte_t pte, ptr_t prot)
140 return __mkpte_from((pte.val & ~_PTE_PROT_MASK) | (prot & _PTE_PROT_MASK));
143 static inline pte_attr_t
146 return (pte.val & _PTE_PROT_MASK);
150 pte_isnull(pte_t pte)
156 pte_mkhuge(pte_t pte)
158 return __mkpte_from(pte.val | _PTE_PS);
162 pte_mkvolatile(pte_t pte)
164 return __mkpte_from(pte.val | _PTE_WT | _PTE_CD);
168 pte_mkroot(pte_t pte)
170 return __mkpte_from(pte.val & ~_PTE_PS);
174 pte_usepat(pte_t pte)
176 return __mkpte_from(pte.val | _PTE_PAT);
182 return !!(pte.val & _PTE_PS);
186 pte_mkloaded(pte_t pte)
188 return __mkpte_from(pte.val | _PTE_P);
192 pte_mkunloaded(pte_t pte)
194 return __mkpte_from(pte.val & ~_PTE_P);
198 pte_isloaded(pte_t pte)
200 return !!(pte.val & _PTE_P);
204 pte_mkwprotect(pte_t pte)
206 return __mkpte_from(pte.val & ~_PTE_W);
210 pte_mkwritable(pte_t pte)
212 return __mkpte_from(pte.val | _PTE_W);
216 pte_iswprotect(pte_t pte)
218 return !(pte.val & _PTE_W);
222 pte_mkuser(pte_t pte)
224 return __mkpte_from(pte.val | _PTE_U);
228 pte_mkkernel(pte_t pte)
230 return __mkpte_from(pte.val & ~_PTE_U);
234 pte_allow_user(pte_t pte)
236 return !!(pte.val & _PTE_U);
240 pte_mkexec(pte_t pte)
242 return __mkpte_from(pte.val & ~_PTE_NX);
246 pte_mknonexec(pte_t pte)
248 return __mkpte_from(pte.val | _PTE_NX);
252 pte_isexec(pte_t pte)
254 return !(pte.val & _PTE_NX);
258 pte_mkuntouch(pte_t pte)
260 return __mkpte_from(pte.val & ~_PTE_A);
264 pte_istouched(pte_t pte)
266 return !!(pte.val & _PTE_A);
270 pte_mkclean(pte_t pte)
272 return __mkpte_from(pte.val & ~_PTE_D);
278 return !!(pte.val & _PTE_D);
282 set_pte(pte_t* ptep, pte_t pte)
288 pte_at(pte_t* ptep) {
293 translate_vmr_prot(unsigned int vmr_prot, pte_t pte);
295 #endif /* __LUNAIX_ARCH_PAGETABLE_H */