1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 291521c2eSGreg Ungerer #ifndef _MCF_PGTABLE_H 391521c2eSGreg Ungerer #define _MCF_PGTABLE_H 491521c2eSGreg Ungerer 591521c2eSGreg Ungerer #include <asm/mcfmmu.h> 691521c2eSGreg Ungerer #include <asm/page.h> 791521c2eSGreg Ungerer 891521c2eSGreg Ungerer /* 991521c2eSGreg Ungerer * MMUDR bits, in proper place. We write these directly into the MMUDR 1091521c2eSGreg Ungerer * after masking from the pte. 1191521c2eSGreg Ungerer */ 1291521c2eSGreg Ungerer #define CF_PAGE_LOCKED MMUDR_LK /* 0x00000002 */ 1391521c2eSGreg Ungerer #define CF_PAGE_EXEC MMUDR_X /* 0x00000004 */ 1491521c2eSGreg Ungerer #define CF_PAGE_WRITABLE MMUDR_W /* 0x00000008 */ 1591521c2eSGreg Ungerer #define CF_PAGE_READABLE MMUDR_R /* 0x00000010 */ 1691521c2eSGreg Ungerer #define CF_PAGE_SYSTEM MMUDR_SP /* 0x00000020 */ 1791521c2eSGreg Ungerer #define CF_PAGE_COPYBACK MMUDR_CM_CCB /* 0x00000040 */ 1891521c2eSGreg Ungerer #define CF_PAGE_NOCACHE MMUDR_CM_NCP /* 0x00000080 */ 1991521c2eSGreg Ungerer 2091521c2eSGreg Ungerer #define CF_CACHEMASK (~MMUDR_CM_CCB) 2191521c2eSGreg Ungerer #define CF_PAGE_MMUDR_MASK 0x000000fe 2291521c2eSGreg Ungerer 2391521c2eSGreg Ungerer #define _PAGE_NOCACHE030 CF_PAGE_NOCACHE 2491521c2eSGreg Ungerer 2591521c2eSGreg Ungerer /* 2691521c2eSGreg Ungerer * MMUTR bits, need shifting down. 2791521c2eSGreg Ungerer */ 2891521c2eSGreg Ungerer #define CF_PAGE_MMUTR_MASK 0x00000c00 2991521c2eSGreg Ungerer #define CF_PAGE_MMUTR_SHIFT 10 3091521c2eSGreg Ungerer 3191521c2eSGreg Ungerer #define CF_PAGE_VALID (MMUTR_V << CF_PAGE_MMUTR_SHIFT) 3291521c2eSGreg Ungerer #define CF_PAGE_SHARED (MMUTR_SG << CF_PAGE_MMUTR_SHIFT) 3391521c2eSGreg Ungerer 3491521c2eSGreg Ungerer /* 3591521c2eSGreg Ungerer * Fake bits, not implemented in CF, will get masked out before 3691521c2eSGreg Ungerer * hitting hardware. 3791521c2eSGreg Ungerer */ 3891521c2eSGreg Ungerer #define CF_PAGE_DIRTY 0x00000001 3991521c2eSGreg Ungerer #define CF_PAGE_ACCESSED 0x00001000 4091521c2eSGreg Ungerer 4191521c2eSGreg Ungerer #define _PAGE_CACHE040 0x020 /* 68040 cache mode, cachable, copyback */ 4291521c2eSGreg Ungerer #define _PAGE_NOCACHE_S 0x040 /* 68040 no-cache mode, serialized */ 4391521c2eSGreg Ungerer #define _PAGE_NOCACHE 0x060 /* 68040 cache mode, non-serialized */ 4491521c2eSGreg Ungerer #define _PAGE_CACHE040W 0x000 /* 68040 cache mode, cachable, write-through */ 4591521c2eSGreg Ungerer #define _DESCTYPE_MASK 0x003 4691521c2eSGreg Ungerer #define _CACHEMASK040 (~0x060) 4791521c2eSGreg Ungerer #define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */ 4891521c2eSGreg Ungerer 499bc47f11SDavid Hildenbrand /* We borrow bit 7 to store the exclusive marker in swap PTEs. */ 50b5c88f21SDavid Hildenbrand #define _PAGE_SWP_EXCLUSIVE CF_PAGE_NOCACHE 51ed415406SDavid Hildenbrand 5291521c2eSGreg Ungerer /* 5391521c2eSGreg Ungerer * Externally used page protection values. 5491521c2eSGreg Ungerer */ 5591521c2eSGreg Ungerer #define _PAGE_PRESENT (CF_PAGE_VALID) 5691521c2eSGreg Ungerer #define _PAGE_ACCESSED (CF_PAGE_ACCESSED) 5791521c2eSGreg Ungerer #define _PAGE_DIRTY (CF_PAGE_DIRTY) 5891521c2eSGreg Ungerer #define _PAGE_READWRITE (CF_PAGE_READABLE \ 5991521c2eSGreg Ungerer | CF_PAGE_WRITABLE \ 6091521c2eSGreg Ungerer | CF_PAGE_SYSTEM \ 6191521c2eSGreg Ungerer | CF_PAGE_SHARED) 6291521c2eSGreg Ungerer 6391521c2eSGreg Ungerer /* 6491521c2eSGreg Ungerer * Compound page protection values. 6591521c2eSGreg Ungerer */ 6691521c2eSGreg Ungerer #define PAGE_NONE __pgprot(CF_PAGE_VALID \ 6791521c2eSGreg Ungerer | CF_PAGE_ACCESSED) 6891521c2eSGreg Ungerer 6991521c2eSGreg Ungerer #define PAGE_SHARED __pgprot(CF_PAGE_VALID \ 7091521c2eSGreg Ungerer | CF_PAGE_ACCESSED \ 7191521c2eSGreg Ungerer | CF_PAGE_SHARED) 7291521c2eSGreg Ungerer 7391521c2eSGreg Ungerer #define PAGE_INIT __pgprot(CF_PAGE_VALID \ 7491521c2eSGreg Ungerer | CF_PAGE_READABLE \ 7591521c2eSGreg Ungerer | CF_PAGE_WRITABLE \ 7691521c2eSGreg Ungerer | CF_PAGE_EXEC \ 7791521c2eSGreg Ungerer | CF_PAGE_SYSTEM) 7891521c2eSGreg Ungerer 7991521c2eSGreg Ungerer #define PAGE_KERNEL __pgprot(CF_PAGE_VALID \ 8091521c2eSGreg Ungerer | CF_PAGE_ACCESSED \ 8191521c2eSGreg Ungerer | CF_PAGE_READABLE \ 8291521c2eSGreg Ungerer | CF_PAGE_WRITABLE \ 8391521c2eSGreg Ungerer | CF_PAGE_EXEC \ 8457e00098SAlexander Stein | CF_PAGE_SYSTEM \ 8557e00098SAlexander Stein | CF_PAGE_SHARED) 8691521c2eSGreg Ungerer 8791521c2eSGreg Ungerer #define PAGE_COPY __pgprot(CF_PAGE_VALID \ 8891521c2eSGreg Ungerer | CF_PAGE_ACCESSED \ 8991521c2eSGreg Ungerer | CF_PAGE_READABLE \ 9091521c2eSGreg Ungerer | CF_PAGE_DIRTY) 9191521c2eSGreg Ungerer 9291521c2eSGreg Ungerer #define PTE_MASK PAGE_MASK 9391521c2eSGreg Ungerer #define CF_PAGE_CHG_MASK (PTE_MASK | CF_PAGE_ACCESSED | CF_PAGE_DIRTY) 9491521c2eSGreg Ungerer 9591521c2eSGreg Ungerer #ifndef __ASSEMBLY__ 9691521c2eSGreg Ungerer 971c2f7d14SAnshuman Khandual #define pmd_pgtable(pmd) pfn_to_virt(pmd_val(pmd) >> PAGE_SHIFT) 981c2f7d14SAnshuman Khandual 9991521c2eSGreg Ungerer /* 10091521c2eSGreg Ungerer * Conversion functions: convert a page and protection to a page entry, 10191521c2eSGreg Ungerer * and a page entry and page directory to the page they refer to. 10291521c2eSGreg Ungerer */ 10391521c2eSGreg Ungerer #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) 10491521c2eSGreg Ungerer 10591521c2eSGreg Ungerer static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 10691521c2eSGreg Ungerer { 10791521c2eSGreg Ungerer pte_val(pte) = (pte_val(pte) & CF_PAGE_CHG_MASK) | pgprot_val(newprot); 10891521c2eSGreg Ungerer return pte; 10991521c2eSGreg Ungerer } 11091521c2eSGreg Ungerer 11191521c2eSGreg Ungerer #define pmd_set(pmdp, ptep) do {} while (0) 11291521c2eSGreg Ungerer 11391521c2eSGreg Ungerer static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) 11491521c2eSGreg Ungerer { 11591521c2eSGreg Ungerer pgd_val(*pgdp) = virt_to_phys(pmdp); 11691521c2eSGreg Ungerer } 11791521c2eSGreg Ungerer 1188f246087SLinus Walleij #define __pte_page(pte) ((void *) (pte_val(pte) & PAGE_MASK)) 119974b9b2cSMike Rapoport #define pmd_page_vaddr(pmd) ((unsigned long) (pmd_val(pmd))) 12091521c2eSGreg Ungerer 12191521c2eSGreg Ungerer static inline int pte_none(pte_t pte) 12291521c2eSGreg Ungerer { 12391521c2eSGreg Ungerer return !pte_val(pte); 12491521c2eSGreg Ungerer } 12591521c2eSGreg Ungerer 12691521c2eSGreg Ungerer static inline int pte_present(pte_t pte) 12791521c2eSGreg Ungerer { 12891521c2eSGreg Ungerer return pte_val(pte) & CF_PAGE_VALID; 12991521c2eSGreg Ungerer } 13091521c2eSGreg Ungerer 13191521c2eSGreg Ungerer static inline void pte_clear(struct mm_struct *mm, unsigned long addr, 13291521c2eSGreg Ungerer pte_t *ptep) 13391521c2eSGreg Ungerer { 13491521c2eSGreg Ungerer pte_val(*ptep) = 0; 13591521c2eSGreg Ungerer } 13691521c2eSGreg Ungerer 13791521c2eSGreg Ungerer #define pte_page(pte) virt_to_page(__pte_page(pte)) 13891521c2eSGreg Ungerer 13991521c2eSGreg Ungerer static inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); } 14091521c2eSGreg Ungerer #define pmd_none(pmd) pmd_none2(&(pmd)) 14191521c2eSGreg Ungerer static inline int pmd_bad2(pmd_t *pmd) { return 0; } 14291521c2eSGreg Ungerer #define pmd_bad(pmd) pmd_bad2(&(pmd)) 14391521c2eSGreg Ungerer #define pmd_present(pmd) (!pmd_none2(&(pmd))) 14491521c2eSGreg Ungerer static inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = 0; } 14591521c2eSGreg Ungerer 14691521c2eSGreg Ungerer #define pte_ERROR(e) \ 14791521c2eSGreg Ungerer printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \ 14891521c2eSGreg Ungerer __FILE__, __LINE__, pte_val(e)) 14991521c2eSGreg Ungerer #define pgd_ERROR(e) \ 15091521c2eSGreg Ungerer printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", \ 15191521c2eSGreg Ungerer __FILE__, __LINE__, pgd_val(e)) 15291521c2eSGreg Ungerer 15391521c2eSGreg Ungerer /* 15491521c2eSGreg Ungerer * The following only work if pte_present() is true. 15591521c2eSGreg Ungerer * Undefined behaviour if not... 15691521c2eSGreg Ungerer * [we have the full set here even if they don't change from m68k] 15791521c2eSGreg Ungerer */ 15891521c2eSGreg Ungerer static inline int pte_read(pte_t pte) 15991521c2eSGreg Ungerer { 16091521c2eSGreg Ungerer return pte_val(pte) & CF_PAGE_READABLE; 16191521c2eSGreg Ungerer } 16291521c2eSGreg Ungerer 16391521c2eSGreg Ungerer static inline int pte_write(pte_t pte) 16491521c2eSGreg Ungerer { 16591521c2eSGreg Ungerer return pte_val(pte) & CF_PAGE_WRITABLE; 16691521c2eSGreg Ungerer } 16791521c2eSGreg Ungerer 16891521c2eSGreg Ungerer static inline int pte_exec(pte_t pte) 16991521c2eSGreg Ungerer { 17091521c2eSGreg Ungerer return pte_val(pte) & CF_PAGE_EXEC; 17191521c2eSGreg Ungerer } 17291521c2eSGreg Ungerer 17391521c2eSGreg Ungerer static inline int pte_dirty(pte_t pte) 17491521c2eSGreg Ungerer { 17591521c2eSGreg Ungerer return pte_val(pte) & CF_PAGE_DIRTY; 17691521c2eSGreg Ungerer } 17791521c2eSGreg Ungerer 17891521c2eSGreg Ungerer static inline int pte_young(pte_t pte) 17991521c2eSGreg Ungerer { 18091521c2eSGreg Ungerer return pte_val(pte) & CF_PAGE_ACCESSED; 18191521c2eSGreg Ungerer } 18291521c2eSGreg Ungerer 18391521c2eSGreg Ungerer static inline pte_t pte_wrprotect(pte_t pte) 18491521c2eSGreg Ungerer { 18591521c2eSGreg Ungerer pte_val(pte) &= ~CF_PAGE_WRITABLE; 18691521c2eSGreg Ungerer return pte; 18791521c2eSGreg Ungerer } 18891521c2eSGreg Ungerer 18991521c2eSGreg Ungerer static inline pte_t pte_rdprotect(pte_t pte) 19091521c2eSGreg Ungerer { 19191521c2eSGreg Ungerer pte_val(pte) &= ~CF_PAGE_READABLE; 19291521c2eSGreg Ungerer return pte; 19391521c2eSGreg Ungerer } 19491521c2eSGreg Ungerer 19591521c2eSGreg Ungerer static inline pte_t pte_exprotect(pte_t pte) 19691521c2eSGreg Ungerer { 19791521c2eSGreg Ungerer pte_val(pte) &= ~CF_PAGE_EXEC; 19891521c2eSGreg Ungerer return pte; 19991521c2eSGreg Ungerer } 20091521c2eSGreg Ungerer 20191521c2eSGreg Ungerer static inline pte_t pte_mkclean(pte_t pte) 20291521c2eSGreg Ungerer { 20391521c2eSGreg Ungerer pte_val(pte) &= ~CF_PAGE_DIRTY; 20491521c2eSGreg Ungerer return pte; 20591521c2eSGreg Ungerer } 20691521c2eSGreg Ungerer 20791521c2eSGreg Ungerer static inline pte_t pte_mkold(pte_t pte) 20891521c2eSGreg Ungerer { 20991521c2eSGreg Ungerer pte_val(pte) &= ~CF_PAGE_ACCESSED; 21091521c2eSGreg Ungerer return pte; 21191521c2eSGreg Ungerer } 21291521c2eSGreg Ungerer 21391521c2eSGreg Ungerer static inline pte_t pte_mkwrite(pte_t pte) 21491521c2eSGreg Ungerer { 21591521c2eSGreg Ungerer pte_val(pte) |= CF_PAGE_WRITABLE; 21691521c2eSGreg Ungerer return pte; 21791521c2eSGreg Ungerer } 21891521c2eSGreg Ungerer 21991521c2eSGreg Ungerer static inline pte_t pte_mkread(pte_t pte) 22091521c2eSGreg Ungerer { 22191521c2eSGreg Ungerer pte_val(pte) |= CF_PAGE_READABLE; 22291521c2eSGreg Ungerer return pte; 22391521c2eSGreg Ungerer } 22491521c2eSGreg Ungerer 22591521c2eSGreg Ungerer static inline pte_t pte_mkexec(pte_t pte) 22691521c2eSGreg Ungerer { 22791521c2eSGreg Ungerer pte_val(pte) |= CF_PAGE_EXEC; 22891521c2eSGreg Ungerer return pte; 22991521c2eSGreg Ungerer } 23091521c2eSGreg Ungerer 23191521c2eSGreg Ungerer static inline pte_t pte_mkdirty(pte_t pte) 23291521c2eSGreg Ungerer { 23391521c2eSGreg Ungerer pte_val(pte) |= CF_PAGE_DIRTY; 23491521c2eSGreg Ungerer return pte; 23591521c2eSGreg Ungerer } 23691521c2eSGreg Ungerer 23791521c2eSGreg Ungerer static inline pte_t pte_mkyoung(pte_t pte) 23891521c2eSGreg Ungerer { 23991521c2eSGreg Ungerer pte_val(pte) |= CF_PAGE_ACCESSED; 24091521c2eSGreg Ungerer return pte; 24191521c2eSGreg Ungerer } 24291521c2eSGreg Ungerer 24391521c2eSGreg Ungerer static inline pte_t pte_mknocache(pte_t pte) 24491521c2eSGreg Ungerer { 24591521c2eSGreg Ungerer pte_val(pte) |= 0x80 | (pte_val(pte) & ~0x40); 24691521c2eSGreg Ungerer return pte; 24791521c2eSGreg Ungerer } 24891521c2eSGreg Ungerer 24991521c2eSGreg Ungerer static inline pte_t pte_mkcache(pte_t pte) 25091521c2eSGreg Ungerer { 25191521c2eSGreg Ungerer pte_val(pte) &= ~CF_PAGE_NOCACHE; 25291521c2eSGreg Ungerer return pte; 25391521c2eSGreg Ungerer } 25491521c2eSGreg Ungerer 25591521c2eSGreg Ungerer #define swapper_pg_dir kernel_pg_dir 25691521c2eSGreg Ungerer extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; 25791521c2eSGreg Ungerer 25891521c2eSGreg Ungerer /* 259ed415406SDavid Hildenbrand * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that 260ed415406SDavid Hildenbrand * are !pte_none() && !pte_present(). 261ed415406SDavid Hildenbrand * 262ed415406SDavid Hildenbrand * Format of swap PTEs: 263ed415406SDavid Hildenbrand * 264ed415406SDavid Hildenbrand * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 265ed415406SDavid Hildenbrand * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 266ed415406SDavid Hildenbrand * <------------------ offset -------------> 0 0 0 E <-- type ---> 267ed415406SDavid Hildenbrand * 268ed415406SDavid Hildenbrand * E is the exclusive marker that is not stored in swap entries. 26991521c2eSGreg Ungerer */ 270ed415406SDavid Hildenbrand #define __swp_type(x) ((x).val & 0x7f) 2711eeda0abSKirill A. Shutemov #define __swp_offset(x) ((x).val >> 11) 272ed415406SDavid Hildenbrand #define __swp_entry(typ, off) ((swp_entry_t) { ((typ) & 0x7f) | \ 2731eeda0abSKirill A. Shutemov (off << 11) }) 27491521c2eSGreg Ungerer #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) 27591521c2eSGreg Ungerer #define __swp_entry_to_pte(x) (__pte((x).val)) 27691521c2eSGreg Ungerer 277ed415406SDavid Hildenbrand static inline int pte_swp_exclusive(pte_t pte) 278ed415406SDavid Hildenbrand { 279ed415406SDavid Hildenbrand return pte_val(pte) & _PAGE_SWP_EXCLUSIVE; 280ed415406SDavid Hildenbrand } 281ed415406SDavid Hildenbrand 282ed415406SDavid Hildenbrand static inline pte_t pte_swp_mkexclusive(pte_t pte) 283ed415406SDavid Hildenbrand { 284ed415406SDavid Hildenbrand pte_val(pte) |= _PAGE_SWP_EXCLUSIVE; 285ed415406SDavid Hildenbrand return pte; 286ed415406SDavid Hildenbrand } 287ed415406SDavid Hildenbrand 288ed415406SDavid Hildenbrand static inline pte_t pte_swp_clear_exclusive(pte_t pte) 289ed415406SDavid Hildenbrand { 290ed415406SDavid Hildenbrand pte_val(pte) &= ~_PAGE_SWP_EXCLUSIVE; 291ed415406SDavid Hildenbrand return pte; 292ed415406SDavid Hildenbrand } 293ed415406SDavid Hildenbrand 294*5553b15aSMatthew Wilcox (Oracle) #define PFN_PTE_SHIFT PAGE_SHIFT 2957106c51eSMike Rapoport #define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT) 29691521c2eSGreg Ungerer #define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) 29791521c2eSGreg Ungerer 29891521c2eSGreg Ungerer #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) 29991521c2eSGreg Ungerer #define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) 30091521c2eSGreg Ungerer 30191521c2eSGreg Ungerer #endif /* !__ASSEMBLY__ */ 30291521c2eSGreg Ungerer #endif /* _MCF_PGTABLE_H */ 303