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