Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm Add read_insn and read_thumb_insn inlines to hi...



details:   https://anonhg.NetBSD.org/src/rev/bcdff0750c61
branches:  trunk
changeset: 793187:bcdff0750c61
user:      matt <matt%NetBSD.org@localhost>
date:      Wed Jan 29 18:45:20 2014 +0000

description:
Add read_insn and read_thumb_insn inlines to hide the endianness of
instructions and use them as appropriate.

diffstat:

 sys/arch/arm/arm/syscall.c    |  12 +++-------
 sys/arch/arm/arm/undefined.c  |  23 +++++----------------
 sys/arch/arm/arm32/fault.c    |  45 +++++++++++++++++++++---------------------
 sys/arch/arm/include/locore.h |  36 ++++++++++++++++++++++++++++++++++
 4 files changed, 69 insertions(+), 47 deletions(-)

diffs (235 lines):

diff -r e02b4cd2957e -r bcdff0750c61 sys/arch/arm/arm/syscall.c
--- a/sys/arch/arm/arm/syscall.c        Wed Jan 29 18:42:14 2014 +0000
+++ b/sys/arch/arm/arm/syscall.c        Wed Jan 29 18:45:20 2014 +0000
@@ -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 @@
        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
        }
 
diff -r e02b4cd2957e -r bcdff0750c61 sys/arch/arm/arm/undefined.c
--- a/sys/arch/arm/arm/undefined.c      Wed Jan 29 18:42:14 2014 +0000
+++ b/sys/arch/arm/arm/undefined.c      Wed Jan 29 18:45:20 2014 +0000
@@ -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 @@
 
 #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 @@
                 * 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 */
diff -r e02b4cd2957e -r bcdff0750c61 sys/arch/arm/arm32/fault.c
--- a/sys/arch/arm/arm32/fault.c        Wed Jan 29 18:42:14 2014 +0000
+++ b/sys/arch/arm/arm32/fault.c        Wed Jan 29 18:45:20 2014 +0000
@@ -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 @@
 #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 @@
        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 @@
 #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 @@
                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 @@
        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 @@
        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);
diff -r e02b4cd2957e -r bcdff0750c61 sys/arch/arm/include/locore.h
--- a/sys/arch/arm/include/locore.h     Wed Jan 29 18:42:14 2014 +0000
+++ b/sys/arch/arm/include/locore.h     Wed Jan 29 18:45:20 2014 +0000
@@ -170,6 +170,42 @@
 #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



Home | Main Index | Thread Index | Old Index