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