Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Create an ARM2-specific undefined-instruction handl...



details:   https://anonhg.NetBSD.org/src/rev/7443166e91e6
branches:  trunk
changeset: 507239:7443166e91e6
user:      bjh21 <bjh21%NetBSD.org@localhost>
date:      Sat Mar 17 18:12:09 2001 +0000

description:
Create an ARM2-specific undefined-instruction handler which deals with the
undef/SWI bug and handles emulating SWP.

Untested bacuse my ARM2 machine isn't currently set up.

diffstat:

 sys/arch/arm/arm/undefined.c |  16 +------
 sys/arch/arm26/arm26/cpu.c   |  82 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 83 insertions(+), 15 deletions(-)

diffs (162 lines):

diff -r 1d46f5d47dfd -r 7443166e91e6 sys/arch/arm/arm/undefined.c
--- a/sys/arch/arm/arm/undefined.c      Sat Mar 17 17:00:38 2001 +0000
+++ b/sys/arch/arm/arm/undefined.c      Sat Mar 17 18:12:09 2001 +0000
@@ -1,6 +1,7 @@
-/*     $NetBSD: undefined.c,v 1.7 2001/03/13 23:56:48 bjh21 Exp $      */
+/*     $NetBSD: undefined.c,v 1.8 2001/03/17 18:12:09 bjh21 Exp $      */
 
 /*
+ * Copyright (c) 2001 Ben Harris.
  * Copyright (c) 1995 Mark Brinicombe.
  * Copyright (c) 1995 Brini.
  * All rights reserved.
@@ -51,7 +52,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: undefined.c,v 1.7 2001/03/13 23:56:48 bjh21 Exp $");
+__KERNEL_RCSID(0, "$NetBSD: undefined.c,v 1.8 2001/03/17 18:12:09 bjh21 Exp $");
 
 #include <sys/malloc.h>
 #include <sys/queue.h>
@@ -186,17 +187,6 @@
 
        fault_instruction = *(u_int32_t *)fault_pc;
 
-#ifdef CPU_ARM2
-       /*
-        * Check if the aborted instruction was a SWI (ARM2 bug --
-        * ARM3 data sheet p87) and call SWI handler if so.
-        */
-       if ((fault_instruction & 0x0f000000) == 0x0f000000) {
-               swi_handler(frame);
-               return;
-       }
-#endif
-
        /* Update vmmeter statistics */
        uvmexp.traps++;
 
diff -r 1d46f5d47dfd -r 7443166e91e6 sys/arch/arm26/arm26/cpu.c
--- a/sys/arch/arm26/arm26/cpu.c        Sat Mar 17 17:00:38 2001 +0000
+++ b/sys/arch/arm26/arm26/cpu.c        Sat Mar 17 18:12:09 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.9 2001/03/11 16:18:39 bjh21 Exp $ */
+/* $NetBSD: cpu.c,v 1.10 2001/03/17 18:12:10 bjh21 Exp $ */
 
 /*-
  * Copyright (c) 2000, 2001 Ben Harris
@@ -33,13 +33,14 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.9 2001/03/11 16:18:39 bjh21 Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.10 2001/03/17 18:12:10 bjh21 Exp $");
 
 #include <sys/device.h>
 #include <sys/proc.h>
 #include <sys/systm.h>
 #include <sys/time.h>
 #include <sys/user.h>
+#include <uvm/uvm_extern.h>
 #include <arm/armreg.h>
 #include <arm/undefined.h>
 #include <machine/machdep.h>
@@ -53,6 +54,10 @@
 static void cpu_attach(struct device *, struct device *, void *);
 static int cpu_search(struct device *, struct cfdata *, void *);
 static register_t cpu_identify(void);
+#ifdef CPU_ARM2
+static int arm2_undef_handler(u_int, u_int, struct trapframe *, int);
+static int swp_handler(u_int, u_int, struct trapframe *, int);
+#endif
 #ifdef CPU_ARM3
 static void cpu_arm3_setup(struct device *, int);
 #endif
@@ -96,6 +101,7 @@
                printf("ARM2");
 #ifdef CPU_ARM2
                supported = 1;
+               install_coproc_handler(0, arm2_undef_handler);
 #endif
                break;
        case CPU_ID_ARM250:
@@ -164,6 +170,78 @@
        return id;
 }
 
+#ifdef CPU_ARM2
+static int
+arm2_undef_handler(u_int addr, u_int insn, struct trapframe *frame,
+    int fault_code)
+{
+
+       if ((insn & 0x0fb00ff0) == 0x01000090)
+               /* It's a SWP */
+               return swp_handler(addr, insn, frame, fault_code);
+       /*
+        * Check if the aborted instruction was a SWI (ARM2 bug --
+        * ARM3 data sheet p87) and call SWI handler if so.
+        */
+       if ((insn & 0x0f000000) == 0x0f000000) {
+               swi_handler(frame);
+               return 0;
+       }
+       return 1;
+}
+
+/*
+ * In order for the following macro to work, any function using it
+ * must ensure that tf->r15 is copied into getreg(15).  This is safe
+ * with the current trapframe layout on arm26, but be careful.
+ */
+#define getreg(r) (((register_t *)&tf->tf_r0)[r])
+
+static int
+swp_handler(u_int addr, u_int insn, struct trapframe *tf, int fault_code)
+{
+       struct proc *p;
+       int rd, rm, rn, byte;
+       register_t temp;
+       caddr_t uaddr;
+       int err;
+       
+       KASSERT(fault_code & FAULT_USER);
+       rd = (insn & 0x0000f000) >> 12;
+       rm = (insn & 0x0000000f);
+       rn = (insn & 0x000f0000) >> 16;
+       byte = insn & 0x00400000;
+
+       if (rd == 15 || rm == 15 || rn == 15)
+               /* UNPREDICTABLE.  Arbitrarily do nothing. */
+               return 0;
+       uaddr = (caddr_t)getreg(rn);
+       /* We want the page wired so we won't sleep */
+       /* XXX only wire one byte due to wierdness with unaligned words */
+       err = uvm_vslock(curproc, uaddr, 1, VM_PROT_READ | VM_PROT_WRITE);
+       if (err != 0) {
+               trapsignal(p, SIGSEGV, (u_int)uaddr);
+               return 0;
+       }
+       /* I believe the uvm_vslock() guarantees the fetch/store won't fail. */
+       if (byte) {
+               temp = fubyte(uaddr);
+               subyte(uaddr, getreg(rm));
+               getreg(rd) = temp;
+       } else {
+               /*
+                * XXX Unaligned addresses happen to be handled
+                * appropriately by [fs]uword at present.
+                */
+               temp = fuword(uaddr);
+               suword(uaddr, getreg(rm));
+               getreg(rd) = temp;
+       }
+       uvm_vsunlock(curproc, uaddr, 1);
+       return 0;
+}
+#endif
+
 #ifdef CPU_ARM3
 
 #define ARM3_READ(reg, var) \



Home | Main Index | Thread Index | Old Index