aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm/pgtable.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/include/asm/pgtable.h')
-rw-r--r--arch/arm/include/asm/pgtable.h74
1 files changed, 53 insertions, 21 deletions
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 1cd2d6416bd..201ccaa11f6 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -162,10 +162,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
162 * entries are stored 1024 bytes below. 162 * entries are stored 1024 bytes below.
163 */ 163 */
164#define L_PTE_PRESENT (1 << 0) 164#define L_PTE_PRESENT (1 << 0)
165#define L_PTE_FILE (1 << 1) /* only when !PRESENT */
166#define L_PTE_YOUNG (1 << 1) 165#define L_PTE_YOUNG (1 << 1)
167#define L_PTE_BUFFERABLE (1 << 2) /* obsolete, matches PTE */ 166#define L_PTE_FILE (1 << 2) /* only when !PRESENT */
168#define L_PTE_CACHEABLE (1 << 3) /* obsolete, matches PTE */
169#define L_PTE_DIRTY (1 << 6) 167#define L_PTE_DIRTY (1 << 6)
170#define L_PTE_WRITE (1 << 7) 168#define L_PTE_WRITE (1 << 7)
171#define L_PTE_USER (1 << 8) 169#define L_PTE_USER (1 << 8)
@@ -264,10 +262,19 @@ extern struct page *empty_zero_page;
264#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) 262#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
265#define pte_page(pte) (pfn_to_page(pte_pfn(pte))) 263#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
266#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) 264#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)) 265
268#define pte_offset_map_nested(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) 266#define pte_offset_map(dir,addr) (__pte_map(dir, KM_PTE0) + __pte_index(addr))
269#define pte_unmap(pte) do { } while (0) 267#define pte_offset_map_nested(dir,addr) (__pte_map(dir, KM_PTE1) + __pte_index(addr))
270#define pte_unmap_nested(pte) do { } while (0) 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
271 278
272#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) 279#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
273 280
@@ -285,15 +292,6 @@ extern struct page *empty_zero_page;
285#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) 292#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
286#define pte_special(pte) (0) 293#define pte_special(pte) (0)
287 294
288/*
289 * The following only works if pte_present() is not true.
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) \ 295#define PTE_BIT_FUNC(fn,op) \
298static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } 296static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
299 297
@@ -384,16 +382,50 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
384 382
385extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; 383extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
386 384
387/* Encode and decode a swap entry. 385/*
386 * Encode and decode a swap entry. Swap entries are stored in the Linux
387 * page tables as follows:
388 *
389 * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
390 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
391 * <--------------- offset --------------------> <- type --> 0 0 0
388 * 392 *
389 * We support up to 32GB of swap on 4k machines 393 * This gives us up to 63 swap files and 32GB per swap file. Note that
394 * the offset field is always non-zero.
390 */ 395 */
391#define __swp_type(x) (((x).val >> 2) & 0x7f) 396#define __SWP_TYPE_SHIFT 3
392#define __swp_offset(x) ((x).val >> 9) 397#define __SWP_TYPE_BITS 6
393#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) }) 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
394#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) 405#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
395#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) 406#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
396 407
408/*
409 * It is an error for the kernel to have more swap files than we can
410 * encode in the PTEs. This ensures that we know when MAX_SWAPFILES
411 * is increased beyond what we presently support.
412 */
413#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
414
415/*
416 * Encode and decode a file entry. File entries are stored in the Linux
417 * page tables as follows:
418 *
419 * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
420 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
421 * <----------------------- offset ------------------------> 1 0 0
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
397/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ 429/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
398/* FIXME: this is not correct */ 430/* FIXME: this is not correct */
399#define kern_addr_valid(addr) (1) 431#define kern_addr_valid(addr) (1)