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