Blame view

include/asm-arm/pgtable.h 13.5 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   *  linux/include/asm-arm/pgtable.h
   *
   *  Copyright (C) 1995-2002 Russell King
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
  #ifndef _ASMARM_PGTABLE_H
  #define _ASMARM_PGTABLE_H
  
  #include <asm-generic/4level-fixup.h>
002547b4f   Russell King   [ARM] nommu: adju...
14
15
16
17
18
19
20
  #include <asm/proc-fns.h>
  
  #ifndef CONFIG_MMU
  
  #include "pgtable-nommu.h"
  
  #else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
  
  #include <asm/memory.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
  #include <asm/arch/vmalloc.h>
ad1ae2fe7   Russell King   [ARM] Unuse anoth...
24
  #include <asm/pgtable-hwdef.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
  
  /*
5c3073e69   Russell King   [PATCH] ARM: clea...
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
   * Just any arbitrary offset to the start of the vmalloc VM area: the
   * current 8MB value just means that there will be a 8MB "hole" after the
   * physical memory until the kernel virtual memory starts.  That means that
   * any out-of-bounds memory accesses will hopefully be caught.
   * The vmalloc() routines leaves a hole of 4kB between each vmalloced
   * area for the same reason. ;)
   *
   * Note that platforms may override VMALLOC_START, but they must provide
   * VMALLOC_END.  VMALLOC_END defines the (exclusive) limit of this space,
   * which may not overlap IO space.
   */
  #ifndef VMALLOC_START
  #define VMALLOC_OFFSET		(8*1024*1024)
  #define VMALLOC_START		(((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
  #endif
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
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
   * Hardware-wise, we have a two level page table structure, where the first
   * level has 4096 entries, and the second level has 256 entries.  Each entry
   * is one 32-bit word.  Most of the bits in the second level entry are used
   * by hardware, and there aren't any "accessed" and "dirty" bits.
   *
   * Linux on the other hand has a three level page table structure, which can
   * be wrapped to fit a two level page table structure easily - using the PGD
   * and PTE only.  However, Linux also expects one "PTE" table per page, and
   * at least a "dirty" bit.
   *
   * Therefore, we tweak the implementation slightly - we tell Linux that we
   * have 2048 entries in the first level, each of which is 8 bytes (iow, two
   * hardware pointers to the second level.)  The second level contains two
   * hardware PTE tables arranged contiguously, followed by Linux versions
   * which contain the state information Linux needs.  We, therefore, end up
   * with 512 entries in the "PTE" level.
   *
   * This leads to the page tables having the following layout:
   *
   *    pgd             pte
   * |        |
   * +--------+ +0
   * |        |-----> +------------+ +0
   * +- - - - + +4    |  h/w pt 0  |
   * |        |-----> +------------+ +1024
   * +--------+ +8    |  h/w pt 1  |
   * |        |       +------------+ +2048
   * +- - - - +       | Linux pt 0 |
   * |        |       +------------+ +3072
   * +--------+       | Linux pt 1 |
   * |        |       +------------+ +4096
   *
   * See L_PTE_xxx below for definitions of bits in the "Linux pt", and
   * PTE_xxx for definitions of bits appearing in the "h/w pt".
   *
   * PMD_xxx definitions refer to bits in the first level page table.
   *
   * The "dirty" bit is emulated by only granting hardware write permission
   * iff the page is marked "writable" and "dirty" in the Linux PTE.  This
   * means that a write to a clean page will cause a permission fault, and
   * the Linux MM layer will mark the page dirty via handle_pte_fault().
   * For the hardware to notice the permission change, the TLB entry must
   * be flushed, and ptep_establish() does that for us.
   *
   * The "accessed" or "young" bit is emulated by a similar method; we only
   * allow accesses to the page if the "young" bit is set.  Accesses to the
   * page will cause a fault, and handle_pte_fault() will set the young bit
   * for us as long as the page is marked present in the corresponding Linux
   * PTE entry.  Again, ptep_establish() will ensure that the TLB is up to
   * date.
   *
   * However, when the "young" bit is cleared, we deny access to the page
   * by clearing the hardware PTE.  Currently Linux does not flush the TLB
   * for us in this case, which means the TLB will retain the transation
   * until either the TLB entry is evicted under pressure, or a context
   * switch which changes the user space mapping occurs.
   */
  #define PTRS_PER_PTE		512
  #define PTRS_PER_PMD		1
  #define PTRS_PER_PGD		2048
  
  /*
   * PMD_SHIFT determines the size of the area a second-level page table can map
   * PGDIR_SHIFT determines what a third-level page table entry can map
   */
  #define PMD_SHIFT		21
  #define PGDIR_SHIFT		21
  
  #define LIBRARY_TEXT_START	0x0c000000
  
  #ifndef __ASSEMBLY__
  extern void __pte_error(const char *file, int line, unsigned long val);
  extern void __pmd_error(const char *file, int line, unsigned long val);
  extern void __pgd_error(const char *file, int line, unsigned long val);
  
  #define pte_ERROR(pte)		__pte_error(__FILE__, __LINE__, pte_val(pte))
  #define pmd_ERROR(pmd)		__pmd_error(__FILE__, __LINE__, pmd_val(pmd))
  #define pgd_ERROR(pgd)		__pgd_error(__FILE__, __LINE__, pgd_val(pgd))
  #endif /* !__ASSEMBLY__ */
  
  #define PMD_SIZE		(1UL << PMD_SHIFT)
  #define PMD_MASK		(~(PMD_SIZE-1))
  #define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
  #define PGDIR_MASK		(~(PGDIR_SIZE-1))
