Module Name: src
Committed By: matt
Date: Wed Aug 17 06:59:29 UTC 2011
Modified Files:
src/sys/arch/mips/include: mips_opcode.h
src/sys/arch/mips/mips: mips_emul.c
Log Message:
emulate the special3 opcode LX (lwx, ldx, lhx, lbux) instructions.
To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/mips/include/mips_opcode.h
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/mips/mips/mips_emul.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/mips/include/mips_opcode.h
diff -u src/sys/arch/mips/include/mips_opcode.h:1.16 src/sys/arch/mips/include/mips_opcode.h:1.17
--- src/sys/arch/mips/include/mips_opcode.h:1.16 Tue Mar 15 07:33:54 2011
+++ src/sys/arch/mips/include/mips_opcode.h Wed Aug 17 06:59:28 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: mips_opcode.h,v 1.16 2011/03/15 07:33:54 matt Exp $ */
+/* $NetBSD: mips_opcode.h,v 1.17 2011/08/17 06:59:28 matt Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -266,8 +266,14 @@
/*
* Values for the 'func' field when 'op' == OP_SPECIAL3.
*/
+#define OP_LX 012 /* DSP */
#define OP_RDHWR 073 /* MIPS32/64 r2 */
+#define OP_LX_LWX 0 /* lwx */
+#define OP_LX_LHX 4 /* lhx */
+#define OP_LX_LBUX 6 /* lbux */
+#define OP_LX_LDX 8 /* ldx */
+
/*
* Values for the 'func' field when 'op' == OP_BCOND.
*/
Index: src/sys/arch/mips/mips/mips_emul.c
diff -u src/sys/arch/mips/mips/mips_emul.c:1.23 src/sys/arch/mips/mips/mips_emul.c:1.24
--- src/sys/arch/mips/mips/mips_emul.c:1.23 Tue Mar 15 07:39:23 2011
+++ src/sys/arch/mips/mips/mips_emul.c Wed Aug 17 06:59:29 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: mips_emul.c,v 1.23 2011/03/15 07:39:23 matt Exp $ */
+/* $NetBSD: mips_emul.c,v 1.24 2011/08/17 06:59:29 matt Exp $ */
/*
* Copyright (c) 1999 Shuichiro URATA. All rights reserved.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mips_emul.c,v 1.23 2011/03/15 07:39:23 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_emul.c,v 1.24 2011/08/17 06:59:29 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -399,6 +399,59 @@
ksiginfo_t ksi;
const InstFmt instfmt = { .word = inst };
switch (instfmt.RType.func) {
+ case OP_LX: {
+ const intptr_t vaddr = tf->tf_regs[instfmt.RType.rs]
+ + tf->tf_regs[instfmt.RType.rt];
+ mips_reg_t r;
+ int error = EFAULT;
+ if (vaddr < 0) {
+ addr_err:
+ send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
+ return;
+ }
+ switch (instfmt.RType.shamt) {
+#if !defined(__mips_o32)
+ case OP_LX_LDX: {
+ uint64_t tmp64;
+ if (vaddr & 7)
+ goto addr_err;
+ error = copyin((void *)vaddr, &tmp64, sizeof(tmp64));
+ r = tmp64;
+ break;
+ }
+#endif
+ case OP_LX_LWX: {
+ int32_t tmp32;
+ if (vaddr & 3)
+ goto addr_err;
+ error = copyin((void *)vaddr, &tmp32, sizeof(tmp32));
+ r = tmp32;
+ break;
+ }
+ case OP_LX_LHX: {
+ int16_t tmp16;
+ if (vaddr & 1)
+ goto addr_err;
+ error = copyin((void *)vaddr, &tmp16, sizeof(tmp16));
+ r = tmp16;
+ break;
+ }
+ case OP_LX_LBUX: {
+ uint8_t tmp8;
+ error = copyin((void *)vaddr, &tmp8, sizeof(tmp8));
+ r = tmp8;
+ break;
+ }
+ default:
+ goto illopc;
+ }
+ if (error) {
+ send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
+ return;
+ }
+ tf->tf_regs[instfmt.RType.rd] = r;
+ break;
+ }
case OP_RDHWR:
switch (instfmt.RType.rd) {
case 29:
@@ -407,6 +460,7 @@
break;
}
/* FALLTHROUGH */
+ illopc:
default:
tf->tf_regs[_R_CAUSE] = cause;
tf->tf_regs[_R_BADVADDR] = tf->tf_regs[_R_PC];