xref: /linux/arch/m68k/include/asm/mcf_pgtable.h (revision 5553b15a)
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 
pte_modify(pte_t pte,pgprot_t newprot)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 
pgd_set(pgd_t * pgdp,pmd_t * pmdp)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 
pte_none(pte_t pte)12191521c2eSGreg Ungerer static inline int pte_none(pte_t pte)
12291521c2eSGreg Ungerer {
12391521c2eSGreg Ungerer 	return !pte_val(pte);
12491521c2eSGreg Ungerer }
12591521c2eSGreg Ungerer 
pte_present(pte_t pte)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 
pte_clear(struct mm_struct * mm,unsigned long addr,pte_t * ptep)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 
pmd_none2(pmd_t * pmd)13991521c2eSGreg Ungerer static inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); }
14091521c2eSGreg Ungerer #define pmd_none(pmd) pmd_none2(&(pmd))
pmd_bad2(pmd_t * 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)))
pmd_clear(pmd_t * pmdp)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  */
pte_read(pte_t pte)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 
pte_write(pte_t pte)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 
pte_exec(pte_t pte)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 
pte_dirty(pte_t pte)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 
pte_young(pte_t pte)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 
pte_wrprotect(pte_t pte)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 
pte_rdprotect(pte_t pte)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 
pte_exprotect(pte_t pte)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 
pte_mkclean(pte_t pte)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 
pte_mkold(pte_t pte)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 
pte_mkwrite_novma(pte_t pte)21391521c2eSGreg Ungerer static inline pte_t pte_mkwrite_novma(pte_t pte)
21491521c2eSGreg Ungerer {
21591521c2eSGreg Ungerer 	pte_val(pte) |= CF_PAGE_WRITABLE;
21691521c2eSGreg Ungerer 	return pte;
21791521c2eSGreg Ungerer }
21891521c2eSGreg Ungerer 
pte_mkread(pte_t pte)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 
pte_mkexec(pte_t pte)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 
pte_mkdirty(pte_t pte)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 
pte_mkyoung(pte_t pte)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 
pte_mknocache(pte_t pte)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 
pte_mkcache(pte_t pte)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 
pte_swp_exclusive(pte_t pte)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 
pte_swp_mkexclusive(pte_t pte)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 
pte_swp_clear_exclusive(pte_t pte)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