1 #ifndef __ARM_LPAE_H__
2 #define __ARM_LPAE_H__
3
4 #ifndef __ASSEMBLY__
5
6 #include <xen/page-defs.h>
7
8 /*
9 * WARNING! Unlike the x86 pagetable code, where l1 is the lowest level and
10 * l4 is the root of the trie, the ARM pagetables follow ARM's documentation:
11 * the levels are called first, second &c in the order that the MMU walks them
12 * (i.e. "first" is the root of the trie).
13 */
14
15 /******************************************************************************
16 * ARMv7-A LPAE pagetables: 3-level trie, mapping 40-bit input to
17 * 40-bit output addresses. Tables at all levels have 512 64-bit entries
18 * (i.e. are 4Kb long).
19 *
20 * The bit-shuffling that has the permission bits in branch nodes in a
21 * different place from those in leaf nodes seems to be to allow linear
22 * pagetable tricks. If we're not doing that then the set of permission
23 * bits that's not in use in a given node type can be used as
24 * extra software-defined bits.
25 */
26
27 typedef struct __packed {
28 /* These are used in all kinds of entry. */
29 unsigned long valid:1; /* Valid mapping */
30 unsigned long table:1; /* == 1 in 4k map entries too */
31
32 /*
33 * These ten bits are only used in Block entries and are ignored
34 * in Table entries.
35 */
36 unsigned long ai:3; /* Attribute Index */
37 unsigned long ns:1; /* Not-Secure */
38 unsigned long up:1; /* Unpriviledged access */
39 unsigned long ro:1; /* Read-Only */
40 unsigned long sh:2; /* Shareability */
41 unsigned long af:1; /* Access Flag */
42 unsigned long ng:1; /* Not-Global */
43
44 /* The base address must be appropriately aligned for Block entries */
45 unsigned long long base:36; /* Base address of block or next table */
46 unsigned long sbz:4; /* Must be zero */
47
48 /*
49 * These seven bits are only used in Block entries and are ignored
50 * in Table entries.
51 */
52 unsigned long contig:1; /* In a block of 16 contiguous entries */
53 unsigned long pxn:1; /* Privileged-XN */
54 unsigned long xn:1; /* eXecute-Never */
55 unsigned long avail:4; /* Ignored by hardware */
56
57 /*
58 * These 5 bits are only used in Table entries and are ignored in
59 * Block entries.
60 */
61 unsigned long pxnt:1; /* Privileged-XN */
62 unsigned long xnt:1; /* eXecute-Never */
63 unsigned long apt:2; /* Access Permissions */
64 unsigned long nst:1; /* Not-Secure */
65 } lpae_pt_t;
66
67 /*
68 * The p2m tables have almost the same layout, but some of the permission
69 * and cache-control bits are laid out differently (or missing).
70 */
71 typedef struct __packed {
72 /* These are used in all kinds of entry. */
73 unsigned long valid:1; /* Valid mapping */
74 unsigned long table:1; /* == 1 in 4k map entries too */
75
76 /*
77 * These ten bits are only used in Block entries and are ignored
78 * in Table entries.
79 */
80 unsigned long mattr:4; /* Memory Attributes */
81 unsigned long read:1; /* Read access */
82 unsigned long write:1; /* Write access */
83 unsigned long sh:2; /* Shareability */
84 unsigned long af:1; /* Access Flag */
85 unsigned long sbz4:1;
86
87 /* The base address must be appropriately aligned for Block entries */
88 unsigned long long base:36; /* Base address of block or next table */
89 unsigned long sbz3:4;
90
91 /*
92 * These seven bits are only used in Block entries and are ignored
93 * in Table entries.
94 */
95 unsigned long contig:1; /* In a block of 16 contiguous entries */
96 unsigned long sbz2:1;
97 unsigned long xn:1; /* eXecute-Never */
98 unsigned long type:4; /* Ignore by hardware. Used to store p2m types */
99
100 unsigned long sbz1:5;
101 } lpae_p2m_t;
102
103 /* Permission mask: xn, write, read */
104 #define P2M_PERM_MASK (0x00400000000000C0ULL)
105 #define P2M_CLEAR_PERM(pte) ((pte).bits & ~P2M_PERM_MASK)
106
107 /*
108 * Walk is the common bits of p2m and pt entries which are needed to
109 * simply walk the table (e.g. for debug).
110 */
111 typedef struct __packed {
112 /* These are used in all kinds of entry. */
113 unsigned long valid:1; /* Valid mapping */
114 unsigned long table:1; /* == 1 in 4k map entries too */
115
116 unsigned long pad2:10;
117
118 /* The base address must be appropriately aligned for Block entries */
119 unsigned long long base:36; /* Base address of block or next table */
120
121 unsigned long pad1:16;
122 } lpae_walk_t;
123
124 typedef union {
125 uint64_t bits;
126 lpae_pt_t pt;
127 lpae_p2m_t p2m;
128 lpae_walk_t walk;
129 } lpae_t;
130
lpae_valid(lpae_t pte)131 static inline bool lpae_valid(lpae_t pte)
132 {
133 return pte.walk.valid;
134 }
135
136 /*
137 * These two can only be used on L0..L2 ptes because L3 mappings set
138 * the table bit and therefore these would return the opposite to what
139 * you would expect.
140 */
lpae_table(lpae_t pte)141 static inline bool lpae_table(lpae_t pte)
142 {
143 return lpae_valid(pte) && pte.walk.table;
144 }
145
lpae_mapping(lpae_t pte)146 static inline bool lpae_mapping(lpae_t pte)
147 {
148 return lpae_valid(pte) && !pte.walk.table;
149 }
150
lpae_is_superpage(lpae_t pte,unsigned int level)151 static inline bool lpae_is_superpage(lpae_t pte, unsigned int level)
152 {
153 return (level < 3) && lpae_mapping(pte);
154 }
155
lpae_is_page(lpae_t pte,unsigned int level)156 static inline bool lpae_is_page(lpae_t pte, unsigned int level)
157 {
158 return (level == 3) && lpae_valid(pte) && pte.walk.table;
159 }
160
161 /*
162 * AArch64 supports pages with different sizes (4K, 16K, and 64K). To enable
163 * page table walks for various configurations, the following helpers enable
164 * walking the translation table with varying page size granularities.
165 */
166
167 #define LPAE_SHIFT_4K (9)
168 #define LPAE_SHIFT_16K (11)
169 #define LPAE_SHIFT_64K (13)
170
171 #define lpae_entries(gran) (_AC(1,U) << LPAE_SHIFT_##gran)
172 #define lpae_entry_mask(gran) (lpae_entries(gran) - 1)
173
174 #define third_shift(gran) (PAGE_SHIFT_##gran)
175 #define third_size(gran) ((paddr_t)1 << third_shift(gran))
176
177 #define second_shift(gran) (third_shift(gran) + LPAE_SHIFT_##gran)
178 #define second_size(gran) ((paddr_t)1 << second_shift(gran))
179
180 #define first_shift(gran) (second_shift(gran) + LPAE_SHIFT_##gran)
181 #define first_size(gran) ((paddr_t)1 << first_shift(gran))
182
183 /* Note that there is no zeroeth lookup level with a 64K granule size. */
184 #define zeroeth_shift(gran) (first_shift(gran) + LPAE_SHIFT_##gran)
185 #define zeroeth_size(gran) ((paddr_t)1 << zeroeth_shift(gran))
186
187 #define TABLE_OFFSET(offs, gran) (offs & lpae_entry_mask(gran))
188 #define TABLE_OFFSET_HELPERS(gran) \
189 static inline paddr_t third_table_offset_##gran##K(paddr_t va) \
190 { \
191 return TABLE_OFFSET((va >> third_shift(gran##K)), gran##K); \
192 } \
193 \
194 static inline paddr_t second_table_offset_##gran##K(paddr_t va) \
195 { \
196 return TABLE_OFFSET((va >> second_shift(gran##K)), gran##K); \
197 } \
198 \
199 static inline paddr_t first_table_offset_##gran##K(paddr_t va) \
200 { \
201 return TABLE_OFFSET((va >> first_shift(gran##K)), gran##K); \
202 } \
203 \
204 static inline paddr_t zeroeth_table_offset_##gran##K(paddr_t va) \
205 { \
206 /* Note that there is no zeroeth lookup level with 64K granule sizes. */\
207 if ( gran == 64 ) \
208 return 0; \
209 else \
210 return TABLE_OFFSET((va >> zeroeth_shift(gran##K)), gran##K); \
211 } \
212
213 TABLE_OFFSET_HELPERS(4);
214 TABLE_OFFSET_HELPERS(16);
215 TABLE_OFFSET_HELPERS(64);
216
217 #undef TABLE_OFFSET
218 #undef TABLE_OFFSET_HELPERS
219
220 #endif /* __ASSEMBLY__ */
221
222 /*
223 * These numbers add up to a 48-bit input address space.
224 *
225 * On 32-bit the zeroeth level does not exist, therefore the total is
226 * 39-bits. The ARMv7-A architecture actually specifies a 40-bit input
227 * address space for the p2m, with an 8K (1024-entry) top-level table.
228 * However Xen only supports 16GB of RAM on 32-bit ARM systems and
229 * therefore 39-bits are sufficient.
230 */
231
232 #define LPAE_SHIFT 9
233 #define LPAE_ENTRIES (_AC(1,U) << LPAE_SHIFT)
234 #define LPAE_ENTRY_MASK (LPAE_ENTRIES - 1)
235
236 #define THIRD_SHIFT (PAGE_SHIFT)
237 #define THIRD_ORDER (THIRD_SHIFT - PAGE_SHIFT)
238 #define THIRD_SIZE ((paddr_t)1 << THIRD_SHIFT)
239 #define THIRD_MASK (~(THIRD_SIZE - 1))
240 #define SECOND_SHIFT (THIRD_SHIFT + LPAE_SHIFT)
241 #define SECOND_ORDER (SECOND_SHIFT - PAGE_SHIFT)
242 #define SECOND_SIZE ((paddr_t)1 << SECOND_SHIFT)
243 #define SECOND_MASK (~(SECOND_SIZE - 1))
244 #define FIRST_SHIFT (SECOND_SHIFT + LPAE_SHIFT)
245 #define FIRST_ORDER (FIRST_SHIFT - PAGE_SHIFT)
246 #define FIRST_SIZE ((paddr_t)1 << FIRST_SHIFT)
247 #define FIRST_MASK (~(FIRST_SIZE - 1))
248 #define ZEROETH_SHIFT (FIRST_SHIFT + LPAE_SHIFT)
249 #define ZEROETH_ORDER (ZEROETH_SHIFT - PAGE_SHIFT)
250 #define ZEROETH_SIZE ((paddr_t)1 << ZEROETH_SHIFT)
251 #define ZEROETH_MASK (~(ZEROETH_SIZE - 1))
252
253 /* Calculate the offsets into the pagetables for a given VA */
254 #define zeroeth_linear_offset(va) ((va) >> ZEROETH_SHIFT)
255 #define first_linear_offset(va) ((va) >> FIRST_SHIFT)
256 #define second_linear_offset(va) ((va) >> SECOND_SHIFT)
257 #define third_linear_offset(va) ((va) >> THIRD_SHIFT)
258
259 #define TABLE_OFFSET(offs) ((unsigned int)(offs) & LPAE_ENTRY_MASK)
260 #define first_table_offset(va) TABLE_OFFSET(first_linear_offset(va))
261 #define second_table_offset(va) TABLE_OFFSET(second_linear_offset(va))
262 #define third_table_offset(va) TABLE_OFFSET(third_linear_offset(va))
263 #define zeroeth_table_offset(va) TABLE_OFFSET(zeroeth_linear_offset(va))
264
265 #endif /* __ARM_LPAE_H__ */
266
267 /*
268 * Local variables:
269 * mode: C
270 * c-file-style: "BSD"
271 * c-basic-offset: 4
272 * tab-width: 4
273 * indent-tabs-mode: nil
274 * End:
275 */
276