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
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
50 typedef struct __pte pte_t;
54 #define _PTE_PPFN_MASK ( (~PAGE_MASK & PMS_MASK))
55 #define _PTE_PROT_MASK ( ~_PTE_PPFN_MASK )
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
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
73 #define SELF_MAP ( KERNEL_PGTAB | _PTE_WT | _PTE_CD )
75 #define __mkpte_from(pte_val) ((pte_t){ .val = (pte_val) })
77 #define null_pte ( __mkpte_from(0) )
78 #define guard_pte ( __mkpte_from(__MEMGUARD) )
79 #define pte_val(pte) ( pte.val )
83 pte_isguardian(pte_t pte)
85 return pte.val == __MEMGUARD;
89 mkpte_prot(pte_attr_t prot)
91 pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
92 return __mkpte_from(attrs);
96 mkpte(ptr_t paddr, pte_attr_t prot)
98 pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
99 return __mkpte_from((paddr & ~_PAGE_BASE_MASK) | attrs);
103 mkpte_root(ptr_t paddr, pte_attr_t prot)
105 pte_attr_t attrs = (prot & _PTE_PROT_MASK) | _PTE_P;
106 return __mkpte_from((paddr & ~_PAGE_BASE_MASK) | attrs);
110 mkpte_raw(unsigned long pte_val)
112 return __mkpte_from(pte_val);
116 pte_setpaddr(pte_t pte, ptr_t paddr)
118 return __mkpte_from((pte.val & _PTE_PROT_MASK) | (paddr & ~_PTE_PROT_MASK));
122 pte_setppfn(pte_t pte, pfn_t ppfn)
124 return pte_setpaddr(pte, ppfn * PAGE_SIZE);
130 return __paddr(pte.val) & ~_PTE_PROT_MASK;
136 return pte_paddr(pte) >> _PAGE_BASE_SHIFT;
140 pte_setprot(pte_t pte, ptr_t prot)
142 return __mkpte_from((pte.val & ~_PTE_PROT_MASK) | (prot & _PTE_PROT_MASK));
145 static inline pte_attr_t
148 return (pte.val & _PTE_PROT_MASK);
152 pte_isnull(pte_t pte)
158 pte_mkhuge(pte_t pte)
160 return __mkpte_from(pte.val | _PTE_PS);
164 pte_mkvolatile(pte_t pte)
166 return __mkpte_from(pte.val | _PTE_WT | _PTE_CD);
170 pte_mkroot(pte_t pte)
172 return __mkpte_from(pte.val & ~_PTE_PS);
176 pte_usepat(pte_t pte)
178 return __mkpte_from(pte.val | _PTE_PAT);
184 return !!(pte.val & _PTE_PS);
188 pte_mkloaded(pte_t pte)
190 return __mkpte_from(pte.val | _PTE_P);
194 pte_mkunloaded(pte_t pte)
196 return __mkpte_from(pte.val & ~_PTE_P);
200 pte_isloaded(pte_t pte)
202 return !!(pte.val & _PTE_P);
206 pte_mkwprotect(pte_t pte)
208 return __mkpte_from(pte.val & ~_PTE_W);
212 pte_mkwritable(pte_t pte)
214 return __mkpte_from(pte.val | _PTE_W);
218 pte_iswprotect(pte_t pte)
220 return !(pte.val & _PTE_W);
224 pte_mkuser(pte_t pte)
226 return __mkpte_from(pte.val | _PTE_U);
230 pte_mkkernel(pte_t pte)
232 return __mkpte_from(pte.val & ~_PTE_U);
236 pte_allow_user(pte_t pte)
238 return !!(pte.val & _PTE_U);
242 pte_mkexec(pte_t pte)
244 return __mkpte_from(pte.val & ~_PTE_NX);
248 pte_mknonexec(pte_t pte)
250 return __mkpte_from(pte.val | _PTE_NX);
254 pte_isexec(pte_t pte)
256 return !(pte.val & _PTE_NX);
260 pte_mkuntouch(pte_t pte)
262 return __mkpte_from(pte.val & ~_PTE_A);
266 pte_istouched(pte_t pte)
268 return !!(pte.val & _PTE_A);
272 pte_mkclean(pte_t pte)
274 return __mkpte_from(pte.val & ~_PTE_D);
280 return !!(pte.val & _PTE_D);
284 set_pte(pte_t* ptep, pte_t pte)
290 pte_at(pte_t* ptep) {
295 #endif /* __LUNAIX_ARCH_PAGETABLE_H */