1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2e44d6c40SPaul Mundt #ifndef __ASM_SH_PGTABLE_3LEVEL_H 3e44d6c40SPaul Mundt #define __ASM_SH_PGTABLE_3LEVEL_H 4e44d6c40SPaul Mundt 59849a569SKirill A. Shutemov #define __ARCH_USE_5LEVEL_HACK 6e44d6c40SPaul Mundt #include <asm-generic/pgtable-nopud.h> 7e44d6c40SPaul Mundt 8e44d6c40SPaul Mundt /* 9e44d6c40SPaul Mundt * Some cores need a 3-level page table layout, for example when using 10e44d6c40SPaul Mundt * 64-bit PTEs and 4K pages. 11e44d6c40SPaul Mundt */ 12e44d6c40SPaul Mundt #define PAGETABLE_LEVELS 3 13e44d6c40SPaul Mundt 14e44d6c40SPaul Mundt #define PTE_MAGNITUDE 3 /* 64-bit PTEs on SH-X2 TLB */ 15e44d6c40SPaul Mundt 16e44d6c40SPaul Mundt /* PGD bits */ 17e44d6c40SPaul Mundt #define PGDIR_SHIFT 30 18e44d6c40SPaul Mundt 19e44d6c40SPaul Mundt #define PTRS_PER_PGD 4 20e44d6c40SPaul Mundt #define USER_PTRS_PER_PGD 2 21e44d6c40SPaul Mundt 22e44d6c40SPaul Mundt /* PMD bits */ 23e44d6c40SPaul Mundt #define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - PTE_MAGNITUDE)) 24e44d6c40SPaul Mundt #define PMD_SIZE (1UL << PMD_SHIFT) 25e44d6c40SPaul Mundt #define PMD_MASK (~(PMD_SIZE-1)) 26e44d6c40SPaul Mundt 27e44d6c40SPaul Mundt #define PTRS_PER_PMD ((1 << PGDIR_SHIFT) / PMD_SIZE) 28e44d6c40SPaul Mundt 29e44d6c40SPaul Mundt #define pmd_ERROR(e) \ 30e44d6c40SPaul Mundt printk("%s:%d: bad pmd %016llx.\n", __FILE__, __LINE__, pmd_val(e)) 31e44d6c40SPaul Mundt 32e44d6c40SPaul Mundt typedef struct { unsigned long long pmd; } pmd_t; 33e44d6c40SPaul Mundt #define pmd_val(x) ((x).pmd) 34e44d6c40SPaul Mundt #define __pmd(x) ((pmd_t) { (x) } ) 35e44d6c40SPaul Mundt 36e44d6c40SPaul Mundt static inline unsigned long pud_page_vaddr(pud_t pud) 37e44d6c40SPaul Mundt { 38e44d6c40SPaul Mundt return pud_val(pud); 39e44d6c40SPaul Mundt } 40e44d6c40SPaul Mundt 412f85e7f9SChristoph Hellwig /* only used by the stubbed out hugetlb gup code, should never be called */ 422f85e7f9SChristoph Hellwig #define pud_page(pud) NULL 432f85e7f9SChristoph Hellwig 44e44d6c40SPaul Mundt #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) 45e44d6c40SPaul Mundt static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) 46e44d6c40SPaul Mundt { 47e44d6c40SPaul Mundt return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address); 48e44d6c40SPaul Mundt } 49e44d6c40SPaul Mundt 50e44d6c40SPaul Mundt #define pud_none(x) (!pud_val(x)) 51e44d6c40SPaul Mundt #define pud_present(x) (pud_val(x)) 52e44d6c40SPaul Mundt #define pud_clear(xp) do { set_pud(xp, __pud(0)); } while (0) 53e44d6c40SPaul Mundt #define pud_bad(x) (pud_val(x) & ~PAGE_MASK) 54e44d6c40SPaul Mundt 55e44d6c40SPaul Mundt /* 56e44d6c40SPaul Mundt * (puds are folded into pgds so this doesn't get actually called, 57e44d6c40SPaul Mundt * but the define is needed for a generic inline function.) 58e44d6c40SPaul Mundt */ 59e44d6c40SPaul Mundt #define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0) 60e44d6c40SPaul Mundt 61e44d6c40SPaul Mundt #endif /* __ASM_SH_PGTABLE_3LEVEL_H */ 62