1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _ASM_POWERPC_BUG_H 3 #define _ASM_POWERPC_BUG_H 4 #ifdef __KERNEL__ 5 6 #include <asm/asm-compat.h> 7 8 /* 9 * Define an illegal instr to trap on the bug. 10 * We don't use 0 because that marks the end of a function 11 * in the ELF ABI. That's "Boo Boo" in case you wonder... 12 */ 13 #define BUG_OPCODE .long 0x00b00b00 /* For asm */ 14 #define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */ 15 16 #ifdef CONFIG_BUG 17 18 #ifdef __ASSEMBLY__ 19 #include <asm/asm-offsets.h> 20 #ifdef CONFIG_DEBUG_BUGVERBOSE 21 .macro EMIT_BUG_ENTRY addr,file,line,flags 22 .section __bug_table,"aw" 23 5001: PPC_LONG \addr, 5002f 24 .short \line, \flags 25 .org 5001b+BUG_ENTRY_SIZE 26 .previous 27 .section .rodata,"a" 28 5002: .asciz "\file" 29 .previous 30 .endm 31 #else 32 .macro EMIT_BUG_ENTRY addr,file,line,flags 33 .section __bug_table,"aw" 34 5001: PPC_LONG \addr 35 .short \flags 36 .org 5001b+BUG_ENTRY_SIZE 37 .previous 38 .endm 39 #endif /* verbose */ 40 41 #else /* !__ASSEMBLY__ */ 42 /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and 43 sizeof(struct bug_entry), respectively */ 44 #ifdef CONFIG_DEBUG_BUGVERBOSE 45 #define _EMIT_BUG_ENTRY \ 46 ".section __bug_table,\"aw\"\n" \ 47 "2:\t" PPC_LONG "1b, %0\n" \ 48 "\t.short %1, %2\n" \ 49 ".org 2b+%3\n" \ 50 ".previous\n" 51 #else 52 #define _EMIT_BUG_ENTRY \ 53 ".section __bug_table,\"aw\"\n" \ 54 "2:\t" PPC_LONG "1b\n" \ 55 "\t.short %2\n" \ 56 ".org 2b+%3\n" \ 57 ".previous\n" 58 #endif 59 60 /* 61 * BUG_ON() and WARN_ON() do their best to cooperate with compile-time 62 * optimisations. However depending on the complexity of the condition 63 * some compiler versions may not produce optimal results. 64 */ 65 66 #define BUG() do { \ 67 __asm__ __volatile__( \ 68 "1: twi 31,0,0\n" \ 69 _EMIT_BUG_ENTRY \ 70 : : "i" (__FILE__), "i" (__LINE__), \ 71 "i" (0), "i" (sizeof(struct bug_entry))); \ 72 unreachable(); \ 73 } while (0) 74 75 #define BUG_ON(x) do { \ 76 if (__builtin_constant_p(x)) { \ 77 if (x) \ 78 BUG(); \ 79 } else { \ 80 __asm__ __volatile__( \ 81 "1: "PPC_TLNEI" %4,0\n" \ 82 _EMIT_BUG_ENTRY \ 83 : : "i" (__FILE__), "i" (__LINE__), "i" (0), \ 84 "i" (sizeof(struct bug_entry)), \ 85 "r" ((__force long)(x))); \ 86 } \ 87 } while (0) 88 89 #define __WARN_FLAGS(flags) do { \ 90 __asm__ __volatile__( \ 91 "1: twi 31,0,0\n" \ 92 _EMIT_BUG_ENTRY \ 93 : : "i" (__FILE__), "i" (__LINE__), \ 94 "i" (BUGFLAG_WARNING|(flags)), \ 95 "i" (sizeof(struct bug_entry))); \ 96 } while (0) 97 98 #define WARN_ON(x) ({ \ 99 int __ret_warn_on = !!(x); \ 100 if (__builtin_constant_p(__ret_warn_on)) { \ 101 if (__ret_warn_on) \ 102 __WARN(); \ 103 } else { \ 104 __asm__ __volatile__( \ 105 "1: "PPC_TLNEI" %4,0\n" \ 106 _EMIT_BUG_ENTRY \ 107 : : "i" (__FILE__), "i" (__LINE__), \ 108 "i" (BUGFLAG_WARNING|BUGFLAG_TAINT(TAINT_WARN)),\ 109 "i" (sizeof(struct bug_entry)), \ 110 "r" (__ret_warn_on)); \ 111 } \ 112 unlikely(__ret_warn_on); \ 113 }) 114 115 #define HAVE_ARCH_BUG 116 #define HAVE_ARCH_BUG_ON 117 #define HAVE_ARCH_WARN_ON 118 #endif /* __ASSEMBLY __ */ 119 #else 120 #ifdef __ASSEMBLY__ 121 .macro EMIT_BUG_ENTRY addr,file,line,flags 122 .endm 123 #else /* !__ASSEMBLY__ */ 124 #define _EMIT_BUG_ENTRY 125 #endif 126 #endif /* CONFIG_BUG */ 127 128 #include <asm-generic/bug.h> 129 130 #ifndef __ASSEMBLY__ 131 132 struct pt_regs; 133 extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); 134 extern void bad_page_fault(struct pt_regs *, unsigned long, int); 135 extern void _exception(int, struct pt_regs *, int, unsigned long); 136 extern void _exception_pkey(int, struct pt_regs *, int, unsigned long, int); 137 extern void die(const char *, struct pt_regs *, long); 138 extern bool die_will_crash(void); 139 extern void panic_flush_kmsg_start(void); 140 extern void panic_flush_kmsg_end(void); 141 #endif /* !__ASSEMBLY__ */ 142 143 #endif /* __KERNEL__ */ 144 #endif /* _ASM_POWERPC_BUG_H */ 145