1/* 2 * linux/arch/cris/traps.c 3 * 4 * Here we handle the break vectors not used by the system call 5 * mechanism, as well as some general stack/register dumping 6 * things. 7 * 8 * Copyright (C) 2000-2007 Axis Communications AB 9 * 10 * Authors: Bjorn Wesen 11 * Hans-Peter Nilsson 12 * 13 */ 14 15#include <linux/init.h> 16#include <linux/module.h> 17 18#include <asm/pgtable.h> 19#include <asm/uaccess.h> 20#include <arch/system.h> 21 22extern void arch_enable_nmi(void); 23extern void stop_watchdog(void); 24extern void reset_watchdog(void); 25extern void show_registers(struct pt_regs *regs); 26 27#ifdef CONFIG_DEBUG_BUGVERBOSE 28extern void handle_BUG(struct pt_regs *regs); 29#else 30#define handle_BUG(regs) 31#endif 32 33static int kstack_depth_to_print = 24; 34 35void (*nmi_handler)(struct pt_regs *); 36 37void 38show_trace(unsigned long *stack) 39{ 40 unsigned long addr, module_start, module_end; 41 extern char _stext, _etext; 42 int i; 43 44 printk("\nCall Trace: "); 45 46 i = 1; 47 module_start = VMALLOC_START; 48 module_end = VMALLOC_END; 49 50 while (((long)stack & (THREAD_SIZE-1)) != 0) { 51 if (__get_user(addr, stack)) { 52 /* This message matches "failing address" marked 53 s390 in ksymoops, so lines containing it will 54 not be filtered out by ksymoops. */ 55 printk("Failing address 0x%lx\n", (unsigned long)stack); 56 break; 57 } 58 stack++; 59 60 /* 61 * If the address is either in the text segment of the 62 * kernel, or in the region which contains vmalloc'ed 63 * memory, it *may* be the address of a calling 64 * routine; if so, print it so that someone tracing 65 * down the cause of the crash will be able to figure 66 * out the call path that was taken. 67 */ 68 if (((addr >= (unsigned long)&_stext) && 69 (addr <= (unsigned long)&_etext)) || 70 ((addr >= module_start) && (addr <= module_end))) { 71 if (i && ((i % 8) == 0)) 72 printk("\n "); 73 printk("[<%08lx>] ", addr); 74 i++; 75 } 76 } 77} 78 79/* 80 * These constants are for searching for possible module text 81 * segments. MODULE_RANGE is a guess of how much space is likely 82 * to be vmalloced. 83 */ 84 85#define MODULE_RANGE (8*1024*1024) 86 87/* 88 * The output (format, strings and order) is adjusted to be usable with 89 * ksymoops-2.4.1 with some necessary CRIS-specific patches. Please don't 90 * change it unless you're serious about adjusting ksymoops and syncing 91 * with the ksymoops maintainer. 92 */ 93 94void 95show_stack(struct task_struct *task, unsigned long *sp) 96{ 97 unsigned long *stack, addr; 98 int i; 99 100 /* 101 * debugging aid: "show_stack(NULL);" prints a 102 * back trace. 103 */ 104 105 if (sp == NULL) { 106 if (task) 107 sp = (unsigned long*)task->thread.ksp; 108 else 109 sp = (unsigned long*)rdsp(); 110 } 111 112 stack = sp; 113 114 printk("\nStack from %08lx:\n ", (unsigned long)stack); 115 for (i = 0; i < kstack_depth_to_print; i++) { 116 if (((long)stack & (THREAD_SIZE-1)) == 0) 117 break; 118 if (i && ((i % 8) == 0)) 119 printk("\n "); 120 if (__get_user(addr, stack)) { 121 /* This message matches "failing address" marked 122 s390 in ksymoops, so lines containing it will 123 not be filtered out by ksymoops. */ 124 printk("Failing address 0x%lx\n", (unsigned long)stack); 125 break; 126 } 127 stack++; 128 printk("%08lx ", addr); 129 } 130 show_trace(sp); 131} 132 133#if 0 134/* displays a short stack trace */ 135 136int 137show_stack(void) 138{ 139 unsigned long *sp = (unsigned long *)rdusp(); 140 int i; 141 142 printk("Stack dump [0x%08lx]:\n", (unsigned long)sp); 143 for (i = 0; i < 16; i++) 144 printk("sp + %d: 0x%08lx\n", i*4, sp[i]); 145 return 0; 146} 147#endif 148 149void 150dump_stack(void) 151{ 152 show_stack(NULL, NULL); 153} 154EXPORT_SYMBOL(dump_stack); 155 156void 157set_nmi_handler(void (*handler)(struct pt_regs *)) 158{ 159 nmi_handler = handler; 160 arch_enable_nmi(); 161} 162 163#ifdef CONFIG_DEBUG_NMI_OOPS 164void 165oops_nmi_handler(struct pt_regs *regs) 166{ 167 stop_watchdog(); 168 oops_in_progress = 1; 169 printk("NMI!\n"); 170 show_registers(regs); 171 oops_in_progress = 0; 172} 173 174static int __init 175oops_nmi_register(void) 176{ 177 set_nmi_handler(oops_nmi_handler); 178 return 0; 179} 180 181__initcall(oops_nmi_register); 182 183#endif 184 185/* 186 * This gets called from entry.S when the watchdog has bitten. Show something 187 * similar to an Oops dump, and if the kernel is configured to be a nice 188 * doggy, then halt instead of reboot. 189 */ 190void 191watchdog_bite_hook(struct pt_regs *regs) 192{ 193#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 194 local_irq_disable(); 195 stop_watchdog(); 196 show_registers(regs); 197 198 while (1) 199 ; /* Do nothing. */ 200#else 201 show_registers(regs); 202#endif 203} 204 205/* This is normally the Oops function. */ 206void 207die_if_kernel(const char *str, struct pt_regs *regs, long err) 208{ 209 if (user_mode(regs)) 210 return; 211 212#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 213 /* 214 * This printout might take too long and could trigger 215 * the watchdog normally. If NICE_DOGGY is set, simply 216 * stop the watchdog during the printout. 217 */ 218 stop_watchdog(); 219#endif 220 221 handle_BUG(regs); 222 223 printk("%s: %04lx\n", str, err & 0xffff); 224 225 show_registers(regs); 226 227 oops_in_progress = 0; 228 229#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 230 reset_watchdog(); 231#endif 232 do_exit(SIGSEGV); 233} 234 235void __init 236trap_init(void) 237{ 238 /* Nothing needs to be done */ 239} 240