diff options
author | Mike Frysinger <vapier.adi@gmail.com> | 2009-01-07 10:14:38 -0500 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2009-01-07 10:14:38 -0500 |
commit | c250bfb93c046a789989af475ae18d08c61b4cfa (patch) | |
tree | e666f2d2702eba6ac50df0ec981526f501b26e7a /arch/blackfin | |
parent | 39ca44536d03cc0cd3e8a265d6e5ca1f7dd60719 (diff) |
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>
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/lib/ins.S | 429 |
1 files changed, 84 insertions, 345 deletions
diff --git a/arch/blackfin/lib/ins.S b/arch/blackfin/lib/ins.S index 1b84b21ca7d1..1863a6ba507c 100644 --- a/arch/blackfin/lib/ins.S +++ b/arch/blackfin/lib/ins.S | |||
@@ -1,31 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * File: arch/blackfin/lib/ins.S | 2 | * arch/blackfin/lib/ins.S - ins{bwl} using hardware loops |
3 | * Based on: | ||
4 | * Author: Bas Vermeulen <bas@buyways.nl> | ||
5 | * | 3 | * |
6 | * Created: Tue Mar 22 15:27:24 CEST 2005 | 4 | * Copyright 2004-2008 Analog Devices Inc. |
7 | * Description: Implementation of ins{bwl} for BlackFin processors using zero overhead loops. | 5 | * Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl> |
8 | * | 6 | * Licensed under the GPL-2 or later. |
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 | ||
29 | */ | 7 | */ |
30 | 8 | ||
31 | #include <linux/linkage.h> | 9 | #include <linux/linkage.h> |
@@ -33,6 +11,46 @@ | |||
33 | 11 | ||
34 | .align 2 | 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 | * Reads on the Blackfin are speculative. In Blackfin terms, this means they | 55 | * Reads on the Blackfin are speculative. In Blackfin terms, this means they |
38 | * can be interrupted at any time (even after they have been issued on to the | 56 | * can be interrupted at any time (even after they have been issued on to the |
@@ -53,327 +71,48 @@ | |||
53 | * buffers in/out of FIFOs. | 71 | * buffers in/out of FIFOs. |
54 | */ | 72 | */ |
55 | 73 | ||
56 | ENTRY(_insl) | 74 | #define COMMON_INS(func, ops) \ |
57 | #ifdef CONFIG_BFIN_INS_LOWOVERHEAD | 75 | ENTRY(_ins##func) \ |
58 | P0 = R0; /* P0 = port */ | 76 | P0 = R0; /* P0 = port */ \ |
59 | #ifdef CONFIG_IPIPE | 77 | CLI_OUTER; /* 3 instructions before first read access */ \ |
60 | [--sp] = rets | 78 | P1 = R1; /* P1 = address */ \ |
61 | [--sp] = (P5:0); | 79 | P2 = R2; /* P2 = count */ \ |
62 | sp += -12 | 80 | SSYNC; \ |
63 | call ___ipipe_stall_root_raw | 81 | \ |
64 | sp += 12 | 82 | LSETUP(1f, 2f) LC0 = P2; \ |
65 | (P5:0) = [sp++]; | 83 | CLI_INNER; \ |
66 | #else | 84 | ops; \ |
67 | cli R3; | 85 | STI_INNER; \ |
68 | #endif | 86 | \ |
69 | P1 = R1; /* P1 = address */ | 87 | STI_OUTER; \ |
70 | P2 = R2; /* P2 = count */ | 88 | RTS; \ |
71 | SSYNC; | 89 | ENDPROC(_ins##func) |
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) | ||
118 | 90 | ||
119 | ENTRY(_insw) | 91 | COMMON_INS(l, \ |
120 | #ifdef CONFIG_BFIN_INS_LOWOVERHEAD | 92 | R0 = [P0]; \ |
121 | P0 = R0; /* P0 = port */ | 93 | [P1++] = R0; \ |
122 | #ifdef CONFIG_IPIPE | 94 | ) |
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; | ||
179 | 95 | ||
180 | #endif | 96 | COMMON_INS(w, \ |
181 | ENDPROC(_insw) | 97 | R0 = W[P0]; \ |
98 | W[P1++] = R0; \ | ||
99 | ) | ||
182 | 100 | ||
183 | ENTRY(_insw_8) | 101 | COMMON_INS(w_8, \ |
184 | #ifdef CONFIG_BFIN_INS_LOWOVERHEAD | 102 | R0 = W[P0]; \ |
185 | P0 = R0; /* P0 = port */ | 103 | B[P1++] = R0; \ |
186 | #ifdef CONFIG_IPIPE | 104 | R0 = R0 >> 8; \ |
187 | [--sp] = rets | 105 | B[P1++] = R0; \ |
188 | [--sp] = (P5:0); | 106 | ) |
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) | ||
250 | 107 | ||
251 | ENTRY(_insb) | 108 | COMMON_INS(b, \ |
252 | #ifdef CONFIG_BFIN_INS_LOWOVERHEAD | 109 | R0 = B[P0]; \ |
253 | P0 = R0; /* P0 = port */ | 110 | B[P1++] = R0; \ |
254 | #ifdef CONFIG_IPIPE | 111 | ) |
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) | ||
313 | 112 | ||
314 | ENTRY(_insl_16) | 113 | COMMON_INS(l_16, \ |
315 | #ifdef CONFIG_BFIN_INS_LOWOVERHEAD | 114 | R0 = [P0]; \ |
316 | P0 = R0; /* P0 = port */ | 115 | W[P1++] = R0; \ |
317 | #ifdef CONFIG_IPIPE | 116 | R0 = R0 >> 16; \ |
318 | [--sp] = rets | 117 | W[P1++] = R0; \ |
319 | [--sp] = (P5:0); | 118 | ) |
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) | ||