Merge branch 'topic/jack-free-fix' into topic/hda
[linux-2.6] / arch / microblaze / kernel / traps.c
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 void __bad_xchg(volatile void *ptr, int size)
26 {
27         printk(KERN_INFO "xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
28                 __builtin_return_address(0), ptr, size);
29         BUG();
30 }
31 EXPORT_SYMBOL(__bad_xchg);
32
33 static int kstack_depth_to_print = 24;
34
35 static int __init kstack_setup(char *s)
36 {
37         kstack_depth_to_print = strict_strtoul(s, 0, 0);
38
39         return 1;
40 }
41 __setup("kstack=", kstack_setup);
42
43 void show_trace(struct task_struct *task, unsigned long *stack)
44 {
45         unsigned long addr;
46
47         if (!stack)
48                 stack = (unsigned long *)&stack;
49
50         printk(KERN_NOTICE "Call Trace: ");
51 #ifdef CONFIG_KALLSYMS
52         printk(KERN_NOTICE "\n");
53 #endif
54         while (!kstack_end(stack)) {
55                 addr = *stack++;
56                 /*
57                  * If the address is either in the text segment of the
58                  * kernel, or in the region which contains vmalloc'ed
59                  * memory, it *may* be the address of a calling
60                  * routine; if so, print it so that someone tracing
61                  * down the cause of the crash will be able to figure
62                  * out the call path that was taken.
63                  */
64                 if (kernel_text_address(addr))
65                         print_ip_sym(addr);
66         }
67         printk(KERN_NOTICE "\n");
68
69         if (!task)
70                 task = current;
71
72         debug_show_held_locks(task);
73 }
74
75 void show_stack(struct task_struct *task, unsigned long *sp)
76 {
77         unsigned long *stack;
78         int i;
79
80         if (sp == NULL) {
81                 if (task)
82                         sp = (unsigned long *) ((struct thread_info *)
83                                                 (task->stack))->cpu_context.r1;
84                 else
85                         sp = (unsigned long *)&sp;
86         }
87
88         stack = sp;
89
90         printk(KERN_INFO "\nStack:\n  ");
91
92         for (i = 0; i < kstack_depth_to_print; i++) {
93                 if (kstack_end(sp))
94                         break;
95                 if (i && ((i % 8) == 0))
96                         printk("\n  ");
97                 printk("%08lx ", *sp++);
98         }
99         printk("\n");
100         show_trace(task, stack);
101 }
102
103 void dump_stack(void)
104 {
105         show_stack(NULL, NULL);
106 }
107 EXPORT_SYMBOL(dump_stack);