162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __ASM_SH_TRAPS_32_H
362306a36Sopenharmony_ci#define __ASM_SH_TRAPS_32_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/types.h>
662306a36Sopenharmony_ci#include <asm/mmu.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifdef CONFIG_CPU_HAS_SR_RB
962306a36Sopenharmony_ci#define lookup_exception_vector()	\
1062306a36Sopenharmony_ci({					\
1162306a36Sopenharmony_ci	unsigned long _vec;		\
1262306a36Sopenharmony_ci					\
1362306a36Sopenharmony_ci	__asm__ __volatile__ (		\
1462306a36Sopenharmony_ci		"stc r2_bank, %0\n\t"	\
1562306a36Sopenharmony_ci		: "=r" (_vec)		\
1662306a36Sopenharmony_ci	);				\
1762306a36Sopenharmony_ci					\
1862306a36Sopenharmony_ci	_vec;				\
1962306a36Sopenharmony_ci})
2062306a36Sopenharmony_ci#else
2162306a36Sopenharmony_ci#define lookup_exception_vector()	\
2262306a36Sopenharmony_ci({					\
2362306a36Sopenharmony_ci	unsigned long _vec;		\
2462306a36Sopenharmony_ci	__asm__ __volatile__ (		\
2562306a36Sopenharmony_ci		"mov r4, %0\n\t"	\
2662306a36Sopenharmony_ci		: "=r" (_vec)		\
2762306a36Sopenharmony_ci	);				\
2862306a36Sopenharmony_ci					\
2962306a36Sopenharmony_ci	_vec;				\
3062306a36Sopenharmony_ci})
3162306a36Sopenharmony_ci#endif
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cistatic inline void trigger_address_error(void)
3462306a36Sopenharmony_ci{
3562306a36Sopenharmony_ci	__asm__ __volatile__ (
3662306a36Sopenharmony_ci		"ldc %0, sr\n\t"
3762306a36Sopenharmony_ci		"mov.l @%1, %0"
3862306a36Sopenharmony_ci		:
3962306a36Sopenharmony_ci		: "r" (0x10000000), "r" (0x80000001)
4062306a36Sopenharmony_ci	);
4162306a36Sopenharmony_ci}
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ciasmlinkage void do_address_error(struct pt_regs *regs,
4462306a36Sopenharmony_ci				 unsigned long writeaccess,
4562306a36Sopenharmony_ci				 unsigned long address);
4662306a36Sopenharmony_ciasmlinkage void do_divide_error(unsigned long r4);
4762306a36Sopenharmony_ciasmlinkage void do_reserved_inst(void);
4862306a36Sopenharmony_ciasmlinkage void do_illegal_slot_inst(void);
4962306a36Sopenharmony_ciasmlinkage void do_exception_error(void);
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#define BUILD_TRAP_HANDLER(name)					\
5262306a36Sopenharmony_ciasmlinkage void name##_trap_handler(unsigned long r4, unsigned long r5,	\
5362306a36Sopenharmony_ci				    unsigned long r6, unsigned long r7,	\
5462306a36Sopenharmony_ci				    struct pt_regs __regs)
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci#define TRAP_HANDLER_DECL				\
5762306a36Sopenharmony_ci	struct pt_regs *regs = RELOC_HIDE(&__regs, 0);	\
5862306a36Sopenharmony_ci	unsigned int vec = regs->tra;			\
5962306a36Sopenharmony_ci	(void)vec;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci#endif /* __ASM_SH_TRAPS_32_H */
62