# define TRAP_ILLEGAL_SLOT_INST 6
# define TRAP_ADDRESS_ERROR 9
# ifdef CONFIG_CPU_SH2A
+# define TRAP_UBC 12
# define TRAP_FPU_ERROR 13
# define TRAP_DIVZERO_ERROR 17
# define TRAP_DIVOVF_ERROR 18
* - userspace errors just cause EFAULT to be returned, resulting in SEGV
* - kernel/userspace interfaces cause a jump to an appropriate handler
* - other kernel errors are bad
- * - return 0 if fixed-up, -EFAULT if non-fatal (to the kernel) fault
*/
-static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
+static void die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
{
if (!user_mode(regs)) {
const struct exception_table_entry *fixup;
fixup = search_exception_tables(regs->pc);
if (fixup) {
regs->pc = fixup->fixup;
- return 0;
+ return;
}
die(str, regs, err);
}
- return -EFAULT;
}
static inline void sign_extend(unsigned int count, unsigned char *dst)
* (if that instruction is in a branch delay slot)
* - return 0 if emulation okay, -EFAULT on existential error
*/
-static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs,
+static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs,
struct mem_access *ma)
{
int ret, index, count;
/* Argh. Address not only misaligned but also non-existent.
* Raise an EFAULT and see if it's trapped
*/
- return die_if_no_fixup("Fault in unaligned fixup", regs, 0);
+ die_if_no_fixup("Fault in unaligned fixup", regs, 0);
+ return -EFAULT;
}
/*
* - fetches the instruction from PC+2
*/
static inline int handle_delayslot(struct pt_regs *regs,
- opcode_t old_instruction,
+ insn_size_t old_instruction,
struct mem_access *ma)
{
- opcode_t instruction;
+ insn_size_t instruction;
void __user *addr = (void __user *)(regs->pc +
instruction_size(old_instruction));
static int handle_unaligned_notify_count = 10;
-int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs,
+int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
struct mem_access *ma)
{
u_int rm;
unsigned long error_code = 0;
mm_segment_t oldfs;
siginfo_t info;
- opcode_t instruction;
+ insn_size_t instruction;
int tmp;
/* Intentional ifdef */
if (is_dsp_inst(regs)) {
/* Enable DSP mode, and restart instruction. */
regs->sr |= SR_DSP;
+ /* Save DSP mode */
+ tsk->thread.dsp_status.status |= SR_DSP;
return;
}
#endif
#endif
#endif
+#ifdef TRAP_UBC
+ set_exception_table_vec(TRAP_UBC, break_point_trap);
+#endif
+
/* Setup VBR for boot cpu */
per_cpu_trap_init();
}