2005-09-20 06:01:54 +08:00
|
|
|
#ifndef _ASM_POWERPC_BUG_H
|
|
|
|
#define _ASM_POWERPC_BUG_H
|
2005-12-17 05:43:46 +08:00
|
|
|
#ifdef __KERNEL__
|
2005-04-17 06:20:36 +08:00
|
|
|
|
[PATCH] powerpc: Consolidate asm compatibility macros
This patch consolidates macros used to generate assembly for
compatibility across different CPUs or configs. A new header,
asm-powerpc/asm-compat.h contains the main compatibility macros. It
uses some preprocessor magic to make the macros suitable both for use
in .S files, and in inline asm in .c files. Headers (bitops.h,
uaccess.h, atomic.h, bug.h) which had their own such compatibility
macros are changed to use asm-compat.h.
ppc_asm.h is now for use in .S files *only*, and a #error enforces
that. As such, we're a lot more careless about namespace pollution
here than in asm-compat.h.
While we're at it, this patch adds a call to the PPC405_ERR77 macro in
futex.h which should have had it already, but didn't.
Built and booted on pSeries, Maple and iSeries (ARCH=powerpc). Built
for 32-bit powermac (ARCH=powerpc) and Walnut (ARCH=ppc).
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2005-11-10 09:56:55 +08:00
|
|
|
#include <asm/asm-compat.h>
|
2008-12-15 03:44:13 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
/*
|
|
|
|
* Define an illegal instr to trap on the bug.
|
|
|
|
* We don't use 0 because that marks the end of a function
|
|
|
|
* in the ELF ABI. That's "Boo Boo" in case you wonder...
|
|
|
|
*/
|
|
|
|
#define BUG_OPCODE .long 0x00b00b00 /* For asm */
|
|
|
|
#define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */
|
|
|
|
|
2005-05-01 23:59:01 +08:00
|
|
|
#ifdef CONFIG_BUG
|
|
|
|
|
2007-01-02 02:45:34 +08:00
|
|
|
#ifdef __ASSEMBLY__
|
2008-12-15 03:44:13 +08:00
|
|
|
#include <asm/asm-offsets.h>
|
2007-01-02 02:45:34 +08:00
|
|
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
|
|
|
.macro EMIT_BUG_ENTRY addr,file,line,flags
|
2017-07-15 13:10:58 +08:00
|
|
|
.section __bug_table,"aw"
|
2007-01-02 02:45:34 +08:00
|
|
|
5001: PPC_LONG \addr, 5002f
|
|
|
|
.short \line, \flags
|
|
|
|
.org 5001b+BUG_ENTRY_SIZE
|
|
|
|
.previous
|
|
|
|
.section .rodata,"a"
|
|
|
|
5002: .asciz "\file"
|
|
|
|
.previous
|
|
|
|
.endm
|
|
|
|
#else
|
2008-12-15 03:44:13 +08:00
|
|
|
.macro EMIT_BUG_ENTRY addr,file,line,flags
|
2017-07-15 13:10:58 +08:00
|
|
|
.section __bug_table,"aw"
|
2007-01-02 02:45:34 +08:00
|
|
|
5001: PPC_LONG \addr
|
|
|
|
.short \flags
|
|
|
|
.org 5001b+BUG_ENTRY_SIZE
|
|
|
|
.previous
|
|
|
|
.endm
|
|
|
|
#endif /* verbose */
|
|
|
|
|
|
|
|
#else /* !__ASSEMBLY__ */
|
2006-12-08 19:30:41 +08:00
|
|
|
/* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
|
|
|
|
sizeof(struct bug_entry), respectively */
|
|
|
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
|
|
|
#define _EMIT_BUG_ENTRY \
|
2017-07-15 13:10:58 +08:00
|
|
|
".section __bug_table,\"aw\"\n" \
|
2006-12-08 19:30:41 +08:00
|
|
|
"2:\t" PPC_LONG "1b, %0\n" \
|
|
|
|
"\t.short %1, %2\n" \
|
|
|
|
".org 2b+%3\n" \
|
|
|
|
".previous\n"
|
|
|
|
#else
|
|
|
|
#define _EMIT_BUG_ENTRY \
|
2017-07-15 13:10:58 +08:00
|
|
|
".section __bug_table,\"aw\"\n" \
|
2006-12-08 19:30:41 +08:00
|
|
|
"2:\t" PPC_LONG "1b\n" \
|
|
|
|
"\t.short %2\n" \
|
|
|
|
".org 2b+%3\n" \
|
|
|
|
".previous\n"
|
|
|
|
#endif
|
|
|
|
|
2006-03-23 20:32:24 +08:00
|
|
|
/*
|
|
|
|
* BUG_ON() and WARN_ON() do their best to cooperate with compile-time
|
|
|
|
* optimisations. However depending on the complexity of the condition
|
|
|
|
* some compiler versions may not produce optimal results.
|
|
|
|
*/
|
|
|
|
|
2006-12-08 19:30:41 +08:00
|
|
|
#define BUG() do { \
|
|
|
|
__asm__ __volatile__( \
|
|
|
|
"1: twi 31,0,0\n" \
|
|
|
|
_EMIT_BUG_ENTRY \
|
|
|
|
: : "i" (__FILE__), "i" (__LINE__), \
|
|
|
|
"i" (0), "i" (sizeof(struct bug_entry))); \
|
2009-12-10 15:28:19 +08:00
|
|
|
unreachable(); \
|
2005-04-17 06:20:36 +08:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define BUG_ON(x) do { \
|
2006-03-23 20:32:24 +08:00
|
|
|
if (__builtin_constant_p(x)) { \
|
|
|
|
if (x) \
|
|
|
|
BUG(); \
|
|
|
|
} else { \
|
|
|
|
__asm__ __volatile__( \
|
2006-12-08 19:30:41 +08:00
|
|
|
"1: "PPC_TLNEI" %4,0\n" \
|
|
|
|
_EMIT_BUG_ENTRY \
|
|
|
|
: : "i" (__FILE__), "i" (__LINE__), "i" (0), \
|
|
|
|
"i" (sizeof(struct bug_entry)), \
|
2007-07-27 00:35:49 +08:00
|
|
|
"r" ((__force long)(x))); \
|
2006-03-23 20:32:24 +08:00
|
|
|
} \
|
2005-04-17 06:20:36 +08:00
|
|
|
} while (0)
|
|
|
|
|
2017-02-25 15:56:53 +08:00
|
|
|
#define __WARN_FLAGS(flags) do { \
|
2005-04-17 06:20:36 +08:00
|
|
|
__asm__ __volatile__( \
|
2006-03-23 20:32:24 +08:00
|
|
|
"1: twi 31,0,0\n" \
|
2006-12-08 19:30:41 +08:00
|
|
|
_EMIT_BUG_ENTRY \
|
|
|
|
: : "i" (__FILE__), "i" (__LINE__), \
|
2017-02-25 15:56:53 +08:00
|
|
|
"i" (BUGFLAG_WARNING|(flags)), \
|
2006-12-08 19:30:41 +08:00
|
|
|
"i" (sizeof(struct bug_entry))); \
|
2006-03-23 20:32:24 +08:00
|
|
|
} while (0)
|
|
|
|
|
2006-09-29 16:59:06 +08:00
|
|
|
#define WARN_ON(x) ({ \
|
2007-08-01 12:12:07 +08:00
|
|
|
int __ret_warn_on = !!(x); \
|
2006-09-29 16:59:06 +08:00
|
|
|
if (__builtin_constant_p(__ret_warn_on)) { \
|
|
|
|
if (__ret_warn_on) \
|
2006-03-28 15:42:49 +08:00
|
|
|
__WARN(); \
|
2006-03-23 20:32:24 +08:00
|
|
|
} else { \
|
|
|
|
__asm__ __volatile__( \
|
2006-12-08 19:30:41 +08:00
|
|
|
"1: "PPC_TLNEI" %4,0\n" \
|
|
|
|
_EMIT_BUG_ENTRY \
|
|
|
|
: : "i" (__FILE__), "i" (__LINE__), \
|
2017-06-14 11:01:25 +08:00
|
|
|
"i" (BUGFLAG_WARNING|BUGFLAG_TAINT(TAINT_WARN)),\
|
2006-12-08 19:30:41 +08:00
|
|
|
"i" (sizeof(struct bug_entry)), \
|
|
|
|
"r" (__ret_warn_on)); \
|
2006-03-23 20:32:24 +08:00
|
|
|
} \
|
2006-09-29 16:59:06 +08:00
|
|
|
unlikely(__ret_warn_on); \
|
|
|
|
})
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
#define HAVE_ARCH_BUG
|
|
|
|
#define HAVE_ARCH_BUG_ON
|
|
|
|
#define HAVE_ARCH_WARN_ON
|
2005-09-20 06:01:54 +08:00
|
|
|
#endif /* __ASSEMBLY __ */
|
2008-12-15 03:44:13 +08:00
|
|
|
#else
|
|
|
|
#ifdef __ASSEMBLY__
|
|
|
|
.macro EMIT_BUG_ENTRY addr,file,line,flags
|
|
|
|
.endm
|
|
|
|
#else /* !__ASSEMBLY__ */
|
|
|
|
#define _EMIT_BUG_ENTRY
|
|
|
|
#endif
|
2007-01-02 02:45:34 +08:00
|
|
|
#endif /* CONFIG_BUG */
|
2005-05-01 23:59:01 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
#include <asm-generic/bug.h>
|
|
|
|
|
2012-03-29 01:30:02 +08:00
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
|
|
|
|
struct pt_regs;
|
|
|
|
extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
|
|
|
|
extern void bad_page_fault(struct pt_regs *, unsigned long, int);
|
|
|
|
extern void _exception(int, struct pt_regs *, int, unsigned long);
|
|
|
|
extern void die(const char *, struct pt_regs *, long);
|
|
|
|
|
|
|
|
#endif /* !__ASSEMBLY__ */
|
|
|
|
|
2005-12-17 05:43:46 +08:00
|
|
|
#endif /* __KERNEL__ */
|
2005-09-20 06:01:54 +08:00
|
|
|
#endif /* _ASM_POWERPC_BUG_H */
|