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 <asm/arch/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_FILE (1 << 1)
166#define L_PTE_YOUNG (1 << 1)
167#define L_PTE_BUFFERABLE (1 << 2)
168#define L_PTE_CACHEABLE (1 << 3)
169#define L_PTE_USER (1 << 4)
170#define L_PTE_WRITE (1 << 5)
171#define L_PTE_EXEC (1 << 6)
172#define L_PTE_DIRTY (1 << 7)
173#define L_PTE_SHARED (1 << 10)
174
175#ifndef __ASSEMBLY__
176
177
178
179
180
181
182
183#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_CACHEABLE | L_PTE_BUFFERABLE
184#define _L_PTE_READ L_PTE_USER | L_PTE_EXEC
185
186extern pgprot_t pgprot_user;
187extern pgprot_t pgprot_kernel;
188
189#define PAGE_NONE pgprot_user
190#define PAGE_COPY __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
191#define PAGE_SHARED __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ | \
192 L_PTE_WRITE)
193#define PAGE_READONLY __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
194#define PAGE_KERNEL pgprot_kernel
195
196#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT)
197#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
198#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
199#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
200
201#endif
202
203
204
205
206
207
208
209
210
211#define __P000 __PAGE_NONE
212#define __P001 __PAGE_READONLY
213#define __P010 __PAGE_COPY
214#define __P011 __PAGE_COPY
215#define __P100 __PAGE_READONLY
216#define __P101 __PAGE_READONLY
217#define __P110 __PAGE_COPY
218#define __P111 __PAGE_COPY
219
220#define __S000 __PAGE_NONE
221#define __S001 __PAGE_READONLY
222#define __S010 __PAGE_SHARED
223#define __S011 __PAGE_SHARED
224#define __S100 __PAGE_READONLY
225#define __S101 __PAGE_READONLY
226#define __S110 __PAGE_SHARED
227#define __S111 __PAGE_SHARED
228
229#ifndef __ASSEMBLY__
230
231
232
233
234extern struct page *empty_zero_page;
235#define ZERO_PAGE(vaddr) (empty_zero_page)
236
237#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
238#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
239
240#define pte_none(pte) (!pte_val(pte))
241#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
242#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
243#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
244#define pte_offset_map(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
245#define pte_offset_map_nested(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
246#define pte_unmap(pte) do { } while (0)
247#define pte_unmap_nested(pte) do { } while (0)
248
249#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
250
251#define set_pte_at(mm,addr,ptep,pteval) do { \
252 set_pte_ext(ptep, pteval, (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \
253 } while (0)
254
255
256
257
258
259#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
260#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE)
261#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
262#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
263#define pte_special(pte) (0)
264
265
266
267
268#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
269#define pte_to_pgoff(x) (pte_val(x) >> 2)
270#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE)
271
272#define PTE_FILE_MAX_BITS 30
273
274#define PTE_BIT_FUNC(fn,op) \
275static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
276
277PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE);
278PTE_BIT_FUNC(mkwrite, |= L_PTE_WRITE);
279PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY);
280PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY);
281PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG);
282PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
283
284static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
285
286
287
288
289#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
290#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~L_PTE_CACHEABLE)
291
292#define pmd_none(pmd) (!pmd_val(pmd))
293#define pmd_present(pmd) (pmd_val(pmd))
294#define pmd_bad(pmd) (pmd_val(pmd) & 2)
295
296#define copy_pmd(pmdpd,pmdps) \
297 do { \
298 pmdpd[0] = pmdps[0]; \
299 pmdpd[1] = pmdps[1]; \
300 flush_pmd_entry(pmdpd); \
301 } while (0)
302
303#define pmd_clear(pmdp) \
304 do { \
305 pmdp[0] = __pmd(0); \
306 pmdp[1] = __pmd(0); \
307 clean_pmd_entry(pmdp); \
308 } while (0)
309
310static inline pte_t *pmd_page_vaddr(pmd_t pmd)
311{
312 unsigned long ptr;
313
314 ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
315 ptr += PTRS_PER_PTE * sizeof(void *);
316
317 return __va(ptr);
318}
319
320#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd)))
321
322
323
324
325#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT))
326
327
328
329
330
331#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
332
333
334
335
336
337
338#define pgd_none(pgd) (0)
339#define pgd_bad(pgd) (0)
340#define pgd_present(pgd) (1)
341#define pgd_clear(pgdp) do { } while (0)
342#define set_pgd(pgd,pgdp) do { } while (0)
343
344
345#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
346
347#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
348
349
350#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
351
352
353#define pmd_offset(dir, addr) ((pmd_t *)(dir))
354
355
356#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
357
358static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
359{
360 const unsigned long mask = L_PTE_EXEC | L_PTE_WRITE | L_PTE_USER;
361 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
362 return pte;
363}
364
365extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
366
367
368
369
370
371#define __swp_type(x) (((x).val >> 2) & 0x7f)
372#define __swp_offset(x) ((x).val >> 9)
373#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) })
374#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
375#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
376
377
378
379#define kern_addr_valid(addr) (1)
380
381#include <asm-generic/pgtable.h>
382
383
384
385
386#define HAVE_ARCH_UNMAPPED_AREA
387
388
389
390
391
392#define io_remap_pfn_range(vma,from,pfn,size,prot) \
393 remap_pfn_range(vma, from, pfn, size, prot)
394
395#define pgtable_cache_init() do { } while (0)
396
397#endif
398
399#endif
400
401#endif
402