1/* $Id: traps.c,v 1.1.1.1 2007-08-03 18:51:42 $ 2 * 3 * linux/arch/cris/traps.c 4 * 5 * Here we handle the break vectors not used by the system call 6 * mechanism, as well as some general stack/register dumping 7 * things. 8 * 9 * Copyright (C) 2000-2002 Axis Communications AB 10 * 11 * Authors: Bjorn Wesen 12 * Hans-Peter Nilsson 13 * 14 */ 15 16#include <linux/init.h> 17#include <linux/module.h> 18#include <asm/pgtable.h> 19#include <asm/uaccess.h> 20 21static int kstack_depth_to_print = 24; 22 23extern int raw_printk(const char *fmt, ...); 24 25void show_trace(unsigned long * stack) 26{ 27 unsigned long addr, module_start, module_end; 28 extern char _stext, _etext; 29 int i; 30 31 raw_printk("\nCall Trace: "); 32 33 i = 1; 34 module_start = VMALLOC_START; 35 module_end = VMALLOC_END; 36 37 while (((long) stack & (THREAD_SIZE-1)) != 0) { 38 if (__get_user (addr, stack)) { 39 /* This message matches "failing address" marked 40 s390 in ksymoops, so lines containing it will 41 not be filtered out by ksymoops. */ 42 raw_printk ("Failing address 0x%lx\n", (unsigned long)stack); 43 break; 44 } 45 stack++; 46 47 /* 48 * If the address is either in the text segment of the 49 * kernel, or in the region which contains vmalloc'ed 50 * memory, it *may* be the address of a calling 51 * routine; if so, print it so that someone tracing 52 * down the cause of the crash will be able to figure 53 * out the call path that was taken. 54 */ 55 if (((addr >= (unsigned long) &_stext) && 56 (addr <= (unsigned long) &_etext)) || 57 ((addr >= module_start) && (addr <= module_end))) { 58 if (i && ((i % 8) == 0)) 59 raw_printk("\n "); 60 raw_printk("[<%08lx>] ", addr); 61 i++; 62 } 63 } 64} 65 66/* 67 * These constants are for searching for possible module text 68 * segments. MODULE_RANGE is a guess of how much space is likely 69 * to be vmalloced. 70 */ 71 72#define MODULE_RANGE (8*1024*1024) 73 74/* 75 * The output (format, strings and order) is adjusted to be usable with 76 * ksymoops-2.4.1 with some necessary CRIS-specific patches. Please don't 77 * change it unless you're serious about adjusting ksymoops and syncing 78 * with the ksymoops maintainer. 79 */ 80 81void 82show_stack(struct task_struct *task, unsigned long *sp) 83{ 84 unsigned long *stack, addr; 85 int i; 86 87 /* 88 * debugging aid: "show_stack(NULL);" prints a 89 * back trace. 90 */ 91 92 if(sp == NULL) { 93 if (task) 94 sp = (unsigned long*)task->thread.ksp; 95 else 96 sp = (unsigned long*)rdsp(); 97 } 98 99 stack = sp; 100 101 raw_printk("\nStack from %08lx:\n ", (unsigned long)stack); 102 for(i = 0; i < kstack_depth_to_print; i++) { 103 if (((long) stack & (THREAD_SIZE-1)) == 0) 104 break; 105 if (i && ((i % 8) == 0)) 106 raw_printk("\n "); 107 if (__get_user (addr, stack)) { 108 /* This message matches "failing address" marked 109 s390 in ksymoops, so lines containing it will 110 not be filtered out by ksymoops. */ 111 raw_printk ("Failing address 0x%lx\n", (unsigned long)stack); 112 break; 113 } 114 stack++; 115 raw_printk("%08lx ", addr); 116 } 117 show_trace(sp); 118} 119 120static void (*nmi_handler)(struct pt_regs*); 121extern void arch_enable_nmi(void); 122 123void set_nmi_handler(void (*handler)(struct pt_regs*)) 124{ 125 nmi_handler = handler; 126 arch_enable_nmi(); 127} 128 129void handle_nmi(struct pt_regs* regs) 130{ 131 if (nmi_handler) 132 nmi_handler(regs); 133} 134 135#ifdef CONFIG_DEBUG_NMI_OOPS 136void oops_nmi_handler(struct pt_regs* regs) 137{ 138 stop_watchdog(); 139 raw_printk("NMI!\n"); 140 show_registers(regs); 141} 142 143static int 144__init oops_nmi_register(void) 145{ 146 set_nmi_handler(oops_nmi_handler); 147 return 0; 148} 149 150__initcall(oops_nmi_register); 151 152#endif 153 154 155void dump_stack(void) 156{ 157 show_stack(NULL, NULL); 158} 159 160EXPORT_SYMBOL(dump_stack); 161 162void __init 163trap_init(void) 164{ 165 /* Nothing needs to be done */ 166} 167 168void spinning_cpu(void* addr) 169{ 170 raw_printk("CPU %d spinning on %X\n", smp_processor_id(), addr); 171 dump_stack(); 172} 173