162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _MCF_PGTABLE_H 362306a36Sopenharmony_ci#define _MCF_PGTABLE_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <asm/mcfmmu.h> 662306a36Sopenharmony_ci#include <asm/page.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci/* 962306a36Sopenharmony_ci * MMUDR bits, in proper place. We write these directly into the MMUDR 1062306a36Sopenharmony_ci * after masking from the pte. 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci#define CF_PAGE_LOCKED MMUDR_LK /* 0x00000002 */ 1362306a36Sopenharmony_ci#define CF_PAGE_EXEC MMUDR_X /* 0x00000004 */ 1462306a36Sopenharmony_ci#define CF_PAGE_WRITABLE MMUDR_W /* 0x00000008 */ 1562306a36Sopenharmony_ci#define CF_PAGE_READABLE MMUDR_R /* 0x00000010 */ 1662306a36Sopenharmony_ci#define CF_PAGE_SYSTEM MMUDR_SP /* 0x00000020 */ 1762306a36Sopenharmony_ci#define CF_PAGE_COPYBACK MMUDR_CM_CCB /* 0x00000040 */ 1862306a36Sopenharmony_ci#define CF_PAGE_NOCACHE MMUDR_CM_NCP /* 0x00000080 */ 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define CF_CACHEMASK (~MMUDR_CM_CCB) 2162306a36Sopenharmony_ci#define CF_PAGE_MMUDR_MASK 0x000000fe 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#define _PAGE_NOCACHE030 CF_PAGE_NOCACHE 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* 2662306a36Sopenharmony_ci * MMUTR bits, need shifting down. 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ci#define CF_PAGE_MMUTR_MASK 0x00000c00 2962306a36Sopenharmony_ci#define CF_PAGE_MMUTR_SHIFT 10 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define CF_PAGE_VALID (MMUTR_V << CF_PAGE_MMUTR_SHIFT) 3262306a36Sopenharmony_ci#define CF_PAGE_SHARED (MMUTR_SG << CF_PAGE_MMUTR_SHIFT) 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci/* 3562306a36Sopenharmony_ci * Fake bits, not implemented in CF, will get masked out before 3662306a36Sopenharmony_ci * hitting hardware. 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_ci#define CF_PAGE_DIRTY 0x00000001 3962306a36Sopenharmony_ci#define CF_PAGE_ACCESSED 0x00001000 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#define _PAGE_CACHE040 0x020 /* 68040 cache mode, cachable, copyback */ 4262306a36Sopenharmony_ci#define _PAGE_NOCACHE_S 0x040 /* 68040 no-cache mode, serialized */ 4362306a36Sopenharmony_ci#define _PAGE_NOCACHE 0x060 /* 68040 cache mode, non-serialized */ 4462306a36Sopenharmony_ci#define _PAGE_CACHE040W 0x000 /* 68040 cache mode, cachable, write-through */ 4562306a36Sopenharmony_ci#define _DESCTYPE_MASK 0x003 4662306a36Sopenharmony_ci#define _CACHEMASK040 (~0x060) 4762306a36Sopenharmony_ci#define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */ 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/* We borrow bit 7 to store the exclusive marker in swap PTEs. */ 5062306a36Sopenharmony_ci#define _PAGE_SWP_EXCLUSIVE CF_PAGE_NOCACHE 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/* 5362306a36Sopenharmony_ci * Externally used page protection values. 5462306a36Sopenharmony_ci */ 5562306a36Sopenharmony_ci#define _PAGE_PRESENT (CF_PAGE_VALID) 5662306a36Sopenharmony_ci#define _PAGE_ACCESSED (CF_PAGE_ACCESSED) 5762306a36Sopenharmony_ci#define _PAGE_DIRTY (CF_PAGE_DIRTY) 5862306a36Sopenharmony_ci#define _PAGE_READWRITE (CF_PAGE_READABLE \ 5962306a36Sopenharmony_ci | CF_PAGE_WRITABLE \ 6062306a36Sopenharmony_ci | CF_PAGE_SYSTEM \ 6162306a36Sopenharmony_ci | CF_PAGE_SHARED) 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci/* 6462306a36Sopenharmony_ci * Compound page protection values. 6562306a36Sopenharmony_ci */ 6662306a36Sopenharmony_ci#define PAGE_NONE __pgprot(CF_PAGE_VALID \ 6762306a36Sopenharmony_ci | CF_PAGE_ACCESSED) 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci#define PAGE_SHARED __pgprot(CF_PAGE_VALID \ 7062306a36Sopenharmony_ci | CF_PAGE_ACCESSED \ 7162306a36Sopenharmony_ci | CF_PAGE_SHARED) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci#define PAGE_INIT __pgprot(CF_PAGE_VALID \ 7462306a36Sopenharmony_ci | CF_PAGE_READABLE \ 7562306a36Sopenharmony_ci | CF_PAGE_WRITABLE \ 7662306a36Sopenharmony_ci | CF_PAGE_EXEC \ 7762306a36Sopenharmony_ci | CF_PAGE_SYSTEM) 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci#define PAGE_KERNEL __pgprot(CF_PAGE_VALID \ 8062306a36Sopenharmony_ci | CF_PAGE_ACCESSED \ 8162306a36Sopenharmony_ci | CF_PAGE_READABLE \ 8262306a36Sopenharmony_ci | CF_PAGE_WRITABLE \ 8362306a36Sopenharmony_ci | CF_PAGE_EXEC \ 8462306a36Sopenharmony_ci | CF_PAGE_SYSTEM \ 8562306a36Sopenharmony_ci | CF_PAGE_SHARED) 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci#define PAGE_COPY __pgprot(CF_PAGE_VALID \ 8862306a36Sopenharmony_ci | CF_PAGE_ACCESSED \ 8962306a36Sopenharmony_ci | CF_PAGE_READABLE \ 9062306a36Sopenharmony_ci | CF_PAGE_DIRTY) 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#define PTE_MASK PAGE_MASK 9362306a36Sopenharmony_ci#define CF_PAGE_CHG_MASK (PTE_MASK | CF_PAGE_ACCESSED | CF_PAGE_DIRTY) 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci#define pmd_pgtable(pmd) pfn_to_virt(pmd_val(pmd) >> PAGE_SHIFT) 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci/* 10062306a36Sopenharmony_ci * Conversion functions: convert a page and protection to a page entry, 10162306a36Sopenharmony_ci * and a page entry and page directory to the page they refer to. 10262306a36Sopenharmony_ci */ 10362306a36Sopenharmony_ci#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistatic inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 10662306a36Sopenharmony_ci{ 10762306a36Sopenharmony_ci pte_val(pte) = (pte_val(pte) & CF_PAGE_CHG_MASK) | pgprot_val(newprot); 10862306a36Sopenharmony_ci return pte; 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci#define pmd_set(pmdp, ptep) do {} while (0) 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_cistatic inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci pgd_val(*pgdp) = virt_to_phys(pmdp); 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci#define __pte_page(pte) ((void *) (pte_val(pte) & PAGE_MASK)) 11962306a36Sopenharmony_ci#define pmd_page_vaddr(pmd) ((unsigned long) (pmd_val(pmd))) 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic inline int pte_none(pte_t pte) 12262306a36Sopenharmony_ci{ 12362306a36Sopenharmony_ci return !pte_val(pte); 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic inline int pte_present(pte_t pte) 12762306a36Sopenharmony_ci{ 12862306a36Sopenharmony_ci return pte_val(pte) & CF_PAGE_VALID; 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic inline void pte_clear(struct mm_struct *mm, unsigned long addr, 13262306a36Sopenharmony_ci pte_t *ptep) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci pte_val(*ptep) = 0; 13562306a36Sopenharmony_ci} 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci#define pte_page(pte) virt_to_page(__pte_page(pte)) 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistatic inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); } 14062306a36Sopenharmony_ci#define pmd_none(pmd) pmd_none2(&(pmd)) 14162306a36Sopenharmony_cistatic inline int pmd_bad2(pmd_t *pmd) { return 0; } 14262306a36Sopenharmony_ci#define pmd_bad(pmd) pmd_bad2(&(pmd)) 14362306a36Sopenharmony_ci#define pmd_present(pmd) (!pmd_none2(&(pmd))) 14462306a36Sopenharmony_cistatic inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = 0; } 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci#define pte_ERROR(e) \ 14762306a36Sopenharmony_ci printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \ 14862306a36Sopenharmony_ci __FILE__, __LINE__, pte_val(e)) 14962306a36Sopenharmony_ci#define pgd_ERROR(e) \ 15062306a36Sopenharmony_ci printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", \ 15162306a36Sopenharmony_ci __FILE__, __LINE__, pgd_val(e)) 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci/* 15462306a36Sopenharmony_ci * The following only work if pte_present() is true. 15562306a36Sopenharmony_ci * Undefined behaviour if not... 15662306a36Sopenharmony_ci * [we have the full set here even if they don't change from m68k] 15762306a36Sopenharmony_ci */ 15862306a36Sopenharmony_cistatic inline int pte_read(pte_t pte) 15962306a36Sopenharmony_ci{ 16062306a36Sopenharmony_ci return pte_val(pte) & CF_PAGE_READABLE; 16162306a36Sopenharmony_ci} 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistatic inline int pte_write(pte_t pte) 16462306a36Sopenharmony_ci{ 16562306a36Sopenharmony_ci return pte_val(pte) & CF_PAGE_WRITABLE; 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_cistatic inline int pte_exec(pte_t pte) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci return pte_val(pte) & CF_PAGE_EXEC; 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_cistatic inline int pte_dirty(pte_t pte) 17462306a36Sopenharmony_ci{ 17562306a36Sopenharmony_ci return pte_val(pte) & CF_PAGE_DIRTY; 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistatic inline int pte_young(pte_t pte) 17962306a36Sopenharmony_ci{ 18062306a36Sopenharmony_ci return pte_val(pte) & CF_PAGE_ACCESSED; 18162306a36Sopenharmony_ci} 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_cistatic inline pte_t pte_wrprotect(pte_t pte) 18462306a36Sopenharmony_ci{ 18562306a36Sopenharmony_ci pte_val(pte) &= ~CF_PAGE_WRITABLE; 18662306a36Sopenharmony_ci return pte; 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistatic inline pte_t pte_rdprotect(pte_t pte) 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci pte_val(pte) &= ~CF_PAGE_READABLE; 19262306a36Sopenharmony_ci return pte; 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistatic inline pte_t pte_exprotect(pte_t pte) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci pte_val(pte) &= ~CF_PAGE_EXEC; 19862306a36Sopenharmony_ci return pte; 19962306a36Sopenharmony_ci} 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_cistatic inline pte_t pte_mkclean(pte_t pte) 20262306a36Sopenharmony_ci{ 20362306a36Sopenharmony_ci pte_val(pte) &= ~CF_PAGE_DIRTY; 20462306a36Sopenharmony_ci return pte; 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistatic inline pte_t pte_mkold(pte_t pte) 20862306a36Sopenharmony_ci{ 20962306a36Sopenharmony_ci pte_val(pte) &= ~CF_PAGE_ACCESSED; 21062306a36Sopenharmony_ci return pte; 21162306a36Sopenharmony_ci} 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_cistatic inline pte_t pte_mkwrite_novma(pte_t pte) 21462306a36Sopenharmony_ci{ 21562306a36Sopenharmony_ci pte_val(pte) |= CF_PAGE_WRITABLE; 21662306a36Sopenharmony_ci return pte; 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistatic inline pte_t pte_mkread(pte_t pte) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci pte_val(pte) |= CF_PAGE_READABLE; 22262306a36Sopenharmony_ci return pte; 22362306a36Sopenharmony_ci} 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_cistatic inline pte_t pte_mkexec(pte_t pte) 22662306a36Sopenharmony_ci{ 22762306a36Sopenharmony_ci pte_val(pte) |= CF_PAGE_EXEC; 22862306a36Sopenharmony_ci return pte; 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cistatic inline pte_t pte_mkdirty(pte_t pte) 23262306a36Sopenharmony_ci{ 23362306a36Sopenharmony_ci pte_val(pte) |= CF_PAGE_DIRTY; 23462306a36Sopenharmony_ci return pte; 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic inline pte_t pte_mkyoung(pte_t pte) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci pte_val(pte) |= CF_PAGE_ACCESSED; 24062306a36Sopenharmony_ci return pte; 24162306a36Sopenharmony_ci} 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_cistatic inline pte_t pte_mknocache(pte_t pte) 24462306a36Sopenharmony_ci{ 24562306a36Sopenharmony_ci pte_val(pte) |= 0x80 | (pte_val(pte) & ~0x40); 24662306a36Sopenharmony_ci return pte; 24762306a36Sopenharmony_ci} 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_cistatic inline pte_t pte_mkcache(pte_t pte) 25062306a36Sopenharmony_ci{ 25162306a36Sopenharmony_ci pte_val(pte) &= ~CF_PAGE_NOCACHE; 25262306a36Sopenharmony_ci return pte; 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci#define swapper_pg_dir kernel_pg_dir 25662306a36Sopenharmony_ciextern pgd_t kernel_pg_dir[PTRS_PER_PGD]; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci/* 25962306a36Sopenharmony_ci * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that 26062306a36Sopenharmony_ci * are !pte_none() && !pte_present(). 26162306a36Sopenharmony_ci * 26262306a36Sopenharmony_ci * Format of swap PTEs: 26362306a36Sopenharmony_ci * 26462306a36Sopenharmony_ci * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 26562306a36Sopenharmony_ci * 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 26662306a36Sopenharmony_ci * <------------------ offset -------------> 0 0 0 E <-- type ---> 26762306a36Sopenharmony_ci * 26862306a36Sopenharmony_ci * E is the exclusive marker that is not stored in swap entries. 26962306a36Sopenharmony_ci */ 27062306a36Sopenharmony_ci#define __swp_type(x) ((x).val & 0x7f) 27162306a36Sopenharmony_ci#define __swp_offset(x) ((x).val >> 11) 27262306a36Sopenharmony_ci#define __swp_entry(typ, off) ((swp_entry_t) { ((typ) & 0x7f) | \ 27362306a36Sopenharmony_ci (off << 11) }) 27462306a36Sopenharmony_ci#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) 27562306a36Sopenharmony_ci#define __swp_entry_to_pte(x) (__pte((x).val)) 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_cistatic inline int pte_swp_exclusive(pte_t pte) 27862306a36Sopenharmony_ci{ 27962306a36Sopenharmony_ci return pte_val(pte) & _PAGE_SWP_EXCLUSIVE; 28062306a36Sopenharmony_ci} 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_cistatic inline pte_t pte_swp_mkexclusive(pte_t pte) 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci pte_val(pte) |= _PAGE_SWP_EXCLUSIVE; 28562306a36Sopenharmony_ci return pte; 28662306a36Sopenharmony_ci} 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_cistatic inline pte_t pte_swp_clear_exclusive(pte_t pte) 28962306a36Sopenharmony_ci{ 29062306a36Sopenharmony_ci pte_val(pte) &= ~_PAGE_SWP_EXCLUSIVE; 29162306a36Sopenharmony_ci return pte; 29262306a36Sopenharmony_ci} 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci#define PFN_PTE_SHIFT PAGE_SHIFT 29562306a36Sopenharmony_ci#define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT) 29662306a36Sopenharmony_ci#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) 29962306a36Sopenharmony_ci#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 30262306a36Sopenharmony_ci#endif /* _MCF_PGTABLE_H */ 303