diff options
author | Mike Frysinger <vapier@gentoo.org> | 2009-06-07 17:18:25 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-06-13 07:20:07 -0400 |
commit | 70f12567ac9aca9c2f242ae060d7de245904889e (patch) | |
tree | 6838a6886fbe0c932f50cf5a059ffd798c43ca1c /arch | |
parent | 67834fa93d7a4fac9069a07e739110d3916d8cd4 (diff) |
Blackfin: add support for GENERIC_BUG
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/blackfin/Kconfig | 4 | ||||
-rw-r--r-- | arch/blackfin/include/asm/bug.h | 57 | ||||
-rw-r--r-- | arch/blackfin/kernel/traps.c | 30 | ||||
-rw-r--r-- | arch/blackfin/kernel/vmlinux.lds.S | 16 |
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 | ||
31 | config GENERIC_BUG | ||
32 | def_bool y | ||
33 | depends on BUG | ||
34 | |||
31 | config ZONE_DMA | 35 | config 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 | } |
793 | EXPORT_SYMBOL(dump_bfin_trace_buffer); | 811 | EXPORT_SYMBOL(dump_bfin_trace_buffer); |
794 | 812 | ||
813 | #ifdef CONFIG_BUG | ||
814 | int 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 | } |