xref: /openbmc/linux/arch/powerpc/include/asm/bug.h (revision 8fa5723aa7e053d498336b48448b292fc2e0458b)
1 #ifndef _ASM_POWERPC_BUG_H
2 #define _ASM_POWERPC_BUG_H
3 #ifdef __KERNEL__
4 
5 #include <asm/asm-compat.h>
6 /*
7  * Define an illegal instr to trap on the bug.
8  * We don't use 0 because that marks the end of a function
9  * in the ELF ABI.  That's "Boo Boo" in case you wonder...
10  */
11 #define BUG_OPCODE .long 0x00b00b00  /* For asm */
12 #define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */
13 
14 #ifdef CONFIG_BUG
15 
16 #ifdef __ASSEMBLY__
17 #ifdef CONFIG_DEBUG_BUGVERBOSE
18 .macro EMIT_BUG_ENTRY addr,file,line,flags
19 	 .section __bug_table,"a"
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 */
37 
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
56 
57 /*
58  * BUG_ON() and WARN_ON() do their best to cooperate with compile-time
59  * optimisations. However depending on the complexity of the condition
60  * some compiler versions may not produce optimal results.
61  */
62 
63 #define BUG() do {						\
64 	__asm__ __volatile__(					\
65 		"1:	twi 31,0,0\n"				\
66 		_EMIT_BUG_ENTRY					\
67 		: : "i" (__FILE__), "i" (__LINE__),		\
68 		    "i" (0), "i"  (sizeof(struct bug_entry)));	\
69 	for(;;) ;						\
70 } while (0)
71 
72 #define BUG_ON(x) do {						\
73 	if (__builtin_constant_p(x)) {				\
74 		if (x)						\
75 			BUG();					\
76 	} else {						\
77 		__asm__ __volatile__(				\
78 		"1:	"PPC_TLNEI"	%4,0\n"			\
79 		_EMIT_BUG_ENTRY					\
80 		: : "i" (__FILE__), "i" (__LINE__), "i" (0),	\
81 		  "i" (sizeof(struct bug_entry)),		\
82 		  "r" ((__force long)(x)));			\
83 	}							\
84 } while (0)
85 
86 #define __WARN() do {						\
87 	__asm__ __volatile__(					\
88 		"1:	twi 31,0,0\n"				\
89 		_EMIT_BUG_ENTRY					\
90 		: : "i" (__FILE__), "i" (__LINE__),		\
91 		  "i" (BUGFLAG_WARNING),			\
92 		  "i" (sizeof(struct bug_entry)));		\
93 } while (0)
94 
95 #define WARN_ON(x) ({						\
96 	int __ret_warn_on = !!(x);				\
97 	if (__builtin_constant_p(__ret_warn_on)) {		\
98 		if (__ret_warn_on)				\
99 			__WARN();				\
100 	} else {						\
101 		__asm__ __volatile__(				\
102 		"1:	"PPC_TLNEI"	%4,0\n"			\
103 		_EMIT_BUG_ENTRY					\
104 		: : "i" (__FILE__), "i" (__LINE__),		\
105 		  "i" (BUGFLAG_WARNING),			\
106 		  "i" (sizeof(struct bug_entry)),		\
107 		  "r" (__ret_warn_on));				\
108 	}							\
109 	unlikely(__ret_warn_on);				\
110 })
111 
112 #define HAVE_ARCH_BUG
113 #define HAVE_ARCH_BUG_ON
114 #define HAVE_ARCH_WARN_ON
115 #endif /* __ASSEMBLY __ */
116 #endif /* CONFIG_BUG */
117 
118 #include <asm-generic/bug.h>
119 
120 #endif /* __KERNEL__ */
121 #endif /* _ASM_POWERPC_BUG_H */
122