xref: /openbmc/linux/arch/powerpc/include/asm/bug.h (revision 209e9d50)
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
13b8b572e1SStephen Rothwell .macro EMIT_BUG_ENTRY addr,file,line,flags
14325cdacdSJosh Poimboeuf 	 .section __bug_table,"aw"
151baa1f70SJordan Niethe 5001:	 .4byte \addr - 5001b, 5002f - 5001b
16b8b572e1SStephen Rothwell 	 .short \line, \flags
17b8b572e1SStephen Rothwell 	 .org 5001b+BUG_ENTRY_SIZE
18b8b572e1SStephen Rothwell 	 .previous
19b8b572e1SStephen Rothwell 	 .section .rodata,"a"
20b8b572e1SStephen Rothwell 5002:	 .asciz "\file"
21b8b572e1SStephen Rothwell 	 .previous
22b8b572e1SStephen Rothwell .endm
23b8b572e1SStephen Rothwell #else
24b8b572e1SStephen Rothwell .macro EMIT_BUG_ENTRY addr,file,line,flags
25325cdacdSJosh Poimboeuf 	 .section __bug_table,"aw"
261baa1f70SJordan Niethe 5001:	 .4byte \addr - 5001b
27b8b572e1SStephen Rothwell 	 .short \flags
28b8b572e1SStephen Rothwell 	 .org 5001b+BUG_ENTRY_SIZE
29b8b572e1SStephen Rothwell 	 .previous
30b8b572e1SStephen Rothwell .endm
31b8b572e1SStephen Rothwell #endif /* verbose */
32b8b572e1SStephen Rothwell 
33b8b572e1SStephen Rothwell #else /* !__ASSEMBLY__ */
34b8b572e1SStephen Rothwell /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
35b8b572e1SStephen Rothwell    sizeof(struct bug_entry), respectively */
36b8b572e1SStephen Rothwell #ifdef CONFIG_DEBUG_BUGVERBOSE
37b8b572e1SStephen Rothwell #define _EMIT_BUG_ENTRY				\
38325cdacdSJosh Poimboeuf 	".section __bug_table,\"aw\"\n"		\
391baa1f70SJordan Niethe 	"2:\t.4byte 1b - 2b, %0 - 2b\n"		\
40b8b572e1SStephen Rothwell 	"\t.short %1, %2\n"			\
41b8b572e1SStephen Rothwell 	".org 2b+%3\n"				\
42b8b572e1SStephen Rothwell 	".previous\n"
43b8b572e1SStephen Rothwell #else
44b8b572e1SStephen Rothwell #define _EMIT_BUG_ENTRY				\
45325cdacdSJosh Poimboeuf 	".section __bug_table,\"aw\"\n"		\
461baa1f70SJordan Niethe 	"2:\t.4byte 1b - 2b\n"			\
47b8b572e1SStephen Rothwell 	"\t.short %2\n"				\
48b8b572e1SStephen Rothwell 	".org 2b+%3\n"				\
49b8b572e1SStephen Rothwell 	".previous\n"
50b8b572e1SStephen Rothwell #endif
51b8b572e1SStephen Rothwell 
5243f003bbSChristophe Leroy #define BUG_ENTRY(insn, flags, ...)			\
5343f003bbSChristophe Leroy 	__asm__ __volatile__(				\
5443f003bbSChristophe Leroy 		"1:	" insn "\n"			\
5543f003bbSChristophe Leroy 		_EMIT_BUG_ENTRY				\
5643f003bbSChristophe Leroy 		: : "i" (__FILE__), "i" (__LINE__),	\
5743f003bbSChristophe Leroy 		  "i" (flags),				\
5843f003bbSChristophe Leroy 		  "i" (sizeof(struct bug_entry)),	\
5943f003bbSChristophe Leroy 		  ##__VA_ARGS__)
6043f003bbSChristophe Leroy 
61b8b572e1SStephen Rothwell /*
62b8b572e1SStephen Rothwell  * BUG_ON() and WARN_ON() do their best to cooperate with compile-time
63b8b572e1SStephen Rothwell  * optimisations. However depending on the complexity of the condition
64b8b572e1SStephen Rothwell  * some compiler versions may not produce optimal results.
65b8b572e1SStephen Rothwell  */
66b8b572e1SStephen Rothwell 
67b8b572e1SStephen Rothwell #define BUG() do {						\
6843f003bbSChristophe Leroy 	BUG_ENTRY("twi 31, 0, 0", 0);				\
6901ae45bcSDavid Daney 	unreachable();						\
70b8b572e1SStephen Rothwell } while (0)
71b8b572e1SStephen Rothwell 
72b8b572e1SStephen Rothwell #define BUG_ON(x) do {						\
73b8b572e1SStephen Rothwell 	if (__builtin_constant_p(x)) {				\
74b8b572e1SStephen Rothwell 		if (x)						\
75b8b572e1SStephen Rothwell 			BUG();					\
76b8b572e1SStephen Rothwell 	} else {						\
7743f003bbSChristophe Leroy 		BUG_ENTRY(PPC_TLNEI " %4, 0", 0, "r" ((__force long)(x)));	\
78b8b572e1SStephen Rothwell 	}							\
79b8b572e1SStephen Rothwell } while (0)
80b8b572e1SStephen Rothwell 
8143f003bbSChristophe Leroy #define __WARN_FLAGS(flags) BUG_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (flags))
82b8b572e1SStephen Rothwell 
83b8b572e1SStephen Rothwell #define WARN_ON(x) ({						\
84b8b572e1SStephen Rothwell 	int __ret_warn_on = !!(x);				\
85b8b572e1SStephen Rothwell 	if (__builtin_constant_p(__ret_warn_on)) {		\
86b8b572e1SStephen Rothwell 		if (__ret_warn_on)				\
87b8b572e1SStephen Rothwell 			__WARN();				\
88b8b572e1SStephen Rothwell 	} else {						\
8943f003bbSChristophe Leroy 		BUG_ENTRY(PPC_TLNEI " %4, 0",			\
9043f003bbSChristophe Leroy 			  BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN),	\
91b8b572e1SStephen Rothwell 			  "r" (__ret_warn_on));	\
92b8b572e1SStephen Rothwell 	}							\
93b8b572e1SStephen Rothwell 	unlikely(__ret_warn_on);				\
94b8b572e1SStephen Rothwell })
95b8b572e1SStephen Rothwell 
96b8b572e1SStephen Rothwell #define HAVE_ARCH_BUG
97b8b572e1SStephen Rothwell #define HAVE_ARCH_BUG_ON
98b8b572e1SStephen Rothwell #define HAVE_ARCH_WARN_ON
99b8b572e1SStephen Rothwell #endif /* __ASSEMBLY __ */
100a58f053bSBenjamin Herrenschmidt #else
101a58f053bSBenjamin Herrenschmidt #ifdef __ASSEMBLY__
102a58f053bSBenjamin Herrenschmidt .macro EMIT_BUG_ENTRY addr,file,line,flags
103a58f053bSBenjamin Herrenschmidt .endm
104a58f053bSBenjamin Herrenschmidt #else /* !__ASSEMBLY__ */
105a58f053bSBenjamin Herrenschmidt #define _EMIT_BUG_ENTRY
106a58f053bSBenjamin Herrenschmidt #endif
107b8b572e1SStephen Rothwell #endif /* CONFIG_BUG */
108b8b572e1SStephen Rothwell 
109b8b572e1SStephen Rothwell #include <asm-generic/bug.h>
110b8b572e1SStephen Rothwell 
111ae3a197eSDavid Howells #ifndef __ASSEMBLY__
112ae3a197eSDavid Howells 
113ae3a197eSDavid Howells struct pt_regs;
114a01a3f2dSNicholas Piggin long do_page_fault(struct pt_regs *);
1158458c628SNicholas Piggin void bad_page_fault(struct pt_regs *, int);
1168458c628SNicholas Piggin void __bad_page_fault(struct pt_regs *regs, int sig);
11771f47976SNicholas Piggin void do_bad_page_fault_segv(struct pt_regs *regs);
118ae3a197eSDavid Howells extern void _exception(int, struct pt_regs *, int, unsigned long);
1195d8fb8a5SEric W. Biederman extern void _exception_pkey(struct pt_regs *, unsigned long, int);
120ae3a197eSDavid Howells extern void die(const char *, struct pt_regs *, long);
121*209e9d50SNicholas Piggin void die_mce(const char *str, struct pt_regs *regs, long err);
1226fcd6baaSNicholas Piggin extern bool die_will_crash(void);
12335adacd6SNicholas Piggin extern void panic_flush_kmsg_start(void);
12435adacd6SNicholas Piggin extern void panic_flush_kmsg_end(void);
125ae3a197eSDavid Howells #endif /* !__ASSEMBLY__ */
126ae3a197eSDavid Howells 
127b8b572e1SStephen Rothwell #endif /* __KERNEL__ */
128b8b572e1SStephen Rothwell #endif /* _ASM_POWERPC_BUG_H */
129