1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (C) 2006 Tensilica Inc.
4  * Copyright (C) 2014 - 2016 Cadence Design Systems Inc.
5  */
6 
7 #ifndef _XTENSA_CACHEASM_H
8 #define _XTENSA_CACHEASM_H
9 
10 #include <asm/cache.h>
11 #include <asm/asmmacro.h>
12 #include <linux/stringify.h>
13 
14 #define PAGE_SIZE 4096
15 #define DCACHE_WAY_SIZE (XCHAL_DCACHE_SIZE/XCHAL_DCACHE_WAYS)
16 #define ICACHE_WAY_SIZE (XCHAL_ICACHE_SIZE/XCHAL_ICACHE_WAYS)
17 #define DCACHE_WAY_SHIFT (XCHAL_DCACHE_SETWIDTH + XCHAL_DCACHE_LINEWIDTH)
18 #define ICACHE_WAY_SHIFT (XCHAL_ICACHE_SETWIDTH + XCHAL_ICACHE_LINEWIDTH)
19 
20 /*
21  * Define cache functions as macros here so that they can be used
22  * by the kernel and boot loader. We should consider moving them to a
23  * library that can be linked by both.
24  *
25  * Locking
26  *
27  *   ___unlock_dcache_all
28  *   ___unlock_icache_all
29  *
30  * Flush and invaldating
31  *
32  *   ___flush_invalidate_dcache_{all|range|page}
33  *   ___flush_dcache_{all|range|page}
34  *   ___invalidate_dcache_{all|range|page}
35  *   ___invalidate_icache_{all|range|page}
36  *
37  */
38 
39 	.macro	__loop_cache_all ar at insn size line_width
40 
41 	movi	\ar, 0
42 
43 	__loopi	\ar, \at, \size, (4 << (\line_width))
44 
45 	\insn	\ar, 0 << (\line_width)
46 	\insn	\ar, 1 << (\line_width)
47 	\insn	\ar, 2 << (\line_width)
48 	\insn	\ar, 3 << (\line_width)
49 
50 	__endla	\ar, \at, 4 << (\line_width)
51 
52 	.endm
53 
54 
55 	.macro	__loop_cache_range ar as at insn line_width
56 
57 	extui	\at, \ar, 0, \line_width
58 	add	\as, \as, \at
59 
60 	__loops	\ar, \as, \at, \line_width
61 	\insn	\ar, 0
62 	__endla	\ar, \at, (1 << (\line_width))
63 
64 	.endm
65 
66 
67 	.macro	__loop_cache_page ar at insn line_width
68 
69 	__loopi	\ar, \at, PAGE_SIZE, 4 << (\line_width)
70 
71 	\insn	\ar, 0 << (\line_width)
72 	\insn	\ar, 1 << (\line_width)
73 	\insn	\ar, 2 << (\line_width)
74 	\insn	\ar, 3 << (\line_width)
75 
76 	__endla	\ar, \at, 4 << (\line_width)
77 
78 	.endm
79 
80 
81 	.macro	___unlock_dcache_all ar at
82 
83 #if XCHAL_DCACHE_LINE_LOCKABLE && XCHAL_DCACHE_SIZE
84 	__loop_cache_all \ar \at diu XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
85 #endif
86 
87 	.endm
88 
89 
90 	.macro	___unlock_icache_all ar at
91 
92 #if XCHAL_ICACHE_LINE_LOCKABLE && XCHAL_ICACHE_SIZE
93 	__loop_cache_all \ar \at iiu XCHAL_ICACHE_SIZE XCHAL_ICACHE_LINEWIDTH
94 #endif
95 
96 	.endm
97 
98 
99 	.macro	___flush_invalidate_dcache_all ar at
100 
101 #if XCHAL_DCACHE_SIZE
102 	__loop_cache_all \ar \at diwbi XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
103 #endif
104 
105 	.endm
106 
107 
108 	.macro	___flush_dcache_all ar at
109 
110 #if XCHAL_DCACHE_SIZE
111 	__loop_cache_all \ar \at diwb XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
112 #endif
113 
114 	.endm
115 
116 
117 	.macro	___invalidate_dcache_all ar at
118 
119 #if XCHAL_DCACHE_SIZE
120 	__loop_cache_all \ar \at dii __stringify(DCACHE_WAY_SIZE) \
121 			 XCHAL_DCACHE_LINEWIDTH
122 #endif
123 
124 	.endm
125 
126 
127 	.macro	___invalidate_icache_all ar at
128 
129 #if XCHAL_ICACHE_SIZE
130 	__loop_cache_all \ar \at iii __stringify(ICACHE_WAY_SIZE) \
131 			 XCHAL_ICACHE_LINEWIDTH
132 #endif
133 
134 	.endm
135 
136 
137 	.macro	___flush_invalidate_dcache_range ar as at
138 
139 #if XCHAL_DCACHE_SIZE
140 	__loop_cache_range \ar \as \at dhwbi XCHAL_DCACHE_LINEWIDTH
141 #endif
142 
143 	.endm
144 
145 
146 	.macro	___flush_dcache_range ar as at
147 
148 #if XCHAL_DCACHE_SIZE
149 	__loop_cache_range \ar \as \at dhwb XCHAL_DCACHE_LINEWIDTH
150 #endif
151 
152 	.endm
153 
154 
155 	.macro	___invalidate_dcache_range ar as at
156 
157 #if XCHAL_DCACHE_SIZE
158 	__loop_cache_range \ar \as \at dhi XCHAL_DCACHE_LINEWIDTH
159 #endif
160 
161 	.endm
162 
163 
164 	.macro	___invalidate_icache_range ar as at
165 
166 #if XCHAL_ICACHE_SIZE
167 	__loop_cache_range \ar \as \at ihi XCHAL_ICACHE_LINEWIDTH
168 #endif
169 
170 	.endm
171 
172 
173 	.macro	___flush_invalidate_dcache_page ar as
174 
175 #if XCHAL_DCACHE_SIZE
176 	__loop_cache_page \ar \as dhwbi XCHAL_DCACHE_LINEWIDTH
177 #endif
178 
179 	.endm
180 
181 
182 	.macro ___flush_dcache_page ar as
183 
184 #if XCHAL_DCACHE_SIZE
185 	__loop_cache_page \ar \as dhwb XCHAL_DCACHE_LINEWIDTH
186 #endif
187 
188 	.endm
189 
190 
191 	.macro	___invalidate_dcache_page ar as
192 
193 #if XCHAL_DCACHE_SIZE
194 	__loop_cache_page \ar \as dhi XCHAL_DCACHE_LINEWIDTH
195 #endif
196 
197 	.endm
198 
199 
200 	.macro	___invalidate_icache_page ar as
201 
202 #if XCHAL_ICACHE_SIZE
203 	__loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH
204 #endif
205 
206 	.endm
207 
208 #endif	/* _XTENSA_CACHEASM_H */
209