11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef _ASMARM_BUG_H
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _ASMARM_BUG_H
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
49f97da78bf018206fb623cd351d454af2f105fe0David Howells#include <linux/linkage.h>
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6c8538a7aa5527d02c7191ac5da124efadf6a2827Matt Mackall#ifdef CONFIG_BUG
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
887e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass/*
987e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass * Use a suitable undefined instruction to use for ARM/Thumb2 bug handling.
1087e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass * We need to be careful not to conflict with those used by other modules and
1187e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass * the register_undef_hook() system.
1287e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass */
1387e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#ifdef CONFIG_THUMB2_KERNEL
1487e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#define BUG_INSTR_VALUE 0xde02
1587e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#define BUG_INSTR_TYPE ".hword "
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
1787e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#define BUG_INSTR_VALUE 0xe7f001f2
1887e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#define BUG_INSTR_TYPE ".word "
1987e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#endif
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2287e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#define BUG() _BUG(__FILE__, __LINE__, BUG_INSTR_VALUE)
2387e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#define _BUG(file, line, value) __BUG(file, line, value)
2487e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass
2587e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#ifdef CONFIG_DEBUG_BUGVERBOSE
2687e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass
2787e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass/*
2887e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass * The extra indirection is to ensure that the __FILE__ string comes through
2987e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass * OK. Many version of gcc do not support the asm %c parameter which would be
3087e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass * preferable to this unpleasantness. We use mergeable string sections to
3187e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass * avoid multiple copies of the string appearing in the kernel image.
3287e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass */
3387e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass
3487e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#define __BUG(__file, __line, __value)				\
3587e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glassdo {								\
3687e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass	asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n"	\
3787e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass		".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
3887e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass		"2:\t.asciz " #__file "\n" 			\
3987e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass		".popsection\n" 				\
4087e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass		".pushsection __bug_table,\"a\"\n"		\
4187e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass		"3:\t.word 1b, 2b\n"				\
4287e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass		"\t.hword " #__line ", 0\n"			\
4387e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass		".popsection");					\
4487e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass	unreachable();						\
4587e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass} while (0)
4687e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass
4787e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#else  /* not CONFIG_DEBUG_BUGVERBOSE */
4887e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass
4987e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#define __BUG(__file, __line, __value)				\
5087e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glassdo {								\
5187e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass	asm volatile(BUG_INSTR_TYPE #__value);			\
5287e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass	unreachable();						\
5387e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass} while (0)
5487e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#endif  /* CONFIG_DEBUG_BUGVERBOSE */
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HAVE_ARCH_BUG
5787e040b6456fd3416a1f6831c1eedaef5c0a94ffSimon Glass#endif  /* CONFIG_BUG */
58c8538a7aa5527d02c7191ac5da124efadf6a2827Matt Mackall
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm-generic/bug.h>
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
619f97da78bf018206fb623cd351d454af2f105fe0David Howellsstruct pt_regs;
629f97da78bf018206fb623cd351d454af2f105fe0David Howellsvoid die(const char *msg, struct pt_regs *regs, int err);
639f97da78bf018206fb623cd351d454af2f105fe0David Howells
649f97da78bf018206fb623cd351d454af2f105fe0David Howellsstruct siginfo;
659f97da78bf018206fb623cd351d454af2f105fe0David Howellsvoid arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
669f97da78bf018206fb623cd351d454af2f105fe0David Howells		unsigned long err, unsigned long trap);
679f97da78bf018206fb623cd351d454af2f105fe0David Howells
689f97da78bf018206fb623cd351d454af2f105fe0David Howells#ifdef CONFIG_ARM_LPAE
699f97da78bf018206fb623cd351d454af2f105fe0David Howells#define FAULT_CODE_ALIGNMENT	33
709f97da78bf018206fb623cd351d454af2f105fe0David Howells#define FAULT_CODE_DEBUG	34
719f97da78bf018206fb623cd351d454af2f105fe0David Howells#else
729f97da78bf018206fb623cd351d454af2f105fe0David Howells#define FAULT_CODE_ALIGNMENT	1
739f97da78bf018206fb623cd351d454af2f105fe0David Howells#define FAULT_CODE_DEBUG	2
749f97da78bf018206fb623cd351d454af2f105fe0David Howells#endif
759f97da78bf018206fb623cd351d454af2f105fe0David Howells
769f97da78bf018206fb623cd351d454af2f105fe0David Howellsvoid hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
779f97da78bf018206fb623cd351d454af2f105fe0David Howells				       struct pt_regs *),
789f97da78bf018206fb623cd351d454af2f105fe0David Howells		     int sig, int code, const char *name);
799f97da78bf018206fb623cd351d454af2f105fe0David Howells
809f97da78bf018206fb623cd351d454af2f105fe0David Howellsvoid hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int,
819f97da78bf018206fb623cd351d454af2f105fe0David Howells				       struct pt_regs *),
829f97da78bf018206fb623cd351d454af2f105fe0David Howells		     int sig, int code, const char *name);
839f97da78bf018206fb623cd351d454af2f105fe0David Howells
849f97da78bf018206fb623cd351d454af2f105fe0David Howellsextern asmlinkage void c_backtrace(unsigned long fp, int pmode);
859f97da78bf018206fb623cd351d454af2f105fe0David Howells
869f97da78bf018206fb623cd351d454af2f105fe0David Howellsstruct mm_struct;
879f97da78bf018206fb623cd351d454af2f105fe0David Howellsextern void show_pte(struct mm_struct *mm, unsigned long addr);
889f97da78bf018206fb623cd351d454af2f105fe0David Howellsextern void __show_regs(struct pt_regs *);
899f97da78bf018206fb623cd351d454af2f105fe0David Howells
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
91