xref: /openbmc/linux/arch/powerpc/include/asm/bug.h (revision 5222a1d5)
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 #ifdef CONFIG_BUG
9b8b572e1SStephen Rothwell 
10b8b572e1SStephen Rothwell #ifdef __ASSEMBLY__
11a58f053bSBenjamin Herrenschmidt #include <asm/asm-offsets.h>
12b8b572e1SStephen Rothwell #ifdef CONFIG_DEBUG_BUGVERBOSE
13b49e578bSChristophe Leroy .macro EMIT_BUG_ENTRY addr,file,line,flags
14325cdacdSJosh Poimboeuf 	 .section __bug_table,"aw"
1569505e3dSJosh Poimboeuf 5001:	 .4byte \addr - .
1669505e3dSJosh Poimboeuf 	 .4byte 5002f - .
17b8b572e1SStephen Rothwell 	 .short \line, \flags
18b8b572e1SStephen Rothwell 	 .org 5001b+BUG_ENTRY_SIZE
19b8b572e1SStephen Rothwell 	 .previous
20b8b572e1SStephen Rothwell 	 .section .rodata,"a"
21b8b572e1SStephen Rothwell 5002:	 .asciz "\file"
22b8b572e1SStephen Rothwell 	 .previous
23b8b572e1SStephen Rothwell .endm
24b8b572e1SStephen Rothwell #else
25b49e578bSChristophe Leroy .macro EMIT_BUG_ENTRY addr,file,line,flags
26325cdacdSJosh Poimboeuf 	 .section __bug_table,"aw"
2769505e3dSJosh Poimboeuf 5001:	 .4byte \addr - .
28b8b572e1SStephen Rothwell 	 .short \flags
29b8b572e1SStephen Rothwell 	 .org 5001b+BUG_ENTRY_SIZE
30b8b572e1SStephen Rothwell 	 .previous
31b8b572e1SStephen Rothwell .endm
32b8b572e1SStephen Rothwell #endif /* verbose */
33b8b572e1SStephen Rothwell 
34b8b572e1SStephen Rothwell #else /* !__ASSEMBLY__ */
35b8b572e1SStephen Rothwell /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
36b8b572e1SStephen Rothwell    sizeof(struct bug_entry), respectively */
37b8b572e1SStephen Rothwell #ifdef CONFIG_DEBUG_BUGVERBOSE
38b8b572e1SStephen Rothwell #define _EMIT_BUG_ENTRY				\
39325cdacdSJosh Poimboeuf 	".section __bug_table,\"aw\"\n"		\
4069505e3dSJosh Poimboeuf 	"2:	.4byte 1b - .\n"		\
4169505e3dSJosh Poimboeuf 	"	.4byte %0 - .\n"		\
4269505e3dSJosh Poimboeuf 	"	.short %1, %2\n"		\
43b8b572e1SStephen Rothwell 	".org 2b+%3\n"				\
44b8b572e1SStephen Rothwell 	".previous\n"
45b8b572e1SStephen Rothwell #else
46b8b572e1SStephen Rothwell #define _EMIT_BUG_ENTRY				\
47325cdacdSJosh Poimboeuf 	".section __bug_table,\"aw\"\n"		\
4869505e3dSJosh Poimboeuf 	"2:	.4byte 1b - .\n"		\
4969505e3dSJosh Poimboeuf 	"	.short %2\n"			\
50b8b572e1SStephen Rothwell 	".org 2b+%3\n"				\
51b8b572e1SStephen Rothwell 	".previous\n"
52b8b572e1SStephen Rothwell #endif
53b8b572e1SStephen Rothwell 
5443f003bbSChristophe Leroy #define BUG_ENTRY(insn, flags, ...)			\
5543f003bbSChristophe Leroy 	__asm__ __volatile__(				\
5643f003bbSChristophe Leroy 		"1:	" insn "\n"			\
5743f003bbSChristophe Leroy 		_EMIT_BUG_ENTRY				\
5843f003bbSChristophe Leroy 		: : "i" (__FILE__), "i" (__LINE__),	\
5943f003bbSChristophe Leroy 		  "i" (flags),				\
6043f003bbSChristophe Leroy 		  "i" (sizeof(struct bug_entry)),	\
6143f003bbSChristophe Leroy 		  ##__VA_ARGS__)
6243f003bbSChristophe Leroy 
63b8b572e1SStephen Rothwell /*
64b8b572e1SStephen Rothwell  * BUG_ON() and WARN_ON() do their best to cooperate with compile-time
65b8b572e1SStephen Rothwell  * optimisations. However depending on the complexity of the condition
66b8b572e1SStephen Rothwell  * some compiler versions may not produce optimal results.
67b8b572e1SStephen Rothwell  */
68b8b572e1SStephen Rothwell 
69b8b572e1SStephen Rothwell #define BUG() do {						\
7043f003bbSChristophe Leroy 	BUG_ENTRY("twi 31, 0, 0", 0);				\
7101ae45bcSDavid Daney 	unreachable();						\
72b8b572e1SStephen Rothwell } while (0)
73db87a719SChristophe Leroy #define HAVE_ARCH_BUG
74b8b572e1SStephen Rothwell 
75b49e578bSChristophe Leroy #define __WARN_FLAGS(flags) BUG_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (flags))
76db87a719SChristophe Leroy 
77db87a719SChristophe Leroy #ifdef CONFIG_PPC64
78b8b572e1SStephen Rothwell #define BUG_ON(x) do {						\
79b8b572e1SStephen Rothwell 	if (__builtin_constant_p(x)) {				\
80b8b572e1SStephen Rothwell 		if (x)						\
81b8b572e1SStephen Rothwell 			BUG();					\
82b8b572e1SStephen Rothwell 	} else {						\
8343f003bbSChristophe Leroy 		BUG_ENTRY(PPC_TLNEI " %4, 0", 0, "r" ((__force long)(x)));	\
84b8b572e1SStephen Rothwell 	}							\
85b8b572e1SStephen Rothwell } while (0)
86b8b572e1SStephen Rothwell 
87b8b572e1SStephen Rothwell #define WARN_ON(x) ({						\
88b49e578bSChristophe Leroy 	int __ret_warn_on = !!(x);				\
89b49e578bSChristophe Leroy 	if (__builtin_constant_p(__ret_warn_on)) {		\
90b49e578bSChristophe Leroy 		if (__ret_warn_on)				\
91b8b572e1SStephen Rothwell 			__WARN();				\
92b8b572e1SStephen Rothwell 	} else {						\
93b49e578bSChristophe Leroy 		BUG_ENTRY(PPC_TLNEI " %4, 0",			\
9443f003bbSChristophe Leroy 			  BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN),	\
95b49e578bSChristophe Leroy 			  "r" (__ret_warn_on));	\
96b8b572e1SStephen Rothwell 	}							\
97b8b572e1SStephen Rothwell 	unlikely(__ret_warn_on);				\
98b8b572e1SStephen Rothwell })
99b8b572e1SStephen Rothwell 
100b8b572e1SStephen Rothwell #define HAVE_ARCH_BUG_ON
101b8b572e1SStephen Rothwell #define HAVE_ARCH_WARN_ON
102db87a719SChristophe Leroy #endif
103db87a719SChristophe Leroy 
104b8b572e1SStephen Rothwell #endif /* __ASSEMBLY __ */
105a58f053bSBenjamin Herrenschmidt #else
106a58f053bSBenjamin Herrenschmidt #ifdef __ASSEMBLY__
107a58f053bSBenjamin Herrenschmidt .macro EMIT_BUG_ENTRY addr,file,line,flags
108a58f053bSBenjamin Herrenschmidt .endm
109a58f053bSBenjamin Herrenschmidt #else /* !__ASSEMBLY__ */
110a58f053bSBenjamin Herrenschmidt #define _EMIT_BUG_ENTRY
111a58f053bSBenjamin Herrenschmidt #endif
112b8b572e1SStephen Rothwell #endif /* CONFIG_BUG */
113b8b572e1SStephen Rothwell 
114b49e578bSChristophe Leroy #define EMIT_WARN_ENTRY EMIT_BUG_ENTRY
115b49e578bSChristophe Leroy 
116b8b572e1SStephen Rothwell #include <asm-generic/bug.h>
117b8b572e1SStephen Rothwell 
118ae3a197eSDavid Howells #ifndef __ASSEMBLY__
119ae3a197eSDavid Howells 
120ae3a197eSDavid Howells struct pt_regs;
121c45ba4f4SNicholas Piggin void hash__do_page_fault(struct pt_regs *);
1228458c628SNicholas Piggin void bad_page_fault(struct pt_regs *, int);
123*5222a1d5SChristophe Leroy void emulate_single_step(struct pt_regs *regs);
124ae3a197eSDavid Howells extern void _exception(int, struct pt_regs *, int, unsigned long);
1255d8fb8a5SEric W. Biederman extern void _exception_pkey(struct pt_regs *, unsigned long, int);
126ae3a197eSDavid Howells extern void die(const char *, struct pt_regs *, long);
127209e9d50SNicholas Piggin void die_mce(const char *str, struct pt_regs *regs, long err);
1286fcd6baaSNicholas Piggin extern bool die_will_crash(void);
12935adacd6SNicholas Piggin extern void panic_flush_kmsg_start(void);
13035adacd6SNicholas Piggin extern void panic_flush_kmsg_end(void);
131ae3a197eSDavid Howells #endif /* !__ASSEMBLY__ */
132ae3a197eSDavid Howells 
133b8b572e1SStephen Rothwell #endif /* __KERNEL__ */
134b8b572e1SStephen Rothwell #endif /* _ASM_POWERPC_BUG_H */
135