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 unsigned long kstack_depth_to_print = 24; 26 27 static int __init kstack_setup(char *s) 28 { 29 return !strict_strtoul(s, 0, &kstack_depth_to_print); 30 } 31 __setup("kstack=", kstack_setup); 32 33 void show_trace(struct task_struct *task, unsigned long *stack) 34 { 35 unsigned long addr; 36 37 if (!stack) 38 stack = (unsigned long *)&stack; 39 40 printk(KERN_NOTICE "Call Trace: "); 41 #ifdef CONFIG_KALLSYMS 42 printk(KERN_NOTICE "\n"); 43 #endif 44 while (!kstack_end(stack)) { 45 addr = *stack++; 46 /* 47 * If the address is either in the text segment of the 48 * kernel, or in the region which contains vmalloc'ed 49 * memory, it *may* be the address of a calling 50 * routine; if so, print it so that someone tracing 51 * down the cause of the crash will be able to figure 52 * out the call path that was taken. 53 */ 54 if (kernel_text_address(addr)) 55 print_ip_sym(addr); 56 } 57 printk(KERN_NOTICE "\n"); 58 59 if (!task) 60 task = current; 61 62 debug_show_held_locks(task); 63 } 64 65 void show_stack(struct task_struct *task, unsigned long *sp) 66 { 67 unsigned long *stack; 68 int i; 69 70 if (sp == NULL) { 71 if (task) 72 sp = (unsigned long *) ((struct thread_info *) 73 (task->stack))->cpu_context.r1; 74 else 75 sp = (unsigned long *)&sp; 76 } 77 78 stack = sp; 79 80 printk(KERN_INFO "\nStack:\n "); 81 82 for (i = 0; i < kstack_depth_to_print; i++) { 83 if (kstack_end(sp)) 84 break; 85 if (i && ((i % 8) == 0)) 86 printk("\n "); 87 printk("%08lx ", *sp++); 88 } 89 printk("\n"); 90 show_trace(task, stack); 91 } 92 93 void dump_stack(void) 94 { 95 show_stack(NULL, NULL); 96 } 97 EXPORT_SYMBOL(dump_stack); 98 99 #ifdef CONFIG_MMU 100 void __bug(const char *file, int line, void *data) 101 { 102 if (data) 103 printk(KERN_CRIT "kernel BUG at %s:%d (data = %p)!\n", 104 file, line, data); 105 else 106 printk(KERN_CRIT "kernel BUG at %s:%d!\n", file, line); 107 108 machine_halt(); 109 } 110 111 int bad_trap(int trap_num, struct pt_regs *regs) 112 { 113 printk(KERN_CRIT 114 "unimplemented trap %d called at 0x%08lx, pid %d!\n", 115 trap_num, regs->pc, current->pid); 116 return -ENOSYS; 117 } 118 119 int debug_trap(struct pt_regs *regs) 120 { 121 int i; 122 printk(KERN_CRIT "debug trap\n"); 123 for (i = 0; i < 32; i++) { 124 /* printk("r%i:%08X\t",i,regs->gpr[i]); */ 125 if ((i % 4) == 3) 126 printk(KERN_CRIT "\n"); 127 } 128 printk(KERN_CRIT "pc:%08lX\tmsr:%08lX\n", regs->pc, regs->msr); 129 return -ENOSYS; 130 } 131 #endif 132