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