aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-sh/pgtable.h
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-09-27 02:13:36 -0400
committerPaul Mundt <lethal@linux-sh.org>2006-09-27 02:13:36 -0400
commit26ff6c11ef38e08990c1e417c299246e6ab18ff7 (patch)
treeebd37fd0270b7c7dfe8474a046663db78fcdb1ab /include/asm-sh/pgtable.h
parent9359e757709a211040e4b0151eae69248e7c6eca (diff)
sh: page table alloc cleanups and page fault optimizations.
Cleanup of page table allocators, using generic folded PMD and PUD helpers. TLB flushing operations are moved to a more sensible spot. The page fault handler is also optimized slightly, we no longer waste cycles on IRQ disabling for flushing of the page from the ITLB, since we're already under CLI protection by the initial exception handler. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'include/asm-sh/pgtable.h')
-rw-r--r--include/asm-sh/pgtable.h80
1 files changed, 53 insertions, 27 deletions
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index 40d41a78041e..9728b58f7c13 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -1,42 +1,42 @@
1#ifndef __ASM_SH_PGTABLE_H
2#define __ASM_SH_PGTABLE_H
3
4#include <asm-generic/4level-fixup.h>
5
6/* 1/*
2 * This file contains the functions and defines necessary to modify and
3 * use the SuperH page table tree.
4 *
7 * Copyright (C) 1999 Niibe Yutaka 5 * Copyright (C) 1999 Niibe Yutaka
8 * Copyright (C) 2002, 2003, 2004 Paul Mundt 6 * Copyright (C) 2002 - 2005 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General
9 * Public License. See the file "COPYING" in the main directory of this
10 * archive for more details.
9 */ 11 */
12#ifndef __ASM_SH_PGTABLE_H
13#define __ASM_SH_PGTABLE_H
10 14
11#include <asm/pgtable-2level.h> 15#include <asm-generic/pgtable-nopmd.h>
16#include <asm/page.h>
17
18#define PTRS_PER_PGD 1024
12 19
13/*
14 * This file contains the functions and defines necessary to modify and use
15 * the SuperH page table tree.
16 */
17#ifndef __ASSEMBLY__ 20#ifndef __ASSEMBLY__
18#include <asm/processor.h>
19#include <asm/addrspace.h> 21#include <asm/addrspace.h>
20#include <asm/fixmap.h> 22#include <asm/fixmap.h>
21#include <linux/threads.h>
22 23
23extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; 24extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
24extern void paging_init(void); 25extern void paging_init(void);
25 26
26/* 27/*
27 * Basically we have the same two-level (which is the logical three level
28 * Linux page table layout folded) page tables as the i386.
29 */
30
31/*
32 * ZERO_PAGE is a global shared page that is always zero: used 28 * ZERO_PAGE is a global shared page that is always zero: used
33 * for zero-mapped memory areas etc.. 29 * for zero-mapped memory areas etc..
34 */ 30 */
35extern unsigned long empty_zero_page[1024]; 31extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
36#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) 32#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
37 33
38#endif /* !__ASSEMBLY__ */ 34#endif /* !__ASSEMBLY__ */
39 35
36/* traditional two-level paging structure */
37#define PGDIR_SHIFT 22
38#define PTRS_PER_PMD 1
39#define PTRS_PER_PTE 1024
40#define PMD_SIZE (1UL << PMD_SHIFT) 40#define PMD_SIZE (1UL << PMD_SHIFT)
41#define PMD_MASK (~(PMD_SIZE-1)) 41#define PMD_MASK (~(PMD_SIZE-1))
42#define PGDIR_SIZE (1UL << PGDIR_SHIFT) 42#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
@@ -47,7 +47,6 @@ extern unsigned long empty_zero_page[1024];
47 47
48#define PTE_PHYS_MASK 0x1ffff000 48#define PTE_PHYS_MASK 0x1ffff000
49 49
50#ifndef __ASSEMBLY__
51/* 50/*
52 * First 1MB map is used by fixed purpose. 51 * First 1MB map is used by fixed purpose.
53 * Currently only 4-enty (16kB) is used (see arch/sh/mm/cache.c) 52 * Currently only 4-enty (16kB) is used (see arch/sh/mm/cache.c)
@@ -65,7 +64,7 @@ extern unsigned long empty_zero_page[1024];
65#define _PAGE_SZ1 0x080 /* SZ1-bit : Size of page (on SH-4) */ 64#define _PAGE_SZ1 0x080 /* SZ1-bit : Size of page (on SH-4) */
66#define _PAGE_PRESENT 0x100 /* V-bit : page is valid */ 65#define _PAGE_PRESENT 0x100 /* V-bit : page is valid */
67#define _PAGE_PROTNONE 0x200 /* software: if not present */ 66#define _PAGE_PROTNONE 0x200 /* software: if not present */
68#define _PAGE_ACCESSED 0x400 /* software: page referenced */ 67#define _PAGE_ACCESSED 0x400 /* software: page referenced */
69#define _PAGE_U0_SHARED 0x800 /* software: page is shared in user space */ 68#define _PAGE_U0_SHARED 0x800 /* software: page is shared in user space */
70 69
71#define _PAGE_FILE _PAGE_WT /* software: pagecache or swap? */ 70#define _PAGE_FILE _PAGE_WT /* software: pagecache or swap? */
@@ -83,7 +82,6 @@ extern unsigned long empty_zero_page[1024];
83#define _PAGE_PCC_ATR8 0x60000000 /* Attribute Memory space, 8 bit bus */ 82#define _PAGE_PCC_ATR8 0x60000000 /* Attribute Memory space, 8 bit bus */
84#define _PAGE_PCC_ATR16 0x60000001 /* Attribute Memory space, 6 bit bus */ 83#define _PAGE_PCC_ATR16 0x60000001 /* Attribute Memory space, 6 bit bus */
85 84
86
87/* Mask which drop software flags 85/* Mask which drop software flags
88 * We also drop WT bit since it is used for _PAGE_FILE 86 * We also drop WT bit since it is used for _PAGE_FILE
89 * bit in this implementation. 87 * bit in this implementation.
@@ -115,6 +113,8 @@ extern unsigned long empty_zero_page[1024];
115#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) 113#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
116#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY | _PAGE_SHARED) 114#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY | _PAGE_SHARED)
117 115
116#ifndef __ASSEMBLY__
117
118#ifdef CONFIG_MMU 118#ifdef CONFIG_MMU
119#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE |_PAGE_ACCESSED | _PAGE_FLAGS_HARD) 119#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE |_PAGE_ACCESSED | _PAGE_FLAGS_HARD)
120#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_CACHABLE |_PAGE_ACCESSED | _PAGE_SHARED | _PAGE_FLAGS_HARD) 120#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_CACHABLE |_PAGE_ACCESSED | _PAGE_SHARED | _PAGE_FLAGS_HARD)
@@ -137,12 +137,13 @@ extern unsigned long empty_zero_page[1024];
137#define PAGE_KERNEL_PCC __pgprot(0) 137#define PAGE_KERNEL_PCC __pgprot(0)
138#endif 138#endif
139 139
140#endif /* __ASSEMBLY__ */
141
140/* 142/*
141 * As i386 and MIPS, SuperH can't do page protection for execute, and 143 * As i386 and MIPS, SuperH can't do page protection for execute, and
142 * considers that the same as a read. Also, write permissions imply 144 * considers that the same as a read. Also, write permissions imply
143 * read permissions. This is the closest we can get.. 145 * read permissions. This is the closest we can get..
144 */ 146 */
145
146#define __P000 PAGE_NONE 147#define __P000 PAGE_NONE
147#define __P001 PAGE_READONLY 148#define __P001 PAGE_READONLY
148#define __P010 PAGE_COPY 149#define __P010 PAGE_COPY
@@ -161,6 +162,26 @@ extern unsigned long empty_zero_page[1024];
161#define __S110 PAGE_SHARED 162#define __S110 PAGE_SHARED
162#define __S111 PAGE_SHARED 163#define __S111 PAGE_SHARED
163 164
165#ifndef __ASSEMBLY__
166
167/*
168 * Certain architectures need to do special things when PTEs
169 * within a page table are directly modified. Thus, the following
170 * hook is made available.
171 */
172#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
173#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
174
175/*
176 * (pmds are folded into pgds so this doesn't get actually called,
177 * but the define is needed for a generic inline function.)
178 */
179#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
180
181#define pte_pfn(x) ((unsigned long)(((x).pte >> PAGE_SHIFT)))
182#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
183#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
184
164#define pte_none(x) (!pte_val(x)) 185#define pte_none(x) (!pte_val(x))
165#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) 186#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
166#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) 187#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
@@ -171,7 +192,7 @@ extern unsigned long empty_zero_page[1024];
171#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) 192#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
172 193
173#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) 194#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
174#define pte_page(x) phys_to_page(pte_val(x)&PTE_PHYS_MASK) 195#define pte_page(x) phys_to_page(pte_val(x)&PTE_PHYS_MASK)
175 196
176/* 197/*
177 * The following only work if pte_present() is true. 198 * The following only work if pte_present() is true.
@@ -248,6 +269,11 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
248#define pte_unmap(pte) do { } while (0) 269#define pte_unmap(pte) do { } while (0)
249#define pte_unmap_nested(pte) do { } while (0) 270#define pte_unmap_nested(pte) do { } while (0)
250 271
272#define pte_ERROR(e) \
273 printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
274#define pgd_ERROR(e) \
275 printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
276
251struct vm_area_struct; 277struct vm_area_struct;
252extern void update_mmu_cache(struct vm_area_struct * vma, 278extern void update_mmu_cache(struct vm_area_struct * vma,
253 unsigned long address, pte_t pte); 279 unsigned long address, pte_t pte);
@@ -272,8 +298,6 @@ extern void update_mmu_cache(struct vm_area_struct * vma,
272 298
273typedef pte_t *pte_addr_t; 299typedef pte_t *pte_addr_t;
274 300
275#endif /* !__ASSEMBLY__ */
276
277#define kern_addr_valid(addr) (1) 301#define kern_addr_valid(addr) (1)
278 302
279#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ 303#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
@@ -301,5 +325,7 @@ extern pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t
301 325
302#include <asm-generic/pgtable.h> 326#include <asm-generic/pgtable.h>
303 327
328#endif /* !__ASSEMBLY__ */
329
304#endif /* __ASM_SH_PAGE_H */ 330#endif /* __ASM_SH_PAGE_H */
305 331