Linux Audio

Check our new training course

Linux BSP development engineering services

Need help to port Linux and bootloaders to your hardware?
Loading...
Note: File does not exist in v4.17.
  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#if 0
133/* displays a short stack trace */
134
135int
136show_stack(void)
137{
138	unsigned long *sp = (unsigned long *)rdusp();
139	int i;
140
141	printk("Stack dump [0x%08lx]:\n", (unsigned long)sp);
142	for (i = 0; i < 16; i++)
143		printk("sp + %d: 0x%08lx\n", i*4, sp[i]);
144	return 0;
145}
146#endif
147
148void
149dump_stack(void)
150{
151	show_stack(NULL, NULL);
152}
153EXPORT_SYMBOL(dump_stack);
154
155void
156set_nmi_handler(void (*handler)(struct pt_regs *))
157{
158	nmi_handler = handler;
159	arch_enable_nmi();
160}
161
162#ifdef CONFIG_DEBUG_NMI_OOPS
163void
164oops_nmi_handler(struct pt_regs *regs)
165{
166	stop_watchdog();
167	oops_in_progress = 1;
168	printk("NMI!\n");
169	show_registers(regs);
170	oops_in_progress = 0;
171}
172
173static int __init
174oops_nmi_register(void)
175{
176	set_nmi_handler(oops_nmi_handler);
177	return 0;
178}
179
180__initcall(oops_nmi_register);
181
182#endif
183
184/*
185 * This gets called from entry.S when the watchdog has bitten. Show something
186 * similar to an Oops dump, and if the kernel is configured to be a nice
187 * doggy, then halt instead of reboot.
188 */
189void
190watchdog_bite_hook(struct pt_regs *regs)
191{
192#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
193	local_irq_disable();
194	stop_watchdog();
195	show_registers(regs);
196
197	while (1)
198		; /* Do nothing. */
199#else
200	show_registers(regs);
201#endif
202}
203
204/* This is normally the Oops function. */
205void
206die_if_kernel(const char *str, struct pt_regs *regs, long err)
207{
208	if (user_mode(regs))
209		return;
210
211#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
212	/*
213	 * This printout might take too long and could trigger
214	 * the watchdog normally. If NICE_DOGGY is set, simply
215	 * stop the watchdog during the printout.
216	 */
217	stop_watchdog();
218#endif
219
220	handle_BUG(regs);
221
222	printk("%s: %04lx\n", str, err & 0xffff);
223
224	show_registers(regs);
225
226	oops_in_progress = 0;
227
228#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
229	reset_watchdog();
230#endif
231	do_exit(SIGSEGV);
232}
233
234void __init
235trap_init(void)
236{
237	/* Nothing needs to be done */
238}