allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / arch / mips / kernel / unaligned.c
blob51feafe2bcb0cb7b3c41fb2fce64dac5bb835f9b
1 /*
2 * Handle unaligned accesses by emulation.
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.
8 * Copyright (C) 1996, 1998, 1999, 2002 by Ralf Baechle
9 * Copyright (C) 1999 Silicon Graphics, Inc.
11 * This file contains exception handler for address error exception with the
12 * special capability to execute faulting instructions in software. The
13 * handler does not try to handle the case when the program counter points
14 * to an address not aligned to a word boundary.
16 * Putting data to unaligned addresses is a bad practice even on Intel where
17 * only the performance is affected. Much worse is that such code is non-
18 * portable. Due to several programs that die on MIPS due to alignment
19 * problems I decided to implement this handler anyway though I originally
20 * didn't intend to do this at all for user code.
22 * For now I enable fixing of address errors by default to make life easier.
23 * I however intend to disable this somewhen in the future when the alignment
24 * problems with user programs have been fixed. For programmers this is the
25 * right way to go.
27 * Fixing address errors is a per process option. The option is inherited
28 * across fork(2) and execve(2) calls. If you really want to use the
29 * option in your user programs - I discourage the use of the software
30 * emulation strongly - use the following code in your userland stuff:
32 * #include <sys/sysmips.h>
34 * ...
35 * sysmips(MIPS_FIXADE, x);
36 * ...
38 * The argument x is 0 for disabling software emulation, enabled otherwise.
40 * Below a little program to play around with this feature.
42 * #include <stdio.h>
43 * #include <sys/sysmips.h>
45 * struct foo {
46 * unsigned char bar[8];
47 * };
49 * main(int argc, char *argv[])
50 * {
51 * struct foo x = {0, 1, 2, 3, 4, 5, 6, 7};
52 * unsigned int *p = (unsigned int *) (x.bar + 3);
53 * int i;
55 * if (argc > 1)
56 * sysmips(MIPS_FIXADE, atoi(argv[1]));
58 * printf("*p = %08lx\n", *p);
60 * *p = 0xdeadface;
62 * for(i = 0; i <= 7; i++)
63 * printf("%02x ", x.bar[i]);
64 * printf("\n");
65 * }
67 * Coprocessor loads are not supported; I think this case is unimportant
68 * in the practice.
70 * TODO: Handle ndc (attempted store to doubleword in uncached memory)
71 * exception for the R6000.
72 * A store crossing a page boundary might be executed only partially.
73 * Undo the partial store in this case.
75 #include <linux/mm.h>
76 #include <linux/module.h>
77 #include <linux/signal.h>
78 #include <linux/smp.h>
79 #include <linux/sched.h>
80 #include <asm/asm.h>
81 #include <asm/branch.h>
82 #include <asm/byteorder.h>
83 #include <asm/inst.h>
84 #include <asm/uaccess.h>
85 #include <asm/system.h>
87 #define STR(x) __STR(x)
88 #define __STR(x) #x
90 #ifdef CONFIG_PROC_FS
91 unsigned long unaligned_instructions;
92 #endif
94 static inline int emulate_load_store_insn(struct pt_regs *regs,
95 void __user *addr, unsigned int __user *pc,
96 unsigned long **regptr, unsigned long *newvalue)
98 union mips_instruction insn;
99 unsigned long value;
100 unsigned int res;
102 *regptr=NULL;
105 * This load never faults.
107 __get_user(insn.word, pc);
109 switch (insn.i_format.opcode) {
111 * These are instructions that a compiler doesn't generate. We
112 * can assume therefore that the code is MIPS-aware and
113 * really buggy. Emulating these instructions would break the
114 * semantics anyway.
116 case ll_op:
117 case lld_op:
118 case sc_op:
119 case scd_op:
122 * For these instructions the only way to create an address
123 * error is an attempted access to kernel/supervisor address
124 * space.
126 case ldl_op:
127 case ldr_op:
128 case lwl_op:
129 case lwr_op:
130 case sdl_op:
131 case sdr_op:
132 case swl_op:
133 case swr_op:
134 case lb_op:
135 case lbu_op:
136 case sb_op:
137 goto sigbus;
140 * The remaining opcodes are the ones that are really of interest.
142 case lh_op:
143 if (!access_ok(VERIFY_READ, addr, 2))
144 goto sigbus;
146 __asm__ __volatile__ (".set\tnoat\n"
147 #ifdef __BIG_ENDIAN
148 "1:\tlb\t%0, 0(%2)\n"
149 "2:\tlbu\t$1, 1(%2)\n\t"
150 #endif
151 #ifdef __LITTLE_ENDIAN
152 "1:\tlb\t%0, 1(%2)\n"
153 "2:\tlbu\t$1, 0(%2)\n\t"
154 #endif
155 "sll\t%0, 0x8\n\t"
156 "or\t%0, $1\n\t"
157 "li\t%1, 0\n"
158 "3:\t.set\tat\n\t"
159 ".section\t.fixup,\"ax\"\n\t"
160 "4:\tli\t%1, %3\n\t"
161 "j\t3b\n\t"
162 ".previous\n\t"
163 ".section\t__ex_table,\"a\"\n\t"
164 STR(PTR)"\t1b, 4b\n\t"
165 STR(PTR)"\t2b, 4b\n\t"
166 ".previous"
167 : "=&r" (value), "=r" (res)
168 : "r" (addr), "i" (-EFAULT));
169 if (res)
170 goto fault;
171 *newvalue = value;
172 *regptr = &regs->regs[insn.i_format.rt];
173 break;
175 case lw_op:
176 if (!access_ok(VERIFY_READ, addr, 4))
177 goto sigbus;
179 __asm__ __volatile__ (
180 #ifdef __BIG_ENDIAN
181 "1:\tlwl\t%0, (%2)\n"
182 "2:\tlwr\t%0, 3(%2)\n\t"
183 #endif
184 #ifdef __LITTLE_ENDIAN
185 "1:\tlwl\t%0, 3(%2)\n"
186 "2:\tlwr\t%0, (%2)\n\t"
187 #endif
188 "li\t%1, 0\n"
189 "3:\t.section\t.fixup,\"ax\"\n\t"
190 "4:\tli\t%1, %3\n\t"
191 "j\t3b\n\t"
192 ".previous\n\t"
193 ".section\t__ex_table,\"a\"\n\t"
194 STR(PTR)"\t1b, 4b\n\t"
195 STR(PTR)"\t2b, 4b\n\t"
196 ".previous"
197 : "=&r" (value), "=r" (res)
198 : "r" (addr), "i" (-EFAULT));
199 if (res)
200 goto fault;
201 *newvalue = value;
202 *regptr = &regs->regs[insn.i_format.rt];
203 break;
205 case lhu_op:
206 if (!access_ok(VERIFY_READ, addr, 2))
207 goto sigbus;
209 __asm__ __volatile__ (
210 ".set\tnoat\n"
211 #ifdef __BIG_ENDIAN
212 "1:\tlbu\t%0, 0(%2)\n"
213 "2:\tlbu\t$1, 1(%2)\n\t"
214 #endif
215 #ifdef __LITTLE_ENDIAN
216 "1:\tlbu\t%0, 1(%2)\n"
217 "2:\tlbu\t$1, 0(%2)\n\t"
218 #endif
219 "sll\t%0, 0x8\n\t"
220 "or\t%0, $1\n\t"
221 "li\t%1, 0\n"
222 "3:\t.set\tat\n\t"
223 ".section\t.fixup,\"ax\"\n\t"
224 "4:\tli\t%1, %3\n\t"
225 "j\t3b\n\t"
226 ".previous\n\t"
227 ".section\t__ex_table,\"a\"\n\t"
228 STR(PTR)"\t1b, 4b\n\t"
229 STR(PTR)"\t2b, 4b\n\t"
230 ".previous"
231 : "=&r" (value), "=r" (res)
232 : "r" (addr), "i" (-EFAULT));
233 if (res)
234 goto fault;
235 *newvalue = value;
236 *regptr = &regs->regs[insn.i_format.rt];
237 break;
239 case lwu_op:
240 #ifdef CONFIG_64BIT
242 * A 32-bit kernel might be running on a 64-bit processor. But
243 * if we're on a 32-bit processor and an i-cache incoherency
244 * or race makes us see a 64-bit instruction here the sdl/sdr
245 * would blow up, so for now we don't handle unaligned 64-bit
246 * instructions on 32-bit kernels.
248 if (!access_ok(VERIFY_READ, addr, 4))
249 goto sigbus;
251 __asm__ __volatile__ (
252 #ifdef __BIG_ENDIAN
253 "1:\tlwl\t%0, (%2)\n"
254 "2:\tlwr\t%0, 3(%2)\n\t"
255 #endif
256 #ifdef __LITTLE_ENDIAN
257 "1:\tlwl\t%0, 3(%2)\n"
258 "2:\tlwr\t%0, (%2)\n\t"
259 #endif
260 "dsll\t%0, %0, 32\n\t"
261 "dsrl\t%0, %0, 32\n\t"
262 "li\t%1, 0\n"
263 "3:\t.section\t.fixup,\"ax\"\n\t"
264 "4:\tli\t%1, %3\n\t"
265 "j\t3b\n\t"
266 ".previous\n\t"
267 ".section\t__ex_table,\"a\"\n\t"
268 STR(PTR)"\t1b, 4b\n\t"
269 STR(PTR)"\t2b, 4b\n\t"
270 ".previous"
271 : "=&r" (value), "=r" (res)
272 : "r" (addr), "i" (-EFAULT));
273 if (res)
274 goto fault;
275 *newvalue = value;
276 *regptr = &regs->regs[insn.i_format.rt];
277 break;
278 #endif /* CONFIG_64BIT */
280 /* Cannot handle 64-bit instructions in 32-bit kernel */
281 goto sigill;
283 case ld_op:
284 #ifdef CONFIG_64BIT
286 * A 32-bit kernel might be running on a 64-bit processor. But
287 * if we're on a 32-bit processor and an i-cache incoherency
288 * or race makes us see a 64-bit instruction here the sdl/sdr
289 * would blow up, so for now we don't handle unaligned 64-bit
290 * instructions on 32-bit kernels.
292 if (!access_ok(VERIFY_READ, addr, 8))
293 goto sigbus;
295 __asm__ __volatile__ (
296 #ifdef __BIG_ENDIAN
297 "1:\tldl\t%0, (%2)\n"
298 "2:\tldr\t%0, 7(%2)\n\t"
299 #endif
300 #ifdef __LITTLE_ENDIAN
301 "1:\tldl\t%0, 7(%2)\n"
302 "2:\tldr\t%0, (%2)\n\t"
303 #endif
304 "li\t%1, 0\n"
305 "3:\t.section\t.fixup,\"ax\"\n\t"
306 "4:\tli\t%1, %3\n\t"
307 "j\t3b\n\t"
308 ".previous\n\t"
309 ".section\t__ex_table,\"a\"\n\t"
310 STR(PTR)"\t1b, 4b\n\t"
311 STR(PTR)"\t2b, 4b\n\t"
312 ".previous"
313 : "=&r" (value), "=r" (res)
314 : "r" (addr), "i" (-EFAULT));
315 if (res)
316 goto fault;
317 *newvalue = value;
318 *regptr = &regs->regs[insn.i_format.rt];
319 break;
320 #endif /* CONFIG_64BIT */
322 /* Cannot handle 64-bit instructions in 32-bit kernel */
323 goto sigill;
325 case sh_op:
326 if (!access_ok(VERIFY_WRITE, addr, 2))
327 goto sigbus;
329 value = regs->regs[insn.i_format.rt];
330 __asm__ __volatile__ (
331 #ifdef __BIG_ENDIAN
332 ".set\tnoat\n"
333 "1:\tsb\t%1, 1(%2)\n\t"
334 "srl\t$1, %1, 0x8\n"
335 "2:\tsb\t$1, 0(%2)\n\t"
336 ".set\tat\n\t"
337 #endif
338 #ifdef __LITTLE_ENDIAN
339 ".set\tnoat\n"
340 "1:\tsb\t%1, 0(%2)\n\t"
341 "srl\t$1,%1, 0x8\n"
342 "2:\tsb\t$1, 1(%2)\n\t"
343 ".set\tat\n\t"
344 #endif
345 "li\t%0, 0\n"
346 "3:\n\t"
347 ".section\t.fixup,\"ax\"\n\t"
348 "4:\tli\t%0, %3\n\t"
349 "j\t3b\n\t"
350 ".previous\n\t"
351 ".section\t__ex_table,\"a\"\n\t"
352 STR(PTR)"\t1b, 4b\n\t"
353 STR(PTR)"\t2b, 4b\n\t"
354 ".previous"
355 : "=r" (res)
356 : "r" (value), "r" (addr), "i" (-EFAULT));
357 if (res)
358 goto fault;
359 break;
361 case sw_op:
362 if (!access_ok(VERIFY_WRITE, addr, 4))
363 goto sigbus;
365 value = regs->regs[insn.i_format.rt];
366 __asm__ __volatile__ (
367 #ifdef __BIG_ENDIAN
368 "1:\tswl\t%1,(%2)\n"
369 "2:\tswr\t%1, 3(%2)\n\t"
370 #endif
371 #ifdef __LITTLE_ENDIAN
372 "1:\tswl\t%1, 3(%2)\n"
373 "2:\tswr\t%1, (%2)\n\t"
374 #endif
375 "li\t%0, 0\n"
376 "3:\n\t"
377 ".section\t.fixup,\"ax\"\n\t"
378 "4:\tli\t%0, %3\n\t"
379 "j\t3b\n\t"
380 ".previous\n\t"
381 ".section\t__ex_table,\"a\"\n\t"
382 STR(PTR)"\t1b, 4b\n\t"
383 STR(PTR)"\t2b, 4b\n\t"
384 ".previous"
385 : "=r" (res)
386 : "r" (value), "r" (addr), "i" (-EFAULT));
387 if (res)
388 goto fault;
389 break;
391 case sd_op:
392 #ifdef CONFIG_64BIT
394 * A 32-bit kernel might be running on a 64-bit processor. But
395 * if we're on a 32-bit processor and an i-cache incoherency
396 * or race makes us see a 64-bit instruction here the sdl/sdr
397 * would blow up, so for now we don't handle unaligned 64-bit
398 * instructions on 32-bit kernels.
400 if (!access_ok(VERIFY_WRITE, addr, 8))
401 goto sigbus;
403 value = regs->regs[insn.i_format.rt];
404 __asm__ __volatile__ (
405 #ifdef __BIG_ENDIAN
406 "1:\tsdl\t%1,(%2)\n"
407 "2:\tsdr\t%1, 7(%2)\n\t"
408 #endif
409 #ifdef __LITTLE_ENDIAN
410 "1:\tsdl\t%1, 7(%2)\n"
411 "2:\tsdr\t%1, (%2)\n\t"
412 #endif
413 "li\t%0, 0\n"
414 "3:\n\t"
415 ".section\t.fixup,\"ax\"\n\t"
416 "4:\tli\t%0, %3\n\t"
417 "j\t3b\n\t"
418 ".previous\n\t"
419 ".section\t__ex_table,\"a\"\n\t"
420 STR(PTR)"\t1b, 4b\n\t"
421 STR(PTR)"\t2b, 4b\n\t"
422 ".previous"
423 : "=r" (res)
424 : "r" (value), "r" (addr), "i" (-EFAULT));
425 if (res)
426 goto fault;
427 break;
428 #endif /* CONFIG_64BIT */
430 /* Cannot handle 64-bit instructions in 32-bit kernel */
431 goto sigill;
433 case lwc1_op:
434 case ldc1_op:
435 case swc1_op:
436 case sdc1_op:
438 * I herewith declare: this does not happen. So send SIGBUS.
440 goto sigbus;
442 case lwc2_op:
443 case ldc2_op:
444 case swc2_op:
445 case sdc2_op:
447 * These are the coprocessor 2 load/stores. The current
448 * implementations don't use cp2 and cp2 should always be
449 * disabled in c0_status. So send SIGILL.
450 * (No longer true: The Sony Praystation uses cp2 for
451 * 3D matrix operations. Dunno if that thingy has a MMU ...)
453 default:
455 * Pheeee... We encountered an yet unknown instruction or
456 * cache coherence problem. Die sucker, die ...
458 goto sigill;
461 #ifdef CONFIG_PROC_FS
462 unaligned_instructions++;
463 #endif
465 return 0;
467 fault:
468 /* Did we have an exception handler installed? */
469 if (fixup_exception(regs))
470 return 1;
472 die_if_kernel ("Unhandled kernel unaligned access", regs);
473 force_sig(SIGSEGV, current);
475 return 0;
477 sigbus:
478 die_if_kernel("Unhandled kernel unaligned access", regs);
479 force_sig(SIGBUS, current);
481 return 0;
483 sigill:
484 die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs);
485 force_sig(SIGILL, current);
487 return 0;
490 asmlinkage void do_ade(struct pt_regs *regs)
492 unsigned long *regptr, newval;
493 unsigned int __user *pc;
494 mm_segment_t seg;
497 * Did we catch a fault trying to load an instruction?
498 * Or are we running in MIPS16 mode?
500 if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1))
501 goto sigbus;
503 pc = (unsigned int __user *) exception_epc(regs);
504 if (user_mode(regs) && (current->thread.mflags & MF_FIXADE) == 0)
505 goto sigbus;
508 * Do branch emulation only if we didn't forward the exception.
509 * This is all so but ugly ...
511 seg = get_fs();
512 if (!user_mode(regs))
513 set_fs(KERNEL_DS);
514 if (!emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc,
515 &regptr, &newval)) {
516 compute_return_epc(regs);
518 * Now that branch is evaluated, update the dest
519 * register if necessary
521 if (regptr)
522 *regptr = newval;
524 set_fs(seg);
526 return;
528 sigbus:
529 die_if_kernel("Kernel unaligned instruction access", regs);
530 force_sig(SIGBUS, current);
533 * XXX On return from the signal handler we should advance the epc