3 * @author Lunaixsky (lunaxisky@qq.com)
4 * @brief Generic (skeleton) definition for pagetable.h
8 * @copyright Copyright (c) 2024
12 #ifndef __LUNAIX_ARCH_PAGETABLE_H
13 #define __LUNAIX_ARCH_PAGETABLE_H
15 #include <lunaix/types.h>
16 #include <lunaix/compiler.h>
18 /* ******** Page Table Manipulation ******** */
20 // Levels of page table to traverse for a single page walk
23 #define _PAGE_BASE_SHIFT 12
24 #define _PAGE_BASE_SIZE ( 1UL << _PAGE_BASE_SHIFT )
25 #define _PAGE_BASE_MASK ( _PAGE_BASE_SIZE - 1)
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)) )
32 // Note: we set VMS_SIZE = VMS_MASK as it is impossible
33 // to express 4Gi in 32bit unsigned integer
35 #define VMS_MASK ( -1UL )
36 #define VMS_SIZE VMS_MASK
38 /* General size of a LnT huge page */
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)
46 /* General mask to get page offset of a LnT huge page */
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 )
54 /* Masks to get index of a LnTE */
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 )
62 #define PAGE_SHIFT _PAGE_BASE_SHIFT
63 #define PAGE_SIZE _PAGE_BASE_SIZE
64 #define PAGE_MASK _PAGE_BASE_MASK
66 #define LEVEL_SHIFT _PAGE_LEVEL_SHIFT
67 #define LEVEL_SIZE _PAGE_LEVEL_SIZE
68 #define LEVEL_MASK _PAGE_LEVEL_MASK
71 #define MAX_PTEN _PAGE_LEVEL_SIZE
73 // max translation level supported
74 #define MAX_LEVEL _PTW_LEVEL
77 /* ******** PTE Manipulation ******** */
84 typedef struct __pte pte_t;
87 typedef unsigned int pfn_t;
88 typedef unsigned int pte_attr_t;
98 #define _PTE_PROT_MASK ( _PTE_W | _PTE_U | _PTE_X )
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 )
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 )
110 #define SELF_MAP ( KERNEL_DATA | _PTE_WT | _PTE_CD )
112 #define __mkpte_from(pte_val) ((pte_t){ .val = (pte_val) })
113 #define __MEMGUARD 0xdeadc0deUL
115 #define null_pte ( __mkpte_from(0) )
116 #define guard_pte ( __mkpte_from(__MEMGUARD) )
117 #define pte_val(pte) ( pte.val )
121 pte_isguardian(pte_t pte)
123 return pte.val == __MEMGUARD;
127 mkpte_prot(pte_attr_t prot)
133 mkpte(ptr_t paddr, pte_attr_t prot)
139 mkpte_root(ptr_t paddr, pte_attr_t prot)
145 mkpte_raw(unsigned long pte_val)
151 pte_setpaddr(pte_t pte, ptr_t paddr)
163 pte_setprot(pte_t pte, ptr_t prot)
168 static inline pte_attr_t
175 pte_isnull(pte_t pte)
181 pte_mkhuge(pte_t pte)
187 pte_mkvolatile(pte_t pte)
193 pte_mkroot(pte_t pte)
199 pte_usepat(pte_t pte)
211 pte_mkloaded(pte_t pte)
217 pte_mkunloaded(pte_t pte)
223 pte_isloaded(pte_t pte)
229 pte_mkwprotect(pte_t pte)
235 pte_mkwritable(pte_t pte)
241 pte_iswprotect(pte_t pte)
247 pte_mkuser(pte_t pte)
253 pte_mkkernel(pte_t pte)
259 pte_allow_user(pte_t pte)
265 pte_mkexec(pte_t pte)
271 pte_mknonexec(pte_t pte)
277 pte_isexec(pte_t pte)
283 pte_mkuntouch(pte_t pte)
289 pte_istouched(pte_t pte)
295 pte_mkclean(pte_t pte)
307 set_pte(pte_t* ptep, pte_t pte)
313 pte_at(pte_t* ptep) {
318 #endif /* __LUNAIX_ARCH_PAGETABLE_H */