aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-06-07 17:18:25 -0400
committerMike Frysinger <vapier@gentoo.org>2009-06-13 07:20:07 -0400
commit70f12567ac9aca9c2f242ae060d7de245904889e (patch)
tree6838a6886fbe0c932f50cf5a059ffd798c43ca1c /arch
parent67834fa93d7a4fac9069a07e739110d3916d8cd4 (diff)
Blackfin: add support for GENERIC_BUG
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/blackfin/Kconfig4
-rw-r--r--arch/blackfin/include/asm/bug.h57
-rw-r--r--arch/blackfin/kernel/traps.c30
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S16
4 files changed, 99 insertions, 8 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index c56fd3eb7c10..74cdcf39b41c 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -28,6 +28,10 @@ config BLACKFIN
28 select HAVE_OPROFILE 28 select HAVE_OPROFILE
29 select ARCH_WANT_OPTIONAL_GPIOLIB 29 select ARCH_WANT_OPTIONAL_GPIOLIB
30 30
31config GENERIC_BUG
32 def_bool y
33 depends on BUG
34
31config ZONE_DMA 35config ZONE_DMA
32 bool 36 bool
33 default y 37 default y
diff --git a/arch/blackfin/include/asm/bug.h b/arch/blackfin/include/asm/bug.h
index 6d3e11b1fc57..655e49540e41 100644
--- a/arch/blackfin/include/asm/bug.h
+++ b/arch/blackfin/include/asm/bug.h
@@ -2,13 +2,58 @@
2#define _BLACKFIN_BUG_H 2#define _BLACKFIN_BUG_H
3 3
4#ifdef CONFIG_BUG 4#ifdef CONFIG_BUG
5#define HAVE_ARCH_BUG
6 5
7#define BUG() do { \ 6#define BFIN_BUG_OPCODE 0xefcd
8 dump_bfin_trace_buffer(); \ 7
9 printk(KERN_EMERG "BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \ 8#ifdef CONFIG_DEBUG_BUGVERBOSE
10 panic("BUG!"); \ 9
11} while (0) 10#define _BUG_OR_WARN(flags) \
11 asm volatile( \
12 "1: .hword %0\n" \
13 " .section __bug_table,\"a\",@progbits\n" \
14 "2: .long 1b\n" \
15 " .long %1\n" \
16 " .short %2\n" \
17 " .short %3\n" \
18 " .org 2b + %4\n" \
19 " .previous" \
20 : \
21 : "i"(BFIN_BUG_OPCODE), "i"(__FILE__), \
22 "i"(__LINE__), "i"(flags), \
23 "i"(sizeof(struct bug_entry)))
24
25#else
26
27#define _BUG_OR_WARN(flags) \
28 asm volatile( \
29 "1: .hword %0\n" \
30 " .section __bug_table,\"a\",@progbits\n" \
31 "2: .long 1b\n" \
32 " .short %1\n" \
33 " .org 2b + %2\n" \
34 " .previous" \
35 : \
36 : "i"(BFIN_BUG_OPCODE), "i"(flags), \
37 "i"(sizeof(struct bug_entry)))
38
39#endif /* CONFIG_DEBUG_BUGVERBOSE */
40
41#define BUG() \
42 do { \
43 _BUG_OR_WARN(0); \
44 for (;;); \
45 } while (0)
46
47#define WARN_ON(condition) \
48 ({ \
49 int __ret_warn_on = !!(condition); \
50 if (unlikely(__ret_warn_on)) \
51 _BUG_OR_WARN(BUGFLAG_WARNING); \
52 unlikely(__ret_warn_on); \
53 })
54
55#define HAVE_ARCH_BUG
56#define HAVE_ARCH_WARN_ON
12 57
13#endif 58#endif
14 59
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index aa76dfb0226e..2405f193224e 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -27,6 +27,7 @@
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 28 */
29 29
30#include <linux/bug.h>
30#include <linux/uaccess.h> 31#include <linux/uaccess.h>
31#include <linux/interrupt.h> 32#include <linux/interrupt.h>
32#include <linux/module.h> 33#include <linux/module.h>
@@ -381,6 +382,23 @@ asmlinkage void trap_c(struct pt_regs *fp)
381 /* 0x20 - Reserved, Caught by default */ 382 /* 0x20 - Reserved, Caught by default */
382 /* 0x21 - Undefined Instruction, handled here */ 383 /* 0x21 - Undefined Instruction, handled here */
383 case VEC_UNDEF_I: 384 case VEC_UNDEF_I:
385#ifdef CONFIG_BUG
386 if (kernel_mode_regs(fp)) {
387 switch (report_bug(fp->pc, fp)) {
388 case BUG_TRAP_TYPE_NONE:
389 break;
390 case BUG_TRAP_TYPE_WARN:
391 dump_bfin_trace_buffer();
392 fp->pc += 2;
393 goto traps_done;
394 case BUG_TRAP_TYPE_BUG:
395 /* call to panic() will dump trace, and it is
396 * off at this point, so it won't be clobbered
397 */
398 panic("BUG()");
399 }
400 }
401#endif
384 info.si_code = ILL_ILLOPC; 402 info.si_code = ILL_ILLOPC;
385 sig = SIGILL; 403 sig = SIGILL;
386 verbose_printk(KERN_NOTICE EXC_0x21(KERN_NOTICE)); 404 verbose_printk(KERN_NOTICE EXC_0x21(KERN_NOTICE));
@@ -792,6 +810,18 @@ void dump_bfin_trace_buffer(void)
792} 810}
793EXPORT_SYMBOL(dump_bfin_trace_buffer); 811EXPORT_SYMBOL(dump_bfin_trace_buffer);
794 812
813#ifdef CONFIG_BUG
814int is_valid_bugaddr(unsigned long addr)
815{
816 unsigned short opcode;
817
818 if (!get_instruction(&opcode, (unsigned short *)addr))
819 return 0;
820
821 return opcode == BFIN_BUG_OPCODE;
822}
823#endif
824
795/* 825/*
796 * Checks to see if the address pointed to is either a 826 * Checks to see if the address pointed to is either a
797 * 16-bit CALL instruction, or a 32-bit CALL instruction 827 * 16-bit CALL instruction, or a 32-bit CALL instruction
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index 8b67167cb4f4..119fbdb46475 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -166,6 +166,20 @@ SECTIONS
166 } 166 }
167 PERCPU(4) 167 PERCPU(4)
168 SECURITY_INIT 168 SECURITY_INIT
169
170 /* we have to discard exit text and such at runtime, not link time, to
171 * handle embedded cross-section references (alt instructions, bug
172 * table, eh_frame, etc...)
173 */
174 .exit.text :
175 {
176 EXIT_TEXT
177 }
178 .exit.data :
179 {
180 EXIT_DATA
181 }
182
169 .init.ramfs : 183 .init.ramfs :
170 { 184 {
171 . = ALIGN(4); 185 . = ALIGN(4);
@@ -264,8 +278,6 @@ SECTIONS
264 278
265 /DISCARD/ : 279 /DISCARD/ :
266 { 280 {
267 EXIT_TEXT
268 EXIT_DATA
269 *(.exitcall.exit) 281 *(.exitcall.exit)
270 } 282 }
271} 283}