xref: /openbmc/linux/arch/powerpc/include/asm/bug.h (revision 19d43626)
1b8b572e1SStephen Rothwell #ifndef _ASM_POWERPC_BUG_H
2b8b572e1SStephen Rothwell #define _ASM_POWERPC_BUG_H
3b8b572e1SStephen Rothwell #ifdef __KERNEL__
4b8b572e1SStephen Rothwell 
5b8b572e1SStephen Rothwell #include <asm/asm-compat.h>
6a58f053bSBenjamin Herrenschmidt 
7b8b572e1SStephen Rothwell /*
8b8b572e1SStephen Rothwell  * Define an illegal instr to trap on the bug.
9b8b572e1SStephen Rothwell  * We don't use 0 because that marks the end of a function
10b8b572e1SStephen Rothwell  * in the ELF ABI.  That's "Boo Boo" in case you wonder...
11b8b572e1SStephen Rothwell  */
12b8b572e1SStephen Rothwell #define BUG_OPCODE .long 0x00b00b00  /* For asm */
13b8b572e1SStephen Rothwell #define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */
14b8b572e1SStephen Rothwell 
15b8b572e1SStephen Rothwell #ifdef CONFIG_BUG
16b8b572e1SStephen Rothwell 
17b8b572e1SStephen Rothwell #ifdef __ASSEMBLY__
18a58f053bSBenjamin Herrenschmidt #include <asm/asm-offsets.h>
19b8b572e1SStephen Rothwell #ifdef CONFIG_DEBUG_BUGVERBOSE
20b8b572e1SStephen Rothwell .macro EMIT_BUG_ENTRY addr,file,line,flags
21b8b572e1SStephen Rothwell 	 .section __bug_table,"a"
22b8b572e1SStephen Rothwell 5001:	 PPC_LONG \addr, 5002f
23b8b572e1SStephen Rothwell 	 .short \line, \flags
24b8b572e1SStephen Rothwell 	 .org 5001b+BUG_ENTRY_SIZE
25b8b572e1SStephen Rothwell 	 .previous
26b8b572e1SStephen Rothwell 	 .section .rodata,"a"
27b8b572e1SStephen Rothwell 5002:	 .asciz "\file"
28b8b572e1SStephen Rothwell 	 .previous
29b8b572e1SStephen Rothwell .endm
30b8b572e1SStephen Rothwell #else
31b8b572e1SStephen Rothwell .macro EMIT_BUG_ENTRY addr,file,line,flags
32b8b572e1SStephen Rothwell 	 .section __bug_table,"a"
33b8b572e1SStephen Rothwell 5001:	 PPC_LONG \addr
34b8b572e1SStephen Rothwell 	 .short \flags
35b8b572e1SStephen Rothwell 	 .org 5001b+BUG_ENTRY_SIZE
36b8b572e1SStephen Rothwell 	 .previous
37b8b572e1SStephen Rothwell .endm
38b8b572e1SStephen Rothwell #endif /* verbose */
39b8b572e1SStephen Rothwell 
40b8b572e1SStephen Rothwell #else /* !__ASSEMBLY__ */
41b8b572e1SStephen Rothwell /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
42b8b572e1SStephen Rothwell    sizeof(struct bug_entry), respectively */
43b8b572e1SStephen Rothwell #ifdef CONFIG_DEBUG_BUGVERBOSE
44b8b572e1SStephen Rothwell #define _EMIT_BUG_ENTRY				\
45b8b572e1SStephen Rothwell 	".section __bug_table,\"a\"\n"		\
46b8b572e1SStephen Rothwell 	"2:\t" PPC_LONG "1b, %0\n"		\
47b8b572e1SStephen Rothwell 	"\t.short %1, %2\n"			\
48b8b572e1SStephen Rothwell 	".org 2b+%3\n"				\
49b8b572e1SStephen Rothwell 	".previous\n"
50b8b572e1SStephen Rothwell #else
51b8b572e1SStephen Rothwell #define _EMIT_BUG_ENTRY				\
52b8b572e1SStephen Rothwell 	".section __bug_table,\"a\"\n"		\
53b8b572e1SStephen Rothwell 	"2:\t" PPC_LONG "1b\n"			\
54b8b572e1SStephen Rothwell 	"\t.short %2\n"				\
55b8b572e1SStephen Rothwell 	".org 2b+%3\n"				\
56b8b572e1SStephen Rothwell 	".previous\n"
57b8b572e1SStephen Rothwell #endif
58b8b572e1SStephen Rothwell 
59b8b572e1SStephen Rothwell /*
60b8b572e1SStephen Rothwell  * BUG_ON() and WARN_ON() do their best to cooperate with compile-time
61b8b572e1SStephen Rothwell  * optimisations. However depending on the complexity of the condition
62b8b572e1SStephen Rothwell  * some compiler versions may not produce optimal results.
63b8b572e1SStephen Rothwell  */
64b8b572e1SStephen Rothwell 
65b8b572e1SStephen Rothwell #define BUG() do {						\
66b8b572e1SStephen Rothwell 	__asm__ __volatile__(					\
67b8b572e1SStephen Rothwell 		"1:	twi 31,0,0\n"				\
68b8b572e1SStephen Rothwell 		_EMIT_BUG_ENTRY					\
69b8b572e1SStephen Rothwell 		: : "i" (__FILE__), "i" (__LINE__),		\
70b8b572e1SStephen Rothwell 		    "i" (0), "i"  (sizeof(struct bug_entry)));	\
7101ae45bcSDavid Daney 	unreachable();						\
72b8b572e1SStephen Rothwell } while (0)
73b8b572e1SStephen Rothwell 
74b8b572e1SStephen Rothwell #define BUG_ON(x) do {						\
75b8b572e1SStephen Rothwell 	if (__builtin_constant_p(x)) {				\
76b8b572e1SStephen Rothwell 		if (x)						\
77b8b572e1SStephen Rothwell 			BUG();					\
78b8b572e1SStephen Rothwell 	} else {						\
79b8b572e1SStephen Rothwell 		__asm__ __volatile__(				\
80b8b572e1SStephen Rothwell 		"1:	"PPC_TLNEI"	%4,0\n"			\
81b8b572e1SStephen Rothwell 		_EMIT_BUG_ENTRY					\
82b8b572e1SStephen Rothwell 		: : "i" (__FILE__), "i" (__LINE__), "i" (0),	\
83b8b572e1SStephen Rothwell 		  "i" (sizeof(struct bug_entry)),		\
84b8b572e1SStephen Rothwell 		  "r" ((__force long)(x)));			\
85b8b572e1SStephen Rothwell 	}							\
86b8b572e1SStephen Rothwell } while (0)
87b8b572e1SStephen Rothwell 
8819d43626SPeter Zijlstra #define __WARN_FLAGS(flags) do {				\
89b8b572e1SStephen Rothwell 	__asm__ __volatile__(					\
90b8b572e1SStephen Rothwell 		"1:	twi 31,0,0\n"				\
91b8b572e1SStephen Rothwell 		_EMIT_BUG_ENTRY					\
92b8b572e1SStephen Rothwell 		: : "i" (__FILE__), "i" (__LINE__),		\
9319d43626SPeter Zijlstra 		  "i" (BUGFLAG_WARNING|(flags)),		\
94b8b572e1SStephen Rothwell 		  "i" (sizeof(struct bug_entry)));		\
95b8b572e1SStephen Rothwell } while (0)
96b8b572e1SStephen Rothwell 
97b8b572e1SStephen Rothwell #define WARN_ON(x) ({						\
98b8b572e1SStephen Rothwell 	int __ret_warn_on = !!(x);				\
99b8b572e1SStephen Rothwell 	if (__builtin_constant_p(__ret_warn_on)) {		\
100b8b572e1SStephen Rothwell 		if (__ret_warn_on)				\
101b8b572e1SStephen Rothwell 			__WARN();				\
102b8b572e1SStephen Rothwell 	} else {						\
103b8b572e1SStephen Rothwell 		__asm__ __volatile__(				\
104b8b572e1SStephen Rothwell 		"1:	"PPC_TLNEI"	%4,0\n"			\
105b8b572e1SStephen Rothwell 		_EMIT_BUG_ENTRY					\
106b8b572e1SStephen Rothwell 		: : "i" (__FILE__), "i" (__LINE__),		\
107b2be0527SBen Hutchings 		  "i" (BUGFLAG_TAINT(TAINT_WARN)),		\
108b8b572e1SStephen Rothwell 		  "i" (sizeof(struct bug_entry)),		\
109b8b572e1SStephen Rothwell 		  "r" (__ret_warn_on));				\
110b8b572e1SStephen Rothwell 	}							\
111b8b572e1SStephen Rothwell 	unlikely(__ret_warn_on);				\
112b8b572e1SStephen Rothwell })
113b8b572e1SStephen Rothwell 
114b8b572e1SStephen Rothwell #define HAVE_ARCH_BUG
115b8b572e1SStephen Rothwell #define HAVE_ARCH_BUG_ON
116b8b572e1SStephen Rothwell #define HAVE_ARCH_WARN_ON
117b8b572e1SStephen Rothwell #endif /* __ASSEMBLY __ */
118a58f053bSBenjamin Herrenschmidt #else
119a58f053bSBenjamin Herrenschmidt #ifdef __ASSEMBLY__
120a58f053bSBenjamin Herrenschmidt .macro EMIT_BUG_ENTRY addr,file,line,flags
121a58f053bSBenjamin Herrenschmidt .endm
122a58f053bSBenjamin Herrenschmidt #else /* !__ASSEMBLY__ */
123a58f053bSBenjamin Herrenschmidt #define _EMIT_BUG_ENTRY
124a58f053bSBenjamin Herrenschmidt #endif
125b8b572e1SStephen Rothwell #endif /* CONFIG_BUG */
126b8b572e1SStephen Rothwell 
127b8b572e1SStephen Rothwell #include <asm-generic/bug.h>
128b8b572e1SStephen Rothwell 
129ae3a197eSDavid Howells #ifndef __ASSEMBLY__
130ae3a197eSDavid Howells 
131ae3a197eSDavid Howells struct pt_regs;
132ae3a197eSDavid Howells extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
133ae3a197eSDavid Howells extern void bad_page_fault(struct pt_regs *, unsigned long, int);
134ae3a197eSDavid Howells extern void _exception(int, struct pt_regs *, int, unsigned long);
135ae3a197eSDavid Howells extern void die(const char *, struct pt_regs *, long);
136ae3a197eSDavid Howells 
137ae3a197eSDavid Howells #endif /* !__ASSEMBLY__ */
138ae3a197eSDavid Howells 
139b8b572e1SStephen Rothwell #endif /* __KERNEL__ */
140b8b572e1SStephen Rothwell #endif /* _ASM_POWERPC_BUG_H */
141