Blame view

arch/cris/kernel/traps.c 4.85 KB
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
1
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
   *  linux/arch/cris/traps.c
   *
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
4
5
   *  Here we handle the break vectors not used by the system call
   *  mechanism, as well as some general stack/register dumping
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
   *  things.
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
7
8
   *
   *  Copyright (C) 2000-2007 Axis Communications AB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
   *
   *  Authors:   Bjorn Wesen
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
11
   *             Hans-Peter Nilsson
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
16
   *
   */
  
  #include <linux/init.h>
  #include <linux/module.h>
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
17

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
  #include <asm/pgtable.h>
  #include <asm/uaccess.h>
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
20
21
22
23
24
25
26
27
28
29
  extern void arch_enable_nmi(void);
  extern void stop_watchdog(void);
  extern void reset_watchdog(void);
  extern void show_registers(struct pt_regs *regs);
  
  #ifdef CONFIG_DEBUG_BUGVERBOSE
  extern void handle_BUG(struct pt_regs *regs);
  #else
  #define handle_BUG(regs)
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  static int kstack_depth_to_print = 24;
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
31
  void (*nmi_handler)(struct pt_regs *);
059163cab   Mikael Starvik   [PATCH] CRIS upda...
32

1ddba0257   Jesper Nilsson   CRIS: Minor gener...
33
34
  void
  show_trace(unsigned long *stack)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
