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