xref: /linux/arch/m68k/include/asm/mcf_pgtable.h (revision d59fec29b131f30b27343d54bdf1071ee98eda8e)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _MCF_PGTABLE_H
3 #define _MCF_PGTABLE_H
4 
5 #include <asm/mcfmmu.h>
6 #include <asm/page.h>
7 
8 /*
9  * MMUDR bits, in proper place. We write these directly into the MMUDR
10  * after masking from the pte.
11  */
12 #define CF_PAGE_LOCKED		MMUDR_LK	/* 0x00000002 */
13 #define CF_PAGE_EXEC		MMUDR_X		/* 0x00000004 */
14 #define CF_PAGE_WRITABLE	MMUDR_W		/* 0x00000008 */
15 #define CF_PAGE_READABLE	MMUDR_R		/* 0x00000010 */
16 #define CF_PAGE_SYSTEM		MMUDR_SP	/* 0x00000020 */
17 #define CF_PAGE_COPYBACK	MMUDR_CM_CCB	/* 0x00000040 */
18 #define CF_PAGE_NOCACHE		MMUDR_CM_NCP	/* 0x00000080 */
19 
20 #define CF_CACHEMASK		(~MMUDR_CM_CCB)
21 #define CF_PAGE_MMUDR_MASK	0x000000fe
22 
23 #define _PAGE_NOCACHE030	CF_PAGE_NOCACHE
24 
25 /*
26  * MMUTR bits, need shifting down.
27  */
28 #define CF_PAGE_MMUTR_MASK	0x00000c00
29 #define CF_PAGE_MMUTR_SHIFT	10
30 
31 #define CF_PAGE_VALID		(MMUTR_V << CF_PAGE_MMUTR_SHIFT)
32 #define CF_PAGE_SHARED		(MMUTR_SG << CF_PAGE_MMUTR_SHIFT)
33 
34 /*
35  * Fake bits, not implemented in CF, will get masked out before
36  * hitting hardware.
37  */
38 #define CF_PAGE_DIRTY		0x00000001
39 #define CF_PAGE_ACCESSED	0x00001000
40 
41 #define _PAGE_CACHE040		0x020   /* 68040 cache mode, cachable, copyback */
42 #define _PAGE_NOCACHE_S		0x040   /* 68040 no-cache mode, serialized */
43 #define _PAGE_NOCACHE		0x060   /* 68040 cache mode, non-serialized */
44 #define _PAGE_CACHE040W		0x000   /* 68040 cache mode, cachable, write-through */
45 #define _DESCTYPE_MASK		0x003
46 #define _CACHEMASK040		(~0x060)
47 #define _PAGE_GLOBAL040		0x400   /* 68040 global bit, used for kva descs */
48 
49 /* We borrow bit 7 to store the exclusive marker in swap PTEs. */
50 #define _PAGE_SWP_EXCLUSIVE	CF_PAGE_NOCACHE
51 
52 /*
53  * Externally used page protection values.
54  */
55 #define _PAGE_PRESENT	(CF_PAGE_VALID)
56 #define _PAGE_ACCESSED	(CF_PAGE_ACCESSED)
57 #define _PAGE_DIRTY	(CF_PAGE_DIRTY)
58 #define _PAGE_READWRITE (CF_PAGE_READABLE \
59 				| CF_PAGE_WRITABLE \
60 				| CF_PAGE_SYSTEM \
61 				| CF_PAGE_SHARED)
62 
63 /*
64  * Compound page protection values.
65  */
66 #define PAGE_NONE	__pgprot(CF_PAGE_VALID \
67 				 | CF_PAGE_ACCESSED)
68 
69 #define PAGE_SHARED     __pgprot(CF_PAGE_VALID \
70 				 | CF_PAGE_ACCESSED \
71 				 | CF_PAGE_SHARED)
72 
73 #define PAGE_INIT	__pgprot(CF_PAGE_VALID \
74 				 | CF_PAGE_READABLE \
75 				 | CF_PAGE_WRITABLE \
76 				 | CF_PAGE_EXEC \
77 				 | CF_PAGE_SYSTEM)
78 
79 #define PAGE_KERNEL	__pgprot(CF_PAGE_VALID \
80 				 | CF_PAGE_ACCESSED \
81 				 | CF_PAGE_READABLE \
82 				 | CF_PAGE_WRITABLE \
83 				 | CF_PAGE_EXEC \
84 				 | CF_PAGE_SYSTEM \
85 				 | CF_PAGE_SHARED)
86 
87 #define PAGE_COPY	__pgprot(CF_PAGE_VALID \
88 				 | CF_PAGE_ACCESSED \
89 				 | CF_PAGE_READABLE \
90 				 | CF_PAGE_DIRTY)
91 
92 #define PTE_MASK	PAGE_MASK
93 #define CF_PAGE_CHG_MASK (PTE_MASK | CF_PAGE_ACCESSED | CF_PAGE_DIRTY)
94 
95 #ifndef __ASSEMBLY__
96 
97 #define pmd_pgtable(pmd) pfn_to_virt(pmd_val(pmd) >> PAGE_SHIFT)
98 
99 /*
100  * Conversion functions: convert a page and protection to a page entry,
101  * and a page entry and page directory to the page they refer to.
102  */
103 #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
104 
105 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
106 {
107 	pte_val(pte) = (pte_val(pte) & CF_PAGE_CHG_MASK) | pgprot_val(newprot);
108 	return pte;
109 }
110 
111 #define pmd_set(pmdp, ptep) do {} while (0)
112 
113 static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp)
114 {
115 	pgd_val(*pgdp) = virt_to_phys(pmdp);
116 }
117 
118 #define __pte_page(pte)	((unsigned long) (pte_val(pte) & PAGE_MASK))
119 #define pmd_page_vaddr(pmd)	((unsigned long) (pmd_val(pmd)))
120 
121 static inline int pte_none(pte_t pte)
122 {
123 	return !pte_val(pte);
124 }
125 
126 static inline int pte_present(pte_t pte)
127 {
128 	return pte_val(pte) & CF_PAGE_VALID;
129 }
130 
131 static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
132 	pte_t *ptep)
133 {
134 	pte_val(*ptep) = 0;
135 }
136 
137 #define pte_pagenr(pte)	((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
138 #define pte_page(pte)	virt_to_page(__pte_page(pte))
139 
140 static inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); }
141 #define pmd_none(pmd) pmd_none2(&(pmd))
142 static inline int pmd_bad2(pmd_t *pmd) { return 0; }
143 #define pmd_bad(pmd) pmd_bad2(&(pmd))
144 #define pmd_present(pmd) (!pmd_none2(&(pmd)))
145 static inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = 0; }
146 
147 #define pte_ERROR(e) \
148 	printk(KERN_ERR "%s:%d: bad pte %08lx.\n",	\
149 	__FILE__, __LINE__, pte_val(e))
150 #define pgd_ERROR(e) \
151 	printk(KERN_ERR "%s:%d: bad pgd %08lx.\n",	\
152 	__FILE__, __LINE__, pgd_val(e))
153 
154 /*
155  * The following only work if pte_present() is true.
156  * Undefined behaviour if not...
157  * [we have the full set here even if they don't change from m68k]
158  */
159 static inline int pte_read(pte_t pte)
160 {
161 	return pte_val(pte) & CF_PAGE_READABLE;
162 }
163 
164 static inline int pte_write(pte_t pte)
165 {
166 	return pte_val(pte) & CF_PAGE_WRITABLE;
167 }
168 
169 static inline int pte_exec(pte_t pte)
170 {
171 	return pte_val(pte) & CF_PAGE_EXEC;
172 }
173 
174 static inline int pte_dirty(pte_t pte)
175 {
176 	return pte_val(pte) & CF_PAGE_DIRTY;
177 }
178 
179 static inline int pte_young(pte_t pte)
180 {
181 	return pte_val(pte) & CF_PAGE_ACCESSED;
182 }
183 
184 static inline pte_t pte_wrprotect(pte_t pte)
185 {
186 	pte_val(pte) &= ~CF_PAGE_WRITABLE;
187 	return pte;
188 }
189 
190 static inline pte_t pte_rdprotect(pte_t pte)
191 {
192 	pte_val(pte) &= ~CF_PAGE_READABLE;
193 	return pte;
194 }
195 
196 static inline pte_t pte_exprotect(pte_t pte)
197 {
198 	pte_val(pte) &= ~CF_PAGE_EXEC;
199 	return pte;
200 }
201 
202 static inline pte_t pte_mkclean(pte_t pte)
203 {
204 	pte_val(pte) &= ~CF_PAGE_DIRTY;
205 	return pte;
206 }
207 
208 static inline pte_t pte_mkold(pte_t pte)
209 {
210 	pte_val(pte) &= ~CF_PAGE_ACCESSED;
211 	return pte;
212 }
213 
214 static inline pte_t pte_mkwrite(pte_t pte)
215 {
216 	pte_val(pte) |= CF_PAGE_WRITABLE;
217 	return pte;
218 }
219 
220 static inline pte_t pte_mkread(pte_t pte)
221 {
222 	pte_val(pte) |= CF_PAGE_READABLE;
223 	return pte;
224 }
225 
226 static inline pte_t pte_mkexec(pte_t pte)
227 {
228 	pte_val(pte) |= CF_PAGE_EXEC;
229 	return pte;
230 }
231 
232 static inline pte_t pte_mkdirty(pte_t pte)
233 {
234 	pte_val(pte) |= CF_PAGE_DIRTY;
235 	return pte;
236 }
237 
238 static inline pte_t pte_mkyoung(pte_t pte)
239 {
240 	pte_val(pte) |= CF_PAGE_ACCESSED;
241 	return pte;
242 }
243 
244 static inline pte_t pte_mknocache(pte_t pte)
245 {
246 	pte_val(pte) |= 0x80 | (pte_val(pte) & ~0x40);
247 	return pte;
248 }
249 
250 static inline pte_t pte_mkcache(pte_t pte)
251 {
252 	pte_val(pte) &= ~CF_PAGE_NOCACHE;
253 	return pte;
254 }
255 
256 #define swapper_pg_dir kernel_pg_dir
257 extern pgd_t kernel_pg_dir[PTRS_PER_PGD];
258 
259 /*
260  * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that
261  * are !pte_none() && !pte_present().
262  *
263  * Format of swap PTEs:
264  *
265  *   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
266  *   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
267  *   <------------------ offset -------------> 0 0 0 E <-- type --->
268  *
269  *   E is the exclusive marker that is not stored in swap entries.
270  */
271 #define __swp_type(x)		((x).val & 0x7f)
272 #define __swp_offset(x)		((x).val >> 11)
273 #define __swp_entry(typ, off)	((swp_entry_t) { ((typ) & 0x7f) | \
274 					(off << 11) })
275 #define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
276 #define __swp_entry_to_pte(x)	(__pte((x).val))
277 
278 static inline int pte_swp_exclusive(pte_t pte)
279 {
280 	return pte_val(pte) & _PAGE_SWP_EXCLUSIVE;
281 }
282 
283 static inline pte_t pte_swp_mkexclusive(pte_t pte)
284 {
285 	pte_val(pte) |= _PAGE_SWP_EXCLUSIVE;
286 	return pte;
287 }
288 
289 static inline pte_t pte_swp_clear_exclusive(pte_t pte)
290 {
291 	pte_val(pte) &= ~_PAGE_SWP_EXCLUSIVE;
292 	return pte;
293 }
294 
295 #define pmd_pfn(pmd)		(pmd_val(pmd) >> PAGE_SHIFT)
296 #define pmd_page(pmd)		(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
297 
298 #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
299 #define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
300 
301 #endif	/* !__ASSEMBLY__ */
302 #endif	/* _MCF_PGTABLE_H */
303