GNU Linux-libre 4.19.207-gnu1
[releases.git] / arch / sh / include / asm / bug.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __ASM_SH_BUG_H
3 #define __ASM_SH_BUG_H
4
5 #include <linux/linkage.h>
6
7 #define TRAPA_BUG_OPCODE        0xc33e  /* trapa #0x3e */
8 #define BUGFLAG_UNWINDER        (1 << 1)
9
10 #ifdef CONFIG_GENERIC_BUG
11 #define HAVE_ARCH_BUG
12 #define HAVE_ARCH_WARN_ON
13
14 /**
15  * _EMIT_BUG_ENTRY
16  * %1 - __FILE__
17  * %2 - __LINE__
18  * %3 - trap type
19  * %4 - sizeof(struct bug_entry)
20  *
21  * The trapa opcode itself sits in %0.
22  * The %O notation is used to avoid # generation.
23  *
24  * The offending file and line are encoded in the __bug_table section.
25  */
26 #ifdef CONFIG_DEBUG_BUGVERBOSE
27 #define _EMIT_BUG_ENTRY                         \
28         "\t.pushsection __bug_table,\"aw\"\n"   \
29         "2:\t.long 1b, %O1\n"                   \
30         "\t.short %O2, %O3\n"                   \
31         "\t.org 2b+%O4\n"                       \
32         "\t.popsection\n"
33 #else
34 #define _EMIT_BUG_ENTRY                         \
35         "\t.pushsection __bug_table,\"aw\"\n"   \
36         "2:\t.long 1b\n"                        \
37         "\t.short %O3\n"                        \
38         "\t.org 2b+%O4\n"                       \
39         "\t.popsection\n"
40 #endif
41
42 #define BUG()                                           \
43 do {                                                    \
44         __asm__ __volatile__ (                          \
45                 "1:\t.short %O0\n"                      \
46                 _EMIT_BUG_ENTRY                         \
47                  :                                      \
48                  : "n" (TRAPA_BUG_OPCODE),              \
49                    "i" (__FILE__),                      \
50                    "i" (__LINE__), "i" (0),             \
51                    "i" (sizeof(struct bug_entry)));     \
52         unreachable();                                  \
53 } while (0)
54
55 #define __WARN_FLAGS(flags)                             \
56 do {                                                    \
57         __asm__ __volatile__ (                          \
58                 "1:\t.short %O0\n"                      \
59                  _EMIT_BUG_ENTRY                        \
60                  :                                      \
61                  : "n" (TRAPA_BUG_OPCODE),              \
62                    "i" (__FILE__),                      \
63                    "i" (__LINE__),                      \
64                    "i" (BUGFLAG_WARNING|(flags)),       \
65                    "i" (sizeof(struct bug_entry)));     \
66 } while (0)
67
68 #define WARN_ON(x) ({                                           \
69         int __ret_warn_on = !!(x);                              \
70         if (__builtin_constant_p(__ret_warn_on)) {              \
71                 if (__ret_warn_on)                              \
72                         __WARN();                               \
73         } else {                                                \
74                 if (unlikely(__ret_warn_on))                    \
75                         __WARN();                               \
76         }                                                       \
77         unlikely(__ret_warn_on);                                \
78 })
79
80 #define UNWINDER_BUG()                                  \
81 do {                                                    \
82         __asm__ __volatile__ (                          \
83                 "1:\t.short %O0\n"                      \
84                 _EMIT_BUG_ENTRY                         \
85                  :                                      \
86                  : "n" (TRAPA_BUG_OPCODE),              \
87                    "i" (__FILE__),                      \
88                    "i" (__LINE__),                      \
89                    "i" (BUGFLAG_UNWINDER),              \
90                    "i" (sizeof(struct bug_entry)));     \
91 } while (0)
92
93 #define UNWINDER_BUG_ON(x) ({                                   \
94         int __ret_unwinder_on = !!(x);                          \
95         if (__builtin_constant_p(__ret_unwinder_on)) {          \
96                 if (__ret_unwinder_on)                          \
97                         UNWINDER_BUG();                         \
98         } else {                                                \
99                 if (unlikely(__ret_unwinder_on))                \
100                         UNWINDER_BUG();                         \
101         }                                                       \
102         unlikely(__ret_unwinder_on);                            \
103 })
104
105 #else
106
107 #define UNWINDER_BUG    BUG
108 #define UNWINDER_BUG_ON BUG_ON
109
110 #endif /* CONFIG_GENERIC_BUG */
111
112 #include <asm-generic/bug.h>
113
114 struct pt_regs;
115
116 /* arch/sh/kernel/traps.c */
117 extern void die(const char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn));
118 extern void die_if_kernel(const char *str, struct pt_regs *regs, long err);
119 extern void die_if_no_fixup(const char *str, struct pt_regs *regs, long err);
120
121 #endif /* __ASM_SH_BUG_H */