1/* 2 * Helper functions for trap handlers 3 * 4 * Copyright (C) 2000-2007, Axis Communications AB. 5 * 6 * Authors: Bjorn Wesen 7 * Hans-Peter Nilsson 8 * 9 */ 10 11#include <linux/ptrace.h> 12#include <asm/uaccess.h> 13#include <arch/sv_addr_ag.h> 14 15void 16show_registers(struct pt_regs *regs) 17{ 18 /* 19 * It's possible to use either the USP register or current->thread.usp. 20 * USP might not correspond to the current process for all cases this 21 * function is called, and current->thread.usp isn't up to date for the 22 * current process. Experience shows that using USP is the way to go. 23 */ 24 unsigned long usp = rdusp(); 25 26 printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", 27 regs->irp, regs->srp, regs->dccr, usp, regs->mof); 28 29 printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", 30 regs->r0, regs->r1, regs->r2, regs->r3); 31 32 printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", 33 regs->r4, regs->r5, regs->r6, regs->r7); 34 35 printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", 36 regs->r8, regs->r9, regs->r10, regs->r11); 37 38 printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n", 39 regs->r12, regs->r13, regs->orig_r10, (long unsigned)regs); 40 41 printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE); 42 43 printk("Process %s (pid: %d, stackpage=%08lx)\n", 44 current->comm, current->pid, (unsigned long)current); 45 46 /* 47 * When in-kernel, we also print out the stack and code at the 48 * time of the fault.. 49 */ 50 if (!user_mode(regs)) { 51 int i; 52 53 show_stack(NULL, (unsigned long *)usp); 54 55 /* 56 * If the previous stack-dump wasn't a kernel one, dump the 57 * kernel stack now. 58 */ 59 if (usp != 0) 60 show_stack(NULL, NULL); 61 62 printk("\nCode: "); 63 64 if (regs->irp < PAGE_OFFSET) 65 goto bad_value; 66 67 /* 68 * Quite often the value at regs->irp doesn't point to the 69 * interesting instruction, which often is the previous 70 * instruction. So dump at an offset large enough that the 71 * instruction decoding should be in sync at the interesting 72 * point, but small enough to fit on a row. The regs->irp 73 * location is pointed out in a ksymoops-friendly way by 74 * wrapping the byte for that address in parenthesises. 75 */ 76 for (i = -12; i < 12; i++) { 77 unsigned char c; 78 79 if (__get_user(c, &((unsigned char *)regs->irp)[i])) { 80bad_value: 81 printk(" Bad IP value."); 82 break; 83 } 84 85 if (i == 0) 86 printk("(%02x) ", c); 87 else 88 printk("%02x ", c); 89 } 90 printk("\n"); 91 } 92} 93 94void 95arch_enable_nmi(void) 96{ 97 asm volatile ("setf m"); 98} 99 100extern void (*nmi_handler)(struct pt_regs *); 101void handle_nmi(struct pt_regs *regs) 102{ 103 if (nmi_handler) 104 nmi_handler(regs); 105 106 /* Wait until nmi is no longer active. (We enable NMI immediately after 107 returning from this function, and we don't want it happening while 108 exiting from the NMI interrupt handler.) */ 109 while (*R_IRQ_MASK0_RD & IO_STATE(R_IRQ_MASK0_RD, nmi_pin, active)) 110 ; 111} 112 113#ifdef CONFIG_DEBUG_BUGVERBOSE 114void 115handle_BUG(struct pt_regs *regs) 116{ 117 struct bug_frame f; 118 unsigned char c; 119 unsigned long irp = regs->irp; 120 121 if (__copy_from_user(&f, (const void __user *)(irp - 8), sizeof f)) 122 return; 123 if (f.prefix != BUG_PREFIX || f.magic != BUG_MAGIC) 124 return; 125 if (__get_user(c, f.filename)) 126 f.filename = "<bad filename>"; 127 128 printk("kernel BUG at %s:%d!\n", f.filename, f.line); 129} 130#endif 131