diff options
Diffstat (limited to 'include/asm-powerpc/bug.h')
-rw-r--r-- | include/asm-powerpc/bug.h | 105 |
1 files changed, 63 insertions, 42 deletions
diff --git a/include/asm-powerpc/bug.h b/include/asm-powerpc/bug.h index 978b2c7e84ea..f6fa39474846 100644 --- a/include/asm-powerpc/bug.h +++ b/include/asm-powerpc/bug.h | |||
@@ -11,24 +11,48 @@ | |||
11 | #define BUG_OPCODE .long 0x00b00b00 /* For asm */ | 11 | #define BUG_OPCODE .long 0x00b00b00 /* For asm */ |
12 | #define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */ | 12 | #define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */ |
13 | 13 | ||
14 | #ifndef __ASSEMBLY__ | 14 | #ifdef CONFIG_BUG |
15 | |||
16 | struct bug_entry { | ||
17 | unsigned long bug_addr; | ||
18 | long line; | ||
19 | const char *file; | ||
20 | const char *function; | ||
21 | }; | ||
22 | |||
23 | struct bug_entry *find_bug(unsigned long bugaddr); | ||
24 | 15 | ||
25 | /* | 16 | #ifdef __ASSEMBLY__ |
26 | * If this bit is set in the line number it means that the trap | 17 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
27 | * is for WARN_ON rather than BUG or BUG_ON. | 18 | .macro EMIT_BUG_ENTRY addr,file,line,flags |
28 | */ | 19 | .section __bug_table,"a" |
29 | #define BUG_WARNING_TRAP 0x1000000 | 20 | 5001: PPC_LONG \addr, 5002f |
21 | .short \line, \flags | ||
22 | .org 5001b+BUG_ENTRY_SIZE | ||
23 | .previous | ||
24 | .section .rodata,"a" | ||
25 | 5002: .asciz "\file" | ||
26 | .previous | ||
27 | .endm | ||
28 | #else | ||
29 | .macro EMIT_BUG_ENTRY addr,file,line,flags | ||
30 | .section __bug_table,"a" | ||
31 | 5001: PPC_LONG \addr | ||
32 | .short \flags | ||
33 | .org 5001b+BUG_ENTRY_SIZE | ||
34 | .previous | ||
35 | .endm | ||
36 | #endif /* verbose */ | ||
30 | 37 | ||
31 | #ifdef CONFIG_BUG | 38 | #else /* !__ASSEMBLY__ */ |
39 | /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and | ||
40 | sizeof(struct bug_entry), respectively */ | ||
41 | #ifdef CONFIG_DEBUG_BUGVERBOSE | ||
42 | #define _EMIT_BUG_ENTRY \ | ||
43 | ".section __bug_table,\"a\"\n" \ | ||
44 | "2:\t" PPC_LONG "1b, %0\n" \ | ||
45 | "\t.short %1, %2\n" \ | ||
46 | ".org 2b+%3\n" \ | ||
47 | ".previous\n" | ||
48 | #else | ||
49 | #define _EMIT_BUG_ENTRY \ | ||
50 | ".section __bug_table,\"a\"\n" \ | ||
51 | "2:\t" PPC_LONG "1b\n" \ | ||
52 | "\t.short %2\n" \ | ||
53 | ".org 2b+%3\n" \ | ||
54 | ".previous\n" | ||
55 | #endif | ||
32 | 56 | ||
33 | /* | 57 | /* |
34 | * BUG_ON() and WARN_ON() do their best to cooperate with compile-time | 58 | * BUG_ON() and WARN_ON() do their best to cooperate with compile-time |
@@ -36,13 +60,13 @@ struct bug_entry *find_bug(unsigned long bugaddr); | |||
36 | * some compiler versions may not produce optimal results. | 60 | * some compiler versions may not produce optimal results. |
37 | */ | 61 | */ |
38 | 62 | ||
39 | #define BUG() do { \ | 63 | #define BUG() do { \ |
40 | __asm__ __volatile__( \ | 64 | __asm__ __volatile__( \ |
41 | "1: twi 31,0,0\n" \ | 65 | "1: twi 31,0,0\n" \ |
42 | ".section __bug_table,\"a\"\n" \ | 66 | _EMIT_BUG_ENTRY \ |
43 | "\t"PPC_LONG" 1b,%0,%1,%2\n" \ | 67 | : : "i" (__FILE__), "i" (__LINE__), \ |
44 | ".previous" \ | 68 | "i" (0), "i" (sizeof(struct bug_entry))); \ |
45 | : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \ | 69 | for(;;) ; \ |
46 | } while (0) | 70 | } while (0) |
47 | 71 | ||
48 | #define BUG_ON(x) do { \ | 72 | #define BUG_ON(x) do { \ |
@@ -51,23 +75,21 @@ struct bug_entry *find_bug(unsigned long bugaddr); | |||
51 | BUG(); \ | 75 | BUG(); \ |
52 | } else { \ | 76 | } else { \ |
53 | __asm__ __volatile__( \ | 77 | __asm__ __volatile__( \ |
54 | "1: "PPC_TLNEI" %0,0\n" \ | 78 | "1: "PPC_TLNEI" %4,0\n" \ |
55 | ".section __bug_table,\"a\"\n" \ | 79 | _EMIT_BUG_ENTRY \ |
56 | "\t"PPC_LONG" 1b,%1,%2,%3\n" \ | 80 | : : "i" (__FILE__), "i" (__LINE__), "i" (0), \ |
57 | ".previous" \ | 81 | "i" (sizeof(struct bug_entry)), \ |
58 | : : "r" ((long)(x)), "i" (__LINE__), \ | 82 | "r" ((long)(x))); \ |
59 | "i" (__FILE__), "i" (__FUNCTION__)); \ | ||
60 | } \ | 83 | } \ |
61 | } while (0) | 84 | } while (0) |
62 | 85 | ||
63 | #define __WARN() do { \ | 86 | #define __WARN() do { \ |
64 | __asm__ __volatile__( \ | 87 | __asm__ __volatile__( \ |
65 | "1: twi 31,0,0\n" \ | 88 | "1: twi 31,0,0\n" \ |
66 | ".section __bug_table,\"a\"\n" \ | 89 | _EMIT_BUG_ENTRY \ |
67 | "\t"PPC_LONG" 1b,%0,%1,%2\n" \ | 90 | : : "i" (__FILE__), "i" (__LINE__), \ |
68 | ".previous" \ | 91 | "i" (BUGFLAG_WARNING), \ |
69 | : : "i" (__LINE__ + BUG_WARNING_TRAP), \ | 92 | "i" (sizeof(struct bug_entry))); \ |
70 | "i" (__FILE__), "i" (__FUNCTION__)); \ | ||
71 | } while (0) | 93 | } while (0) |
72 | 94 | ||
73 | #define WARN_ON(x) ({ \ | 95 | #define WARN_ON(x) ({ \ |
@@ -77,13 +99,12 @@ struct bug_entry *find_bug(unsigned long bugaddr); | |||
77 | __WARN(); \ | 99 | __WARN(); \ |
78 | } else { \ | 100 | } else { \ |
79 | __asm__ __volatile__( \ | 101 | __asm__ __volatile__( \ |
80 | "1: "PPC_TLNEI" %0,0\n" \ | 102 | "1: "PPC_TLNEI" %4,0\n" \ |
81 | ".section __bug_table,\"a\"\n" \ | 103 | _EMIT_BUG_ENTRY \ |
82 | "\t"PPC_LONG" 1b,%1,%2,%3\n" \ | 104 | : : "i" (__FILE__), "i" (__LINE__), \ |
83 | ".previous" \ | 105 | "i" (BUGFLAG_WARNING), \ |
84 | : : "r" (__ret_warn_on), \ | 106 | "i" (sizeof(struct bug_entry)), \ |
85 | "i" (__LINE__ + BUG_WARNING_TRAP), \ | 107 | "r" (__ret_warn_on)); \ |
86 | "i" (__FILE__), "i" (__FUNCTION__)); \ | ||
87 | } \ | 108 | } \ |
88 | unlikely(__ret_warn_on); \ | 109 | unlikely(__ret_warn_on); \ |
89 | }) | 110 | }) |
@@ -91,8 +112,8 @@ struct bug_entry *find_bug(unsigned long bugaddr); | |||
91 | #define HAVE_ARCH_BUG | 112 | #define HAVE_ARCH_BUG |
92 | #define HAVE_ARCH_BUG_ON | 113 | #define HAVE_ARCH_BUG_ON |
93 | #define HAVE_ARCH_WARN_ON | 114 | #define HAVE_ARCH_WARN_ON |
94 | #endif /* CONFIG_BUG */ | ||
95 | #endif /* __ASSEMBLY __ */ | 115 | #endif /* __ASSEMBLY __ */ |
116 | #endif /* CONFIG_BUG */ | ||
96 | 117 | ||
97 | #include <asm-generic/bug.h> | 118 | #include <asm-generic/bug.h> |
98 | 119 | ||