This source file includes following definitions.
- paging_init
- pte_write
- pte_dirty
- pte_young
- pte_special
- pte_wrprotect
- pte_mkclean
- pte_mkold
- pte_mkdirty
- pte_mkyoung
- pte_mkwrite
- pte_mkspecial
- pte_modify
- update_pte
- set_pte_at
- set_pte
- set_pmd
- ptep_test_and_clear_young
- ptep_get_and_clear
- ptep_set_wrprotect
1
2
3
4
5
6
7
8 #ifndef _XTENSA_PGTABLE_H
9 #define _XTENSA_PGTABLE_H
10
11 #define __ARCH_USE_5LEVEL_HACK
12 #include <asm/page.h>
13 #include <asm/kmem_layout.h>
14 #include <asm-generic/pgtable-nopmd.h>
15
16
17
18
19
20 #ifdef CONFIG_MMU
21 #define USER_RING 1
22 #else
23 #define USER_RING 0
24 #endif
25 #define KERNEL_RING 0
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 #define PGDIR_SHIFT 22
51 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
52 #define PGDIR_MASK (~(PGDIR_SIZE-1))
53
54
55
56
57
58 #define PTRS_PER_PTE 1024
59 #define PTRS_PER_PTE_SHIFT 10
60 #define PTRS_PER_PGD 1024
61 #define PGD_ORDER 0
62 #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
63 #define FIRST_USER_ADDRESS 0UL
64 #define FIRST_USER_PGD_NR (FIRST_USER_ADDRESS >> PGDIR_SHIFT)
65
66 #ifdef CONFIG_MMU
67
68
69
70
71 #define VMALLOC_START (XCHAL_KSEG_CACHED_VADDR - 0x10000000)
72 #define VMALLOC_END (VMALLOC_START + 0x07FEFFFF)
73 #define TLBTEMP_BASE_1 (VMALLOC_END + 1)
74 #define TLBTEMP_BASE_2 (TLBTEMP_BASE_1 + DCACHE_WAY_SIZE)
75 #if 2 * DCACHE_WAY_SIZE > ICACHE_WAY_SIZE
76 #define TLBTEMP_SIZE (2 * DCACHE_WAY_SIZE)
77 #else
78 #define TLBTEMP_SIZE ICACHE_WAY_SIZE
79 #endif
80
81 #else
82
83 #define VMALLOC_START __XTENSA_UL_CONST(0)
84 #define VMALLOC_END __XTENSA_UL_CONST(0xffffffff)
85
86 #endif
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 #define _PAGE_ATTRIB_MASK 0xf
137
138 #define _PAGE_HW_EXEC (1<<0)
139 #define _PAGE_HW_WRITE (1<<1)
140
141 #define _PAGE_CA_BYPASS (0<<2)
142 #define _PAGE_CA_WB (1<<2)
143 #define _PAGE_CA_WT (2<<2)
144 #define _PAGE_CA_MASK (3<<2)
145 #define _PAGE_CA_INVALID (3<<2)
146
147
148 #if XCHAL_HW_VERSION_MAJOR < 2000
149 #define _PAGE_HW_VALID 0x01
150 #define _PAGE_NONE 0x04
151 #else
152 #define _PAGE_HW_VALID 0x00
153 #define _PAGE_NONE 0x0f
154 #endif
155
156 #define _PAGE_USER (1<<4)
157
158
159 #define _PAGE_WRITABLE_BIT 6
160 #define _PAGE_WRITABLE (1<<6)
161 #define _PAGE_DIRTY (1<<7)
162 #define _PAGE_ACCESSED (1<<8)
163
164 #ifdef CONFIG_MMU
165
166 #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
167 #define _PAGE_PRESENT (_PAGE_HW_VALID | _PAGE_CA_WB | _PAGE_ACCESSED)
168
169 #define PAGE_NONE __pgprot(_PAGE_NONE | _PAGE_USER)
170 #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER)
171 #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_HW_EXEC)
172 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER)
173 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_HW_EXEC)
174 #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_WRITABLE)
175 #define PAGE_SHARED_EXEC \
176 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_WRITABLE | _PAGE_HW_EXEC)
177 #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_HW_WRITE)
178 #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT)
179 #define PAGE_KERNEL_EXEC __pgprot(_PAGE_PRESENT|_PAGE_HW_WRITE|_PAGE_HW_EXEC)
180
181 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
182 # define _PAGE_DIRECTORY (_PAGE_HW_VALID | _PAGE_ACCESSED | _PAGE_CA_BYPASS)
183 #else
184 # define _PAGE_DIRECTORY (_PAGE_HW_VALID | _PAGE_ACCESSED | _PAGE_CA_WB)
185 #endif
186
187 #else
188
189 # define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
190 # define PAGE_NONE __pgprot(0)
191 # define PAGE_SHARED __pgprot(0)
192 # define PAGE_COPY __pgprot(0)
193 # define PAGE_READONLY __pgprot(0)
194 # define PAGE_KERNEL __pgprot(0)
195
196 #endif
197
198
199
200
201
202
203
204
205 #define __P000 PAGE_NONE
206 #define __P001 PAGE_READONLY
207 #define __P010 PAGE_COPY
208 #define __P011 PAGE_COPY
209 #define __P100 PAGE_READONLY_EXEC
210 #define __P101 PAGE_READONLY_EXEC
211 #define __P110 PAGE_COPY_EXEC
212 #define __P111 PAGE_COPY_EXEC
213
214 #define __S000 PAGE_NONE
215 #define __S001 PAGE_READONLY
216 #define __S010 PAGE_SHARED
217 #define __S011 PAGE_SHARED
218 #define __S100 PAGE_READONLY_EXEC
219 #define __S101 PAGE_READONLY_EXEC
220 #define __S110 PAGE_SHARED_EXEC
221 #define __S111 PAGE_SHARED_EXEC
222
223 #ifndef __ASSEMBLY__
224
225 #define pte_ERROR(e) \
226 printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
227 #define pgd_ERROR(e) \
228 printk("%s:%d: bad pgd entry %08lx.\n", __FILE__, __LINE__, pgd_val(e))
229
230 extern unsigned long empty_zero_page[1024];
231
232 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
233
234 #ifdef CONFIG_MMU
235 extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)];
236 extern void paging_init(void);
237 #else
238 # define swapper_pg_dir NULL
239 static inline void paging_init(void) { }
240 #endif
241
242
243
244
245 #define pmd_page_vaddr(pmd) ((unsigned long)(pmd_val(pmd) & PAGE_MASK))
246 #define pmd_page(pmd) virt_to_page(pmd_val(pmd))
247
248
249
250
251 # define pte_none(pte) (pte_val(pte) == (_PAGE_CA_INVALID | _PAGE_USER))
252 #if XCHAL_HW_VERSION_MAJOR < 2000
253 # define pte_present(pte) ((pte_val(pte) & _PAGE_CA_MASK) != _PAGE_CA_INVALID)
254 #else
255 # define pte_present(pte) \
256 (((pte_val(pte) & _PAGE_CA_MASK) != _PAGE_CA_INVALID) \
257 || ((pte_val(pte) & _PAGE_ATTRIB_MASK) == _PAGE_NONE))
258 #endif
259 #define pte_clear(mm,addr,ptep) \
260 do { update_pte(ptep, __pte(_PAGE_CA_INVALID | _PAGE_USER)); } while (0)
261
262 #define pmd_none(pmd) (!pmd_val(pmd))
263 #define pmd_present(pmd) (pmd_val(pmd) & PAGE_MASK)
264 #define pmd_bad(pmd) (pmd_val(pmd) & ~PAGE_MASK)
265 #define pmd_clear(pmdp) do { set_pmd(pmdp, __pmd(0)); } while (0)
266
267 static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITABLE; }
268 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
269 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
270 static inline int pte_special(pte_t pte) { return 0; }
271
272 static inline pte_t pte_wrprotect(pte_t pte)
273 { pte_val(pte) &= ~(_PAGE_WRITABLE | _PAGE_HW_WRITE); return pte; }
274 static inline pte_t pte_mkclean(pte_t pte)
275 { pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HW_WRITE); return pte; }
276 static inline pte_t pte_mkold(pte_t pte)
277 { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
278 static inline pte_t pte_mkdirty(pte_t pte)
279 { pte_val(pte) |= _PAGE_DIRTY; return pte; }
280 static inline pte_t pte_mkyoung(pte_t pte)
281 { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
282 static inline pte_t pte_mkwrite(pte_t pte)
283 { pte_val(pte) |= _PAGE_WRITABLE; return pte; }
284 static inline pte_t pte_mkspecial(pte_t pte)
285 { return pte; }
286
287 #define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) & ~_PAGE_CA_MASK))
288
289
290
291
292
293
294 #define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
295 #define pte_same(a,b) (pte_val(a) == pte_val(b))
296 #define pte_page(x) pfn_to_page(pte_pfn(x))
297 #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
298 #define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot)
299
300 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
301 {
302 return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
303 }
304
305
306
307
308
309
310 static inline void update_pte(pte_t *ptep, pte_t pteval)
311 {
312 *ptep = pteval;
313 #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
314 __asm__ __volatile__ ("dhwb %0, 0" :: "a" (ptep));
315 #endif
316
317 }
318
319 struct mm_struct;
320
321 static inline void
322 set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval)
323 {
324 update_pte(ptep, pteval);
325 }
326
327 static inline void set_pte(pte_t *ptep, pte_t pteval)
328 {
329 update_pte(ptep, pteval);
330 }
331
332 static inline void
333 set_pmd(pmd_t *pmdp, pmd_t pmdval)
334 {
335 *pmdp = pmdval;
336 }
337
338 struct vm_area_struct;
339
340 static inline int
341 ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr,
342 pte_t *ptep)
343 {
344 pte_t pte = *ptep;
345 if (!pte_young(pte))
346 return 0;
347 update_pte(ptep, pte_mkold(pte));
348 return 1;
349 }
350
351 static inline pte_t
352 ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
353 {
354 pte_t pte = *ptep;
355 pte_clear(mm, addr, ptep);
356 return pte;
357 }
358
359 static inline void
360 ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
361 {
362 pte_t pte = *ptep;
363 update_pte(ptep, pte_wrprotect(pte));
364 }
365
366
367 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
368
369
370 #define pgd_offset(mm,address) ((mm)->pgd + pgd_index(address))
371
372 #define pgd_index(address) ((address) >> PGDIR_SHIFT)
373
374
375 #define pmd_offset(dir,address) ((pmd_t*)(dir))
376
377
378 #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
379 #define pte_offset_kernel(dir,addr) \
380 ((pte_t*) pmd_page_vaddr(*(dir)) + pte_index(addr))
381 #define pte_offset_map(dir,addr) pte_offset_kernel((dir),(addr))
382 #define pte_unmap(pte) do { } while (0)
383
384
385
386
387
388 #define SWP_TYPE_BITS 5
389 #define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS)
390
391 #define __swp_type(entry) (((entry).val >> 6) & 0x1f)
392 #define __swp_offset(entry) ((entry).val >> 11)
393 #define __swp_entry(type,offs) \
394 ((swp_entry_t){((type) << 6) | ((offs) << 11) | \
395 _PAGE_CA_INVALID | _PAGE_USER})
396 #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
397 #define __swp_entry_to_pte(x) ((pte_t) { (x).val })
398
399 #endif
400
401
402 #ifdef __ASSEMBLY__
403
404
405
406
407
408
409
410
411
412
413
414
415 #define _PGD_INDEX(rt,rs) extui rt, rs, PGDIR_SHIFT, 32-PGDIR_SHIFT
416 #define _PTE_INDEX(rt,rs) extui rt, rs, PAGE_SHIFT, PTRS_PER_PTE_SHIFT
417
418 #define _PGD_OFFSET(mm,adr,tmp) l32i mm, mm, MM_PGD; \
419 _PGD_INDEX(tmp, adr); \
420 addx4 mm, tmp, mm
421
422 #define _PTE_OFFSET(pmd,adr,tmp) _PTE_INDEX(tmp, adr); \
423 srli pmd, pmd, PAGE_SHIFT; \
424 slli pmd, pmd, PAGE_SHIFT; \
425 addx4 pmd, tmp, pmd
426
427 #else
428
429 #define kern_addr_valid(addr) (1)
430
431 extern void update_mmu_cache(struct vm_area_struct * vma,
432 unsigned long address, pte_t *ptep);
433
434 typedef pte_t *pte_addr_t;
435
436 #endif
437
438 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
439 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
440 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
441 #define __HAVE_ARCH_PTEP_MKDIRTY
442 #define __HAVE_ARCH_PTE_SAME
443
444
445
446 #define HAVE_ARCH_UNMAPPED_AREA
447
448 #include <asm-generic/pgtable.h>
449
450 #endif