Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
0004  */
0005 
0006 /*
0007  * Helpers for implemenintg paging levels
0008  */
0009 
0010 #ifndef _ASM_ARC_PGTABLE_LEVELS_H
0011 #define _ASM_ARC_PGTABLE_LEVELS_H
0012 
0013 #if CONFIG_PGTABLE_LEVELS == 2
0014 
0015 /*
0016  * 2 level paging setup for software walked MMUv3 (ARC700) and MMUv4 (HS)
0017  *
0018  * [31]            32 bit virtual address              [0]
0019  * -------------------------------------------------------
0020  * |               | <---------- PGDIR_SHIFT ----------> |
0021  * |               |                | <-- PAGE_SHIFT --> |
0022  * -------------------------------------------------------
0023  *       |                  |                |
0024  *       |                  |                --> off in page frame
0025  *       |                  ---> index into Page Table
0026  *       ----> index into Page Directory
0027  *
0028  * Given software walk, the vaddr split is arbitrary set to 11:8:13
0029  * However enabling of super page in a 2 level regime pegs PGDIR_SHIFT to
0030  * super page size.
0031  */
0032 
0033 #if defined(CONFIG_ARC_HUGEPAGE_16M)
0034 #define PGDIR_SHIFT     24
0035 #elif defined(CONFIG_ARC_HUGEPAGE_2M)
0036 #define PGDIR_SHIFT     21
0037 #else
0038 /*
0039  * No Super page case
0040  * Default value provides 11:8:13 (8K), 10:10:12 (4K)
0041  * Limits imposed by pgtable_t only PAGE_SIZE long
0042  * (so 4K page can only have 1K entries: or 10 bits)
0043  */
0044 #ifdef CONFIG_ARC_PAGE_SIZE_4K
0045 #define PGDIR_SHIFT     22
0046 #else
0047 #define PGDIR_SHIFT     21
0048 #endif
0049 
0050 #endif
0051 
0052 #else /* CONFIG_PGTABLE_LEVELS != 2 */
0053 
0054 /*
0055  * A default 3 level paging testing setup in software walked MMU
0056  *   MMUv4 (8K page): <4> : <7> : <8> : <13>
0057  * A default 4 level paging testing setup in software walked MMU
0058  *   MMUv4 (8K page): <4> : <3> : <4> : <8> : <13>
0059  */
0060 #define PGDIR_SHIFT     28
0061 #if CONFIG_PGTABLE_LEVELS > 3
0062 #define PUD_SHIFT       25
0063 #endif
0064 #if CONFIG_PGTABLE_LEVELS > 2
0065 #define PMD_SHIFT       21
0066 #endif
0067 
0068 #endif /* CONFIG_PGTABLE_LEVELS */
0069 
0070 #define PGDIR_SIZE      BIT(PGDIR_SHIFT)
0071 #define PGDIR_MASK      (~(PGDIR_SIZE - 1))
0072 #define PTRS_PER_PGD        BIT(32 - PGDIR_SHIFT)
0073 
0074 #if CONFIG_PGTABLE_LEVELS > 3
0075 #define PUD_SIZE        BIT(PUD_SHIFT)
0076 #define PUD_MASK        (~(PUD_SIZE - 1))
0077 #define PTRS_PER_PUD        BIT(PGDIR_SHIFT - PUD_SHIFT)
0078 #endif
0079 
0080 #if CONFIG_PGTABLE_LEVELS > 2
0081 #define PMD_SIZE        BIT(PMD_SHIFT)
0082 #define PMD_MASK        (~(PMD_SIZE - 1))
0083 #define PTRS_PER_PMD        BIT(PUD_SHIFT - PMD_SHIFT)
0084 #endif
0085 
0086 #define PTRS_PER_PTE        BIT(PMD_SHIFT - PAGE_SHIFT)
0087 
0088 #ifndef __ASSEMBLY__
0089 
0090 #if CONFIG_PGTABLE_LEVELS > 3
0091 #include <asm-generic/pgtable-nop4d.h>
0092 #elif CONFIG_PGTABLE_LEVELS > 2
0093 #include <asm-generic/pgtable-nopud.h>
0094 #else
0095 #include <asm-generic/pgtable-nopmd.h>
0096 #endif
0097 
0098 /*
0099  * 1st level paging: pgd
0100  */
0101 #define pgd_ERROR(e) \
0102     pr_crit("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
0103 
0104 #if CONFIG_PGTABLE_LEVELS > 3
0105 
0106 /* In 4 level paging, p4d_* macros work on pgd */
0107 #define p4d_none(x)     (!p4d_val(x))
0108 #define p4d_bad(x)      ((p4d_val(x) & ~PAGE_MASK))
0109 #define p4d_present(x)      (p4d_val(x))
0110 #define p4d_clear(xp)       do { p4d_val(*(xp)) = 0; } while (0)
0111 #define p4d_pgtable(p4d)    ((pud_t *)(p4d_val(p4d) & PAGE_MASK))
0112 #define p4d_page(p4d)       virt_to_page(p4d_pgtable(p4d))
0113 #define set_p4d(p4dp, p4d)  (*(p4dp) = p4d)
0114 
0115 /*
0116  * 2nd level paging: pud
0117  */
0118 #define pud_ERROR(e) \
0119     pr_crit("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
0120 
0121 #endif
0122 
0123 #if CONFIG_PGTABLE_LEVELS > 2
0124 
0125 /*
0126  * In 3 level paging, pud_* macros work on pgd
0127  * In 4 level paging, pud_* macros work on pud
0128  */
0129 #define pud_none(x)     (!pud_val(x))
0130 #define pud_bad(x)      ((pud_val(x) & ~PAGE_MASK))
0131 #define pud_present(x)      (pud_val(x))
0132 #define pud_clear(xp)       do { pud_val(*(xp)) = 0; } while (0)
0133 #define pud_pgtable(pud)    ((pmd_t *)(pud_val(pud) & PAGE_MASK))
0134 #define pud_page(pud)       virt_to_page(pud_pgtable(pud))
0135 #define set_pud(pudp, pud)  (*(pudp) = pud)
0136 
0137 /*
0138  * 3rd level paging: pmd
0139  */
0140 #define pmd_ERROR(e) \
0141     pr_crit("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
0142 
0143 #define pmd_pfn(pmd)        ((pmd_val(pmd) & PMD_MASK) >> PAGE_SHIFT)
0144 #define pfn_pmd(pfn,prot)   __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
0145 #define mk_pmd(page,prot)   pfn_pmd(page_to_pfn(page),prot)
0146 
0147 #endif
0148 
0149 /*
0150  * Due to the strange way generic pgtable level folding works, the pmd_* macros
0151  *  - are valid even for 2 levels (which supposedly only has pgd - pte)
0152  *  - behave differently for 2 vs. 3
0153  * In 2  level paging        (pgd -> pte), pmd_* macros work on pgd
0154  * In 3+ level paging (pgd -> pmd -> pte), pmd_* macros work on pmd
0155  */
0156 #define pmd_none(x)     (!pmd_val(x))
0157 #define pmd_bad(x)      ((pmd_val(x) & ~PAGE_MASK))
0158 #define pmd_present(x)      (pmd_val(x))
0159 #define pmd_clear(xp)       do { pmd_val(*(xp)) = 0; } while (0)
0160 #define pmd_page_vaddr(pmd) (pmd_val(pmd) & PAGE_MASK)
0161 #define pmd_pfn(pmd)        ((pmd_val(pmd) & PAGE_MASK) >> PAGE_SHIFT)
0162 #define pmd_page(pmd)       virt_to_page(pmd_page_vaddr(pmd))
0163 #define set_pmd(pmdp, pmd)  (*(pmdp) = pmd)
0164 #define pmd_pgtable(pmd)    ((pgtable_t) pmd_page_vaddr(pmd))
0165 
0166 /*
0167  * 4th level paging: pte
0168  */
0169 #define pte_ERROR(e) \
0170     pr_crit("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
0171 
0172 #define pte_none(x)     (!pte_val(x))
0173 #define pte_present(x)      (pte_val(x) & _PAGE_PRESENT)
0174 #define pte_clear(mm,addr,ptep) set_pte_at(mm, addr, ptep, __pte(0))
0175 #define pte_page(pte)       pfn_to_page(pte_pfn(pte))
0176 #define set_pte(ptep, pte)  ((*(ptep)) = (pte))
0177 #define pte_pfn(pte)        (pte_val(pte) >> PAGE_SHIFT)
0178 #define pfn_pte(pfn, prot)  __pte(__pfn_to_phys(pfn) | pgprot_val(prot))
0179 #define mk_pte(page, prot)  pfn_pte(page_to_pfn(page), prot)
0180 
0181 #ifdef CONFIG_ISA_ARCV2
0182 #define pmd_leaf(x)     (pmd_val(x) & _PAGE_HW_SZ)
0183 #endif
0184 
0185 #endif  /* !__ASSEMBLY__ */
0186 
0187 #endif