diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2003-07-09 23:56:17 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2003-07-09 23:56:17 +0000 |
commit | 4349d22016903dc6037491064874b2cf95aa1641 (patch) | |
tree | ece818b91a4764779aeb9d632f95dc4ea4ac5d9c /sys | |
parent | e03882a600ec8dd679abd424cc19889176ffa1c1 (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.h | 3 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/emul.c | 19 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/trap.c | 21 |
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; |