1/* 2 * Copyright (C) 2003-2006, Axis Communications AB. 3 */ 4 5#include <linux/ptrace.h> 6#include <linux/module.h> 7#include <asm/uaccess.h> 8#include <hwregs/supp_reg.h> 9#include <hwregs/intr_vect_defs.h> 10#include <asm/irq.h> 11 12void show_registers(struct pt_regs *regs) 13{ 14 /* 15 * It's possible to use either the USP register or current->thread.usp. 16 * USP might not correspond to the current process for all cases this 17 * function is called, and current->thread.usp isn't up to date for the 18 * current process. Experience shows that using USP is the way to go. 19 */ 20 unsigned long usp = rdusp(); 21 unsigned long d_mmu_cause; 22 unsigned long i_mmu_cause; 23 24 printk("CPU: %d\n", smp_processor_id()); 25 26 printk("ERP: %08lx SRP: %08lx CCS: %08lx USP: %08lx MOF: %08lx\n", 27 regs->erp, regs->srp, regs->ccs, 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 acr: %08lx\n", 39 regs->r12, regs->r13, regs->orig_r10, regs->acr); 40 41 printk(" sp: %08lx\n", (unsigned long)regs); 42 43 SUPP_BANK_SEL(BANK_IM); 44 SUPP_REG_RD(RW_MM_CAUSE, i_mmu_cause); 45 46 SUPP_BANK_SEL(BANK_DM); 47 SUPP_REG_RD(RW_MM_CAUSE, d_mmu_cause); 48 49 printk(" Data MMU Cause: %08lx\n", d_mmu_cause); 50 printk("Instruction MMU Cause: %08lx\n", i_mmu_cause); 51 52 printk("Process %s (pid: %d, stackpage=%08lx)\n", 53 current->comm, current->pid, (unsigned long)current); 54 55 /* 56 * When in-kernel, we also print out the stack and code at the 57 * time of the fault.. 58 */ 59 if (!user_mode(regs)) { 60 int i; 61 62 show_stack(NULL, (unsigned long *)usp); 63 64 /* 65 * If the previous stack-dump wasn't a kernel one, dump the 66 * kernel stack now. 67 */ 68 if (usp != 0) 69 show_stack(NULL, NULL); 70 71 printk("\nCode: "); 72 73 if (regs->erp < PAGE_OFFSET) 74 goto bad_value; 75 76 /* 77 * Quite often the value at regs->erp doesn't point to the 78 * interesting instruction, which often is the previous 79 * instruction. So dump at an offset large enough that the 80 * instruction decoding should be in sync at the interesting 81 * point, but small enough to fit on a row. The regs->erp 82 * location is pointed out in a ksymoops-friendly way by 83 * wrapping the byte for that address in parenthesises. 84 */ 85 for (i = -12; i < 12; i++) { 86 unsigned char c; 87 88 if (__get_user(c, &((unsigned char *)regs->erp)[i])) { 89bad_value: 90 printk(" Bad IP value."); 91 break; 92 } 93 94 if (i == 0) 95 printk("(%02x) ", c); 96 else 97 printk("%02x ", c); 98 } 99 printk("\n"); 100 } 101} 102 103void arch_enable_nmi(void) 104{ 105 unsigned long flags; 106 107 local_save_flags(flags); 108 flags |= (1 << 30); /* NMI M flag is at bit 30 */ 109 local_irq_restore(flags); 110} 111 112extern void (*nmi_handler)(struct pt_regs *); 113void handle_nmi(struct pt_regs *regs) 114{ 115#ifdef CONFIG_ETRAXFS 116 reg_intr_vect_r_nmi r; 117#endif 118 119 if (nmi_handler) 120 nmi_handler(regs); 121 122#ifdef CONFIG_ETRAXFS 123 /* Wait until nmi is no longer active. */ 124 do { 125 r = REG_RD(intr_vect, regi_irq, r_nmi); 126 } while (r.ext == regk_intr_vect_on); 127#endif 128} 129 130 131#ifdef CONFIG_BUG 132extern void die_if_kernel(const char *str, struct pt_regs *regs, long err); 133 134/* Copy of the regs at BUG() time. */ 135struct pt_regs BUG_regs; 136 137void do_BUG(char *file, unsigned int line) 138{ 139 printk("kernel BUG at %s:%d!\n", file, line); 140 die_if_kernel("Oops", &BUG_regs, 0); 141} 142EXPORT_SYMBOL(do_BUG); 143 144void fixup_BUG(struct pt_regs *regs) 145{ 146 BUG_regs = *regs; 147 148#ifdef CONFIG_DEBUG_BUGVERBOSE 149 /* 150 * Fixup the BUG arguments through exception handlers. 151 */ 152 { 153 const struct exception_table_entry *fixup; 154 155 /* 156 * ERP points at the "break 14" + 2, compensate for the 2 157 * bytes. 158 */ 159 fixup = search_exception_tables(instruction_pointer(regs) - 2); 160 if (fixup) { 161 /* Adjust the instruction pointer in the stackframe. */ 162 instruction_pointer(regs) = fixup->fixup; 163 arch_fixup(regs); 164 } 165 } 166#else 167 /* Dont try to lookup the filename + line, just dump regs. */ 168 do_BUG("unknown", 0); 169#endif 170} 171 172/* 173 * Break 14 handler. Save regs and jump into the fixup_BUG. 174 */ 175__asm__ ( ".text\n\t" 176 ".global breakh_BUG\n\t" 177 "breakh_BUG:\n\t" 178 SAVE_ALL 179 KGDB_FIXUP 180 "move.d $sp, $r10\n\t" 181 "jsr fixup_BUG\n\t" 182 "nop\n\t" 183 "jump ret_from_intr\n\t" 184 "nop\n\t"); 185 186 187#ifdef CONFIG_DEBUG_BUGVERBOSE 188void 189handle_BUG(struct pt_regs *regs) 190{ 191} 192#endif 193#endif 194