aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm/pgtable.h
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/arm/include/asm/pgtable.h
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/arm/include/asm/pgtable.h')
-rw-r--r--arch/arm/include/asm/pgtable.h309
1 files changed, 163 insertions, 146 deletions
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index e90b167ea848..5750704e0271 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,76 +280,32 @@ 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
261#define pte_none(pte) (!pte_val(pte))
262#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
263#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
264#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
265 283
266#define pte_offset_map(dir,addr) (__pte_map(dir, KM_PTE0) + __pte_index(addr)) 284extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
267#define pte_offset_map_nested(dir,addr) (__pte_map(dir, KM_PTE1) + __pte_index(addr))
268#define pte_unmap(pte) __pte_unmap(pte, KM_PTE0)
269#define pte_unmap_nested(pte) __pte_unmap(pte, KM_PTE1)
270 285
271#ifndef CONFIG_HIGHPTE 286/* to find an entry in a page-table-directory */
272#define __pte_map(dir,km) pmd_page_vaddr(*(dir)) 287#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
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
278 288
279#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) 289#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
280 290
281#define set_pte_at(mm,addr,ptep,pteval) do { \ 291/* to find an entry in a kernel page-table-directory */
282 set_pte_ext(ptep, pteval, (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \ 292#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
283 } while (0)
284 293
285/* 294/*
286 * The following only work if pte_present() is true. 295 * The "pgd_xxx()" functions here are trivial for a folded two-level
287 * Undefined behaviour if not.. 296 * setup: the pgd is never bad, and a pmd always exists (as it's folded
297 * into the pgd entry)
288 */ 298 */
289#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) 299#define pgd_none(pgd) (0)
290#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE) 300#define pgd_bad(pgd) (0)
291#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) 301#define pgd_present(pgd) (1)
292#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) 302#define pgd_clear(pgdp) do { } while (0)
293#define pte_special(pte) (0) 303#define set_pgd(pgd,pgdp) do { } while (0)
294 304#define set_pud(pud,pudp) do { } while (0)
295#define PTE_BIT_FUNC(fn,op) \
296static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
297
298PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE);
299PTE_BIT_FUNC(mkwrite, |= L_PTE_WRITE);
300PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY);
301PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY);
302PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG);
303PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
304
305static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
306 305
307#define __pgprot_modify(prot,mask,bits) \
308 __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
309 306
310/* 307/* Find an entry in the second-level page table.. */
311 * Mark the prot value as uncacheable and unbufferable. 308#define pmd_offset(dir, addr) ((pmd_t *)(dir))
312 */
313#define pgprot_noncached(prot) \
314 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
315#define pgprot_writecombine(prot) \
316 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
317#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
318#define pgprot_dmacoherent(prot) \
319 __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
320#define __HAVE_PHYS_MEM_ACCESS_PROT
321struct file;
322extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
323 unsigned long size, pgprot_t vma_prot);
324#else
325#define pgprot_dmacoherent(prot) \
326 __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED)
327#endif
328 309
329#define pmd_none(pmd) (!pmd_val(pmd)) 310#define pmd_none(pmd) (!pmd_val(pmd))
330#define pmd_present(pmd) (pmd_val(pmd)) 311#define pmd_present(pmd) (pmd_val(pmd))
@@ -346,56 +327,89 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
346 327
347static inline pte_t *pmd_page_vaddr(pmd_t pmd) 328static inline pte_t *pmd_page_vaddr(pmd_t pmd)
348{ 329{
349 unsigned long ptr; 330 return __va(pmd_val(pmd) & PAGE_MASK);
350
351 ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
352 ptr += PTRS_PER_PTE * sizeof(void *);
353
354 return __va(ptr);
355} 331}
356 332
357#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd))) 333#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
358 334
359/* 335/* we don't need complex calculations here as the pmd is folded into the pgd */
360 * Conversion functions: convert a page and protection to a page entry, 336#define pmd_addr_end(addr,end) (end)
361 * and a page entry and page directory to the page they refer to.
362 */
363#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
364 337
365/*
366 * The "pgd_xxx()" functions here are trivial for a folded two-level
367 * setup: the pgd is never bad, and a pmd always exists (as it's folded
368 * into the pgd entry)
369 */
370#define pgd_none(pgd) (0)
371#define pgd_bad(pgd) (0)
372#define pgd_present(pgd) (1)
373#define pgd_clear(pgdp) do { } while (0)
374#define set_pgd(pgd,pgdp) do { } while (0)
375 338
376/* to find an entry in a page-table-directory */ 339#ifndef CONFIG_HIGHPTE
377#define pgd_index(addr) ((addr) >> PGDIR_SHIFT) 340#define __pte_map(pmd) pmd_page_vaddr(*(pmd))
341#define __pte_unmap(pte) do { } while (0)
342#else
343#define __pte_map(pmd) (pte_t *)kmap_atomic(pmd_page(*(pmd)))
344#define __pte_unmap(pte) kunmap_atomic(pte)
345#endif
378 346
379#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr)) 347#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
380 348
381/* to find an entry in a kernel page-table-directory */ 349#define pte_offset_kernel(pmd,addr) (pmd_page_vaddr(*(pmd)) + pte_index(addr))
382#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
383 350
384/* Find an entry in the second-level page table.. */ 351#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr))
385#define pmd_offset(dir, addr) ((pmd_t *)(dir)) 352#define pte_unmap(pte) __pte_unmap(pte)
386 353
387/* Find an entry in the third-level page table.. */ 354#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
388#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) 355#define pfn_pte(pfn,prot) __pte(__pfn_to_phys(pfn) | pgprot_val(prot))
356
357#define pte_page(pte) pfn_to_page(pte_pfn(pte))
358#define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot)
359
360#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
361#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
362
363#if __LINUX_ARM_ARCH__ < 6
364static inline void __sync_icache_dcache(pte_t pteval)
365{
366}
367#else
368extern void __sync_icache_dcache(pte_t pteval);
369#endif
370
371static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
372 pte_t *ptep, pte_t pteval)
373{
374 if (addr >= TASK_SIZE)
375 set_pte_ext(ptep, pteval, 0);
376 else {
377 __sync_icache_dcache(pteval);
378 set_pte_ext(ptep, pteval, PTE_EXT_NG);
379 }
380}
381
382#define pte_none(pte) (!pte_val(pte))
383#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
384#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY))
385#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
386#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
387#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN))
388#define pte_special(pte) (0)
389
390#define pte_present_user(pte) \
391 ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \
392 (L_PTE_PRESENT | L_PTE_USER))
393
394#define PTE_BIT_FUNC(fn,op) \
395static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
396
397PTE_BIT_FUNC(wrprotect, |= L_PTE_RDONLY);
398PTE_BIT_FUNC(mkwrite, &= ~L_PTE_RDONLY);
399PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY);
400PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY);
401PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG);
402PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
403
404static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
389 405
390static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 406static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
391{ 407{
392 const unsigned long mask = L_PTE_EXEC | L_PTE_WRITE | L_PTE_USER; 408 const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER;
393 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); 409 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
394 return pte; 410 return pte;
395} 411}
396 412
397extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
398
399/* 413/*
400 * Encode and decode a swap entry. Swap entries are stored in the Linux 414 * Encode and decode a swap entry. Swap entries are stored in the Linux
401 * page tables as follows: 415 * page tables as follows:
@@ -460,6 +474,9 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
460 474
461#define pgtable_cache_init() do { } while (0) 475#define pgtable_cache_init() do { } while (0)
462 476
477void identity_mapping_add(pgd_t *, unsigned long, unsigned long);
478void identity_mapping_del(pgd_t *, unsigned long, unsigned long);
479
463#endif /* !__ASSEMBLY__ */ 480#endif /* !__ASSEMBLY__ */
464 481
465#endif /* CONFIG_MMU */ 482#endif /* CONFIG_MMU */