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