1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020 Loongson Technology Corporation Limited
4  */
5 #ifndef _ASM_PGTABLE_BITS_H
6 #define _ASM_PGTABLE_BITS_H
7 
8 /* Page table bits */
9 #define	_PAGE_VALID_SHIFT	0
10 #define	_PAGE_ACCESSED_SHIFT	0  /* Reuse Valid for Accessed */
11 #define	_PAGE_DIRTY_SHIFT	1
12 #define	_PAGE_PLV_SHIFT		2  /* 2~3, two bits */
13 #define	_CACHE_SHIFT 		4  /* 4~5, two bits */
14 #define	_PAGE_GLOBAL_SHIFT 	6
15 #define	_PAGE_HUGE_SHIFT	6  /* HUGE is a PMD bit */
16 #define	_PAGE_PRESENT_SHIFT	7
17 #define	_PAGE_WRITE_SHIFT	8
18 #define	_PAGE_MODIFIED_SHIFT 	9
19 #define	_PAGE_PROTNONE_SHIFT 	10
20 #define	_PAGE_SPECIAL_SHIFT 	11
21 #define	_PAGE_HGLOBAL_SHIFT 	12 /* HGlobal is a PMD bit */
22 #define	_PAGE_PFN_SHIFT 	12
23 #define	_PAGE_PFN_END_SHIFT 	48
24 #define	_PAGE_PRESENT_INVALID_SHIFT 60
25 #define	_PAGE_NO_READ_SHIFT 	61
26 #define	_PAGE_NO_EXEC_SHIFT 	62
27 #define	_PAGE_RPLV_SHIFT 	63
28 
29 /* Used by software */
30 #define _PAGE_PRESENT		(_ULCAST_(1) << _PAGE_PRESENT_SHIFT)
31 #define _PAGE_PRESENT_INVALID	(_ULCAST_(1) << _PAGE_PRESENT_INVALID_SHIFT)
32 #define _PAGE_WRITE		(_ULCAST_(1) << _PAGE_WRITE_SHIFT)
33 #define _PAGE_ACCESSED		(_ULCAST_(1) << _PAGE_ACCESSED_SHIFT)
34 #define _PAGE_MODIFIED		(_ULCAST_(1) << _PAGE_MODIFIED_SHIFT)
35 #define _PAGE_PROTNONE		(_ULCAST_(1) << _PAGE_PROTNONE_SHIFT)
36 #define _PAGE_SPECIAL		(_ULCAST_(1) << _PAGE_SPECIAL_SHIFT)
37 
38 /* Used by TLB hardware (placed in EntryLo*) */
39 #define _PAGE_VALID		(_ULCAST_(1) << _PAGE_VALID_SHIFT)
40 #define _PAGE_DIRTY		(_ULCAST_(1) << _PAGE_DIRTY_SHIFT)
41 #define _PAGE_PLV		(_ULCAST_(3) << _PAGE_PLV_SHIFT)
42 #define _PAGE_GLOBAL		(_ULCAST_(1) << _PAGE_GLOBAL_SHIFT)
43 #define _PAGE_HUGE		(_ULCAST_(1) << _PAGE_HUGE_SHIFT)
44 #define _PAGE_HGLOBAL		(_ULCAST_(1) << _PAGE_HGLOBAL_SHIFT)
45 #define _PAGE_NO_READ		(_ULCAST_(1) << _PAGE_NO_READ_SHIFT)
46 #define _PAGE_NO_EXEC		(_ULCAST_(1) << _PAGE_NO_EXEC_SHIFT)
47 #define _PAGE_RPLV		(_ULCAST_(1) << _PAGE_RPLV_SHIFT)
48 #define _CACHE_MASK		(_ULCAST_(3) << _CACHE_SHIFT)
49 #define _PFN_SHIFT		(PAGE_SHIFT - 12 + _PAGE_PFN_SHIFT)
50 
51 #define _PAGE_USER	(PLV_USER << _PAGE_PLV_SHIFT)
52 #define _PAGE_KERN	(PLV_KERN << _PAGE_PLV_SHIFT)
53 
54 #define _PFN_MASK (~((_ULCAST_(1) << (_PFN_SHIFT)) - 1) & \
55 		  ((_ULCAST_(1) << (_PAGE_PFN_END_SHIFT)) - 1))
56 
57 /*
58  * Cache attributes
59  */
60 #ifndef _CACHE_SUC
61 #define _CACHE_SUC			(0<<_CACHE_SHIFT) /* Strong-ordered UnCached */
62 #endif
63 #ifndef _CACHE_CC
64 #define _CACHE_CC			(1<<_CACHE_SHIFT) /* Coherent Cached */
65 #endif
66 #ifndef _CACHE_WUC
67 #define _CACHE_WUC			(2<<_CACHE_SHIFT) /* Weak-ordered UnCached */
68 #endif
69 
70 #define __READABLE	(_PAGE_VALID)
71 #define __WRITEABLE	(_PAGE_DIRTY | _PAGE_WRITE)
72 
73 #define _PAGE_CHG_MASK	(_PAGE_MODIFIED | _PAGE_SPECIAL | _PFN_MASK | _CACHE_MASK | _PAGE_PLV)
74 #define _HPAGE_CHG_MASK	(_PAGE_MODIFIED | _PAGE_SPECIAL | _PFN_MASK | _CACHE_MASK | _PAGE_PLV | _PAGE_HUGE)
75 
76 #define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_NO_READ | \
77 				 _PAGE_USER | _CACHE_CC)
78 #define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
79 				 _PAGE_USER | _CACHE_CC)
80 #define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _CACHE_CC)
81 
82 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
83 				 _PAGE_GLOBAL | _PAGE_KERN | _CACHE_CC)
84 #define PAGE_KERNEL_SUC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
85 				 _PAGE_GLOBAL | _PAGE_KERN |  _CACHE_SUC)
86 #define PAGE_KERNEL_WUC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
87 				 _PAGE_GLOBAL | _PAGE_KERN |  _CACHE_WUC)
88 
89 #define __P000 __pgprot(_CACHE_CC | _PAGE_USER | _PAGE_PROTNONE | _PAGE_NO_EXEC | _PAGE_NO_READ)
90 #define __P001 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT | _PAGE_NO_EXEC)
91 #define __P010 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT | _PAGE_NO_EXEC)
92 #define __P011 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT | _PAGE_NO_EXEC)
93 #define __P100 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT)
94 #define __P101 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT)
95 #define __P110 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT)
96 #define __P111 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT)
97 
98 #define __S000 __pgprot(_CACHE_CC | _PAGE_USER | _PAGE_PROTNONE | _PAGE_NO_EXEC | _PAGE_NO_READ)
99 #define __S001 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT | _PAGE_NO_EXEC)
100 #define __S010 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE)
101 #define __S011 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE)
102 #define __S100 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT)
103 #define __S101 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT)
104 #define __S110 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT | _PAGE_WRITE)
105 #define __S111 __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT | _PAGE_WRITE)
106 
107 #ifndef __ASSEMBLY__
108 
109 #define _PAGE_IOREMAP		pgprot_val(PAGE_KERNEL_SUC)
110 
111 #define pgprot_noncached pgprot_noncached
112 
pgprot_noncached(pgprot_t _prot)113 static inline pgprot_t pgprot_noncached(pgprot_t _prot)
114 {
115 	unsigned long prot = pgprot_val(_prot);
116 
117 	prot = (prot & ~_CACHE_MASK) | _CACHE_SUC;
118 
119 	return __pgprot(prot);
120 }
121 
122 extern bool wc_enabled;
123 
124 #define pgprot_writecombine pgprot_writecombine
125 
pgprot_writecombine(pgprot_t _prot)126 static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
127 {
128 	unsigned long prot = pgprot_val(_prot);
129 
130 	prot = (prot & ~_CACHE_MASK) | (wc_enabled ? _CACHE_WUC : _CACHE_SUC);
131 
132 	return __pgprot(prot);
133 }
134 
135 #endif /* !__ASSEMBLY__ */
136 
137 #endif /* _ASM_PGTABLE_BITS_H */
138