include/linux/of.h: make for_each_child_of_node() reference its args when CONFIG_OF=n
[deliverable/linux.git] / arch / arm64 / include / asm / pgtable.h
CommitLineData
4f04d8f0
CM
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_PGTABLE_H
17#define __ASM_PGTABLE_H
18
19#include <asm/proc-fns.h>
20
21#include <asm/memory.h>
22#include <asm/pgtable-hwdef.h>
23
24/*
25 * Software defined PTE bits definition.
26 */
a6fadf7e 27#define PTE_VALID (_AT(pteval_t, 1) << 0)
3676f9ef 28#define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */
4f04d8f0
CM
29#define PTE_DIRTY (_AT(pteval_t, 1) << 55)
30#define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
3676f9ef
CM
31 /* bit 57 for PMD_SECT_SPLITTING */
32#define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */
4f04d8f0
CM
33
34/*
35 * VMALLOC and SPARSEMEM_VMEMMAP ranges.
36 */
847264fb 37#define VMALLOC_START (UL(0xffffffffffffffff) << VA_BITS)
4f04d8f0
CM
38#define VMALLOC_END (PAGE_OFFSET - UL(0x400000000) - SZ_64K)
39
40#define vmemmap ((struct page *)(VMALLOC_END + SZ_64K))
41
42#define FIRST_USER_ADDRESS 0
43
44#ifndef __ASSEMBLY__
45extern void __pte_error(const char *file, int line, unsigned long val);
46extern void __pmd_error(const char *file, int line, unsigned long val);
47extern void __pgd_error(const char *file, int line, unsigned long val);
48
49#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte))
50#ifndef CONFIG_ARM64_64K_PAGES
51#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd))
52#endif
53#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
54
55/*
56 * The pgprot_* and protection_map entries will be fixed up at runtime to
57 * include the cachable and bufferable bits based on memory policy, as well as
58 * any architecture dependent bits like global/ASID and SMP shared mapping
59 * bits.
60 */
61#define _PAGE_DEFAULT PTE_TYPE_PAGE | PTE_AF
62
63extern pgprot_t pgprot_default;
64
a6fadf7e
WD
65#define __pgprot_modify(prot,mask,bits) \
66 __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
67
68#define _MOD_PROT(p, b) __pgprot_modify(p, 0, b)
4f04d8f0 69
072b1b62 70#define PAGE_NONE __pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN)
8e620b04
CM
71#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
72#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
73#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
74#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
75#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
76#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
77#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY)
78#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY)
79
36311607
MZ
80#define PAGE_HYP _MOD_PROT(pgprot_default, PTE_HYP)
81#define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
82
83#define PAGE_S2 __pgprot_modify(pgprot_default, PTE_S2_MEMATTR_MASK, PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
84#define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDWR | PTE_UXN)
85
072b1b62 86#define __PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN)
8e620b04
CM
87#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
88#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
89#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
90#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
91#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
92#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
4f04d8f0
CM
93
94#endif /* __ASSEMBLY__ */
95
96#define __P000 __PAGE_NONE
97#define __P001 __PAGE_READONLY
98#define __P010 __PAGE_COPY
99#define __P011 __PAGE_COPY
100#define __P100 __PAGE_READONLY_EXEC
101#define __P101 __PAGE_READONLY_EXEC
102#define __P110 __PAGE_COPY_EXEC
103#define __P111 __PAGE_COPY_EXEC
104
105#define __S000 __PAGE_NONE
106#define __S001 __PAGE_READONLY
107#define __S010 __PAGE_SHARED
108#define __S011 __PAGE_SHARED
109#define __S100 __PAGE_READONLY_EXEC
110#define __S101 __PAGE_READONLY_EXEC
111#define __S110 __PAGE_SHARED_EXEC
112#define __S111 __PAGE_SHARED_EXEC
113
114#ifndef __ASSEMBLY__
115/*
116 * ZERO_PAGE is a global shared page that is always zero: used
117 * for zero-mapped memory areas etc..
118 */
119extern struct page *empty_zero_page;
120#define ZERO_PAGE(vaddr) (empty_zero_page)
121
122#define pte_pfn(pte) ((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT)
123
124#define pfn_pte(pfn,prot) (__pte(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
125
126#define pte_none(pte) (!pte_val(pte))
127#define pte_clear(mm,addr,ptep) set_pte(ptep, __pte(0))
128#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
9ab6d02f 129#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + pte_index(addr))
4f04d8f0
CM
130
131#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
132#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr))
133#define pte_unmap(pte) do { } while (0)
134#define pte_unmap_nested(pte) do { } while (0)
135
136/*
137 * The following only work if pte_present(). Undefined behaviour otherwise.
138 */
a6fadf7e 139#define pte_present(pte) (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE))
4f04d8f0
CM
140#define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY)
141#define pte_young(pte) (pte_val(pte) & PTE_AF)
142#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL)
143#define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY))
8e620b04 144#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
4f04d8f0 145
a6fadf7e 146#define pte_valid_user(pte) \
02522463 147 ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
4f04d8f0
CM
148
149#define PTE_BIT_FUNC(fn,op) \
150static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
151
152PTE_BIT_FUNC(wrprotect, |= PTE_RDONLY);
153PTE_BIT_FUNC(mkwrite, &= ~PTE_RDONLY);
154PTE_BIT_FUNC(mkclean, &= ~PTE_DIRTY);
155PTE_BIT_FUNC(mkdirty, |= PTE_DIRTY);
156PTE_BIT_FUNC(mkold, &= ~PTE_AF);
157PTE_BIT_FUNC(mkyoung, |= PTE_AF);
158PTE_BIT_FUNC(mkspecial, |= PTE_SPECIAL);
159
160static inline void set_pte(pte_t *ptep, pte_t pte)
161{
162 *ptep = pte;
163}
164
165extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
166
167static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
168 pte_t *ptep, pte_t pte)
169{
a6fadf7e 170 if (pte_valid_user(pte)) {
02522463
WD
171 if (pte_exec(pte))
172 __sync_icache_dcache(pte, addr);
173 if (!pte_dirty(pte))
174 pte = pte_wrprotect(pte);
175 }
176
4f04d8f0
CM
177 set_pte(ptep, pte);
178}
179
180/*
181 * Huge pte definitions.
182 */
084bd298
SC
183#define pte_huge(pte) (!(pte_val(pte) & PTE_TABLE_BIT))
184#define pte_mkhuge(pte) (__pte(pte_val(pte) & ~PTE_TABLE_BIT))
185
186/*
187 * Hugetlb definitions.
188 */
189#define HUGE_MAX_HSTATE 2
190#define HPAGE_SHIFT PMD_SHIFT
191#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
192#define HPAGE_MASK (~(HPAGE_SIZE - 1))
193#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
4f04d8f0 194
4f04d8f0
CM
195#define __HAVE_ARCH_PTE_SPECIAL
196
af074848
SC
197/*
198 * Software PMD bits for THP
199 */
200
201#define PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55)
202#define PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 57)
203
204/*
205 * THP definitions.
206 */
207#define pmd_young(pmd) (pmd_val(pmd) & PMD_SECT_AF)
208
209#define __HAVE_ARCH_PMD_WRITE
210#define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY))
211
212#ifdef CONFIG_TRANSPARENT_HUGEPAGE
213#define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
214#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
215#endif
216
217#define PMD_BIT_FUNC(fn,op) \
218static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
219
220PMD_BIT_FUNC(wrprotect, |= PMD_SECT_RDONLY);
221PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF);
222PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING);
223PMD_BIT_FUNC(mkwrite, &= ~PMD_SECT_RDONLY);
224PMD_BIT_FUNC(mkdirty, |= PMD_SECT_DIRTY);
225PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
226PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
227
228#define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
229
230#define pmd_pfn(pmd) (((pmd_val(pmd) & PMD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
231#define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
232#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
233
234#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
235
236static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
237{
238 const pmdval_t mask = PMD_SECT_USER | PMD_SECT_PXN | PMD_SECT_UXN |
239 PMD_SECT_RDONLY | PMD_SECT_PROT_NONE |
240 PMD_SECT_VALID;
241 pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
242 return pmd;
243}
244
245#define set_pmd_at(mm, addr, pmdp, pmd) set_pmd(pmdp, pmd)
246
247static inline int has_transparent_hugepage(void)
248{
249 return 1;
250}
251
4f04d8f0
CM
252/*
253 * Mark the prot value as uncacheable and unbufferable.
254 */
255#define pgprot_noncached(prot) \
256 __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
257#define pgprot_writecombine(prot) \
4f00130b 258 __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
4f04d8f0
CM
259#define pgprot_dmacoherent(prot) \
260 __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
261#define __HAVE_PHYS_MEM_ACCESS_PROT
262struct file;
263extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
264 unsigned long size, pgprot_t vma_prot);
265
266#define pmd_none(pmd) (!pmd_val(pmd))
267#define pmd_present(pmd) (pmd_val(pmd))
268
269#define pmd_bad(pmd) (!(pmd_val(pmd) & 2))
270
36311607
MZ
271#define pmd_table(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == \
272 PMD_TYPE_TABLE)
273#define pmd_sect(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == \
274 PMD_TYPE_SECT)
275
276
4f04d8f0
CM
277static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
278{
279 *pmdp = pmd;
280 dsb();
281}
282
283static inline void pmd_clear(pmd_t *pmdp)
284{
285 set_pmd(pmdp, __pmd(0));
286}
287
288static inline pte_t *pmd_page_vaddr(pmd_t pmd)
289{
290 return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
291}
292
293#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
294
295/*
296 * Conversion functions: convert a page and protection to a page entry,
297 * and a page entry and page directory to the page they refer to.
298 */
299#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
300
301#ifndef CONFIG_ARM64_64K_PAGES
302
303#define pud_none(pud) (!pud_val(pud))
304#define pud_bad(pud) (!(pud_val(pud) & 2))
305#define pud_present(pud) (pud_val(pud))
306
307static inline void set_pud(pud_t *pudp, pud_t pud)
308{
309 *pudp = pud;
310 dsb();
311}
312
313static inline void pud_clear(pud_t *pudp)
314{
315 set_pud(pudp, __pud(0));
316}
317
318static inline pmd_t *pud_page_vaddr(pud_t pud)
319{
320 return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
321}
322
323#endif /* CONFIG_ARM64_64K_PAGES */
324
325/* to find an entry in a page-table-directory */
326#define pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
327
328#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
329
330/* to find an entry in a kernel page-table-directory */
331#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
332
333/* Find an entry in the second-level page table.. */
334#ifndef CONFIG_ARM64_64K_PAGES
335#define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
336static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
337{
338 return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
339}
340#endif
341
342/* Find an entry in the third-level page table.. */
9ab6d02f 343#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
4f04d8f0
CM
344
345static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
346{
a6fadf7e
WD
347 const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY |
348 PTE_PROT_NONE | PTE_VALID;
4f04d8f0
CM
349 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
350 return pte;
351}
352
353extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
354extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
355
356#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
357#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
358
359/*
360 * Encode and decode a swap entry:
3676f9ef
CM
361 * bits 0-1: present (must be zero)
362 * bit 2: PTE_FILE
363 * bits 3-8: swap type
364 * bits 9-57: swap offset
4f04d8f0 365 */
3676f9ef 366#define __SWP_TYPE_SHIFT 3
4f04d8f0 367#define __SWP_TYPE_BITS 6
3676f9ef 368#define __SWP_OFFSET_BITS 49
4f04d8f0
CM
369#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
370#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
3676f9ef 371#define __SWP_OFFSET_MASK ((1UL << __SWP_OFFSET_BITS) - 1)
4f04d8f0
CM
372
373#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
3676f9ef 374#define __swp_offset(x) (((x).val >> __SWP_OFFSET_SHIFT) & __SWP_OFFSET_MASK)
4f04d8f0
CM
375#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) })
376
377#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
378#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
379
380/*
381 * Ensure that there are not more swap files than can be encoded in the kernel
382 * the PTEs.
383 */
384#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
385
386/*
387 * Encode and decode a file entry:
3676f9ef
CM
388 * bits 0-1: present (must be zero)
389 * bit 2: PTE_FILE
390 * bits 3-57: file offset / PAGE_SIZE
4f04d8f0
CM
391 */
392#define pte_file(pte) (pte_val(pte) & PTE_FILE)
3676f9ef
CM
393#define pte_to_pgoff(x) (pte_val(x) >> 3)
394#define pgoff_to_pte(x) __pte(((x) << 3) | PTE_FILE)
4f04d8f0 395
3676f9ef 396#define PTE_FILE_MAX_BITS 55
4f04d8f0
CM
397
398extern int kern_addr_valid(unsigned long addr);
399
400#include <asm-generic/pgtable.h>
401
4f04d8f0
CM
402#define pgtable_cache_init() do { } while (0)
403
404#endif /* !__ASSEMBLY__ */
405
406#endif /* __ASM_PGTABLE_H */
This page took 0.245175 seconds and 5 git commands to generate.