1/* $Id: traps.c,v 1.1.1.1 2007-08-03 18:51:41 $ 2 * 3 * linux/arch/cris/arch-v10/traps.c 4 * 5 * Heler functions for trap handlers 6 * 7 * Copyright (C) 2000-2002 Axis Communications AB 8 * 9 * Authors: Bjorn Wesen 10 * Hans-Peter Nilsson 11 * 12 */ 13 14#include <linux/ptrace.h> 15#include <asm/uaccess.h> 16#include <asm/arch/sv_addr_ag.h> 17 18extern int raw_printk(const char *fmt, ...); 19 20void 21show_registers(struct pt_regs * regs) 22{ 23 /* We either use rdusp() - the USP register, which might not 24 correspond to the current process for all cases we're called, 25 or we use the current->thread.usp, which is not up to date for 26 the current process. Experience shows we want the USP 27 register. */ 28 unsigned long usp = rdusp(); 29 30 raw_printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", 31 regs->irp, regs->srp, regs->dccr, usp, regs->mof ); 32 raw_printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", 33 regs->r0, regs->r1, regs->r2, regs->r3); 34 raw_printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", 35 regs->r4, regs->r5, regs->r6, regs->r7); 36 raw_printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", 37 regs->r8, regs->r9, regs->r10, regs->r11); 38 raw_printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n", 39 regs->r12, regs->r13, regs->orig_r10, regs); 40 raw_printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE); 41 raw_printk("Process %s (pid: %d, stackpage=%08lx)\n", 42 current->comm, current->pid, (unsigned long)current); 43 44 /* 45 * When in-kernel, we also print out the stack and code at the 46 * time of the fault.. 47 */ 48 if (! user_mode(regs)) { 49 int i; 50 51 show_stack(NULL, (unsigned long*)usp); 52 53 /* Dump kernel stack if the previous dump wasn't one. */ 54 if (usp != 0) 55 show_stack (NULL, NULL); 56 57 raw_printk("\nCode: "); 58 if(regs->irp < PAGE_OFFSET) 59 goto bad; 60 61 /* Often enough the value at regs->irp does not point to 62 the interesting instruction, which is most often the 63 _previous_ instruction. So we dump at an offset large 64 enough that instruction decoding should be in sync at 65 the interesting point, but small enough to fit on a row 66 (sort of). We point out the regs->irp location in a 67 ksymoops-friendly way by wrapping the byte for that 68 address in parentheses. */ 69 for(i = -12; i < 12; i++) 70 { 71 unsigned char c; 72 if(__get_user(c, &((unsigned char*)regs->irp)[i])) { 73bad: 74 raw_printk(" Bad IP value."); 75 break; 76 } 77 78 if (i == 0) 79 raw_printk("(%02x) ", c); 80 else 81 raw_printk("%02x ", c); 82 } 83 raw_printk("\n"); 84 } 85} 86 87/* Called from entry.S when the watchdog has bitten 88 * We print out something resembling an oops dump, and if 89 * we have the nice doggy development flag set, we halt here 90 * instead of rebooting. 91 */ 92 93extern void reset_watchdog(void); 94extern void stop_watchdog(void); 95 96 97void 98watchdog_bite_hook(struct pt_regs *regs) 99{ 100#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 101 local_irq_disable(); 102 stop_watchdog(); 103 show_registers(regs); 104 while(1) /* nothing */; 105#else 106 show_registers(regs); 107#endif 108} 109 110/* This is normally the 'Oops' routine */ 111void 112die_if_kernel(const char * str, struct pt_regs * regs, long err) 113{ 114 if(user_mode(regs)) 115 return; 116 117#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 118 /* This printout might take too long and trigger the 119 * watchdog normally. If we're in the nice doggy 120 * development mode, stop the watchdog during printout. 121 */ 122 stop_watchdog(); 123#endif 124 125 raw_printk("%s: %04lx\n", str, err & 0xffff); 126 127 show_registers(regs); 128 129#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 130 reset_watchdog(); 131#endif 132 do_exit(SIGSEGV); 133} 134 135void arch_enable_nmi(void) 136{ 137 asm volatile("setf m"); 138} 139