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