summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2003-07-09 23:56:17 +0000
committerJason Wright <jason@cvs.openbsd.org>2003-07-09 23:56:17 +0000
commit4349d22016903dc6037491064874b2cf95aa1641 (patch)
treeece818b91a4764779aeb9d632f95dc4ea4ac5d9c /sys
parente03882a600ec8dd679abd424cc19889176ffa1c1 (diff)
part of infrastructure to deal with emulated stqf/ldqf:
T_ILLINST handler fetches instruction and decodes it. If it's stqf, ldqf, stqfa, or ldqfa call emulation instead of SIGILL directly. Note: this still SIGILL's in the end, the emulation isn't done yet.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc64/include/cpu.h3
-rw-r--r--sys/arch/sparc64/sparc64/emul.c19
-rw-r--r--sys/arch/sparc64/sparc64/trap.c21
3 files changed, 40 insertions, 3 deletions
diff --git a/sys/arch/sparc64/include/cpu.h b/sys/arch/sparc64/include/cpu.h
index e706dd0b77e..58b0864f2b4 100644
--- a/sys/arch/sparc64/include/cpu.h
+++ b/sys/arch/sparc64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.22 2003/06/24 21:54:39 henric Exp $ */
+/* $OpenBSD: cpu.h,v 1.23 2003/07/09 23:56:16 jason Exp $ */
/* $NetBSD: cpu.h,v 1.28 2001/06/14 22:56:58 thorpej Exp $ */
/*
@@ -280,6 +280,7 @@ void kgdb_panic(void);
/* emul.c */
int fixalign(struct proc *, struct trapframe64 *);
int emulinstr(vaddr_t, struct trapframe64 *);
+int emul_qf(int32_t, struct proc *, union sigval);
/*
*
diff --git a/sys/arch/sparc64/sparc64/emul.c b/sys/arch/sparc64/sparc64/emul.c
index 566885d0171..96fcf536168 100644
--- a/sys/arch/sparc64/sparc64/emul.c
+++ b/sys/arch/sparc64/sparc64/emul.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: emul.c,v 1.3 2002/03/14 01:26:45 millert Exp $ */
+/* $OpenBSD: emul.c,v 1.4 2003/07/09 23:56:16 jason Exp $ */
/* $NetBSD: emul.c,v 1.8 2001/06/29 23:58:40 eeh Exp $ */
/*-
@@ -40,6 +40,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
+#include <sys/signalvar.h>
#include <machine/reg.h>
#include <machine/instr.h>
#include <machine/cpu.h>
@@ -455,3 +456,19 @@ emulinstr(pc, tf)
return 0;
}
+
+int
+emul_qf(int32_t insv, struct proc *p, union sigval sv)
+{
+ union instr ins;
+
+ ins.i_int = insv;
+
+ if (ins.i_op3.i_rd & 0x20) {
+ trapsignal(p, SIGILL, 0, ILL_ILLOPN, sv);
+ return (0);
+ }
+
+ trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv);
+ return (0);
+}
diff --git a/sys/arch/sparc64/sparc64/trap.c b/sys/arch/sparc64/sparc64/trap.c
index 519957c5d21..40a7191cd6a 100644
--- a/sys/arch/sparc64/sparc64/trap.c
+++ b/sys/arch/sparc64/sparc64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.25 2003/07/09 15:52:53 jason Exp $ */
+/* $OpenBSD: trap.c,v 1.26 2003/07/09 23:56:16 jason Exp $ */
/* $NetBSD: trap.c,v 1.73 2001/08/09 01:03:01 eeh Exp $ */
/*
@@ -543,8 +543,27 @@ badtrap:
break; /* the work is all in userret() */
case T_ILLINST:
+ {
+ union instr ins;
+
+ if (copyin((caddr_t)pc, &ins, sizeof(ins)) != 0) {
+ /* XXX Can this happen? */
+ trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv);
+ break;
+ }
+ if (ins.i_any.i_op == IOP_mem &&
+ (ins.i_op3.i_op3 == IOP3_LDQF ||
+ ins.i_op3.i_op3 == IOP3_STQF ||
+ ins.i_op3.i_op3 == IOP3_LDQFA ||
+ ins.i_op3.i_op3 == IOP3_STQFA)) {
+ if (emul_qf(ins.i_int, p, sv))
+ ADVANCE;
+ break;
+ }
trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); /* XXX code?? */
break;
+ }
+
case T_INST_EXCEPT:
trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); /* XXX code?? */
break;