6119be0bb   Hugh Dickins   [PATCH] freepgt: ...
128
129
130
131
132
133
  /*
   * This is the lowest virtual address we can permit any user space
   * mapping to be mapped at.  This is particularly important for
   * non-high vector CPUs.
   */
  #define FIRST_USER_ADDRESS	PAGE_SIZE
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
137
  #define FIRST_USER_PGD_NR	1
  #define USER_PTRS_PER_PGD	((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
  
  /*
4052ebb7a   George G. Davis   [ARM] 3859/1: Fix...
138
139
140
141
142
143
144
   * section address mask and size definitions.
   */
  #define SECTION_SHIFT		20
  #define SECTION_SIZE		(1UL << SECTION_SHIFT)
  #define SECTION_MASK		(~(SECTION_SIZE-1))
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
148
149
150
151
   * ARMv6 supersection address mask and size definitions.
   */
  #define SUPERSECTION_SHIFT	24
  #define SUPERSECTION_SIZE	(1UL << SUPERSECTION_SHIFT)
  #define SUPERSECTION_MASK	(~(SUPERSECTION_SIZE-1))
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
   * "Linux" PTE definitions.
   *
   * We keep two sets of PTEs - the hardware and the linux version.
   * This allows greater flexibility in the way we map the Linux bits
   * onto the hardware tables, and allows us to have YOUNG and DIRTY
   * bits.
   *
   * The PTE table pointer refers to the hardware entries; the "Linux"
   * entries are stored 1024 bytes below.
   */
  #define L_PTE_PRESENT		(1 << 0)
  #define L_PTE_FILE		(1 << 1)	/* only when !PRESENT */
  #define L_PTE_YOUNG		(1 << 1)
  #define L_PTE_BUFFERABLE	(1 << 2)	/* matches PTE */
  #define L_PTE_CACHEABLE		(1 << 3)	/* matches PTE */
  #define L_PTE_USER		(1 << 4)
  #define L_PTE_WRITE		(1 << 5)
  #define L_PTE_EXEC		(1 << 6)
  #define L_PTE_DIRTY		(1 << 7)
0e5fdca76   Lennert Buytenhek   [ARM] 3971/1: xsc...
171
  #define L_PTE_SHARED		(1 << 10)	/* shared(v6), coherent(xsc3) */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
  
  #ifndef __ASSEMBLY__
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
  /*
44b186939   Imre_Deak   [ARM] 4158/1: Fix...
175
176
177
178
   * The pgprot_* and protection_map entries will be fixed up in runtime
   * to include the cachable and bufferable bits based on memory policy,
   * as well as any architecture dependent bits like global/ASID and SMP
   * shared mapping bits.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
180
181
   */
  #define _L_PTE_DEFAULT	L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_CACHEABLE | L_PTE_BUFFERABLE
  #define _L_PTE_READ	L_PTE_USER | L_PTE_EXEC
44b186939   Imre_Deak   [ARM] 4158/1: Fix...
182
  extern pgprot_t		pgprot_user;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
  extern pgprot_t		pgprot_kernel;
44b186939   Imre_Deak   [ARM] 4158/1: Fix...
184
185
186
187
188
  #define PAGE_NONE	pgprot_user
  #define PAGE_COPY	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
  #define PAGE_SHARED	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ | \
  				 L_PTE_WRITE)
  #define PAGE_READONLY	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
  #define PAGE_KERNEL	pgprot_kernel
