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 )
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
70 #define SELF_MAP ( KERNEL_PGTAB | _PTE_WT | _PTE_CD )
72 #define __mkpte_from(pte_val) ((pte_t){ .val = (pte_val) })
74 #define null_pte ( __mkpte_from(0) )
75 #define guard_pte ( __mkpte_from(__MEMGUARD) )
76 #define pte_val(pte) ( pte.val )
80 pte_isguardian(pte_t pte)
82 return pte.val == __MEMGUARD;
86 mkpte_prot(pte_attr_t prot)
88 pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
89 return __mkpte_from(attrs);
93 mkpte(ptr_t paddr, pte_attr_t prot)
95 pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
96 return __mkpte_from((paddr & ~_PAGE_BASE_MASK) | attrs);
100 mkpte_root(ptr_t paddr, pte_attr_t prot)
102 pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
103 return __mkpte_from((paddr & ~_PAGE_BASE_MASK) | attrs);
107 mkpte_raw(unsigned long pte_val)
109 return __mkpte_from(pte_val);
113 pte_setpaddr(pte_t pte, ptr_t paddr)
115 return __mkpte_from((pte.val & _PTE_PROT_MASK) | (paddr & ~_PTE_PROT_MASK));
119 pte_setppfn(pte_t pte, pfn_t ppfn)
121 return pte_setpaddr(pte, ppfn * PAGE_SIZE);
127 return __paddr(pte.val) & ~_PTE_PROT_MASK;
133 return pte_paddr(pte) >> _PAGE_BASE_SHIFT;
137 pte_setprot(pte_t pte, ptr_t prot)
139 return __mkpte_from((pte.val & ~_PTE_PROT_MASK) | (prot & _PTE_PROT_MASK));
142 static inline pte_attr_t
145 return (pte.val & _PTE_PROT_MASK);
149 pte_isnull(pte_t pte)
155 pte_mkhuge(pte_t pte)
157 return __mkpte_from(pte.val | _PTE_PS);
161 pte_mkvolatile(pte_t pte)
163 return __mkpte_from(pte.val | _PTE_WT | _PTE_CD);
167 pte_mkroot(pte_t pte)
169 return __mkpte_from(pte.val & ~_PTE_PS);
173 pte_usepat(pte_t pte)
175 return __mkpte_from(pte.val | _PTE_PAT);
181 return !!(pte.val & _PTE_PS);
185 pte_mkloaded(pte_t pte)
187 return __mkpte_from(pte.val | _PTE_P);
191 pte_mkunloaded(pte_t pte)
193 return __mkpte_from(pte.val & ~_PTE_P);
197 pte_isloaded(pte_t pte)
199 return !!(pte.val & _PTE_P);
203 pte_mkwprotect(pte_t pte)
205 return __mkpte_from(pte.val & ~_PTE_W);
209 pte_mkwritable(pte_t pte)
211 return __mkpte_from(pte.val | _PTE_W);
215 pte_iswprotect(pte_t pte)
217 return !(pte.val & _PTE_W);
221 pte_mkuser(pte_t pte)
223 return __mkpte_from(pte.val | _PTE_U);
227 pte_mkkernel(pte_t pte)
229 return __mkpte_from(pte.val & ~_PTE_U);
233 pte_allow_user(pte_t pte)
235 return !!(pte.val & _PTE_U);
239 pte_mkexec(pte_t pte)
241 return __mkpte_from(pte.val & ~_PTE_NX);
245 pte_mknonexec(pte_t pte)
247 return __mkpte_from(pte.val | _PTE_NX);
251 pte_isexec(pte_t pte)
253 return !(pte.val & _PTE_NX);
257 pte_mkuntouch(pte_t pte)
259 return __mkpte_from(pte.val & ~_PTE_A);
263 pte_istouched(pte_t pte)
265 return !!(pte.val & _PTE_A);
269 pte_mkclean(pte_t pte)
271 return __mkpte_from(pte.val & ~_PTE_D);
277 return !!(pte.val & _PTE_D);
281 set_pte(pte_t* ptep, pte_t pte)
287 pte_at(pte_t* ptep) {
292 translate_vmr_prot(unsigned int vmr_prot, pte_t pte);
294 #endif /* __LUNAIX_ARCH_PAGETABLE_H */