xref: /openbmc/linux/arch/powerpc/include/asm/bug.h (revision db87a719)
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)
71*db87a719SChristophe Leroy #define HAVE_ARCH_BUG
72b8b572e1SStephen Rothwell 
73*db87a719SChristophe Leroy #define __WARN_FLAGS(flags) BUG_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (flags))
74*db87a719SChristophe Leroy 
75*db87a719SChristophe Leroy #ifdef CONFIG_PPC64
76b8b572e1SStephen Rothwell #define BUG_ON(x) do {						\
77b8b572e1SStephen Rothwell 	if (__builtin_constant_p(x)) {				\
78b8b572e1SStephen Rothwell 		if (x)						\
79b8b572e1SStephen Rothwell 			BUG();					\
80b8b572e1SStephen Rothwell 	} else {						\
8143f003bbSChristophe Leroy 		BUG_ENTRY(PPC_TLNEI " %4, 0", 0, "r" ((__force long)(x)));	\
82b8b572e1SStephen Rothwell 	}							\
83b8b572e1SStephen Rothwell } while (0)
84b8b572e1SStephen Rothwell 
85b8b572e1SStephen Rothwell #define WARN_ON(x) ({						\
86b8b572e1SStephen Rothwell 	int __ret_warn_on = !!(x);				\
87b8b572e1SStephen Rothwell 	if (__builtin_constant_p(__ret_warn_on)) {		\
88b8b572e1SStephen Rothwell 		if (__ret_warn_on)				\
89b8b572e1SStephen Rothwell 			__WARN();				\
90b8b572e1SStephen Rothwell 	} else {						\
9143f003bbSChristophe Leroy 		BUG_ENTRY(PPC_TLNEI " %4, 0",			\
9243f003bbSChristophe Leroy 			  BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN),	\
93b8b572e1SStephen Rothwell 			  "r" (__ret_warn_on));	\
94b8b572e1SStephen Rothwell 	}							\
95b8b572e1SStephen Rothwell 	unlikely(__ret_warn_on);				\
96b8b572e1SStephen Rothwell })
97b8b572e1SStephen Rothwell 
98b8b572e1SStephen Rothwell #define HAVE_ARCH_BUG_ON
99b8b572e1SStephen Rothwell #define HAVE_ARCH_WARN_ON
100*db87a719SChristophe Leroy #endif
101*db87a719SChristophe Leroy 
102b8b572e1SStephen Rothwell #endif /* __ASSEMBLY __ */
103a58f053bSBenjamin Herrenschmidt #else
104a58f053bSBenjamin Herrenschmidt #ifdef __ASSEMBLY__
105a58f053bSBenjamin Herrenschmidt .macro EMIT_BUG_ENTRY addr,file,line,flags
106a58f053bSBenjamin Herrenschmidt .endm
107a58f053bSBenjamin Herrenschmidt #else /* !__ASSEMBLY__ */
108a58f053bSBenjamin Herrenschmidt #define _EMIT_BUG_ENTRY
109a58f053bSBenjamin Herrenschmidt #endif
110b8b572e1SStephen Rothwell #endif /* CONFIG_BUG */
111b8b572e1SStephen Rothwell 
112b8b572e1SStephen Rothwell #include <asm-generic/bug.h>
113b8b572e1SStephen Rothwell 
114ae3a197eSDavid Howells #ifndef __ASSEMBLY__
115ae3a197eSDavid Howells 
116ae3a197eSDavid Howells struct pt_regs;
117c45ba4f4SNicholas Piggin void hash__do_page_fault(struct pt_regs *);
1188458c628SNicholas Piggin void bad_page_fault(struct pt_regs *, int);
119ae3a197eSDavid Howells extern void _exception(int, struct pt_regs *, int, unsigned long);
1205d8fb8a5SEric W. Biederman extern void _exception_pkey(struct pt_regs *, unsigned long, int);
121ae3a197eSDavid Howells extern void die(const char *, struct pt_regs *, long);
122209e9d50SNicholas Piggin void die_mce(const char *str, struct pt_regs *regs, long err);
1236fcd6baaSNicholas Piggin extern bool die_will_crash(void);
12435adacd6SNicholas Piggin extern void panic_flush_kmsg_start(void);
12535adacd6SNicholas Piggin extern void panic_flush_kmsg_end(void);
126ae3a197eSDavid Howells #endif /* !__ASSEMBLY__ */
127ae3a197eSDavid Howells 
128b8b572e1SStephen Rothwell #endif /* __KERNEL__ */
129b8b572e1SStephen Rothwell #endif /* _ASM_POWERPC_BUG_H */
130