44b186939   Imre_Deak   [ARM] 4158/1: Fix...
190
191
192
193
  #define __PAGE_NONE	__pgprot(_L_PTE_DEFAULT)
  #define __PAGE_COPY	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
  #define __PAGE_SHARED	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
  #define __PAGE_READONLY	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
195
196
197
198
199
200
201
202
203
  #endif /* __ASSEMBLY__ */
  
  /*
   * The table below defines the page protection levels that we insert into our
   * Linux page table version.  These get translated into the best that the
   * architecture can perform.  Note that on most ARM hardware:
   *  1) We cannot do execute protection
   *  2) If we could do execute protection, then read is implied
   *  3) write implies read permissions
   */
44b186939   Imre_Deak   [ARM] 4158/1: Fix...
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
  #define __P000  __PAGE_NONE
  #define __P001  __PAGE_READONLY
  #define __P010  __PAGE_COPY
  #define __P011  __PAGE_COPY
  #define __P100  __PAGE_READONLY
  #define __P101  __PAGE_READONLY
  #define __P110  __PAGE_COPY
  #define __P111  __PAGE_COPY
  
  #define __S000  __PAGE_NONE
  #define __S001  __PAGE_READONLY
  #define __S010  __PAGE_SHARED
  #define __S011  __PAGE_SHARED
  #define __S100  __PAGE_READONLY
  #define __S101  __PAGE_READONLY
  #define __S110  __PAGE_SHARED
  #define __S111  __PAGE_SHARED
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
222
223
224
225
226
227
228
229
230
231
232
233
  
  #ifndef __ASSEMBLY__
  /*
   * ZERO_PAGE is a global shared page that is always zero: used
   * for zero-mapped memory areas etc..
   */
  extern struct page *empty_zero_page;
  #define ZERO_PAGE(vaddr)	(empty_zero_page)
  
  #define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
  #define pfn_pte(pfn,prot)	(__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
  
  #define pte_none(pte)		(!pte_val(pte))
ad1ae2fe7   Russell King   [ARM] Unuse anoth...
234
  #define pte_clear(mm,addr,ptep)	set_pte_ext(ptep, __pte(0), 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
  #define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
46a82b2d5   Dave McCracken   [PATCH] Standardi...
236
237
238
  #define pte_offset_kernel(dir,addr)	(pmd_page_vaddr(*(dir)) + __pte_index(addr))
  #define pte_offset_map(dir,addr)	(pmd_page_vaddr(*(dir)) + __pte_index(addr))
  #define pte_offset_map_nested(dir,addr)	(pmd_page_vaddr(*(dir)) + __pte_index(addr))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
240
  #define pte_unmap(pte)		do { } while (0)
  #define pte_unmap_nested(pte)	do { } while (0)
ad1ae2fe7   Russell King   [ARM] Unuse anoth...
241
242
243
244
245
  #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
  
  #define set_pte_at(mm,addr,ptep,pteval) do { \
  	set_pte_ext(ptep, pteval, (addr) >= PAGE_OFFSET ? 0 : PTE_EXT_NG); \
   } while (0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
  
  /*
   * The following only work if pte_present() is true.
   * Undefined behaviour if not..
   */
  #define pte_present(pte)	(pte_val(pte) & L_PTE_PRESENT)
  #define pte_read(pte)		(pte_val(pte) & L_PTE_USER)
  #define pte_write(pte)		(pte_val(pte) & L_PTE_WRITE)
  #define pte_exec(pte)		(pte_val(pte) & L_PTE_EXEC)
  #define pte_dirty(pte)		(pte_val(pte) & L_PTE_DIRTY)
  #define pte_young(pte)		(pte_val(pte) & L_PTE_YOUNG)
  
  /*
   * The following only works if pte_present() is not true.
   */
  #define pte_file(pte)		(pte_val(pte) & L_PTE_FILE)
  #define pte_to_pgoff(x)		(pte_val(x) >> 2)
  #define pgoff_to_pte(x)		__pte(((x) << 2) | L_PTE_FILE)
  
  #define PTE_FILE_MAX_BITS	30
  
  #define PTE_BIT_FUNC(fn,op) \
  static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
  
  /*PTE_BIT_FUNC(rdprotect, &= ~L_PTE_USER);*/
  /*PTE_BIT_FUNC(mkread,    |= L_PTE_USER);*/
  PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE);
  PTE_BIT_FUNC(mkwrite,   |= L_PTE_WRITE);
  PTE_BIT_FUNC(exprotect, &= ~L_PTE_EXEC);
  PTE_BIT_FUNC(mkexec,    |= L_PTE_EXEC);
  PTE_BIT_FUNC(mkclean,   &= ~L_PTE_DIRTY);
  PTE_BIT_FUNC(mkdirty,   |= L_PTE_DIRTY);
  PTE_BIT_FUNC(mkold,     &= ~L_PTE_YOUNG);
  PTE_BIT_FUNC(mkyoung,   |= L_PTE_YOUNG);
  
  /*
   * Mark the prot value as uncacheable and unbufferable.
   */
  #define pgprot_noncached(prot)	__pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
  #define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~L_PTE_CACHEABLE)
  
  #define pmd_none(pmd)		(!pmd_val(pmd))
  #define pmd_present(pmd)	(pmd_val(pmd))
  #define pmd_bad(pmd)		(pmd_val(pmd) & 2)
  
  #define copy_pmd(pmdpd,pmdps)		\
  	do {				\
  		pmdpd[0] = pmdps[0];	\
  		pmdpd[1] = pmdps[1];	\
  		flush_pmd_entry(pmdpd);	\
  	} while (0)
  
  #define pmd_clear(pmdp)			\
  	do {				\
  		pmdp[0] = __pmd(0);	\
  		pmdp[1] = __pmd(0);	\
  		clean_pmd_entry(pmdp);	\
  	} while (0)
