kernel: add support for 3.9-rc2
[openwrt/openwrt.git] / target / linux / generic / patches-3.9 / 001-mips_fix_code_non_dsp_cpu.patch
1 From f9b4e05597e636a550af8392e80b15f79d9f9e11 Mon Sep 17 00:00:00 2001
2 From: Florian Fainelli <florian@openwrt.org>
3 Date: Thu, 14 Mar 2013 14:07:20 +0100
4 Subject: [PATCH] MIPS: fix code generation for non-DSP capable CPUs
5
6 Commit 32a7ede (MIPS: dsp: Add assembler support for DSP ASEs) has
7 enabled the use of DSP ASE specific instructions such as rddsp and wrdsp
8 under the idea that all code path that will make use of these two
9 instructions are properly checking for cpu_has_dsp to ensure that the
10 particular CPU we are running on *actually* supports DSP ASE.
11
12 This commit actually causes the following oops on QEMU Malta emulating a
13 MIPS 24Kc without the DSP ASE implemented:
14
15 [ 7.960000] Reserved instruction in kernel
16 [ 7.960000] Cpu 0
17 [ 7.960000] $ 0 : 00000000 00000000 00000014 00000005
18 [ 7.960000] $ 4 : 8fc2de48 00000001 00000000 8f59ddb0
19 [ 7.960000] $ 8 : 8f5ceec4 00000018 00000c00 00800000
20 [ 7.960000] $12 : 00000100 00000200 00000000 00457b84
21 [ 7.960000] $16 : 00000000 8fc2ba78 8f4ec980 00000001
22 [ 7.960000] $20 : 80418f90 00000000 00000000 000002dd
23 [ 7.960000] $24 : 0000009c 7730d7b8
24 [ 7.960000] $28 : 8f59c000 8f59dd38 00000001 80104248
25 [ 7.960000] Hi : 0000001d
26 [ 7.960000] Lo : 0000000b
27 [ 7.960000] epc : 801041ec thread_saved_pc+0x2c/0x38
28 [ 7.960000] Not tainted
29 [ 7.960000] ra : 80104248 get_wchan+0x48/0xac
30 [ 7.960000] Status: 1000b703 KERNEL EXL IE
31 [ 7.960000] Cause : 10800028
32 [ 7.960000] PrId : 00019300 (MIPS 24Kc)
33 [ 7.960000] Modules linked in:
34 [ 7.960000] Process killall (pid: 1574, threadinfo=8f59c000,
35 task=8fd14558, tls=773aa440)
36 [ 7.960000] Stack : 8fc2ba78 8012b008 0000000c 0000001d 00000000
37 00000000 8f58a380
38 8f58a380 8fc2ba78 80202668 8f59de78 8f468600 8f59de28
39 801b2a3c 8f59df00 8f98ba20 74696e69
40 8f468600 8f59de28 801b7308 0081c007 00000000 00000000
41 00000000 00000000 00000000 00000000
42 00000000 8fc2bbb4 00000001 0000001d 0000000b 77f038cc
43 7fe80648 ffffffff ffffffff 00000000
44 00000001 0016e000 00000000 ...
45 [ 7.960000] Call Trace:
46 [ 7.960000] [<801041ec>] thread_saved_pc+0x2c/0x38
47 [ 7.960000] [<80104248>] get_wchan+0x48/0xac
48
49 The disassembly of thread_saved_pc points to the following:
50 000006d0 <thread_saved_pc>:
51 6d0: 8c820208 lw v0,520(a0)
52 6d4: 3c030000 lui v1,0x0
53 6d8: 24630000 addiu v1,v1,0
54 6dc: 10430008 beq v0,v1,700 <thread_saved_pc+0x30>
55 6e0: 00000000 nop
56 6e4: 3c020000 lui v0,0x0
57 6e8: 8c43000c lw v1,12(v0)
58 6ec: 04620004 bltzl v1,700 <thread_saved_pc+0x30>
59 6f0: 00001021 move v0,zero
60 6f4: 8c840200 lw a0,512(a0)
61 6f8: 00031080 sll v0,v1,0x2
62 6fc: 7c44100a lwx v0,a0(v0) <------------
63 700: 03e00008 jr ra
64 704: 00000000 nop
65
66 If we specifically disable -mdsp/-mdspr2 for arch/mips/kernel/process.o,
67 we get the following (non-crashing) assembly:
68
69 00000708 <thread_saved_pc>:
70 708: 8c820208 lw v0,520(a0)
71 70c: 3c030000 lui v1,0x0
72 710: 24630000 addiu v1,v1,0
73 714: 10430009 beq v0,v1,73c <thread_saved_pc+0x34>
74 718: 00000000 nop
75 71c: 3c020000 lui v0,0x0
76 720: 8c42000c lw v0,12(v0)
77 724: 04420005 bltzl v0,73c <thread_saved_pc+0x34>
78 728: 00001021 move v0,zero
79 72c: 8c830200 lw v1,512(a0)
80 730: 00021080 sll v0,v0,0x2
81 734: 00431021 addu v0,v0,v1
82 738: 8c420000 lw v0,0(v0)
83 73c: 03e00008 jr ra
84 740: 00000000 nop
85
86 The specific line that leads a different assembly being produced is:
87
88 unsigned long thread_saved_pc(struct task_struct *tsk)
89 ...
90 return ((unsigned long *)t->reg29)[schedule_mfi.pc_offset]; <---
91
92 The problem here is that the compiler was given the right to use DSP
93 instructions with the -mdsp / -mdspr2 command-line switches and
94 performed some optimization for us and used DSP ASE instructions where
95 we are not checking that the running CPU actually supports DSP ASE.
96
97 This patch fixes the issue by partially reverting commit 32a7ede for
98 arch/mips/kernel/Makefile in order to remove the -mdsp / -mdspr2
99 compiler command-line switches such that we are now guaranteed that the
100 compiler will not optimize using DSP ASE reserved instructions. We also
101 need to fixup the rddsp/wrdsp and m{t,h}{hi,lo}{0,1,2,3} macros in
102 arch/mips/include/asm/mipsregs.h to tell the assembler that we are going
103 to explicitely use DSP ASE reserved instructions.
104
105 Signed-off-by: Florian Fainelli <florian@openwrt.org>
106 ---
107 Ralf, John,
108
109 This should be part of your 3.9-rc3 pull request if I may ;)
110
111 arch/mips/include/asm/mipsregs.h | 209 ++++++++++++++++++++++++++++++++++----
112 arch/mips/kernel/Makefile | 14 ---
113 2 files changed, 190 insertions(+), 33 deletions(-)
114
115 diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
116 index 12b70c2..0da44d4 100644
117 --- a/arch/mips/include/asm/mipsregs.h
118 +++ b/arch/mips/include/asm/mipsregs.h
119 @@ -1166,7 +1166,10 @@ do { \
120 unsigned int __dspctl; \
121 \
122 __asm__ __volatile__( \
123 + " .set push \n" \
124 + " .set dsp \n" \
125 " rddsp %0, %x1 \n" \
126 + " .set pop \n" \
127 : "=r" (__dspctl) \
128 : "i" (mask)); \
129 __dspctl; \
130 @@ -1175,30 +1178,198 @@ do { \
131 #define wrdsp(val, mask) \
132 do { \
133 __asm__ __volatile__( \
134 + " .set push \n" \
135 + " .set dsp \n" \
136 " wrdsp %0, %x1 \n" \
137 + " .set pop \n" \
138 : \
139 : "r" (val), "i" (mask)); \
140 } while (0)
141
142 -#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;})
143 -#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;})
144 -#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;})
145 -#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;})
146 -
147 -#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;})
148 -#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;})
149 -#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;})
150 -#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;})
151 -
152 -#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x))
153 -#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x))
154 -#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x))
155 -#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x))
156 -
157 -#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x))
158 -#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x))
159 -#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x))
160 -#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x))
161 +#define mflo0() \
162 +({ \
163 + long mflo0; \
164 + __asm__( \
165 + " .set push \n" \
166 + " .set dsp \n" \
167 + " mflo %0, $ac0 \n" \
168 + " .set pop \n" \
169 + : "=r" (mflo0)); \
170 + mflo0; \
171 +})
172 +
173 +#define mflo1() \
174 +({ \
175 + long mflo1; \
176 + __asm__( \
177 + " .set push \n" \
178 + " .set dsp \n" \
179 + " mflo %0, $ac1 \n" \
180 + " .set pop \n" \
181 + : "=r" (mflo1)); \
182 + mflo1; \
183 +})
184 +
185 +#define mflo2() \
186 +({ \
187 + long mflo2; \
188 + __asm__( \
189 + " .set push \n" \
190 + " .set dsp \n" \
191 + " mflo %0, $ac2 \n" \
192 + " .set pop \n" \
193 + : "=r" (mflo2)); \
194 + mflo2; \
195 +})
196 +
197 +#define mflo3() \
198 +({ \
199 + long mflo3; \
200 + __asm__( \
201 + " .set push \n" \
202 + " .set dsp \n" \
203 + " mflo %0, $ac3 \n" \
204 + " .set pop \n" \
205 + : "=r" (mflo3)); \
206 + mflo3; \
207 +})
208 +
209 +#define mfhi0() \
210 +({ \
211 + long mfhi0; \
212 + __asm__( \
213 + " .set push \n" \
214 + " .set dsp \n" \
215 + " mfhi %0, $ac0 \n" \
216 + " .set pop \n" \
217 + : "=r" (mfhi0)); \
218 + mfhi0; \
219 +})
220 +
221 +#define mfhi1() \
222 +({ \
223 + long mfhi1; \
224 + __asm__( \
225 + " .set push \n" \
226 + " .set dsp \n" \
227 + " mfhi %0, $ac1 \n" \
228 + " .set pop \n" \
229 + : "=r" (mfhi1)); \
230 + mfhi1; \
231 +})
232 +
233 +#define mfhi2() \
234 +({ \
235 + long mfhi2; \
236 + __asm__( \
237 + " .set push \n" \
238 + " .set dsp \n" \
239 + " mfhi %0, $ac2 \n" \
240 + " .set pop \n" \
241 + : "=r" (mfhi2)); \
242 + mfhi2; \
243 +})
244 +
245 +#define mfhi3() \
246 +({ \
247 + long mfhi3; \
248 + __asm__( \
249 + " .set push \n" \
250 + " .set dsp \n" \
251 + " mfhi %0, $ac3 \n" \
252 + " .set pop \n" \
253 + : "=r" (mfhi3)); \
254 + mfhi3; \
255 +})
256 +
257 +
258 +#define mtlo0(x) \
259 +({ \
260 + __asm__( \
261 + " .set push \n" \
262 + " .set dsp \n" \
263 + " mtlo %0, $ac0 \n" \
264 + " .set pop \n" \
265 + : \
266 + : "r" (x)); \
267 +})
268 +
269 +#define mtlo1(x) \
270 +({ \
271 + __asm__( \
272 + " .set push \n" \
273 + " .set dsp \n" \
274 + " mtlo %0, $ac1 \n" \
275 + " .set pop \n" \
276 + : \
277 + : "r" (x)); \
278 +})
279 +
280 +#define mtlo2(x) \
281 +({ \
282 + __asm__( \
283 + " .set push \n" \
284 + " .set dsp \n" \
285 + " mtlo %0, $ac2 \n" \
286 + " .set pop \n" \
287 + : \
288 + : "r" (x)); \
289 +})
290 +
291 +#define mtlo3(x) \
292 +({ \
293 + __asm__( \
294 + " .set push \n" \
295 + " .set dsp \n" \
296 + " mtlo %0, $ac3 \n" \
297 + " .set pop \n" \
298 + : \
299 + : "r" (x)); \
300 +})
301 +
302 +#define mthi0(x) \
303 +({ \
304 + __asm__( \
305 + " .set push \n" \
306 + " .set dsp \n" \
307 + " mthi %0, $ac0 \n" \
308 + " .set pop \n" \
309 + : \
310 + : "r" (x)); \
311 +})
312 +
313 +#define mthi1(x) \
314 +({ \
315 + __asm__( \
316 + " .set push \n" \
317 + " .set dsp \n" \
318 + " mthi %0, $ac1 \n" \
319 + " .set pop \n" \
320 + : \
321 + : "r" (x)); \
322 +})
323 +
324 +#define mthi2(x) \
325 +({ \
326 + __asm__( \
327 + " .set push \n" \
328 + " .set dsp \n" \
329 + " mthi %0, $ac2 \n" \
330 + " .set pop \n" \
331 + : \
332 + : "r" (x)); \
333 +})
334 +
335 +#define mthi3(x) \
336 +({ \
337 + __asm__( \
338 + " .set push \n" \
339 + " .set dsp \n" \
340 + " mthi %0, $ac3 \n" \
341 + " .set pop \n" \
342 + : \
343 + : "r" (x)); \
344 +})
345
346 #else
347
348 diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
349 index f81d98f..2e8a9c1 100644
350 --- a/arch/mips/kernel/Makefile
351 +++ b/arch/mips/kernel/Makefile
352 @@ -109,20 +109,6 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
353 ifeq ($(CONFIG_CPU_MIPSR2), y)
354 CFLAGS_DSP = -DHAVE_AS_DSP
355
356 -#
357 -# Check if assembler supports DSP ASE
358 -#
359 -ifeq ($(call cc-option-yn,-mdsp), y)
360 -CFLAGS_DSP += -mdsp
361 -endif
362 -
363 -#
364 -# Check if assembler supports DSP ASE Rev2
365 -#
366 -ifeq ($(call cc-option-yn,-mdspr2), y)
367 -CFLAGS_DSP += -mdspr2
368 -endif
369 -
370 CFLAGS_signal.o = $(CFLAGS_DSP)
371 CFLAGS_signal32.o = $(CFLAGS_DSP)
372 CFLAGS_process.o = $(CFLAGS_DSP)
373 --
374 1.7.10.4
375