traps_32.c revision ba84be2338d3a2b6020d39279335bb06fcd332e1
1/* 2 * 'traps.c' handles hardware traps and faults after we have saved some 3 * state in 'entry.S'. 4 * 5 * SuperH version: Copyright (C) 1999 Niibe Yutaka 6 * Copyright (C) 2000 Philipp Rumpf 7 * Copyright (C) 2000 David Howells 8 * Copyright (C) 2002 - 2007 Paul Mundt 9 * 10 * This file is subject to the terms and conditions of the GNU General Public 11 * License. See the file "COPYING" in the main directory of this archive 12 * for more details. 13 */ 14#include <linux/kernel.h> 15#include <linux/ptrace.h> 16#include <linux/hardirq.h> 17#include <linux/init.h> 18#include <linux/spinlock.h> 19#include <linux/module.h> 20#include <linux/kallsyms.h> 21#include <linux/io.h> 22#include <linux/bug.h> 23#include <linux/debug_locks.h> 24#include <linux/kdebug.h> 25#include <linux/kexec.h> 26#include <linux/limits.h> 27#include <asm/system.h> 28#include <asm/uaccess.h> 29#include <asm/fpu.h> 30#include <asm/kprobes.h> 31 32#ifdef CONFIG_CPU_SH2 33# define TRAP_RESERVED_INST 4 34# define TRAP_ILLEGAL_SLOT_INST 6 35# define TRAP_ADDRESS_ERROR 9 36# ifdef CONFIG_CPU_SH2A 37# define TRAP_FPU_ERROR 13 38# define TRAP_DIVZERO_ERROR 17 39# define TRAP_DIVOVF_ERROR 18 40# endif 41#else 42#define TRAP_RESERVED_INST 12 43#define TRAP_ILLEGAL_SLOT_INST 13 44#endif 45 46static void dump_mem(const char *str, unsigned long bottom, unsigned long top) 47{ 48 unsigned long p; 49 int i; 50 51 printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); 52 53 for (p = bottom & ~31; p < top; ) { 54 printk("%04lx: ", p & 0xffff); 55 56 for (i = 0; i < 8; i++, p += 4) { 57 unsigned int val; 58 59 if (p < bottom || p >= top) 60 printk(" "); 61 else { 62 if (__get_user(val, (unsigned int __user *)p)) { 63 printk("\n"); 64 return; 65 } 66 printk("%08x ", val); 67 } 68 } 69 printk("\n"); 70 } 71} 72 73static DEFINE_SPINLOCK(die_lock); 74 75void die(const char * str, struct pt_regs * regs, long err) 76{ 77 static int die_counter; 78 79 oops_enter(); 80 81 console_verbose(); 82 spin_lock_irq(&die_lock); 83 bust_spinlocks(1); 84 85 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); 86 87 print_modules(); 88 show_regs(regs); 89 90 printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm, 91 task_pid_nr(current), task_stack_page(current) + 1); 92 93 if (!user_mode(regs) || in_interrupt()) 94 dump_mem("Stack: ", regs->regs[15], THREAD_SIZE + 95 (unsigned long)task_stack_page(current)); 96 97 notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV); 98 99 bust_spinlocks(0); 100 add_taint(TAINT_DIE); 101 spin_unlock_irq(&die_lock); 102 103 if (kexec_should_crash(current)) 104 crash_kexec(regs); 105 106 if (in_interrupt()) 107 panic("Fatal exception in interrupt"); 108 109 if (panic_on_oops) 110 panic("Fatal exception"); 111 112 oops_exit(); 113 do_exit(SIGSEGV); 114} 115 116static inline void die_if_kernel(const char *str, struct pt_regs *regs, 117 long err) 118{ 119 if (!user_mode(regs)) 120 die(str, regs, err); 121} 122 123/* 124 * try and fix up kernelspace address errors 125 * - userspace errors just cause EFAULT to be returned, resulting in SEGV 126 * - kernel/userspace interfaces cause a jump to an appropriate handler 127 * - other kernel errors are bad 128 * - return 0 if fixed-up, -EFAULT if non-fatal (to the kernel) fault 129 */ 130static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err) 131{ 132 if (!user_mode(regs)) { 133 const struct exception_table_entry *fixup; 134 fixup = search_exception_tables(regs->pc); 135 if (fixup) { 136 regs->pc = fixup->fixup; 137 return 0; 138 } 139 die(str, regs, err); 140 } 141 return -EFAULT; 142} 143 144static inline void sign_extend(unsigned int count, unsigned char *dst) 145{ 146#ifdef __LITTLE_ENDIAN__ 147 if ((count == 1) && dst[0] & 0x80) { 148 dst[1] = 0xff; 149 dst[2] = 0xff; 150 dst[3] = 0xff; 151 } 152 if ((count == 2) && dst[1] & 0x80) { 153 dst[2] = 0xff; 154 dst[3] = 0xff; 155 } 156#else 157 if ((count == 1) && dst[3] & 0x80) { 158 dst[2] = 0xff; 159 dst[1] = 0xff; 160 dst[0] = 0xff; 161 } 162 if ((count == 2) && dst[2] & 0x80) { 163 dst[1] = 0xff; 164 dst[0] = 0xff; 165 } 166#endif 167} 168 169static struct mem_access user_mem_access = { 170 copy_from_user, 171 copy_to_user, 172}; 173 174/* 175 * handle an instruction that does an unaligned memory access by emulating the 176 * desired behaviour 177 * - note that PC _may not_ point to the faulting instruction 178 * (if that instruction is in a branch delay slot) 179 * - return 0 if emulation okay, -EFAULT on existential error 180 */ 181static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs, 182 struct mem_access *ma) 183{ 184 int ret, index, count; 185 unsigned long *rm, *rn; 186 unsigned char *src, *dst; 187 unsigned char __user *srcu, *dstu; 188 189 index = (instruction>>8)&15; /* 0x0F00 */ 190 rn = ®s->regs[index]; 191 192 index = (instruction>>4)&15; /* 0x00F0 */ 193 rm = ®s->regs[index]; 194 195 count = 1<<(instruction&3); 196 197 ret = -EFAULT; 198 switch (instruction>>12) { 199 case 0: /* mov.[bwl] to/from memory via r0+rn */ 200 if (instruction & 8) { 201 /* from memory */ 202 srcu = (unsigned char __user *)*rm; 203 srcu += regs->regs[0]; 204 dst = (unsigned char *)rn; 205 *(unsigned long *)dst = 0; 206 207#if !defined(__LITTLE_ENDIAN__) 208 dst += 4-count; 209#endif 210 if (ma->from(dst, srcu, count)) 211 goto fetch_fault; 212 213 sign_extend(count, dst); 214 } else { 215 /* to memory */ 216 src = (unsigned char *)rm; 217#if !defined(__LITTLE_ENDIAN__) 218 src += 4-count; 219#endif 220 dstu = (unsigned char __user *)*rn; 221 dstu += regs->regs[0]; 222 223 if (ma->to(dstu, src, count)) 224 goto fetch_fault; 225 } 226 ret = 0; 227 break; 228 229 case 1: /* mov.l Rm,@(disp,Rn) */ 230 src = (unsigned char*) rm; 231 dstu = (unsigned char __user *)*rn; 232 dstu += (instruction&0x000F)<<2; 233 234 if (ma->to(dstu, src, 4)) 235 goto fetch_fault; 236 ret = 0; 237 break; 238 239 case 2: /* mov.[bwl] to memory, possibly with pre-decrement */ 240 if (instruction & 4) 241 *rn -= count; 242 src = (unsigned char*) rm; 243 dstu = (unsigned char __user *)*rn; 244#if !defined(__LITTLE_ENDIAN__) 245 src += 4-count; 246#endif 247 if (ma->to(dstu, src, count)) 248 goto fetch_fault; 249 ret = 0; 250 break; 251 252 case 5: /* mov.l @(disp,Rm),Rn */ 253 srcu = (unsigned char __user *)*rm; 254 srcu += (instruction & 0x000F) << 2; 255 dst = (unsigned char *)rn; 256 *(unsigned long *)dst = 0; 257 258 if (ma->from(dst, srcu, 4)) 259 goto fetch_fault; 260 ret = 0; 261 break; 262 263 case 6: /* mov.[bwl] from memory, possibly with post-increment */ 264 srcu = (unsigned char __user *)*rm; 265 if (instruction & 4) 266 *rm += count; 267 dst = (unsigned char*) rn; 268 *(unsigned long*)dst = 0; 269 270#if !defined(__LITTLE_ENDIAN__) 271 dst += 4-count; 272#endif 273 if (ma->from(dst, srcu, count)) 274 goto fetch_fault; 275 sign_extend(count, dst); 276 ret = 0; 277 break; 278 279 case 8: 280 switch ((instruction&0xFF00)>>8) { 281 case 0x81: /* mov.w R0,@(disp,Rn) */ 282 src = (unsigned char *) ®s->regs[0]; 283#if !defined(__LITTLE_ENDIAN__) 284 src += 2; 285#endif 286 dstu = (unsigned char __user *)*rm; /* called Rn in the spec */ 287 dstu += (instruction & 0x000F) << 1; 288 289 if (ma->to(dstu, src, 2)) 290 goto fetch_fault; 291 ret = 0; 292 break; 293 294 case 0x85: /* mov.w @(disp,Rm),R0 */ 295 srcu = (unsigned char __user *)*rm; 296 srcu += (instruction & 0x000F) << 1; 297 dst = (unsigned char *) ®s->regs[0]; 298 *(unsigned long *)dst = 0; 299 300#if !defined(__LITTLE_ENDIAN__) 301 dst += 2; 302#endif 303 if (ma->from(dst, srcu, 2)) 304 goto fetch_fault; 305 sign_extend(2, dst); 306 ret = 0; 307 break; 308 } 309 break; 310 } 311 return ret; 312 313 fetch_fault: 314 /* Argh. Address not only misaligned but also non-existent. 315 * Raise an EFAULT and see if it's trapped 316 */ 317 return die_if_no_fixup("Fault in unaligned fixup", regs, 0); 318} 319 320/* 321 * emulate the instruction in the delay slot 322 * - fetches the instruction from PC+2 323 */ 324static inline int handle_delayslot(struct pt_regs *regs, 325 opcode_t old_instruction, 326 struct mem_access *ma) 327{ 328 opcode_t instruction; 329 void __user *addr = (void __user *)(regs->pc + 330 instruction_size(old_instruction)); 331 332 if (copy_from_user(&instruction, addr, sizeof(instruction))) { 333 /* the instruction-fetch faulted */ 334 if (user_mode(regs)) 335 return -EFAULT; 336 337 /* kernel */ 338 die("delay-slot-insn faulting in handle_unaligned_delayslot", 339 regs, 0); 340 } 341 342 return handle_unaligned_ins(instruction, regs, ma); 343} 344 345/* 346 * handle an instruction that does an unaligned memory access 347 * - have to be careful of branch delay-slot instructions that fault 348 * SH3: 349 * - if the branch would be taken PC points to the branch 350 * - if the branch would not be taken, PC points to delay-slot 351 * SH4: 352 * - PC always points to delayed branch 353 * - return 0 if handled, -EFAULT if failed (may not return if in kernel) 354 */ 355 356/* Macros to determine offset from current PC for branch instructions */ 357/* Explicit type coercion is used to force sign extension where needed */ 358#define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4) 359#define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4) 360 361/* 362 * XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit 363 * opcodes.. 364 */ 365 366static int handle_unaligned_notify_count = 10; 367 368int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs, 369 struct mem_access *ma) 370{ 371 u_int rm; 372 int ret, index; 373 374 index = (instruction>>8)&15; /* 0x0F00 */ 375 rm = regs->regs[index]; 376 377 /* shout about the first ten userspace fixups */ 378 if (user_mode(regs) && handle_unaligned_notify_count>0) { 379 handle_unaligned_notify_count--; 380 381 printk(KERN_NOTICE "Fixing up unaligned userspace access " 382 "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", 383 current->comm, task_pid_nr(current), 384 (void *)regs->pc, instruction); 385 } 386 387 ret = -EFAULT; 388 switch (instruction&0xF000) { 389 case 0x0000: 390 if (instruction==0x000B) { 391 /* rts */ 392 ret = handle_delayslot(regs, instruction, ma); 393 if (ret==0) 394 regs->pc = regs->pr; 395 } 396 else if ((instruction&0x00FF)==0x0023) { 397 /* braf @Rm */ 398 ret = handle_delayslot(regs, instruction, ma); 399 if (ret==0) 400 regs->pc += rm + 4; 401 } 402 else if ((instruction&0x00FF)==0x0003) { 403 /* bsrf @Rm */ 404 ret = handle_delayslot(regs, instruction, ma); 405 if (ret==0) { 406 regs->pr = regs->pc + 4; 407 regs->pc += rm + 4; 408 } 409 } 410 else { 411 /* mov.[bwl] to/from memory via r0+rn */ 412 goto simple; 413 } 414 break; 415 416 case 0x1000: /* mov.l Rm,@(disp,Rn) */ 417 goto simple; 418 419 case 0x2000: /* mov.[bwl] to memory, possibly with pre-decrement */ 420 goto simple; 421 422 case 0x4000: 423 if ((instruction&0x00FF)==0x002B) { 424 /* jmp @Rm */ 425 ret = handle_delayslot(regs, instruction, ma); 426 if (ret==0) 427 regs->pc = rm; 428 } 429 else if ((instruction&0x00FF)==0x000B) { 430 /* jsr @Rm */ 431 ret = handle_delayslot(regs, instruction, ma); 432 if (ret==0) { 433 regs->pr = regs->pc + 4; 434 regs->pc = rm; 435 } 436 } 437 else { 438 /* mov.[bwl] to/from memory via r0+rn */ 439 goto simple; 440 } 441 break; 442 443 case 0x5000: /* mov.l @(disp,Rm),Rn */ 444 goto simple; 445 446 case 0x6000: /* mov.[bwl] from memory, possibly with post-increment */ 447 goto simple; 448 449 case 0x8000: /* bf lab, bf/s lab, bt lab, bt/s lab */ 450 switch (instruction&0x0F00) { 451 case 0x0100: /* mov.w R0,@(disp,Rm) */ 452 goto simple; 453 case 0x0500: /* mov.w @(disp,Rm),R0 */ 454 goto simple; 455 case 0x0B00: /* bf lab - no delayslot*/ 456 break; 457 case 0x0F00: /* bf/s lab */ 458 ret = handle_delayslot(regs, instruction, ma); 459 if (ret==0) { 460#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) 461 if ((regs->sr & 0x00000001) != 0) 462 regs->pc += 4; /* next after slot */ 463 else 464#endif 465 regs->pc += SH_PC_8BIT_OFFSET(instruction); 466 } 467 break; 468 case 0x0900: /* bt lab - no delayslot */ 469 break; 470 case 0x0D00: /* bt/s lab */ 471 ret = handle_delayslot(regs, instruction, ma); 472 if (ret==0) { 473#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) 474 if ((regs->sr & 0x00000001) == 0) 475 regs->pc += 4; /* next after slot */ 476 else 477#endif 478 regs->pc += SH_PC_8BIT_OFFSET(instruction); 479 } 480 break; 481 } 482 break; 483 484 case 0xA000: /* bra label */ 485 ret = handle_delayslot(regs, instruction, ma); 486 if (ret==0) 487 regs->pc += SH_PC_12BIT_OFFSET(instruction); 488 break; 489 490 case 0xB000: /* bsr label */ 491 ret = handle_delayslot(regs, instruction, ma); 492 if (ret==0) { 493 regs->pr = regs->pc + 4; 494 regs->pc += SH_PC_12BIT_OFFSET(instruction); 495 } 496 break; 497 } 498 return ret; 499 500 /* handle non-delay-slot instruction */ 501 simple: 502 ret = handle_unaligned_ins(instruction, regs, ma); 503 if (ret==0) 504 regs->pc += instruction_size(instruction); 505 return ret; 506} 507 508/* 509 * Handle various address error exceptions: 510 * - instruction address error: 511 * misaligned PC 512 * PC >= 0x80000000 in user mode 513 * - data address error (read and write) 514 * misaligned data access 515 * access to >= 0x80000000 is user mode 516 * Unfortuntaly we can't distinguish between instruction address error 517 * and data address errors caused by read accesses. 518 */ 519asmlinkage void do_address_error(struct pt_regs *regs, 520 unsigned long writeaccess, 521 unsigned long address) 522{ 523 unsigned long error_code = 0; 524 mm_segment_t oldfs; 525 siginfo_t info; 526 opcode_t instruction; 527 int tmp; 528 529 /* Intentional ifdef */ 530#ifdef CONFIG_CPU_HAS_SR_RB 531 error_code = lookup_exception_vector(); 532#endif 533 534 oldfs = get_fs(); 535 536 if (user_mode(regs)) { 537 int si_code = BUS_ADRERR; 538 539 local_irq_enable(); 540 541 /* bad PC is not something we can fix */ 542 if (regs->pc & 1) { 543 si_code = BUS_ADRALN; 544 goto uspace_segv; 545 } 546 547 set_fs(USER_DS); 548 if (copy_from_user(&instruction, (void __user *)(regs->pc), 549 sizeof(instruction))) { 550 /* Argh. Fault on the instruction itself. 551 This should never happen non-SMP 552 */ 553 set_fs(oldfs); 554 goto uspace_segv; 555 } 556 557 tmp = handle_unaligned_access(instruction, regs, 558 &user_mem_access); 559 set_fs(oldfs); 560 561 if (tmp==0) 562 return; /* sorted */ 563uspace_segv: 564 printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned " 565 "access (PC %lx PR %lx)\n", current->comm, regs->pc, 566 regs->pr); 567 568 info.si_signo = SIGBUS; 569 info.si_errno = 0; 570 info.si_code = si_code; 571 info.si_addr = (void __user *)address; 572 force_sig_info(SIGBUS, &info, current); 573 } else { 574 if (regs->pc & 1) 575 die("unaligned program counter", regs, error_code); 576 577 set_fs(KERNEL_DS); 578 if (copy_from_user(&instruction, (void __user *)(regs->pc), 579 sizeof(instruction))) { 580 /* Argh. Fault on the instruction itself. 581 This should never happen non-SMP 582 */ 583 set_fs(oldfs); 584 die("insn faulting in do_address_error", regs, 0); 585 } 586 587 handle_unaligned_access(instruction, regs, &user_mem_access); 588 set_fs(oldfs); 589 } 590} 591 592#ifdef CONFIG_SH_DSP 593/* 594 * SH-DSP support gerg@snapgear.com. 595 */ 596int is_dsp_inst(struct pt_regs *regs) 597{ 598 unsigned short inst = 0; 599 600 /* 601 * Safe guard if DSP mode is already enabled or we're lacking 602 * the DSP altogether. 603 */ 604 if (!(current_cpu_data.flags & CPU_HAS_DSP) || (regs->sr & SR_DSP)) 605 return 0; 606 607 get_user(inst, ((unsigned short *) regs->pc)); 608 609 inst &= 0xf000; 610 611 /* Check for any type of DSP or support instruction */ 612 if ((inst == 0xf000) || (inst == 0x4000)) 613 return 1; 614 615 return 0; 616} 617#else 618#define is_dsp_inst(regs) (0) 619#endif /* CONFIG_SH_DSP */ 620 621#ifdef CONFIG_CPU_SH2A 622asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, 623 unsigned long r6, unsigned long r7, 624 struct pt_regs __regs) 625{ 626 siginfo_t info; 627 628 switch (r4) { 629 case TRAP_DIVZERO_ERROR: 630 info.si_code = FPE_INTDIV; 631 break; 632 case TRAP_DIVOVF_ERROR: 633 info.si_code = FPE_INTOVF; 634 break; 635 } 636 637 force_sig_info(SIGFPE, &info, current); 638} 639#endif 640 641asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, 642 unsigned long r6, unsigned long r7, 643 struct pt_regs __regs) 644{ 645 struct pt_regs *regs = RELOC_HIDE(&__regs, 0); 646 unsigned long error_code; 647 struct task_struct *tsk = current; 648 649#ifdef CONFIG_SH_FPU_EMU 650 unsigned short inst = 0; 651 int err; 652 653 get_user(inst, (unsigned short*)regs->pc); 654 655 err = do_fpu_inst(inst, regs); 656 if (!err) { 657 regs->pc += instruction_size(inst); 658 return; 659 } 660 /* not a FPU inst. */ 661#endif 662 663#ifdef CONFIG_SH_DSP 664 /* Check if it's a DSP instruction */ 665 if (is_dsp_inst(regs)) { 666 /* Enable DSP mode, and restart instruction. */ 667 regs->sr |= SR_DSP; 668 return; 669 } 670#endif 671 672 error_code = lookup_exception_vector(); 673 674 local_irq_enable(); 675 force_sig(SIGILL, tsk); 676 die_if_no_fixup("reserved instruction", regs, error_code); 677} 678 679#ifdef CONFIG_SH_FPU_EMU 680static int emulate_branch(unsigned short inst, struct pt_regs *regs) 681{ 682 /* 683 * bfs: 8fxx: PC+=d*2+4; 684 * bts: 8dxx: PC+=d*2+4; 685 * bra: axxx: PC+=D*2+4; 686 * bsr: bxxx: PC+=D*2+4 after PR=PC+4; 687 * braf:0x23: PC+=Rn*2+4; 688 * bsrf:0x03: PC+=Rn*2+4 after PR=PC+4; 689 * jmp: 4x2b: PC=Rn; 690 * jsr: 4x0b: PC=Rn after PR=PC+4; 691 * rts: 000b: PC=PR; 692 */ 693 if (((inst & 0xf000) == 0xb000) || /* bsr */ 694 ((inst & 0xf0ff) == 0x0003) || /* bsrf */ 695 ((inst & 0xf0ff) == 0x400b)) /* jsr */ 696 regs->pr = regs->pc + 4; 697 698 if ((inst & 0xfd00) == 0x8d00) { /* bfs, bts */ 699 regs->pc += SH_PC_8BIT_OFFSET(inst); 700 return 0; 701 } 702 703 if ((inst & 0xe000) == 0xa000) { /* bra, bsr */ 704 regs->pc += SH_PC_12BIT_OFFSET(inst); 705 return 0; 706 } 707 708 if ((inst & 0xf0df) == 0x0003) { /* braf, bsrf */ 709 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4; 710 return 0; 711 } 712 713 if ((inst & 0xf0df) == 0x400b) { /* jmp, jsr */ 714 regs->pc = regs->regs[(inst & 0x0f00) >> 8]; 715 return 0; 716 } 717 718 if ((inst & 0xffff) == 0x000b) { /* rts */ 719 regs->pc = regs->pr; 720 return 0; 721 } 722 723 return 1; 724} 725#endif 726 727asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, 728 unsigned long r6, unsigned long r7, 729 struct pt_regs __regs) 730{ 731 struct pt_regs *regs = RELOC_HIDE(&__regs, 0); 732 unsigned long inst; 733 struct task_struct *tsk = current; 734 735 if (kprobe_handle_illslot(regs->pc) == 0) 736 return; 737 738#ifdef CONFIG_SH_FPU_EMU 739 get_user(inst, (unsigned short *)regs->pc + 1); 740 if (!do_fpu_inst(inst, regs)) { 741 get_user(inst, (unsigned short *)regs->pc); 742 if (!emulate_branch(inst, regs)) 743 return; 744 /* fault in branch.*/ 745 } 746 /* not a FPU inst. */ 747#endif 748 749 inst = lookup_exception_vector(); 750 751 local_irq_enable(); 752 force_sig(SIGILL, tsk); 753 die_if_no_fixup("illegal slot instruction", regs, inst); 754} 755 756asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, 757 unsigned long r6, unsigned long r7, 758 struct pt_regs __regs) 759{ 760 struct pt_regs *regs = RELOC_HIDE(&__regs, 0); 761 long ex; 762 763 ex = lookup_exception_vector(); 764 die_if_kernel("exception", regs, ex); 765} 766 767#if defined(CONFIG_SH_STANDARD_BIOS) 768void *gdb_vbr_vector; 769 770static inline void __init gdb_vbr_init(void) 771{ 772 register unsigned long vbr; 773 774 /* 775 * Read the old value of the VBR register to initialise 776 * the vector through which debug and BIOS traps are 777 * delegated by the Linux trap handler. 778 */ 779 asm volatile("stc vbr, %0" : "=r" (vbr)); 780 781 gdb_vbr_vector = (void *)(vbr + 0x100); 782 printk("Setting GDB trap vector to 0x%08lx\n", 783 (unsigned long)gdb_vbr_vector); 784} 785#endif 786 787void __cpuinit per_cpu_trap_init(void) 788{ 789 extern void *vbr_base; 790 791#ifdef CONFIG_SH_STANDARD_BIOS 792 if (raw_smp_processor_id() == 0) 793 gdb_vbr_init(); 794#endif 795 796 /* NOTE: The VBR value should be at P1 797 (or P2, virtural "fixed" address space). 798 It's definitely should not in physical address. */ 799 800 asm volatile("ldc %0, vbr" 801 : /* no output */ 802 : "r" (&vbr_base) 803 : "memory"); 804} 805 806void *set_exception_table_vec(unsigned int vec, void *handler) 807{ 808 extern void *exception_handling_table[]; 809 void *old_handler; 810 811 old_handler = exception_handling_table[vec]; 812 exception_handling_table[vec] = handler; 813 return old_handler; 814} 815 816void __init trap_init(void) 817{ 818 set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst); 819 set_exception_table_vec(TRAP_ILLEGAL_SLOT_INST, do_illegal_slot_inst); 820 821#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_FPU) || \ 822 defined(CONFIG_SH_FPU_EMU) 823 /* 824 * For SH-4 lacking an FPU, treat floating point instructions as 825 * reserved. They'll be handled in the math-emu case, or faulted on 826 * otherwise. 827 */ 828 set_exception_table_evt(0x800, do_reserved_inst); 829 set_exception_table_evt(0x820, do_illegal_slot_inst); 830#elif defined(CONFIG_SH_FPU) 831#ifdef CONFIG_CPU_SUBTYPE_SHX3 832 set_exception_table_evt(0xd80, fpu_state_restore_trap_handler); 833 set_exception_table_evt(0xda0, fpu_state_restore_trap_handler); 834#else 835 set_exception_table_evt(0x800, fpu_state_restore_trap_handler); 836 set_exception_table_evt(0x820, fpu_state_restore_trap_handler); 837#endif 838#endif 839 840#ifdef CONFIG_CPU_SH2 841 set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_trap_handler); 842#endif 843#ifdef CONFIG_CPU_SH2A 844 set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error); 845 set_exception_table_vec(TRAP_DIVOVF_ERROR, do_divide_error); 846#ifdef CONFIG_SH_FPU 847 set_exception_table_vec(TRAP_FPU_ERROR, fpu_error_trap_handler); 848#endif 849#endif 850 851 /* Setup VBR for boot cpu */ 852 per_cpu_trap_init(); 853} 854 855void show_trace(struct task_struct *tsk, unsigned long *sp, 856 struct pt_regs *regs) 857{ 858 unsigned long addr; 859 860 if (regs && user_mode(regs)) 861 return; 862 863 printk("\nCall trace:\n"); 864 865 while (!kstack_end(sp)) { 866 addr = *sp++; 867 if (kernel_text_address(addr)) 868 print_ip_sym(addr); 869 } 870 871 printk("\n"); 872 873 if (!tsk) 874 tsk = current; 875 876 debug_show_held_locks(tsk); 877} 878 879void show_stack(struct task_struct *tsk, unsigned long *sp) 880{ 881 unsigned long stack; 882 883 if (!tsk) 884 tsk = current; 885 if (tsk == current) 886 sp = (unsigned long *)current_stack_pointer; 887 else 888 sp = (unsigned long *)tsk->thread.sp; 889 890 stack = (unsigned long)sp; 891 dump_mem("Stack: ", stack, THREAD_SIZE + 892 (unsigned long)task_stack_page(tsk)); 893 show_trace(tsk, sp, NULL); 894} 895 896void dump_stack(void) 897{ 898 show_stack(NULL, NULL); 899} 900EXPORT_SYMBOL(dump_stack); 901