46a82b2d5   Dave McCracken   [PATCH] Standardi...
304
  static inline pte_t *pmd_page_vaddr(pmd_t pmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
  {
  	unsigned long ptr;
  
  	ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
  	ptr += PTRS_PER_PTE * sizeof(void *);
  
  	return __va(ptr);
  }
  
  #define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd)))
  
  /*
   * Permanent address of a page. We never have highmem, so this is trivial.
   */
  #define pages_to_mb(x)		((x) >> (20 - PAGE_SHIFT))
  
  /*
   * Conversion functions: convert a page and protection to a page entry,
   * and a page entry and page directory to the page they refer to.
   */
  #define mk_pte(page,prot)	pfn_pte(page_to_pfn(page),prot)
  
  /*
   * The "pgd_xxx()" functions here are trivial for a folded two-level
   * setup: the pgd is never bad, and a pmd always exists (as it's folded
   * into the pgd entry)
   */
  #define pgd_none(pgd)		(0)
  #define pgd_bad(pgd)		(0)
  #define pgd_present(pgd)	(1)
  #define pgd_clear(pgdp)		do { } while (0)
  #define set_pgd(pgd,pgdp)	do { } while (0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
  /* to find an entry in a page-table-directory */
  #define pgd_index(addr)		((addr) >> PGDIR_SHIFT)
  
  #define pgd_offset(mm, addr)	((mm)->pgd+pgd_index(addr))
  
  /* to find an entry in a kernel page-table-directory */
  #define pgd_offset_k(addr)	pgd_offset(&init_mm, addr)
  
  /* Find an entry in the second-level page table.. */
  #define pmd_offset(dir, addr)	((pmd_t *)(dir))
  
  /* Find an entry in the third-level page table.. */
  #define __pte_index(addr)	(((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
  
  static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  {
  	const unsigned long mask = L_PTE_EXEC | L_PTE_WRITE | L_PTE_USER;
  	pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
  	return pte;
  }
  
  extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
  
  /* Encode and decode a swap entry.
   *
   * We support up to 32GB of swap on 4k machines
   */
  #define __swp_type(x)		(((x).val >> 2) & 0x7f)
  #define __swp_offset(x)		((x).val >> 9)
  #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) })
  #define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
  #define __swp_entry_to_pte(swp)	((pte_t) { (swp).val })
  
  /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
  /* FIXME: this is not correct */
  #define kern_addr_valid(addr)	(1)
  
  #include <asm-generic/pgtable.h>
  
  /*
   * We provide our own arch_get_unmapped_area to cope with VIPT caches.
   */
  #define HAVE_ARCH_UNMAPPED_AREA
  
  /*
33bf56106   Randy Dunlap   [PATCH] feature r...
382
   * remap a physical page `pfn' of size `size' with page protection `prot'
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
384
   * into virtual address `from'
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
386
  #define io_remap_pfn_range(vma,from,pfn,size,prot) \
  		remap_pfn_range(vma, from, pfn, size, prot)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
388
389
  #define pgtable_cache_init() do { } while (0)
  
  #endif /* !__ASSEMBLY__ */
002547b4f   Russell King   [ARM] nommu: adju...
390
  #endif /* CONFIG_MMU */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
  #endif /* _ASMARM_PGTABLE_H */