Module Name: src Committed By: matt Date: Wed Jan 29 18:45:21 UTC 2014
Modified Files: src/sys/arch/arm/arm: syscall.c undefined.c src/sys/arch/arm/arm32: fault.c src/sys/arch/arm/include: locore.h Log Message: Add read_insn and read_thumb_insn inlines to hide the endianness of instructions and use them as appropriate. To generate a diff of this commit: cvs rdiff -u -r1.58 -r1.59 src/sys/arch/arm/arm/syscall.c cvs rdiff -u -r1.50 -r1.51 src/sys/arch/arm/arm/undefined.c cvs rdiff -u -r1.92 -r1.93 src/sys/arch/arm/arm32/fault.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/include/locore.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/arm/syscall.c diff -u src/sys/arch/arm/arm/syscall.c:1.58 src/sys/arch/arm/arm/syscall.c:1.59 --- src/sys/arch/arm/arm/syscall.c:1.58 Sun Aug 18 06:28:18 2013 +++ src/sys/arch/arm/arm/syscall.c Wed Jan 29 18:45:21 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: syscall.c,v 1.58 2013/08/18 06:28:18 matt Exp $ */ +/* $NetBSD: syscall.c,v 1.59 2014/01/29 18:45:21 matt Exp $ */ /*- * Copyright (c) 2000, 2003 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ #include <sys/param.h> -__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.58 2013/08/18 06:28:18 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.59 2014/01/29 18:45:21 matt Exp $"); #include <sys/cpu.h> #include <sys/device.h> @@ -148,14 +148,10 @@ swi_handler(trapframe_t *tf) else #endif { - /* XXX fuword? */ #ifdef __PROG32 - insn = *(uint32_t *)(tf->tf_pc - INSN_SIZE); -#if defined(__ARMEB__) && defined(_ARM_ARCH_7) - insn = le32toh(insn); /* BE armv7 insn are in LE */ -#endif + insn = read_insn(tf->tf_pc - INSN_SIZE, true); #else - insn = *(uint32_t *)((tf->tf_r15 & R15_PC) - INSN_SIZE); + insn = read_insn((tf->tf_r15 & R15_PC) - INSN_SIZE, true); #endif } Index: src/sys/arch/arm/arm/undefined.c diff -u src/sys/arch/arm/arm/undefined.c:1.50 src/sys/arch/arm/arm/undefined.c:1.51 --- src/sys/arch/arm/arm/undefined.c:1.50 Sun Aug 18 08:08:15 2013 +++ src/sys/arch/arm/arm/undefined.c Wed Jan 29 18:45:21 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: undefined.c,v 1.50 2013/08/18 08:08:15 matt Exp $ */ +/* $NetBSD: undefined.c,v 1.51 2014/01/29 18:45:21 matt Exp $ */ /* * Copyright (c) 2001 Ben Harris. @@ -54,7 +54,7 @@ #include <sys/kgdb.h> #endif -__KERNEL_RCSID(0, "$NetBSD: undefined.c,v 1.50 2013/08/18 08:08:15 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: undefined.c,v 1.51 2014/01/29 18:45:21 matt Exp $"); #include <sys/kmem.h> #include <sys/queue.h> @@ -303,17 +303,10 @@ undefinedinstruction(trapframe_t *frame) #ifdef THUMB_CODE if (frame->tf_spsr & PSR_T_bit) { - const uint16_t * const pc = (const uint16_t *)(fault_pc & ~1); - fault_instruction = pc[0]; -#if defined(__ARMEB__) && defined(_ARM_ARCH_7) - fault_instruction = le16toh(fault_instruction); -#endif + fault_instruction = read_thumb_insn(fault_pc, user); if (fault_instruction >= 0xe000) { - uint16_t tmp = pc[1]; -#if defined(__ARMEB__) && defined(_ARM_ARCH_7) - tmp = le16toh(tmp); -#endif - fault_instruction = (fault_instruction << 16) | tmp; + fault_instruction = (fault_instruction << 16) + | read_thumb_insn(fault_pc + 2, user); } } else @@ -342,11 +335,7 @@ undefinedinstruction(trapframe_t *frame) * the kernel is screwed up in which case it does * not really matter does it ? */ - - fault_instruction = *(const uint32_t *)fault_pc; -#if defined(__ARMEB__) && defined(_ARM_ARCH_7) - fault_instruction = le32toh(fault_instruction); -#endif + fault_instruction = read_insn(fault_pc, user); } /* Update vmmeter statistics */ Index: src/sys/arch/arm/arm32/fault.c diff -u src/sys/arch/arm/arm32/fault.c:1.92 src/sys/arch/arm/arm32/fault.c:1.93 --- src/sys/arch/arm/arm32/fault.c:1.92 Sat Jan 11 17:32:20 2014 +++ src/sys/arch/arm/arm32/fault.c Wed Jan 29 18:45:21 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: fault.c,v 1.92 2014/01/11 17:32:20 matt Exp $ */ +/* $NetBSD: fault.c,v 1.93 2014/01/29 18:45:21 matt Exp $ */ /* * Copyright 2003 Wasabi Systems, Inc. @@ -81,7 +81,7 @@ #include "opt_kgdb.h" #include <sys/types.h> -__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.92 2014/01/11 17:32:20 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.93 2014/01/29 18:45:21 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -168,8 +168,23 @@ static const struct data_abort data_abor #endif static inline void -call_trapsignal(struct lwp *l, ksiginfo_t *ksi) +call_trapsignal(struct lwp *l, const struct trapframe *tf, ksiginfo_t *ksi) { + if (l->l_proc->p_pid == 1 || cpu_printfataltraps) { + printf("%d.%d(%s): trap: signo=%d code=%d addr=%p trap=%#x\n", + l->l_proc->p_pid, l->l_lid, l->l_proc->p_comm, + ksi->ksi_signo, ksi->ksi_code, ksi->ksi_addr, + ksi->ksi_trap); + printf("r0=%08x r1=%08x r2=%08x r3=%08x\n", + tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3); + printf("r4=%08x r5=%08x r6=%08x r7=%08x\n", + tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7); + printf("r8=%08x r9=%08x rA=%08x rB=%08x\n", + tf->tf_r8, tf->tf_r9, tf->tf_r10, tf->tf_r11); + printf("ip=%08x sp=%08x lr=%08x pc=%08x spsr=%08x\n", + tf->tf_r12, tf->tf_usr_sp, tf->tf_usr_lr, tf->tf_pc, + tf->tf_spsr); + } TRAPSIGNAL(l, ksi); } @@ -360,7 +375,7 @@ data_abort_handler(trapframe_t *tf) if (!user && (va >= VM_MIN_KERNEL_ADDRESS || (va < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW)) && __predict_true((pcb->pcb_onfault == NULL || - (ReadWord(tf->tf_pc) & 0x05200000) != 0x04200000))) { + (read_insn(tf->tf_pc, false) & 0x05200000) != 0x04200000))) { map = kernel_map; /* Was the fault due to the FPE/IPKDB ? */ @@ -402,7 +417,7 @@ data_abort_handler(trapframe_t *tf) #ifdef THUMB_CODE /* Fast track the ARM case. */ if (__predict_false(tf->tf_spsr & PSR_T_bit)) { - u_int insn = fusword((void *)(tf->tf_pc & ~1)); + u_int insn = read_thumb_insn(tf->tf_pc, user); u_int insn_f8 = insn & 0xf800; u_int insn_fe = insn & 0xfe00; @@ -421,7 +436,7 @@ data_abort_handler(trapframe_t *tf) else #endif { - u_int insn = ReadWord(tf->tf_pc); + u_int insn = read_insn(tf->tf_pc, user); if (((insn & 0x0c100000) == 0x04000000) || /* STR[B] */ ((insn & 0x0e1000b0) == 0x000000b0) || /* STR[HD]*/ @@ -499,21 +514,7 @@ data_abort_handler(trapframe_t *tf) UVMHIST_LOG(maphist, " <- error (%d)", error, 0, 0, 0); do_trapsignal: - if (l->l_proc->p_pid == 1 || cpu_printfataltraps) { - printf("%d.%d(%s): trap: signo=%d code=%d addr=%p trap=%#x\n", - l->l_proc->p_pid, l->l_lid, l->l_proc->p_comm, - ksi.ksi_signo, ksi.ksi_code, ksi.ksi_addr, ksi.ksi_trap); - printf("r0=%08x r1=%08x r2=%08x r3=%08x\n", - tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3); - printf("r4=%08x r5=%08x r6=%08x r7=%08x\n", - tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7); - printf("r8=%08x r9=%08x rA=%08x rB=%08x\n", - tf->tf_r8, tf->tf_r9, tf->tf_r10, tf->tf_r11); - printf("ip=%08x sp=%08x lr=%08x pc=%08x spsr=%08x\n", - tf->tf_r12, tf->tf_usr_sp, tf->tf_usr_lr, tf->tf_pc, - tf->tf_spsr); - } - call_trapsignal(l, &ksi); + call_trapsignal(l, tf, &ksi); out: /* If returning to user mode, make sure to invoke userret() */ if (user) @@ -880,7 +881,7 @@ prefetch_abort_handler(trapframe_t *tf) ksi.ksi_trap = fault_pc; do_trapsignal: - call_trapsignal(l, &ksi); + call_trapsignal(l, tf, &ksi); out: KASSERT(!TRAP_USERMODE(tf) || (tf->tf_spsr & IF32_bits) == 0); Index: src/sys/arch/arm/include/locore.h diff -u src/sys/arch/arm/include/locore.h:1.7 src/sys/arch/arm/include/locore.h:1.8 --- src/sys/arch/arm/include/locore.h:1.7 Sat Jan 11 17:32:20 2014 +++ src/sys/arch/arm/include/locore.h Wed Jan 29 18:45:20 2014 @@ -170,6 +170,42 @@ extern bool cpu_armv6_p; #define CPU_IS_ARMV6_P() true #endif +/* + * User by the fault code to read the current instruction. + */ +static inline uint32_t +read_insn(vaddr_t va, bool user_p) +{ + uint32_t insn; + if (user_p) { + __asm __volatile("ldrt %0, [%1]" : "=&r"(insn) : "r"(va)); + } else { + insn = *(const uint32_t *)va; + } +#if defined(__ARMEB__) && defined(_ARM_ARCH_7) + insn = bswap32(insn); +#endif + return insn; +} + +/* + * User by the fault code to read the current thumb instruction. + */ +static inline uint32_t +read_thumb_insn(vaddr_t va, bool user_p) +{ + va &= ~1; + uint32_t insn; + if (user_p) { + __asm __volatile("ldrht %0, [%1]" : "=&r"(insn) : "r"(va)); + } else { + insn = *(const uint16_t *)va; + } +#if defined(__ARMEB__) && defined(_ARM_ARCH_7) + insn = bswap16(insn); +#endif + return insn; +} /* * Random cruft