1 /* 2 * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> 3 * Copyright (C) 2007-2009 PetaLogix 4 * Copyright (C) 2006 Atmark Techno, Inc. 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/kallsyms.h> 13 #include <linux/module.h> 14 #include <linux/sched.h> 15 #include <linux/debug_locks.h> 16 17 #include <asm/exceptions.h> 18 #include <asm/system.h> 19 20 void trap_init(void) 21 { 22 __enable_hw_exceptions(); 23 } 24 25 static int kstack_depth_to_print = 24; 26 27 static int __init kstack_setup(char *s) 28 { 29 kstack_depth_to_print = strict_strtoul(s, 0, NULL); 30 31 return 1; 32 } 33 __setup("kstack=", kstack_setup); 34 35 void show_trace(struct task_struct *task, unsigned long *stack) 36 { 37 unsigned long addr; 38 39 if (!stack) 40 stack = (unsigned long *)&stack; 41 42 printk(KERN_NOTICE "Call Trace: "); 43 #ifdef CONFIG_KALLSYMS 44 printk(KERN_NOTICE "\n"); 45 #endif 46 while (!kstack_end(stack)) { 47 addr = *stack++; 48 /* 49 * If the address is either in the text segment of the 50 * kernel, or in the region which contains vmalloc'ed 51 * memory, it *may* be the address of a calling 52 * routine; if so, print it so that someone tracing 53 * down the cause of the crash will be able to figure 54 * out the call path that was taken. 55 */ 56 if (kernel_text_address(addr)) 57 print_ip_sym(addr); 58 } 59 printk(KERN_NOTICE "\n"); 60 61 if (!task) 62 task = current; 63 64 debug_show_held_locks(task); 65 } 66 67 void show_stack(struct task_struct *task, unsigned long *sp) 68 { 69 unsigned long *stack; 70 int i; 71 72 if (sp == NULL) { 73 if (task) 74 sp = (unsigned long *) ((struct thread_info *) 75 (task->stack))->cpu_context.r1; 76 else 77 sp = (unsigned long *)&sp; 78 } 79 80 stack = sp; 81 82 printk(KERN_INFO "\nStack:\n "); 83 84 for (i = 0; i < kstack_depth_to_print; i++) { 85 if (kstack_end(sp)) 86 break; 87 if (i && ((i % 8) == 0)) 88 printk("\n "); 89 printk("%08lx ", *sp++); 90 } 91 printk("\n"); 92 show_trace(task, stack); 93 } 94 95 void dump_stack(void) 96 { 97 show_stack(NULL, NULL); 98 } 99 EXPORT_SYMBOL(dump_stack); 100 101 #ifdef CONFIG_MMU 102 void __bug(const char *file, int line, void *data) 103 { 104 if (data) 105 printk(KERN_CRIT "kernel BUG at %s:%d (data = %p)!\n", 106 file, line, data); 107 else 108 printk(KERN_CRIT "kernel BUG at %s:%d!\n", file, line); 109 110 machine_halt(); 111 } 112 113 int bad_trap(int trap_num, struct pt_regs *regs) 114 { 115 printk(KERN_CRIT 116 "unimplemented trap %d called at 0x%08lx, pid %d!\n", 117 trap_num, regs->pc, current->pid); 118 return -ENOSYS; 119 } 120 121 int debug_trap(struct pt_regs *regs) 122 { 123 int i; 124 printk(KERN_CRIT "debug trap\n"); 125 for (i = 0; i < 32; i++) { 126 /* printk("r%i:%08X\t",i,regs->gpr[i]); */ 127 if ((i % 4) == 3) 128 printk(KERN_CRIT "\n"); 129 } 130 printk(KERN_CRIT "pc:%08lX\tmsr:%08lX\n", regs->pc, regs->msr); 131 return -ENOSYS; 132 } 133 #endif 134