1 /* MN10300 Exception handling 2 * 3 * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. 4 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 5 * Modified by David Howells (dhowells@redhat.com) 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public Licence 9 * as published by the Free Software Foundation; either version 10 * 2 of the Licence, or (at your option) any later version. 11 */ 12 #include <linux/sched.h> 13 #include <linux/kernel.h> 14 #include <linux/string.h> 15 #include <linux/errno.h> 16 #include <linux/ptrace.h> 17 #include <linux/timer.h> 18 #include <linux/mm.h> 19 #include <linux/smp.h> 20 #include <linux/init.h> 21 #include <linux/delay.h> 22 #include <linux/spinlock.h> 23 #include <linux/interrupt.h> 24 #include <linux/kallsyms.h> 25 #include <linux/pci.h> 26 #include <linux/kdebug.h> 27 #include <linux/bug.h> 28 #include <linux/irq.h> 29 #include <asm/processor.h> 30 #include <asm/system.h> 31 #include <asm/uaccess.h> 32 #include <asm/io.h> 33 #include <asm/atomic.h> 34 #include <asm/smp.h> 35 #include <asm/pgalloc.h> 36 #include <asm/cacheflush.h> 37 #include <asm/cpu-regs.h> 38 #include <asm/busctl-regs.h> 39 #include <unit/leds.h> 40 #include <asm/fpu.h> 41 #include <asm/gdb-stub.h> 42 #include <asm/sections.h> 43 44 #if (CONFIG_INTERRUPT_VECTOR_BASE & 0xffffff) 45 #error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!" 46 #endif 47 48 struct pt_regs *__frame; /* current frame pointer */ 49 EXPORT_SYMBOL(__frame); 50 51 int kstack_depth_to_print = 24; 52 53 spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock); 54 55 ATOMIC_NOTIFIER_HEAD(mn10300_die_chain); 56 57 /* 58 * These constants are for searching for possible module text 59 * segments. MODULE_RANGE is a guess of how much space is likely 60 * to be vmalloced. 61 */ 62 #define MODULE_RANGE (8 * 1024 * 1024) 63 64 #define DO_ERROR(signr, prologue, str, name) \ 65 asmlinkage void name(struct pt_regs *regs, u32 intcode) \ 66 { \ 67 prologue; \ 68 if (die_if_no_fixup(str, regs, intcode)) \ 69 return; \ 70 force_sig(signr, current); \ 71 } 72 73 #define DO_EINFO(signr, prologue, str, name, sicode) \ 74 asmlinkage void name(struct pt_regs *regs, u32 intcode) \ 75 { \ 76 siginfo_t info; \ 77 prologue; \ 78 if (die_if_no_fixup(str, regs, intcode)) \ 79 return; \ 80 info.si_signo = signr; \ 81 if (signr == SIGILL && sicode == ILL_ILLOPC) { \ 82 uint8_t opcode; \ 83 if (get_user(opcode, (uint8_t __user *)regs->pc) == 0) \ 84 if (opcode == 0xff) \ 85 info.si_signo = SIGTRAP; \ 86 } \ 87 info.si_errno = 0; \ 88 info.si_code = sicode; \ 89 info.si_addr = (void *) regs->pc; \ 90 force_sig_info(info.si_signo, &info, current); \ 91 } 92 93 DO_ERROR(SIGTRAP, {}, "trap", trap); 94 DO_ERROR(SIGSEGV, {}, "ibreak", ibreak); 95 DO_ERROR(SIGSEGV, {}, "obreak", obreak); 96 DO_EINFO(SIGSEGV, {}, "access error", access_error, SEGV_ACCERR); 97 DO_EINFO(SIGSEGV, {}, "insn access error", insn_acc_error, SEGV_ACCERR); 98 DO_EINFO(SIGSEGV, {}, "data access error", data_acc_error, SEGV_ACCERR); 99 DO_EINFO(SIGILL, {}, "privileged opcode", priv_op, ILL_PRVOPC); 100 DO_EINFO(SIGILL, {}, "invalid opcode", invalid_op, ILL_ILLOPC); 101 DO_EINFO(SIGILL, {}, "invalid ex opcode", invalid_exop, ILL_ILLOPC); 102 DO_EINFO(SIGBUS, {}, "invalid address", mem_error, BUS_ADRERR); 103 DO_EINFO(SIGBUS, {}, "bus error", bus_error, BUS_ADRERR); 104 DO_EINFO(SIGILL, {}, "FPU invalid opcode", fpu_invalid_op, ILL_COPROC); 105 106 DO_ERROR(SIGTRAP, 107 #ifndef CONFIG_MN10300_USING_JTAG 108 DCR &= ~0x0001, 109 #else 110 {}, 111 #endif 112 "single step", istep); 113 114 /* 115 * handle NMI 116 */ 117 asmlinkage void nmi(struct pt_regs *regs, enum exception_code code) 118 { 119 /* see if gdbstub wants to deal with it */ 120 #ifdef CONFIG_GDBSTUB 121 if (gdbstub_intercept(regs, code)) 122 return; 123 #endif 124 125 printk(KERN_WARNING "--- Register Dump ---\n"); 126 show_registers(regs); 127 printk(KERN_WARNING "---------------------\n"); 128 } 129 130 /* 131 * show a stack trace from the specified stack pointer 132 */ 133 void show_trace(unsigned long *sp) 134 { 135 unsigned long *stack, addr, module_start, module_end; 136 int i; 137 138 printk(KERN_EMERG "\nCall Trace:"); 139 140 stack = sp; 141 i = 0; 142 module_start = VMALLOC_START; 143 module_end = VMALLOC_END; 144 145 while (((long) stack & (THREAD_SIZE - 1)) != 0) { 146 addr = *stack++; 147 if (__kernel_text_address(addr)) { 148 #if 1 149 printk(" [<%08lx>]", addr); 150 print_symbol(" %s", addr); 151 printk("\n"); 152 #else 153 if ((i % 6) == 0) 154 printk(KERN_EMERG " "); 155 printk("[<%08lx>] ", addr); 156 i++; 157 #endif 158 } 159 } 160 161 printk("\n"); 162 } 163 164 /* 165 * show the raw stack from the specified stack pointer 166 */ 167 void show_stack(struct task_struct *task, unsigned long *sp) 168 { 169 unsigned long *stack; 170 int i; 171 172 if (!sp) 173 sp = (unsigned long *) &sp; 174 175 stack = sp; 176 printk(KERN_EMERG "Stack:"); 177 for (i = 0; i < kstack_depth_to_print; i++) { 178 if (((long) stack & (THREAD_SIZE - 1)) == 0) 179 break; 180 if ((i % 8) == 0) 181 printk(KERN_EMERG " "); 182 printk("%08lx ", *stack++); 183 } 184 185 show_trace(sp); 186 } 187 188 /* 189 * the architecture-independent dump_stack generator 190 */ 191 void dump_stack(void) 192 { 193 unsigned long stack; 194 195 show_stack(current, &stack); 196 } 197 EXPORT_SYMBOL(dump_stack); 198 199 /* 200 * dump the register file in the specified exception frame 201 */ 202 void show_registers_only(struct pt_regs *regs) 203 { 204 unsigned long ssp; 205 206 ssp = (unsigned long) regs + sizeof(*regs); 207 208 printk(KERN_EMERG "PC: %08lx EPSW: %08lx SSP: %08lx mode: %s\n", 209 regs->pc, regs->epsw, ssp, user_mode(regs) ? "User" : "Super"); 210 printk(KERN_EMERG "d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", 211 regs->d0, regs->d1, regs->d2, regs->d3); 212 printk(KERN_EMERG "a0: %08lx a1: %08lx a2: %08lx a3: %08lx\n", 213 regs->a0, regs->a1, regs->a2, regs->a3); 214 printk(KERN_EMERG "e0: %08lx e1: %08lx e2: %08lx e3: %08lx\n", 215 regs->e0, regs->e1, regs->e2, regs->e3); 216 printk(KERN_EMERG "e4: %08lx e5: %08lx e6: %08lx e7: %08lx\n", 217 regs->e4, regs->e5, regs->e6, regs->e7); 218 printk(KERN_EMERG "lar: %08lx lir: %08lx mdr: %08lx usp: %08lx\n", 219 regs->lar, regs->lir, regs->mdr, regs->sp); 220 printk(KERN_EMERG "cvf: %08lx crl: %08lx crh: %08lx drq: %08lx\n", 221 regs->mcvf, regs->mcrl, regs->mcrh, regs->mdrq); 222 printk(KERN_EMERG "threadinfo=%p task=%p)\n", 223 current_thread_info(), current); 224 225 if ((unsigned long) current >= 0x90000000UL && 226 (unsigned long) current < 0x94000000UL) 227 printk(KERN_EMERG "Process %s (pid: %d)\n", 228 current->comm, current->pid); 229 230 printk(KERN_EMERG "CPUP: %04hx\n", CPUP); 231 printk(KERN_EMERG "TBR: %08x\n", TBR); 232 printk(KERN_EMERG "DEAR: %08x\n", DEAR); 233 printk(KERN_EMERG "sISR: %08x\n", sISR); 234 printk(KERN_EMERG "NMICR: %04hx\n", NMICR); 235 printk(KERN_EMERG "BCBERR: %08x\n", BCBERR); 236 printk(KERN_EMERG "BCBEAR: %08x\n", BCBEAR); 237 printk(KERN_EMERG "MMUFCR: %08x\n", MMUFCR); 238 printk(KERN_EMERG "IPTEU : %08x IPTEL2: %08x\n", IPTEU, IPTEL2); 239 printk(KERN_EMERG "DPTEU: %08x DPTEL2: %08x\n", DPTEU, DPTEL2); 240 } 241 242 /* 243 * dump the registers and the stack 244 */ 245 void show_registers(struct pt_regs *regs) 246 { 247 unsigned long sp; 248 int i; 249 250 show_registers_only(regs); 251 252 if (!user_mode(regs)) 253 sp = (unsigned long) regs + sizeof(*regs); 254 else 255 sp = regs->sp; 256 257 /* when in-kernel, we also print out the stack and code at the 258 * time of the fault.. 259 */ 260 if (!user_mode(regs)) { 261 printk(KERN_EMERG "\n"); 262 show_stack(current, (unsigned long *) sp); 263 264 #if 0 265 printk(KERN_EMERG "\nCode: "); 266 if (regs->pc < PAGE_OFFSET) 267 goto bad; 268 269 for (i = 0; i < 20; i++) { 270 unsigned char c; 271 if (__get_user(c, &((unsigned char *) regs->pc)[i])) 272 goto bad; 273 printk("%02x ", c); 274 } 275 #else 276 i = 0; 277 #endif 278 } 279 280 printk("\n"); 281 return; 282 283 #if 0 284 bad: 285 printk(KERN_EMERG " Bad PC value."); 286 break; 287 #endif 288 } 289 290 /* 291 * 292 */ 293 void show_trace_task(struct task_struct *tsk) 294 { 295 unsigned long sp = tsk->thread.sp; 296 297 /* User space on another CPU? */ 298 if ((sp ^ (unsigned long) tsk) & (PAGE_MASK << 1)) 299 return; 300 301 show_trace((unsigned long *) sp); 302 } 303 304 /* 305 * note the untimely death of part of the kernel 306 */ 307 void die(const char *str, struct pt_regs *regs, enum exception_code code) 308 { 309 console_verbose(); 310 spin_lock_irq(&die_lock); 311 printk(KERN_EMERG "\n%s: %04x\n", 312 str, code & 0xffff); 313 show_registers(regs); 314 315 if (regs->pc >= 0x02000000 && regs->pc < 0x04000000 && 316 (regs->epsw & (EPSW_IM | EPSW_IE)) != (EPSW_IM | EPSW_IE)) { 317 printk(KERN_EMERG "Exception in usermode interrupt handler\n"); 318 printk(KERN_EMERG "\nPlease connect to kernel debugger !!\n"); 319 asm volatile ("0: bra 0b"); 320 } 321 322 spin_unlock_irq(&die_lock); 323 do_exit(SIGSEGV); 324 } 325 326 /* 327 * see if there's a fixup handler we can force a jump to when an exception 328 * happens due to something kernel code did 329 */ 330 int die_if_no_fixup(const char *str, struct pt_regs *regs, 331 enum exception_code code) 332 { 333 if (user_mode(regs)) 334 return 0; 335 336 peripheral_leds_display_exception(code); 337 338 switch (code) { 339 /* see if we can fixup the kernel accessing memory */ 340 case EXCEP_ITLBMISS: 341 case EXCEP_DTLBMISS: 342 case EXCEP_IAERROR: 343 case EXCEP_DAERROR: 344 case EXCEP_MEMERR: 345 case EXCEP_MISALIGN: 346 case EXCEP_BUSERROR: 347 case EXCEP_ILLDATACC: 348 case EXCEP_IOINSACC: 349 case EXCEP_PRIVINSACC: 350 case EXCEP_PRIVDATACC: 351 case EXCEP_DATINSACC: 352 if (fixup_exception(regs)) 353 return 1; 354 case EXCEP_UNIMPINS: 355 if (regs->pc && *(uint8_t *)regs->pc == 0xff) 356 if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0)) 357 return 1; 358 break; 359 default: 360 break; 361 } 362 363 /* see if gdbstub wants to deal with it */ 364 #ifdef CONFIG_GDBSTUB 365 if (gdbstub_intercept(regs, code)) 366 return 1; 367 #endif 368 369 if (notify_die(DIE_GPF, str, regs, code, 0, 0)) 370 return 1; 371 372 /* make the process die as the last resort */ 373 die(str, regs, code); 374 } 375 376 /* 377 * handle unsupported syscall instructions (syscall 1-15) 378 */ 379 static asmlinkage void unsupported_syscall(struct pt_regs *regs, 380 enum exception_code code) 381 { 382 struct task_struct *tsk = current; 383 siginfo_t info; 384 385 /* catch a kernel BUG() */ 386 if (code == EXCEP_SYSCALL15 && !user_mode(regs)) { 387 if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_BUG) { 388 #ifdef CONFIG_GDBSTUB 389 gdbstub_intercept(regs, code); 390 #endif 391 } 392 } 393 394 regs->pc -= 2; /* syscall return addr is _after_ the instruction */ 395 396 die_if_no_fixup("An unsupported syscall insn was used by the kernel\n", 397 regs, code); 398 399 info.si_signo = SIGILL; 400 info.si_errno = ENOSYS; 401 info.si_code = ILL_ILLTRP; 402 info.si_addr = (void *) regs->pc; 403 force_sig_info(SIGILL, &info, tsk); 404 } 405 406 /* 407 * display the register file when the stack pointer gets clobbered 408 */ 409 asmlinkage void do_double_fault(struct pt_regs *regs) 410 { 411 struct task_struct *tsk = current; 412 413 strcpy(tsk->comm, "emergency tsk"); 414 tsk->pid = 0; 415 console_verbose(); 416 printk(KERN_EMERG "--- double fault ---\n"); 417 show_registers(regs); 418 } 419 420 /* 421 * asynchronous bus error (external, usually I/O DMA) 422 */ 423 asmlinkage void io_bus_error(u32 bcberr, u32 bcbear, struct pt_regs *regs) 424 { 425 console_verbose(); 426 427 printk(KERN_EMERG "Asynchronous I/O Bus Error\n"); 428 printk(KERN_EMERG "==========================\n"); 429 430 if (bcberr & BCBERR_BEME) 431 printk(KERN_EMERG "- Multiple recorded errors\n"); 432 433 printk(KERN_EMERG "- Faulting Buses:%s%s%s\n", 434 bcberr & BCBERR_BEMR_CI ? " CPU-Ins-Fetch" : "", 435 bcberr & BCBERR_BEMR_CD ? " CPU-Data" : "", 436 bcberr & BCBERR_BEMR_DMA ? " DMA" : ""); 437 438 printk(KERN_EMERG "- %s %s access made to %s at address %08x\n", 439 bcberr & BCBERR_BEBST ? "Burst" : "Single", 440 bcberr & BCBERR_BERW ? "Read" : "Write", 441 bcberr & BCBERR_BESB_MON ? "Monitor Space" : 442 bcberr & BCBERR_BESB_IO ? "Internal CPU I/O Space" : 443 bcberr & BCBERR_BESB_EX ? "External I/O Bus" : 444 bcberr & BCBERR_BESB_OPEX ? "External Memory Bus" : 445 "On Chip Memory", 446 bcbear 447 ); 448 449 printk(KERN_EMERG "- Detected by the %s\n", 450 bcberr&BCBERR_BESD ? "Bus Control Unit" : "Slave Bus"); 451 452 #ifdef CONFIG_PCI 453 #define BRIDGEREGB(X) (*(volatile __u8 *)(0xBE040000 + (X))) 454 #define BRIDGEREGW(X) (*(volatile __u16 *)(0xBE040000 + (X))) 455 #define BRIDGEREGL(X) (*(volatile __u32 *)(0xBE040000 + (X))) 456 457 printk(KERN_EMERG "- PCI Memory Paging Reg: %08x\n", 458 *(volatile __u32 *) (0xBFFFFFF4)); 459 printk(KERN_EMERG "- PCI Bridge Base Address 0: %08x\n", 460 BRIDGEREGL(PCI_BASE_ADDRESS_0)); 461 printk(KERN_EMERG "- PCI Bridge AMPCI Base Address: %08x\n", 462 BRIDGEREGL(0x48)); 463 printk(KERN_EMERG "- PCI Bridge Command: %04hx\n", 464 BRIDGEREGW(PCI_COMMAND)); 465 printk(KERN_EMERG "- PCI Bridge Status: %04hx\n", 466 BRIDGEREGW(PCI_STATUS)); 467 printk(KERN_EMERG "- PCI Bridge Int Status: %08hx\n", 468 BRIDGEREGL(0x4c)); 469 #endif 470 471 printk(KERN_EMERG "\n"); 472 show_registers(regs); 473 474 panic("Halted due to asynchronous I/O Bus Error\n"); 475 } 476 477 /* 478 * handle an exception for which a handler has not yet been installed 479 */ 480 asmlinkage void uninitialised_exception(struct pt_regs *regs, 481 enum exception_code code) 482 { 483 484 /* see if gdbstub wants to deal with it */ 485 #ifdef CONFIG_GDBSTUB 486 if (gdbstub_intercept(regs, code)) 487 return; 488 #endif 489 490 peripheral_leds_display_exception(code); 491 printk(KERN_EMERG "Uninitialised Exception 0x%04x\n", code & 0xFFFF); 492 show_registers(regs); 493 494 for (;;) 495 continue; 496 } 497 498 /* 499 * set an interrupt stub to jump to a handler 500 * ! NOTE: this does *not* flush the caches 501 */ 502 void __init __set_intr_stub(enum exception_code code, void *handler) 503 { 504 unsigned long addr; 505 u8 *vector = (u8 *)(CONFIG_INTERRUPT_VECTOR_BASE + code); 506 507 addr = (unsigned long) handler - (unsigned long) vector; 508 vector[0] = 0xdc; /* JMP handler */ 509 vector[1] = addr; 510 vector[2] = addr >> 8; 511 vector[3] = addr >> 16; 512 vector[4] = addr >> 24; 513 vector[5] = 0xcb; 514 vector[6] = 0xcb; 515 vector[7] = 0xcb; 516 } 517 518 /* 519 * set an interrupt stub to jump to a handler 520 */ 521 void __init set_intr_stub(enum exception_code code, void *handler) 522 { 523 unsigned long addr; 524 u8 *vector = (u8 *)(CONFIG_INTERRUPT_VECTOR_BASE + code); 525 526 addr = (unsigned long) handler - (unsigned long) vector; 527 vector[0] = 0xdc; /* JMP handler */ 528 vector[1] = addr; 529 vector[2] = addr >> 8; 530 vector[3] = addr >> 16; 531 vector[4] = addr >> 24; 532 vector[5] = 0xcb; 533 vector[6] = 0xcb; 534 vector[7] = 0xcb; 535 536 mn10300_dcache_flush_inv(); 537 mn10300_icache_inv(); 538 } 539 540 /* 541 * set an interrupt stub to invoke the JTAG unit and then jump to a handler 542 */ 543 void __init set_jtag_stub(enum exception_code code, void *handler) 544 { 545 unsigned long addr; 546 u8 *vector = (u8 *)(CONFIG_INTERRUPT_VECTOR_BASE + code); 547 548 addr = (unsigned long) handler - ((unsigned long) vector + 1); 549 vector[0] = 0xff; /* PI to jump into JTAG debugger */ 550 vector[1] = 0xdc; /* jmp handler */ 551 vector[2] = addr; 552 vector[3] = addr >> 8; 553 vector[4] = addr >> 16; 554 vector[5] = addr >> 24; 555 vector[6] = 0xcb; 556 vector[7] = 0xcb; 557 558 mn10300_dcache_flush_inv(); 559 flush_icache_range((unsigned long) vector, (unsigned long) vector + 8); 560 } 561 562 /* 563 * initialise the exception table 564 */ 565 void __init trap_init(void) 566 { 567 set_excp_vector(EXCEP_TRAP, trap); 568 set_excp_vector(EXCEP_ISTEP, istep); 569 set_excp_vector(EXCEP_IBREAK, ibreak); 570 set_excp_vector(EXCEP_OBREAK, obreak); 571 572 set_excp_vector(EXCEP_PRIVINS, priv_op); 573 set_excp_vector(EXCEP_UNIMPINS, invalid_op); 574 set_excp_vector(EXCEP_UNIMPEXINS, invalid_exop); 575 set_excp_vector(EXCEP_MEMERR, mem_error); 576 set_excp_vector(EXCEP_MISALIGN, misalignment); 577 set_excp_vector(EXCEP_BUSERROR, bus_error); 578 set_excp_vector(EXCEP_ILLINSACC, insn_acc_error); 579 set_excp_vector(EXCEP_ILLDATACC, data_acc_error); 580 set_excp_vector(EXCEP_IOINSACC, insn_acc_error); 581 set_excp_vector(EXCEP_PRIVINSACC, insn_acc_error); 582 set_excp_vector(EXCEP_PRIVDATACC, data_acc_error); 583 set_excp_vector(EXCEP_DATINSACC, insn_acc_error); 584 set_excp_vector(EXCEP_FPU_DISABLED, fpu_disabled); 585 set_excp_vector(EXCEP_FPU_UNIMPINS, fpu_invalid_op); 586 set_excp_vector(EXCEP_FPU_OPERATION, fpu_exception); 587 588 set_excp_vector(EXCEP_NMI, nmi); 589 590 set_excp_vector(EXCEP_SYSCALL1, unsupported_syscall); 591 set_excp_vector(EXCEP_SYSCALL2, unsupported_syscall); 592 set_excp_vector(EXCEP_SYSCALL3, unsupported_syscall); 593 set_excp_vector(EXCEP_SYSCALL4, unsupported_syscall); 594 set_excp_vector(EXCEP_SYSCALL5, unsupported_syscall); 595 set_excp_vector(EXCEP_SYSCALL6, unsupported_syscall); 596 set_excp_vector(EXCEP_SYSCALL7, unsupported_syscall); 597 set_excp_vector(EXCEP_SYSCALL8, unsupported_syscall); 598 set_excp_vector(EXCEP_SYSCALL9, unsupported_syscall); 599 set_excp_vector(EXCEP_SYSCALL10, unsupported_syscall); 600 set_excp_vector(EXCEP_SYSCALL11, unsupported_syscall); 601 set_excp_vector(EXCEP_SYSCALL12, unsupported_syscall); 602 set_excp_vector(EXCEP_SYSCALL13, unsupported_syscall); 603 set_excp_vector(EXCEP_SYSCALL14, unsupported_syscall); 604 set_excp_vector(EXCEP_SYSCALL15, unsupported_syscall); 605 } 606 607 /* 608 * determine if a program counter value is a valid bug address 609 */ 610 int is_valid_bugaddr(unsigned long pc) 611 { 612 return pc >= PAGE_OFFSET; 613 } 614
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.