xref: /linux/arch/loongarch/include/asm/pgtable-bits.h (revision 9551a26f17d9445eed497bd7c639d48dfc3c0af4)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4  */
5 #ifndef _ASM_PGTABLE_BITS_H
6 #define _ASM_PGTABLE_BITS_H
7 
8 /* Page table bits */
9 
10 #ifdef CONFIG_32BIT
11 #define	_PAGE_VALID_SHIFT	0
12 #define	_PAGE_ACCESSED_SHIFT	0  /* Reuse Valid for Accessed */
13 #define	_PAGE_DIRTY_SHIFT	1
14 #define	_PAGE_PLV_SHIFT		2  /* 2~3, two bits */
15 #define	_CACHE_SHIFT		4  /* 4~5, two bits */
16 #define	_PAGE_GLOBAL_SHIFT	6
17 #define	_PAGE_HUGE_SHIFT	6  /* HUGE is a PMD bit */
18 #define	_PAGE_PRESENT_SHIFT	7
19 #define	_PAGE_PFN_SHIFT		8
20 #define	_PAGE_HGLOBAL_SHIFT	12 /* HGlobal is a PMD bit */
21 #define	_PAGE_SWP_EXCLUSIVE_SHIFT 13
22 #define	_PAGE_PFN_END_SHIFT	28
23 #define	_PAGE_WRITE_SHIFT	29
24 #define	_PAGE_MODIFIED_SHIFT	30
25 #define	_PAGE_PRESENT_INVALID_SHIFT 31
26 #endif
27 
28 #ifdef CONFIG_64BIT
29 #define	_PAGE_VALID_SHIFT	0
30 #define	_PAGE_ACCESSED_SHIFT	0  /* Reuse Valid for Accessed */
31 #define	_PAGE_DIRTY_SHIFT	1
32 #define	_PAGE_PLV_SHIFT		2  /* 2~3, two bits */
33 #define	_CACHE_SHIFT		4  /* 4~5, two bits */
34 #define	_PAGE_GLOBAL_SHIFT	6
35 #define	_PAGE_HUGE_SHIFT	6  /* HUGE is a PMD bit */
36 #define	_PAGE_PRESENT_SHIFT	7
37 #define	_PAGE_WRITE_SHIFT	8
38 #define	_PAGE_MODIFIED_SHIFT	9
39 #define	_PAGE_PROTNONE_SHIFT	10
40 #define	_PAGE_SPECIAL_SHIFT	11
41 #define	_PAGE_PFN_SHIFT		12
42 #define	_PAGE_HGLOBAL_SHIFT	12 /* HGlobal is a PMD bit */
43 #define	_PAGE_SWP_EXCLUSIVE_SHIFT 23
44 #define	_PAGE_PFN_END_SHIFT	48
45 #define	_PAGE_PRESENT_INVALID_SHIFT 60
46 #define	_PAGE_NO_READ_SHIFT	61
47 #define	_PAGE_NO_EXEC_SHIFT	62
48 #define	_PAGE_RPLV_SHIFT	63
49 #endif
50 
51 /* Used by software */
52 #define _PAGE_PRESENT		(_ULCAST_(1) << _PAGE_PRESENT_SHIFT)
53 #define _PAGE_PRESENT_INVALID	(_ULCAST_(1) << _PAGE_PRESENT_INVALID_SHIFT)
54 #define _PAGE_WRITE		(_ULCAST_(1) << _PAGE_WRITE_SHIFT)
55 #define _PAGE_ACCESSED		(_ULCAST_(1) << _PAGE_ACCESSED_SHIFT)
56 #define _PAGE_MODIFIED		(_ULCAST_(1) << _PAGE_MODIFIED_SHIFT)
57 #ifdef CONFIG_32BIT
58 #define _PAGE_PROTNONE		0
59 #define _PAGE_SPECIAL		0
60 #else
61 #define _PAGE_PROTNONE		(_ULCAST_(1) << _PAGE_PROTNONE_SHIFT)
62 #define _PAGE_SPECIAL		(_ULCAST_(1) << _PAGE_SPECIAL_SHIFT)
63 #endif
64 
65 /* We borrow bit 13/23 to store the exclusive marker in swap PTEs. */
66 #define _PAGE_SWP_EXCLUSIVE	(_ULCAST_(1) << _PAGE_SWP_EXCLUSIVE_SHIFT)
67 
68 /* Used by TLB hardware (placed in EntryLo*) */
69 #define _PAGE_VALID		(_ULCAST_(1) << _PAGE_VALID_SHIFT)
70 #define _PAGE_DIRTY		(_ULCAST_(1) << _PAGE_DIRTY_SHIFT)
71 #define _PAGE_PLV		(_ULCAST_(3) << _PAGE_PLV_SHIFT)
72 #define _PAGE_GLOBAL		(_ULCAST_(1) << _PAGE_GLOBAL_SHIFT)
73 #define _PAGE_HUGE		(_ULCAST_(1) << _PAGE_HUGE_SHIFT)
74 #define _PAGE_HGLOBAL		(_ULCAST_(1) << _PAGE_HGLOBAL_SHIFT)
75 #ifdef CONFIG_32BIT
76 #define _PAGE_NO_READ		0
77 #define _PAGE_NO_EXEC		0
78 #define _PAGE_RPLV		0
79 #else
80 #define _PAGE_NO_READ		(_ULCAST_(1) << _PAGE_NO_READ_SHIFT)
81 #define _PAGE_NO_EXEC		(_ULCAST_(1) << _PAGE_NO_EXEC_SHIFT)
82 #define _PAGE_RPLV		(_ULCAST_(1) << _PAGE_RPLV_SHIFT)
83 #endif
84 #define _CACHE_MASK		(_ULCAST_(3) << _CACHE_SHIFT)
85 #define PFN_PTE_SHIFT		(PAGE_SHIFT - 12 + _PAGE_PFN_SHIFT)
86 
87 #define _PAGE_USER	(PLV_USER << _PAGE_PLV_SHIFT)
88 #define _PAGE_KERN	(PLV_KERN << _PAGE_PLV_SHIFT)
89 
90 #define _PFN_MASK (~((_ULCAST_(1) << (PFN_PTE_SHIFT)) - 1) & \
91 		  ((_ULCAST_(1) << (_PAGE_PFN_END_SHIFT)) - 1))
92 
93 /*
94  * Cache attributes
95  */
96 #ifndef _CACHE_SUC
97 #define _CACHE_SUC			(0<<_CACHE_SHIFT) /* Strong-ordered UnCached */
98 #endif
99 #ifndef _CACHE_CC
100 #define _CACHE_CC			(1<<_CACHE_SHIFT) /* Coherent Cached */
101 #endif
102 #ifndef _CACHE_WUC
103 #define _CACHE_WUC			(2<<_CACHE_SHIFT) /* Weak-ordered UnCached */
104 #endif
105 
106 #define __READABLE	(_PAGE_VALID)
107 #define __WRITEABLE	(_PAGE_DIRTY | _PAGE_WRITE)
108 
109 #define _PAGE_CHG_MASK	(_PAGE_MODIFIED | _PAGE_SPECIAL | _PFN_MASK | _CACHE_MASK | _PAGE_PLV)
110 #define _HPAGE_CHG_MASK	(_PAGE_MODIFIED | _PAGE_SPECIAL | _PFN_MASK | _CACHE_MASK | _PAGE_PLV | _PAGE_HUGE)
111 
112 #define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_NO_READ | \
113 				 _PAGE_USER | _CACHE_CC)
114 #define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
115 				 _PAGE_USER | _CACHE_CC)
116 #define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _CACHE_CC)
117 
118 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
119 				 _PAGE_GLOBAL | _PAGE_KERN | _CACHE_CC)
120 #define PAGE_KERNEL_SUC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
121 				 _PAGE_GLOBAL | _PAGE_KERN |  _CACHE_SUC)
122 #define PAGE_KERNEL_WUC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
123 				 _PAGE_GLOBAL | _PAGE_KERN |  _CACHE_WUC)
124 
125 #ifndef __ASSEMBLER__
126 
127 #define _PAGE_IOREMAP		pgprot_val(PAGE_KERNEL_SUC)
128 
129 #define pgprot_nx pgprot_nx
130 
pgprot_nx(pgprot_t _prot)131 static inline pgprot_t pgprot_nx(pgprot_t _prot)
132 {
133 	return __pgprot(pgprot_val(_prot) | _PAGE_NO_EXEC);
134 }
135 
136 #define pgprot_noncached pgprot_noncached
137 
pgprot_noncached(pgprot_t _prot)138 static inline pgprot_t pgprot_noncached(pgprot_t _prot)
139 {
140 	unsigned long prot = pgprot_val(_prot);
141 
142 	prot = (prot & ~_CACHE_MASK) | _CACHE_SUC;
143 
144 	return __pgprot(prot);
145 }
146 
147 extern bool wc_enabled;
148 
149 #define pgprot_writecombine pgprot_writecombine
150 
pgprot_writecombine(pgprot_t _prot)151 static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
152 {
153 	unsigned long prot = pgprot_val(_prot);
154 
155 	prot = (prot & ~_CACHE_MASK) | (wc_enabled ? _CACHE_WUC : _CACHE_SUC);
156 
157 	return __pgprot(prot);
158 }
159 
160 #endif /* !__ASSEMBLER__ */
161 
162 #endif /* _ASM_PGTABLE_BITS_H */
163