37
38
  {
  	unsigned long addr, module_start, module_end;
  	extern char _stext, _etext;
  	int i;
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
39
40
  	printk("
  Call Trace: ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41

1ddba0257   Jesper Nilsson   CRIS: Minor gener...
42
43
44
  	i = 1;
  	module_start = VMALLOC_START;
  	module_end = VMALLOC_END;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45

1ddba0257   Jesper Nilsson   CRIS: Minor gener...
46
47
  	while (((long)stack & (THREAD_SIZE-1)) != 0) {
  		if (__get_user(addr, stack)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
49
50
  			/* This message matches "failing address" marked
  			   s390 in ksymoops, so lines containing it will
  			   not be filtered out by ksymoops.  */
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
51
52
  			printk("Failing address 0x%lx
  ", (unsigned long)stack);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
54
55
  			break;
  		}
  		stack++;
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  		/*
  		 * If the address is either in the text segment of the
  		 * kernel, or in the region which contains vmalloc'ed
  		 * memory, it *may* be the address of a calling
  		 * routine; if so, print it so that someone tracing
  		 * down the cause of the crash will be able to figure
  		 * out the call path that was taken.
  		 */
  		if (((addr >= (unsigned long)&_stext) &&
  		     (addr <= (unsigned long)&_etext)) ||
  		    ((addr >= module_start) && (addr <= module_end))) {
  			if (i && ((i % 8) == 0))
  				printk("
         ");
  			printk("[<%08lx>] ", addr);
  			i++;
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  }
  
  /*
   * These constants are for searching for possible module text
   * segments. MODULE_RANGE is a guess of how much space is likely
   * to be vmalloced.
   */
  
  #define MODULE_RANGE (8*1024*1024)
  
  /*
   * The output (format, strings and order) is adjusted to be usable with
   * ksymoops-2.4.1 with some necessary CRIS-specific patches.  Please don't
   * change it unless you're serious about adjusting ksymoops and syncing
   * with the ksymoops maintainer.
   */
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
90
  void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
  show_stack(struct task_struct *task, unsigned long *sp)
  {
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
93
94
  	unsigned long *stack, addr;
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
96
97
98
99
  
  	/*
  	 * debugging aid: "show_stack(NULL);" prints a
  	 * back trace.
  	 */
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
100
  	if (sp == NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
105
  		if (task)
  			sp = (unsigned long*)task->thread.ksp;
  		else
  			sp = (unsigned long*)rdsp();
  	}
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
106
  	stack = sp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107

1ddba0257   Jesper Nilsson   CRIS: Minor gener...
108
109
110
111
112
113
114
115
116
117
  	printk("
  Stack from %08lx:
         ", (unsigned long)stack);
  	for (i = 0; i < kstack_depth_to_print; i++) {
  		if (((long)stack & (THREAD_SIZE-1)) == 0)
  			break;
  		if (i && ((i % 8) == 0))
  			printk("
         ");
  		if (__get_user(addr, stack)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
120
  			/* This message matches "failing address" marked
  			   s390 in ksymoops, so lines containing it will
  			   not be filtered out by ksymoops.  */
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
121
122
  			printk("Failing address 0x%lx
  ", (unsigned long)stack);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
124
125
  			break;
  		}
  		stack++;
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
126
127
  		printk("%08lx ", addr);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
  	show_trace(sp);
  }
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
130
131
  #if 0
  /* displays a short stack trace */
059163cab   Mikael Starvik   [PATCH] CRIS upda...
132

1ddba0257   Jesper Nilsson   CRIS: Minor gener...
133
134
  int
  show_stack(void)
059163cab   Mikael Starvik   [PATCH] CRIS upda...
135
  {
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
136
137
138
139
140
141
142
143
144
  	unsigned long *sp = (unsigned long *)rdusp();
  	int i;
  
  	printk("Stack dump [0x%08lx]:
  ", (unsigned long)sp);
  	for (i = 0; i < 16; i++)
  		printk("sp + %d: 0x%08lx
  ", i*4, sp[i]);
  	return 0;
059163cab   Mikael Starvik   [PATCH] CRIS upda...
145
  }
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
146
  #endif
059163cab   Mikael Starvik   [PATCH] CRIS upda...
147

1ddba0257   Jesper Nilsson   CRIS: Minor gener...
148
149
  void
  dump_stack(void)
059163cab   Mikael Starvik   [PATCH] CRIS upda...
150
  {
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
151
152
153
154
155
156
157
158
159
  	show_stack(NULL, NULL);
  }
  EXPORT_SYMBOL(dump_stack);
  
  void
  set_nmi_handler(void (*handler)(struct pt_regs *))
  {
  	nmi_handler = handler;
  	arch_enable_nmi();
059163cab   Mikael Starvik   [PATCH] CRIS upda...
160
161
162
  }
  
  #ifdef CONFIG_DEBUG_NMI_OOPS
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
163
164
  void
  oops_nmi_handler(struct pt_regs *regs)
059163cab   Mikael Starvik   [PATCH] CRIS upda...
165
  {
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
166
167
168
169
170
171
  	stop_watchdog();
  	oops_in_progress = 1;
  	printk("NMI!
  ");
  	show_registers(regs);
  	oops_in_progress = 0;
059163cab   Mikael Starvik   [PATCH] CRIS upda...
172
  }
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
173
174
  static int __init
  oops_nmi_register(void)
059163cab   Mikael Starvik   [PATCH] CRIS upda...
175
  {
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
176
177
  	set_nmi_handler(oops_nmi_handler);
  	return 0;
059163cab   Mikael Starvik   [PATCH] CRIS upda...
178
179
180
181
182
  }
  
  __initcall(oops_nmi_register);
  
  #endif
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
183
184
  /*
   * This gets called from entry.S when the watchdog has bitten. Show something
25985edce   Lucas De Marchi   Fix common misspe...
185
   * similar to an Oops dump, and if the kernel is configured to be a nice
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
186
187
188
189
   * doggy, then halt instead of reboot.
   */
  void
  watchdog_bite_hook(struct pt_regs *regs)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
  {
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
191
192
193
194
195
196
197
198
199
  #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  	local_irq_disable();
  	stop_watchdog();
  	show_registers(regs);
  
  	while (1)
  		; /* Do nothing. */
  #else
  	show_registers(regs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
  #endif
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
201
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202

1ddba0257   Jesper Nilsson   CRIS: Minor gener...
203
204
205
  /* This is normally the Oops function. */
  void
  die_if_kernel(const char *str, struct pt_regs *regs, long err)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
  {
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
207
208
  	if (user_mode(regs))
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209

1ddba0257   Jesper Nilsson   CRIS: Minor gener...
210
211
212
213
214
215
216
217
  #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  	/*
  	 * This printout might take too long and could trigger
  	 * the watchdog normally. If NICE_DOGGY is set, simply
  	 * stop the watchdog during the printout.
  	 */
  	stop_watchdog();
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218

1ddba0257   Jesper Nilsson   CRIS: Minor gener...
219
220
221
222
223
224
225
226
227
228
229
230
231
  	handle_BUG(regs);
  
  	printk("%s: %04lx
  ", str, err & 0xffff);
  
  	show_registers(regs);
  
  	oops_in_progress = 0;
  
  #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  	reset_watchdog();
  #endif
  	do_exit(SIGSEGV);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
232
  }
059163cab   Mikael Starvik   [PATCH] CRIS upda...
233

1ddba0257   Jesper Nilsson   CRIS: Minor gener...
234
235
  void __init
  trap_init(void)
059163cab   Mikael Starvik   [PATCH] CRIS upda...
236
  {
1ddba0257   Jesper Nilsson   CRIS: Minor gener...
237
  	/* Nothing needs to be done */
059163cab   Mikael Starvik   [PATCH] CRIS upda...
238
  }