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 
138 	.macro	___flush_invalidate_dcache_range ar as at
139 
140 #if XCHAL_DCACHE_SIZE
141 	__loop_cache_range \ar \as \at dhwbi XCHAL_DCACHE_LINEWIDTH
142 #endif
143 
144 	.endm
145 
146 
147 	.macro	___flush_dcache_range ar as at
148 
149 #if XCHAL_DCACHE_SIZE
150 	__loop_cache_range \ar \as \at dhwb XCHAL_DCACHE_LINEWIDTH
151 #endif
152 
153 	.endm
154 
155 
156 	.macro	___invalidate_dcache_range ar as at
157 
158 #if XCHAL_DCACHE_SIZE
159 	__loop_cache_range \ar \as \at dhi XCHAL_DCACHE_LINEWIDTH
160 #endif
161 
162 	.endm
163 
164 
165 	.macro	___invalidate_icache_range ar as at
166 
167 #if XCHAL_ICACHE_SIZE
168 	__loop_cache_range \ar \as \at ihi XCHAL_ICACHE_LINEWIDTH
169 #endif
170 
171 	.endm
172 
173 
174 
175 	.macro	___flush_invalidate_dcache_page ar as
176 
177 #if XCHAL_DCACHE_SIZE
178 	__loop_cache_page \ar \as dhwbi XCHAL_DCACHE_LINEWIDTH
179 #endif
180 
181 	.endm
182 
183 
184 	.macro ___flush_dcache_page ar as
185 
186 #if XCHAL_DCACHE_SIZE
187 	__loop_cache_page \ar \as dhwb XCHAL_DCACHE_LINEWIDTH
188 #endif
189 
190 	.endm
191 
192 
193 	.macro	___invalidate_dcache_page ar as
194 
195 #if XCHAL_DCACHE_SIZE
196 	__loop_cache_page \ar \as dhi XCHAL_DCACHE_LINEWIDTH
197 #endif
198 
199 	.endm
200 
201 
202 	.macro	___invalidate_icache_page ar as
203 
204 #if XCHAL_ICACHE_SIZE
205 	__loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH
206 #endif
207 
208 	.endm
209 
210 #endif	/* _XTENSA_CACHEASM_H */
211