Commit c250bfb93c046a789989af475ae18d08c61b4cfa
Committed by
Bryan Wu
1 parent
39ca44536d
Exists in
master
and in
7 other branches
Blackfin arch: cleanup and unify the ins functions
this also fixes some errors in the ipipe merge Signed-off-by: Mike Frysinger <vapier.adi@gmail.com> Signed-off-by: Bryan Wu <cooloney@kernel.org>
Showing 1 changed file with 84 additions and 345 deletions Side-by-side Diff
arch/blackfin/lib/ins.S
1 | 1 | /* |
2 | - * File: arch/blackfin/lib/ins.S | |
3 | - * Based on: | |
4 | - * Author: Bas Vermeulen <bas@buyways.nl> | |
2 | + * arch/blackfin/lib/ins.S - ins{bwl} using hardware loops | |
5 | 3 | * |
6 | - * Created: Tue Mar 22 15:27:24 CEST 2005 | |
7 | - * Description: Implementation of ins{bwl} for BlackFin processors using zero overhead loops. | |
8 | - * | |
9 | - * Modified: | |
10 | - * Copyright 2004-2008 Analog Devices Inc. | |
11 | - * Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl> | |
12 | - * | |
13 | - * Bugs: Enter bugs at http://blackfin.uclinux.org/ | |
14 | - * | |
15 | - * This program is free software; you can redistribute it and/or modify | |
16 | - * it under the terms of the GNU General Public License as published by | |
17 | - * the Free Software Foundation; either version 2 of the License, or | |
18 | - * (at your option) any later version. | |
19 | - * | |
20 | - * This program is distributed in the hope that it will be useful, | |
21 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23 | - * GNU General Public License for more details. | |
24 | - * | |
25 | - * You should have received a copy of the GNU General Public License | |
26 | - * along with this program; if not, see the file COPYING, or write | |
27 | - * to the Free Software Foundation, Inc., | |
28 | - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
4 | + * Copyright 2004-2008 Analog Devices Inc. | |
5 | + * Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl> | |
6 | + * Licensed under the GPL-2 or later. | |
29 | 7 | */ |
30 | 8 | |
31 | 9 | #include <linux/linkage.h> |
... | ... | @@ -33,6 +11,46 @@ |
33 | 11 | |
34 | 12 | .align 2 |
35 | 13 | |
14 | +#ifdef CONFIG_IPIPE | |
15 | +# define DO_CLI \ | |
16 | + [--sp] = rets; \ | |
17 | + [--sp] = (P5:0); \ | |
18 | + sp += -12; \ | |
19 | + call ___ipipe_stall_root_raw; \ | |
20 | + sp += 12; \ | |
21 | + (P5:0) = [sp++]; | |
22 | +# define CLI_INNER_NOP | |
23 | +#else | |
24 | +# define DO_CLI cli R3; | |
25 | +# define CLI_INNER_NOP nop; nop; nop; | |
26 | +#endif | |
27 | + | |
28 | +#ifdef CONFIG_IPIPE | |
29 | +# define DO_STI \ | |
30 | + sp += -12; \ | |
31 | + call ___ipipe_unstall_root_raw; \ | |
32 | + sp += 12; \ | |
33 | +2: rets = [sp++]; | |
34 | +#else | |
35 | +# define DO_STI 2: sti R3; | |
36 | +#endif | |
37 | + | |
38 | +#ifdef CONFIG_BFIN_INS_LOWOVERHEAD | |
39 | +# define CLI_OUTER DO_CLI; | |
40 | +# define STI_OUTER DO_STI; | |
41 | +# define CLI_INNER 1: | |
42 | +# if ANOMALY_05000416 | |
43 | +# define STI_INNER nop; 2: nop; | |
44 | +# else | |
45 | +# define STI_INNER 2: | |
46 | +# endif | |
47 | +#else | |
48 | +# define CLI_OUTER | |
49 | +# define STI_OUTER | |
50 | +# define CLI_INNER 1: DO_CLI; CLI_INNER_NOP; | |
51 | +# define STI_INNER DO_STI; | |
52 | +#endif | |
53 | + | |
36 | 54 | /* |
37 | 55 | * Reads on the Blackfin are speculative. In Blackfin terms, this means they |
38 | 56 | * can be interrupted at any time (even after they have been issued on to the |
39 | 57 | |
40 | 58 | |
41 | 59 | |
42 | 60 | |
43 | 61 | |
... | ... | @@ -53,328 +71,49 @@ |
53 | 71 | * buffers in/out of FIFOs. |
54 | 72 | */ |
55 | 73 | |
56 | -ENTRY(_insl) | |
57 | -#ifdef CONFIG_BFIN_INS_LOWOVERHEAD | |
58 | - P0 = R0; /* P0 = port */ | |
59 | -#ifdef CONFIG_IPIPE | |
60 | - [--sp] = rets | |
61 | - [--sp] = (P5:0); | |
62 | - sp += -12 | |
63 | - call ___ipipe_stall_root_raw | |
64 | - sp += 12 | |
65 | - (P5:0) = [sp++]; | |
66 | -#else | |
67 | - cli R3; | |
68 | -#endif | |
69 | - P1 = R1; /* P1 = address */ | |
70 | - P2 = R2; /* P2 = count */ | |
71 | - SSYNC; | |
72 | - LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2; | |
73 | -.Llong_loop_s: R0 = [P0]; | |
74 | - [P1++] = R0; | |
75 | - NOP; | |
76 | -.Llong_loop_e: NOP; | |
77 | -#ifdef CONFIG_IPIPE | |
78 | - sp += -12 | |
79 | - call ___ipipe_unstall_root_raw | |
80 | - sp += 12 | |
81 | - rets = [sp++] | |
82 | -#else | |
83 | - sti R3; | |
84 | -#endif | |
85 | - RTS; | |
86 | -#else | |
87 | - P0 = R0; /* P0 = port */ | |
88 | - P1 = R1; /* P1 = address */ | |
89 | - P2 = R2; /* P2 = count */ | |
90 | - SSYNC; | |
91 | - LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2; | |
92 | -.Llong_loop_s: | |
93 | -#ifdef CONFIG_IPIPE | |
94 | - [--sp] = rets | |
95 | - [--sp] = (P5:0); | |
96 | - sp += -12 | |
97 | - call ___ipipe_stall_root_raw | |
98 | - sp += 12 | |
99 | - (P5:0) = [sp++]; | |
100 | -#else | |
101 | - CLI R3; | |
102 | -#endif | |
103 | - NOP; NOP; NOP; | |
104 | - R0 = [P0]; | |
105 | - [P1++] = R0; | |
106 | -.Llong_loop_e: | |
107 | -#ifdef CONFIG_IPIPE | |
108 | - sp += -12 | |
109 | - call ___ipipe_unstall_root_raw | |
110 | - sp += 12 | |
111 | - rets = [sp++] | |
112 | -#else | |
113 | - STI R3; | |
114 | -#endif | |
115 | - RTS; | |
116 | -#endif | |
117 | -ENDPROC(_insl) | |
74 | +#define COMMON_INS(func, ops) \ | |
75 | +ENTRY(_ins##func) \ | |
76 | + P0 = R0; /* P0 = port */ \ | |
77 | + CLI_OUTER; /* 3 instructions before first read access */ \ | |
78 | + P1 = R1; /* P1 = address */ \ | |
79 | + P2 = R2; /* P2 = count */ \ | |
80 | + SSYNC; \ | |
81 | + \ | |
82 | + LSETUP(1f, 2f) LC0 = P2; \ | |
83 | + CLI_INNER; \ | |
84 | + ops; \ | |
85 | + STI_INNER; \ | |
86 | + \ | |
87 | + STI_OUTER; \ | |
88 | + RTS; \ | |
89 | +ENDPROC(_ins##func) | |
118 | 90 | |
119 | -ENTRY(_insw) | |
120 | -#ifdef CONFIG_BFIN_INS_LOWOVERHEAD | |
121 | - P0 = R0; /* P0 = port */ | |
122 | -#ifdef CONFIG_IPIPE | |
123 | - [--sp] = rets | |
124 | - [--sp] = (P5:0); | |
125 | - sp += -12 | |
126 | - call ___ipipe_stall_root_raw | |
127 | - sp += 12 | |
128 | - (P5:0) = [sp++]; | |
129 | -#else | |
130 | - cli R3; | |
131 | -#endif | |
132 | - P1 = R1; /* P1 = address */ | |
133 | - P2 = R2; /* P2 = count */ | |
134 | - SSYNC; | |
135 | - LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2; | |
136 | -.Lword_loop_s: R0 = W[P0]; | |
137 | - W[P1++] = R0; | |
138 | - NOP; | |
139 | -.Lword_loop_e: NOP; | |
140 | -#ifdef CONFIG_IPIPE | |
141 | - sp += -12 | |
142 | - call ___ipipe_unstall_root_raw | |
143 | - sp += 12 | |
144 | - rets = [sp++] | |
145 | -#else | |
146 | - sti R3; | |
147 | -#endif | |
148 | - RTS; | |
149 | -#else | |
150 | - P0 = R0; /* P0 = port */ | |
151 | - P1 = R1; /* P1 = address */ | |
152 | - P2 = R2; /* P2 = count */ | |
153 | - SSYNC; | |
154 | - LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2; | |
155 | -.Lword_loop_s: | |
156 | -#ifdef CONFIG_IPIPE | |
157 | - [--sp] = rets | |
158 | - [--sp] = (P5:0); | |
159 | - sp += -12 | |
160 | - call ___ipipe_stall_root_raw | |
161 | - sp += 12 | |
162 | - (P5:0) = [sp++]; | |
163 | -#else | |
164 | - CLI R3; | |
165 | -#endif | |
166 | - NOP; NOP; NOP; | |
167 | - R0 = W[P0]; | |
168 | - W[P1++] = R0; | |
169 | -.Lword_loop_e: | |
170 | -#ifdef CONFIG_IPIPE | |
171 | - sp += -12 | |
172 | - call ___ipipe_unstall_root_raw | |
173 | - sp += 12 | |
174 | - rets = [sp++] | |
175 | -#else | |
176 | - STI R3; | |
177 | -#endif | |
178 | - RTS; | |
91 | +COMMON_INS(l, \ | |
92 | + R0 = [P0]; \ | |
93 | + [P1++] = R0; \ | |
94 | +) | |
179 | 95 | |
180 | -#endif | |
181 | -ENDPROC(_insw) | |
96 | +COMMON_INS(w, \ | |
97 | + R0 = W[P0]; \ | |
98 | + W[P1++] = R0; \ | |
99 | +) | |
182 | 100 | |
183 | -ENTRY(_insw_8) | |
184 | -#ifdef CONFIG_BFIN_INS_LOWOVERHEAD | |
185 | - P0 = R0; /* P0 = port */ | |
186 | -#ifdef CONFIG_IPIPE | |
187 | - [--sp] = rets | |
188 | - [--sp] = (P5:0); | |
189 | - sp += -12 | |
190 | - call ___ipipe_stall_root_raw | |
191 | - sp += 12 | |
192 | - (P5:0) = [sp++]; | |
193 | -#else | |
194 | - cli R3; | |
195 | -#endif | |
196 | - P1 = R1; /* P1 = address */ | |
197 | - P2 = R2; /* P2 = count */ | |
198 | - SSYNC; | |
199 | - LSETUP( .Lword8_loop_s, .Lword8_loop_e) LC0 = P2; | |
200 | -.Lword8_loop_s: R0 = W[P0]; | |
201 | - B[P1++] = R0; | |
202 | - R0 = R0 >> 8; | |
203 | - B[P1++] = R0; | |
204 | - NOP; | |
205 | -.Lword8_loop_e: NOP; | |
206 | -#ifdef CONFIG_IPIPE | |
207 | - sp += -12 | |
208 | - call ___ipipe_unstall_root_raw | |
209 | - sp += 12 | |
210 | - rets = [sp++] | |
211 | -#else | |
212 | - sti R3; | |
213 | -#endif | |
214 | - RTS; | |
215 | -#else | |
216 | - P0 = R0; /* P0 = port */ | |
217 | - P1 = R1; /* P1 = address */ | |
218 | - P2 = R2; /* P2 = count */ | |
219 | - SSYNC; | |
220 | - LSETUP( .Lword8_loop_s, .Lword8_loop_e) LC0 = P2; | |
221 | -.Lword8_loop_s: | |
222 | -#ifdef CONFIG_IPIPE | |
223 | - [--sp] = rets | |
224 | - [--sp] = (P5:0); | |
225 | - sp += -12 | |
226 | - call ___ipipe_stall_root_raw | |
227 | - sp += 12 | |
228 | - (P5:0) = [sp++]; | |
229 | -#else | |
230 | - CLI R3; | |
231 | -#endif | |
232 | - NOP; NOP; NOP; | |
233 | - R0 = W[P0]; | |
234 | - B[P1++] = R0; | |
235 | - R0 = R0 >> 8; | |
236 | - B[P1++] = R0; | |
237 | - NOP; | |
238 | -.Lword8_loop_e: | |
239 | -#ifdef CONFIG_IPIPE | |
240 | - sp += -12 | |
241 | - call ___ipipe_unstall_root_raw | |
242 | - sp += 12 | |
243 | - rets = [sp++] | |
244 | -#else | |
245 | - STI R3; | |
246 | -#endif | |
247 | - RTS; | |
248 | -#endif | |
249 | -ENDPROC(_insw_8) | |
101 | +COMMON_INS(w_8, \ | |
102 | + R0 = W[P0]; \ | |
103 | + B[P1++] = R0; \ | |
104 | + R0 = R0 >> 8; \ | |
105 | + B[P1++] = R0; \ | |
106 | +) | |
250 | 107 | |
251 | -ENTRY(_insb) | |
252 | -#ifdef CONFIG_BFIN_INS_LOWOVERHEAD | |
253 | - P0 = R0; /* P0 = port */ | |
254 | -#ifdef CONFIG_IPIPE | |
255 | - [--sp] = rets | |
256 | - [--sp] = (P5:0); | |
257 | - sp += -12 | |
258 | - call ___ipipe_stall_root_raw | |
259 | - sp += 12 | |
260 | - (P5:0) = [sp++]; | |
261 | -#else | |
262 | - cli R3; | |
263 | -#endif | |
264 | - P1 = R1; /* P1 = address */ | |
265 | - P2 = R2; /* P2 = count */ | |
266 | - SSYNC; | |
267 | - LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2; | |
268 | -.Lbyte_loop_s: R0 = B[P0]; | |
269 | - B[P1++] = R0; | |
270 | - NOP; | |
271 | -.Lbyte_loop_e: NOP; | |
272 | -#ifdef CONFIG_IPIPE | |
273 | - sp += -12 | |
274 | - call ___ipipe_unstall_root_raw | |
275 | - sp += 12 | |
276 | - rets = [sp++] | |
277 | -#else | |
278 | - sti R3; | |
279 | -#endif | |
280 | - RTS; | |
281 | -#else | |
282 | - P0 = R0; /* P0 = port */ | |
283 | - P1 = R1; /* P1 = address */ | |
284 | - P2 = R2; /* P2 = count */ | |
285 | - SSYNC; | |
286 | - LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2; | |
287 | -.Lbyte_loop_s: | |
288 | -#ifdef CONFIG_IPIPE | |
289 | - [--sp] = rets | |
290 | - [--sp] = (P5:0); | |
291 | - sp += -12 | |
292 | - call ___ipipe_stall_root_raw | |
293 | - sp += 12 | |
294 | - (P5:0) = [sp++]; | |
295 | -#else | |
296 | - CLI R3; | |
297 | -#endif | |
298 | - NOP; NOP; NOP; | |
299 | - R0 = B[P0]; | |
300 | - B[P1++] = R0; | |
301 | -.Lbyte_loop_e: | |
302 | -#ifdef CONFIG_IPIPE | |
303 | - sp += -12 | |
304 | - call ___ipipe_unstall_root_raw | |
305 | - sp += 12 | |
306 | - rets = [sp++] | |
307 | -#else | |
308 | - STI R3; | |
309 | -#endif | |
310 | - RTS; | |
311 | -#endif | |
312 | -ENDPROC(_insb) | |
108 | +COMMON_INS(b, \ | |
109 | + R0 = B[P0]; \ | |
110 | + B[P1++] = R0; \ | |
111 | +) | |
313 | 112 | |
314 | -ENTRY(_insl_16) | |
315 | -#ifdef CONFIG_BFIN_INS_LOWOVERHEAD | |
316 | - P0 = R0; /* P0 = port */ | |
317 | -#ifdef CONFIG_IPIPE | |
318 | - [--sp] = rets | |
319 | - [--sp] = (P5:0); | |
320 | - sp += -12 | |
321 | - call ___ipipe_stall_root_raw | |
322 | - sp += 12 | |
323 | - (P5:0) = [sp++]; | |
324 | -#else | |
325 | - cli R3; | |
326 | -#endif | |
327 | - P1 = R1; /* P1 = address */ | |
328 | - P2 = R2; /* P2 = count */ | |
329 | - SSYNC; | |
330 | - LSETUP( .Llong16_loop_s, .Llong16_loop_e) LC0 = P2; | |
331 | -.Llong16_loop_s: R0 = [P0]; | |
332 | - W[P1++] = R0; | |
333 | - R0 = R0 >> 16; | |
334 | - W[P1++] = R0; | |
335 | - NOP; | |
336 | -.Llong16_loop_e: NOP; | |
337 | -#ifdef CONFIG_IPIPE | |
338 | - sp += -12 | |
339 | - call ___ipipe_unstall_root_raw | |
340 | - sp += 12 | |
341 | - rets = [sp++] | |
342 | -#else | |
343 | - sti R3; | |
344 | -#endif | |
345 | - RTS; | |
346 | -#else | |
347 | - P0 = R0; /* P0 = port */ | |
348 | - P1 = R1; /* P1 = address */ | |
349 | - P2 = R2; /* P2 = count */ | |
350 | - SSYNC; | |
351 | - LSETUP( .Llong16_loop_s, .Llong16_loop_e) LC0 = P2; | |
352 | -.Llong16_loop_s: | |
353 | -#ifdef CONFIG_IPIPE | |
354 | - [--sp] = rets | |
355 | - [--sp] = (P5:0); | |
356 | - sp += -12 | |
357 | - call ___ipipe_stall_root_raw | |
358 | - sp += 12 | |
359 | - (P5:0) = [sp++]; | |
360 | -#else | |
361 | - CLI R3; | |
362 | -#endif | |
363 | - NOP; NOP; NOP; | |
364 | - R0 = [P0]; | |
365 | - W[P1++] = R0; | |
366 | - R0 = R0 >> 16; | |
367 | - W[P1++] = R0; | |
368 | -.Llong16_loop_e: | |
369 | -#ifdef CONFIG_IPIPE | |
370 | - sp += -12 | |
371 | - call ___ipipe_unstall_root_raw | |
372 | - sp += 12 | |
373 | - rets = [sp++] | |
374 | -#else | |
375 | - STI R3; | |
376 | -#endif | |
377 | - RTS; | |
378 | -#endif | |
379 | -ENDPROC(_insl_16) | |
113 | +COMMON_INS(l_16, \ | |
114 | + R0 = [P0]; \ | |
115 | + W[P1++] = R0; \ | |
116 | + R0 = R0 >> 16; \ | |
117 | + W[P1++] = R0; \ | |
118 | +) |