1
2
3
4
5
6
7
8
9
10#ifndef _ASMARM_PGTABLE_H
11#define _ASMARM_PGTABLE_H
12
13#include <asm-generic/4level-fixup.h>
14#include <asm/proc-fns.h>
15
16#ifndef CONFIG_MMU
17
18#include "pgtable-nommu.h"
19
20#else
21
22#include <asm/memory.h>
23#include <mach/vmalloc.h>
24#include <asm/pgtable-hwdef.h>
25
26
27
28
29
30
31
32
33
34
35
36
37
38#ifndef VMALLOC_START
39#define VMALLOC_OFFSET (8*1024*1024)
40#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
41#endif
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101#define PTRS_PER_PTE 512
102#define PTRS_PER_PMD 1
103#define PTRS_PER_PGD 2048
104
105
106
107
108
109#define PMD_SHIFT 21
110#define PGDIR_SHIFT 21
111
112#define LIBRARY_TEXT_START 0x0c000000
113
114#ifndef __ASSEMBLY__
115extern void __pte_error(const char *file, int line, unsigned long val);
116extern void __pmd_error(const char *file, int line, unsigned long val);
117extern void __pgd_error(const char *file, int line, unsigned long val);
118
119#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte))
120#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd))
121#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
122#endif
123
124#define PMD_SIZE (1UL << PMD_SHIFT)
125#define PMD_MASK (~(PMD_SIZE-1))
126#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
127#define PGDIR_MASK (~(PGDIR_SIZE-1))
128
129
130
131
132
133
134#define FIRST_USER_ADDRESS PAGE_SIZE
135
136#define FIRST_USER_PGD_NR 1
137#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
138
139
140
141
142#define SECTION_SHIFT 20
143#define SECTION_SIZE (1UL << SECTION_SHIFT)
144#define SECTION_MASK (~(SECTION_SIZE-1))
145
146
147
148
149#define SUPERSECTION_SHIFT 24
150#define SUPERSECTION_SIZE (1UL << SUPERSECTION_SHIFT)
151#define SUPERSECTION_MASK (~(SUPERSECTION_SIZE-1))
152
153
154
155
156
157
158
159
160
161
162
163
164#define L_PTE_PRESENT (1 << 0)
165#define L_PTE_YOUNG (1 << 1)
166#define L_PTE_FILE (1 << 2)
167#define L_PTE_DIRTY (1 << 6)
168#define L_PTE_WRITE (1 << 7)
169#define L_PTE_USER (1 << 8)
170#define L_PTE_EXEC (1 << 9)
171#define L_PTE_SHARED (1 << 10)
172
173
174
175
176
177#define L_PTE_MT_UNCACHED (0x00 << 2)
178#define L_PTE_MT_BUFFERABLE (0x01 << 2)
179#define L_PTE_MT_WRITETHROUGH (0x02 << 2)
180#define L_PTE_MT_WRITEBACK (0x03 << 2)
181#define L_PTE_MT_MINICACHE (0x06 << 2)
182#define L_PTE_MT_WRITEALLOC (0x07 << 2)
183#define L_PTE_MT_DEV_SHARED (0x04 << 2)
184#define L_PTE_MT_DEV_NONSHARED (0x0c << 2)
185#define L_PTE_MT_DEV_WC (0x09 << 2)
186#define L_PTE_MT_DEV_CACHED (0x0b << 2)
187#define L_PTE_MT_MASK (0x0f << 2)
188
189#ifndef __ASSEMBLY__
190
191
192
193
194
195
196
197#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG
198
199extern pgprot_t pgprot_user;
200extern pgprot_t pgprot_kernel;
201
202#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
203
204#define PAGE_NONE pgprot_user
205#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE)
206#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC)
207#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER)
208#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC)
209#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER)
210#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC)
211#define PAGE_KERNEL pgprot_kernel
212#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_kernel, L_PTE_EXEC)
213
214#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT)
215#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE)
216#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC)
217#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
218#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC)
219#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
220#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC)
221
222#endif
223
224
225
226
227
228
229
230
231
232#define __P000 __PAGE_NONE
233#define __P001 __PAGE_READONLY
234#define __P010 __PAGE_COPY
235#define __P011 __PAGE_COPY
236#define __P100 __PAGE_READONLY_EXEC
237#define __P101 __PAGE_READONLY_EXEC
238#define __P110 __PAGE_COPY_EXEC
239#define __P111 __PAGE_COPY_EXEC
240
241#define __S000 __PAGE_NONE
242#define __S001 __PAGE_READONLY
243#define __S010 __PAGE_SHARED
244#define __S011 __PAGE_SHARED
245#define __S100 __PAGE_READONLY_EXEC
246#define __S101 __PAGE_READONLY_EXEC
247#define __S110 __PAGE_SHARED_EXEC
248#define __S111 __PAGE_SHARED_EXEC
249
250#ifndef __ASSEMBLY__
251
252
253
254
255extern struct page *empty_zero_page;
256#define ZERO_PAGE(vaddr) (empty_zero_page)
257
258#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
259#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
260
261#define pte_none(pte) (!pte_val(pte))
262#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
263#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
264#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
265
266#define pte_offset_map(dir,addr) (__pte_map(dir, KM_PTE0) + __pte_index(addr))
267#define pte_offset_map_nested(dir,addr) (__pte_map(dir, KM_PTE1) + __pte_index(addr))
268#define pte_unmap(pte) __pte_unmap(pte, KM_PTE0)
269#define pte_unmap_nested(pte) __pte_unmap(pte, KM_PTE1)
270
271#ifndef CONFIG_HIGHPTE
272#define __pte_map(dir,km) pmd_page_vaddr(*(dir))
273#define __pte_unmap(pte,km) do { } while (0)
274#else
275#define __pte_map(dir,km) ((pte_t *)kmap_atomic(pmd_page(*(dir)), km) + PTRS_PER_PTE)
276#define __pte_unmap(pte,km) kunmap_atomic((pte - PTRS_PER_PTE), km)
277#endif
278
279#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
280
281#define set_pte_at(mm,addr,ptep,pteval) do { \
282 set_pte_ext(ptep, pteval, (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \
283 } while (0)
284
285
286
287
288
289#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
290#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE)
291#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
292#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
293#define pte_special(pte) (0)
294
295#define PTE_BIT_FUNC(fn,op) \
296static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
297
298PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE);
299PTE_BIT_FUNC(mkwrite, |= L_PTE_WRITE);
300PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY);
301PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY);
302PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG);
303PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
304
305static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
306
307
308
309
310#define pgprot_noncached(prot) \
311 __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_UNCACHED)
312#define pgprot_writecombine(prot) \
313 __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_BUFFERABLE)
314
315#define pmd_none(pmd) (!pmd_val(pmd))
316#define pmd_present(pmd) (pmd_val(pmd))
317#define pmd_bad(pmd) (pmd_val(pmd) & 2)
318
319#define copy_pmd(pmdpd,pmdps) \
320 do { \
321 pmdpd[0] = pmdps[0]; \
322 pmdpd[1] = pmdps[1]; \
323 flush_pmd_entry(pmdpd); \
324 } while (0)
325
326#define pmd_clear(pmdp) \
327 do { \
328 pmdp[0] = __pmd(0); \
329 pmdp[1] = __pmd(0); \
330 clean_pmd_entry(pmdp); \
331 } while (0)
332
333static inline pte_t *pmd_page_vaddr(pmd_t pmd)
334{
335 unsigned long ptr;
336
337 ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
338 ptr += PTRS_PER_PTE * sizeof(void *);
339
340 return __va(ptr);
341}
342
343#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
344
345
346
347
348
349#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
350
351
352
353
354
355
356#define pgd_none(pgd) (0)
357#define pgd_bad(pgd) (0)
358#define pgd_present(pgd) (1)
359#define pgd_clear(pgdp) do { } while (0)
360#define set_pgd(pgd,pgdp) do { } while (0)
361
362
363#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
364
365#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
366
367
368#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
369
370
371#define pmd_offset(dir, addr) ((pmd_t *)(dir))
372
373
374#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
375
376static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
377{
378 const unsigned long mask = L_PTE_EXEC | L_PTE_WRITE | L_PTE_USER;
379 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
380 return pte;
381}
382
383extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
384
385
386
387
388
389
390
391
392
393
394
395
396#define __SWP_TYPE_SHIFT 3
397#define __SWP_TYPE_BITS 6
398#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
399#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
400
401#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
402#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT)
403#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) })
404
405#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
406#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
407
408
409
410
411
412
413#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
414
415
416
417
418
419
420
421
422
423#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
424#define pte_to_pgoff(x) (pte_val(x) >> 3)
425#define pgoff_to_pte(x) __pte(((x) << 3) | L_PTE_FILE)
426
427#define PTE_FILE_MAX_BITS 29
428
429
430
431#define kern_addr_valid(addr) (1)
432
433#include <asm-generic/pgtable.h>
434
435
436
437
438#define HAVE_ARCH_UNMAPPED_AREA
439
440
441
442
443
444#define io_remap_pfn_range(vma,from,pfn,size,prot) \
445 remap_pfn_range(vma, from, pfn, size, prot)
446
447#define pgtable_cache_init() do { } while (0)
448
449#endif
450
451#endif
452
453#endif
454