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.h315
1 files changed, 155 insertions, 160 deletions
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 53d1d5deb111..ebcb6432f45f 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -10,6 +10,7 @@
10#ifndef _ASMARM_PGTABLE_H 10#ifndef _ASMARM_PGTABLE_H
11#define _ASMARM_PGTABLE_H 11#define _ASMARM_PGTABLE_H
12 12
13#include <linux/const.h>
13#include <asm-generic/4level-fixup.h> 14#include <asm-generic/4level-fixup.h>
14#include <asm/proc-fns.h> 15#include <asm/proc-fns.h>
15 16
@@ -54,7 +55,7 @@
54 * Therefore, we tweak the implementation slightly - we tell Linux that we 55 * Therefore, we tweak the implementation slightly - we tell Linux that we
55 * have 2048 entries in the first level, each of which is 8 bytes (iow, two 56 * have 2048 entries in the first level, each of which is 8 bytes (iow, two
56 * hardware pointers to the second level.) The second level contains two 57 * hardware pointers to the second level.) The second level contains two
57 * hardware PTE tables arranged contiguously, followed by Linux versions 58 * hardware PTE tables arranged contiguously, preceded by Linux versions
58 * which contain the state information Linux needs. We, therefore, end up 59 * which contain the state information Linux needs. We, therefore, end up
59 * with 512 entries in the "PTE" level. 60 * with 512 entries in the "PTE" level.
60 * 61 *
@@ -62,15 +63,15 @@
62 * 63 *
63 * pgd pte 64 * pgd pte
64 * | | 65 * | |
65 * +--------+ +0 66 * +--------+
66 * | |-----> +------------+ +0 67 * | | +------------+ +0
68 * +- - - - + | Linux pt 0 |
69 * | | +------------+ +1024
70 * +--------+ +0 | Linux pt 1 |
71 * | |-----> +------------+ +2048
67 * +- - - - + +4 | h/w pt 0 | 72 * +- - - - + +4 | h/w pt 0 |
68 * | |-----> +------------+ +1024 73 * | |-----> +------------+ +3072
69 * +--------+ +8 | h/w pt 1 | 74 * +--------+ +8 | h/w pt 1 |
70 * | | +------------+ +2048
71 * +- - - - + | Linux pt 0 |
72 * | | +------------+ +3072
73 * +--------+ | Linux pt 1 |
74 * | | +------------+ +4096 75 * | | +------------+ +4096
75 * 76 *
76 * See L_PTE_xxx below for definitions of bits in the "Linux pt", and 77 * See L_PTE_xxx below for definitions of bits in the "Linux pt", and
@@ -102,6 +103,10 @@
102#define PTRS_PER_PMD 1 103#define PTRS_PER_PMD 1
103#define PTRS_PER_PGD 2048 104#define PTRS_PER_PGD 2048
104 105
106#define PTE_HWTABLE_PTRS (PTRS_PER_PTE)
107#define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t))
108#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32))
109
105/* 110/*
106 * PMD_SHIFT determines the size of the area a second-level page table can map 111 * PMD_SHIFT determines the size of the area a second-level page table can map
107 * PGDIR_SHIFT determines what a third-level page table entry can map 112 * PGDIR_SHIFT determines what a third-level page table entry can map
@@ -112,13 +117,13 @@
112#define LIBRARY_TEXT_START 0x0c000000 117#define LIBRARY_TEXT_START 0x0c000000
113 118
114#ifndef __ASSEMBLY__ 119#ifndef __ASSEMBLY__
115extern void __pte_error(const char *file, int line, unsigned long val); 120extern void __pte_error(const char *file, int line, pte_t);
116extern void __pmd_error(const char *file, int line, unsigned long val); 121extern void __pmd_error(const char *file, int line, pmd_t);
117extern void __pgd_error(const char *file, int line, unsigned long val); 122extern void __pgd_error(const char *file, int line, pgd_t);
118 123
119#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte)) 124#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte)
120#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd)) 125#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd)
121#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) 126#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd)
122#endif /* !__ASSEMBLY__ */ 127#endif /* !__ASSEMBLY__ */
123 128
124#define PMD_SIZE (1UL << PMD_SHIFT) 129#define PMD_SIZE (1UL << PMD_SHIFT)
@@ -133,8 +138,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
133 */ 138 */
134#define FIRST_USER_ADDRESS PAGE_SIZE 139#define FIRST_USER_ADDRESS PAGE_SIZE
135 140
136#define FIRST_USER_PGD_NR 1 141#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
137#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
138 142
139/* 143/*
140 * section address mask and size definitions. 144 * section address mask and size definitions.
@@ -161,30 +165,30 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
161 * The PTE table pointer refers to the hardware entries; the "Linux" 165 * The PTE table pointer refers to the hardware entries; the "Linux"
162 * entries are stored 1024 bytes below. 166 * entries are stored 1024 bytes below.
163 */ 167 */
164#define L_PTE_PRESENT (1 << 0) 168#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
165#define L_PTE_YOUNG (1 << 1) 169#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
166#define L_PTE_FILE (1 << 2) /* only when !PRESENT */ 170#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
167#define L_PTE_DIRTY (1 << 6) 171#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6)
168#define L_PTE_WRITE (1 << 7) 172#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7)
169#define L_PTE_USER (1 << 8) 173#define L_PTE_USER (_AT(pteval_t, 1) << 8)
170#define L_PTE_EXEC (1 << 9) 174#define L_PTE_XN (_AT(pteval_t, 1) << 9)
171#define L_PTE_SHARED (1 << 10) /* shared(v6), coherent(xsc3) */ 175#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
172 176
173/* 177/*
174 * These are the memory types, defined to be compatible with 178 * These are the memory types, defined to be compatible with
175 * pre-ARMv6 CPUs cacheable and bufferable bits: XXCB 179 * pre-ARMv6 CPUs cacheable and bufferable bits: XXCB
176 */ 180 */
177#define L_PTE_MT_UNCACHED (0x00 << 2) /* 0000 */ 181#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0x00) << 2) /* 0000 */
178#define L_PTE_MT_BUFFERABLE (0x01 << 2) /* 0001 */ 182#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 0x01) << 2) /* 0001 */
179#define L_PTE_MT_WRITETHROUGH (0x02 << 2) /* 0010 */ 183#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 0x02) << 2) /* 0010 */
180#define L_PTE_MT_WRITEBACK (0x03 << 2) /* 0011 */ 184#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 0x03) << 2) /* 0011 */
181#define L_PTE_MT_MINICACHE (0x06 << 2) /* 0110 (sa1100, xscale) */ 185#define L_PTE_MT_MINICACHE (_AT(pteval_t, 0x06) << 2) /* 0110 (sa1100, xscale) */
182#define L_PTE_MT_WRITEALLOC (0x07 << 2) /* 0111 */ 186#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 0x07) << 2) /* 0111 */
183#define L_PTE_MT_DEV_SHARED (0x04 << 2) /* 0100 */ 187#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 0x04) << 2) /* 0100 */
184#define L_PTE_MT_DEV_NONSHARED (0x0c << 2) /* 1100 */ 188#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */
185#define L_PTE_MT_DEV_WC (0x09 << 2) /* 1001 */ 189#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */
186#define L_PTE_MT_DEV_CACHED (0x0b << 2) /* 1011 */ 190#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */
187#define L_PTE_MT_MASK (0x0f << 2) 191#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
188 192
189#ifndef __ASSEMBLY__ 193#ifndef __ASSEMBLY__
190 194
@@ -201,23 +205,44 @@ extern pgprot_t pgprot_kernel;
201 205
202#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) 206#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
203 207
204#define PAGE_NONE pgprot_user 208#define PAGE_NONE _MOD_PROT(pgprot_user, L_PTE_XN | L_PTE_RDONLY)
205#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE) 209#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
206#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC) 210#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER)
207#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER) 211#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
208#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC) 212#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
209#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER) 213#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
210#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC) 214#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
211#define PAGE_KERNEL pgprot_kernel 215#define PAGE_KERNEL _MOD_PROT(pgprot_kernel, L_PTE_XN)
212#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_kernel, L_PTE_EXEC) 216#define PAGE_KERNEL_EXEC pgprot_kernel
213 217
214#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT) 218#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN)
215#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE) 219#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
216#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC) 220#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
217#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER) 221#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
218#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC) 222#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
219#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER) 223#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
220#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC) 224#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
225
226#define __pgprot_modify(prot,mask,bits) \
227 __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
228
229#define pgprot_noncached(prot) \
230 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
231
232#define pgprot_writecombine(prot) \
233 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
234
235#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
236#define pgprot_dmacoherent(prot) \
237 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE | L_PTE_XN)
238#define __HAVE_PHYS_MEM_ACCESS_PROT
239struct file;
240extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
241 unsigned long size, pgprot_t vma_prot);
242#else
243#define pgprot_dmacoherent(prot) \
244 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
245#endif
221 246
222#endif /* __ASSEMBLY__ */ 247#endif /* __ASSEMBLY__ */
223 248
@@ -255,26 +280,84 @@ extern pgprot_t pgprot_kernel;
255extern struct page *empty_zero_page; 280extern struct page *empty_zero_page;
256#define ZERO_PAGE(vaddr) (empty_zero_page) 281#define ZERO_PAGE(vaddr) (empty_zero_page)
257 282
258#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
259#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
260 283
261#define pte_none(pte) (!pte_val(pte)) 284extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
262#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) 285
263#define pte_page(pte) (pfn_to_page(pte_pfn(pte))) 286/* to find an entry in a page-table-directory */
264#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) 287#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
288
289#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
290
291/* to find an entry in a kernel page-table-directory */
292#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
293
294/*
295 * The "pgd_xxx()" functions here are trivial for a folded two-level
296 * setup: the pgd is never bad, and a pmd always exists (as it's folded
297 * into the pgd entry)
298 */
299#define pgd_none(pgd) (0)
300#define pgd_bad(pgd) (0)
301#define pgd_present(pgd) (1)
302#define pgd_clear(pgdp) do { } while (0)
303#define set_pgd(pgd,pgdp) do { } while (0)
304
305
306/* Find an entry in the second-level page table.. */
307#define pmd_offset(dir, addr) ((pmd_t *)(dir))
308
309#define pmd_none(pmd) (!pmd_val(pmd))
310#define pmd_present(pmd) (pmd_val(pmd))
311#define pmd_bad(pmd) (pmd_val(pmd) & 2)
312
313#define copy_pmd(pmdpd,pmdps) \
314 do { \
315 pmdpd[0] = pmdps[0]; \
316 pmdpd[1] = pmdps[1]; \
317 flush_pmd_entry(pmdpd); \
318 } while (0)
319
320#define pmd_clear(pmdp) \
321 do { \
322 pmdp[0] = __pmd(0); \
323 pmdp[1] = __pmd(0); \
324 clean_pmd_entry(pmdp); \
325 } while (0)
326
327static inline pte_t *pmd_page_vaddr(pmd_t pmd)
328{
329 return __va(pmd_val(pmd) & PAGE_MASK);
330}
331
332#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
333
334/* we don't need complex calculations here as the pmd is folded into the pgd */
335#define pmd_addr_end(addr,end) (end)
265 336
266#define pte_offset_map(dir,addr) (__pte_map(dir) + __pte_index(addr))
267#define pte_unmap(pte) __pte_unmap(pte)
268 337
269#ifndef CONFIG_HIGHPTE 338#ifndef CONFIG_HIGHPTE
270#define __pte_map(dir) pmd_page_vaddr(*(dir)) 339#define __pte_map(pmd) pmd_page_vaddr(*(pmd))
271#define __pte_unmap(pte) do { } while (0) 340#define __pte_unmap(pte) do { } while (0)
272#else 341#else
273#define __pte_map(dir) ((pte_t *)kmap_atomic(pmd_page(*(dir))) + PTRS_PER_PTE) 342#define __pte_map(pmd) (pte_t *)kmap_atomic(pmd_page(*(pmd)))
274#define __pte_unmap(pte) kunmap_atomic((pte - PTRS_PER_PTE)) 343#define __pte_unmap(pte) kunmap_atomic(pte)
275#endif 344#endif
276 345
346#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
347
348#define pte_offset_kernel(pmd,addr) (pmd_page_vaddr(*(pmd)) + pte_index(addr))
349
350#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr))
351#define pte_unmap(pte) __pte_unmap(pte)
352
353#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
354#define pfn_pte(pfn,prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
355
356#define pte_page(pte) pfn_to_page(pte_pfn(pte))
357#define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot)
358
277#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) 359#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
360#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
278 361
279#if __LINUX_ARM_ARCH__ < 6 362#if __LINUX_ARM_ARCH__ < 6
280static inline void __sync_icache_dcache(pte_t pteval) 363static inline void __sync_icache_dcache(pte_t pteval)
@@ -295,15 +378,12 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
295 } 378 }
296} 379}
297 380
298/* 381#define pte_none(pte) (!pte_val(pte))
299 * The following only work if pte_present() is true.
300 * Undefined behaviour if not..
301 */
302#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) 382#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
303#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE) 383#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY))
304#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) 384#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
305#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) 385#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
306#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC) 386#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN))
307#define pte_special(pte) (0) 387#define pte_special(pte) (0)
308 388
309#define pte_present_user(pte) \ 389#define pte_present_user(pte) \
@@ -313,8 +393,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
313#define PTE_BIT_FUNC(fn,op) \ 393#define PTE_BIT_FUNC(fn,op) \
314static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } 394static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
315 395
316PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE); 396PTE_BIT_FUNC(wrprotect, |= L_PTE_RDONLY);
317PTE_BIT_FUNC(mkwrite, |= L_PTE_WRITE); 397PTE_BIT_FUNC(mkwrite, &= ~L_PTE_RDONLY);
318PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY); 398PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY);
319PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); 399PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY);
320PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); 400PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG);
@@ -322,101 +402,13 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
322 402
323static inline pte_t pte_mkspecial(pte_t pte) { return pte; } 403static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
324 404
325#define __pgprot_modify(prot,mask,bits) \
326 __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
327
328/*
329 * Mark the prot value as uncacheable and unbufferable.
330 */
331#define pgprot_noncached(prot) \
332 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
333#define pgprot_writecombine(prot) \
334 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
335#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
336#define pgprot_dmacoherent(prot) \
337 __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
338#define __HAVE_PHYS_MEM_ACCESS_PROT
339struct file;
340extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
341 unsigned long size, pgprot_t vma_prot);
342#else
343#define pgprot_dmacoherent(prot) \
344 __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED)
345#endif
346
347#define pmd_none(pmd) (!pmd_val(pmd))
348#define pmd_present(pmd) (pmd_val(pmd))
349#define pmd_bad(pmd) (pmd_val(pmd) & 2)
350
351#define copy_pmd(pmdpd,pmdps) \
352 do { \
353 pmdpd[0] = pmdps[0]; \
354 pmdpd[1] = pmdps[1]; \
355 flush_pmd_entry(pmdpd); \
356 } while (0)
357
358#define pmd_clear(pmdp) \
359 do { \
360 pmdp[0] = __pmd(0); \
361 pmdp[1] = __pmd(0); \
362 clean_pmd_entry(pmdp); \
363 } while (0)
364
365static inline pte_t *pmd_page_vaddr(pmd_t pmd)
366{
367 unsigned long ptr;
368
369 ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
370 ptr += PTRS_PER_PTE * sizeof(void *);
371
372 return __va(ptr);
373}
374
375#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
376
377/* we don't need complex calculations here as the pmd is folded into the pgd */
378#define pmd_addr_end(addr,end) (end)
379
380/*
381 * Conversion functions: convert a page and protection to a page entry,
382 * and a page entry and page directory to the page they refer to.
383 */
384#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
385
386/*
387 * The "pgd_xxx()" functions here are trivial for a folded two-level
388 * setup: the pgd is never bad, and a pmd always exists (as it's folded
389 * into the pgd entry)
390 */
391#define pgd_none(pgd) (0)
392#define pgd_bad(pgd) (0)
393#define pgd_present(pgd) (1)
394#define pgd_clear(pgdp) do { } while (0)
395#define set_pgd(pgd,pgdp) do { } while (0)
396
397/* to find an entry in a page-table-directory */
398#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
399
400#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
401
402/* to find an entry in a kernel page-table-directory */
403#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
404
405/* Find an entry in the second-level page table.. */
406#define pmd_offset(dir, addr) ((pmd_t *)(dir))
407
408/* Find an entry in the third-level page table.. */
409#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
410
411static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 405static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
412{ 406{
413 const unsigned long mask = L_PTE_EXEC | L_PTE_WRITE | L_PTE_USER; 407 const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER;
414 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); 408 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
415 return pte; 409 return pte;
416} 410}
417 411
418extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
419
420/* 412/*
421 * Encode and decode a swap entry. Swap entries are stored in the Linux 413 * Encode and decode a swap entry. Swap entries are stored in the Linux
422 * page tables as follows: 414 * page tables as follows:
@@ -481,6 +473,9 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
481 473
482#define pgtable_cache_init() do { } while (0) 474#define pgtable_cache_init() do { } while (0)
483 475
476void identity_mapping_add(pgd_t *, unsigned long, unsigned long);
477void identity_mapping_del(pgd_t *, unsigned long, unsigned long);
478
484#endif /* !__ASSEMBLY__ */ 479#endif /* !__ASSEMBLY__ */
485 480
486#endif /* CONFIG_MMU */ 481#endif /* CONFIG_MMU */