• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/cris/kernel/
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