svn commit: r253585 - head/sys/amd64/vmm
Neel Natu
neel at FreeBSD.org
Tue Jul 23 23:43:02 UTC 2013
Author: neel
Date: Tue Jul 23 23:43:00 2013
New Revision: 253585
URL: http://svnweb.freebsd.org/changeset/base/253585
Log:
Add support for emulation of the "or r/m, imm8" instruction.
Submitted by: Zhixiang Yu (zxyu.core at gmail.com)
Obtained from: GSoC 2013 (AHCI device emulation for bhyve)
Modified:
head/sys/amd64/vmm/vmm_instruction_emul.c
Modified: head/sys/amd64/vmm/vmm_instruction_emul.c
==============================================================================
--- head/sys/amd64/vmm/vmm_instruction_emul.c Tue Jul 23 22:53:01 2013 (r253584)
+++ head/sys/amd64/vmm/vmm_instruction_emul.c Tue Jul 23 23:43:00 2013 (r253585)
@@ -60,6 +60,7 @@ enum {
VIE_OP_TYPE_NONE = 0,
VIE_OP_TYPE_MOV,
VIE_OP_TYPE_AND,
+ VIE_OP_TYPE_OR,
VIE_OP_TYPE_LAST
};
@@ -94,7 +95,13 @@ static const struct vie_op one_byte_opco
.op_byte = 0x81,
.op_type = VIE_OP_TYPE_AND,
.op_flags = VIE_OP_F_IMM,
- }
+ },
+ [0x83] = {
+ /* XXX Group 1 extended opcode - not just OR */
+ .op_byte = 0x83,
+ .op_type = VIE_OP_TYPE_OR,
+ .op_flags = VIE_OP_F_IMM8,
+ },
};
/* struct vie.mod */
@@ -338,8 +345,8 @@ emulate_and(void *vm, int vcpuid, uint64
break;
case 0x81:
/*
- * AND reg (ModRM:reg) with immediate and store the
- * result in reg
+ * AND mem (ModRM:r/m) with immediate and store the
+ * result in mem.
*
* 81/ and r/m32, imm32
* REX.W + 81/ and r/m64, imm32 sign-extended to 64
@@ -371,6 +378,52 @@ emulate_and(void *vm, int vcpuid, uint64
return (error);
}
+static int
+emulate_or(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
+ mem_region_read_t memread, mem_region_write_t memwrite, void *arg)
+{
+ int error, size;
+ uint64_t val1;
+
+ size = 4;
+ error = EINVAL;
+
+ switch (vie->op.op_byte) {
+ case 0x83:
+ /*
+ * OR mem (ModRM:r/m) with immediate and store the
+ * result in mem.
+ *
+ * 83/ OR r/m32, imm8 sign-extended to 32
+ * REX.W + 83/ OR r/m64, imm8 sign-extended to 64
+ *
+ * Currently, only the OR operation of the 0x83 opcode
+ * is implemented (ModRM:reg = b001).
+ */
+ if ((vie->reg & 7) != 1)
+ break;
+
+ if (vie->rex_w)
+ size = 8;
+
+ /* get the first operand */
+ error = memread(vm, vcpuid, gpa, &val1, size, arg);
+ if (error)
+ break;
+
+ /*
+ * perform the operation with the pre-fetched immediate
+ * operand and write the result
+ */
+ val1 |= vie->immediate;
+ error = memwrite(vm, vcpuid, gpa, val1, size, arg);
+ break;
+ default:
+ break;
+ }
+ return (error);
+}
+
int
vmm_emulate_instruction(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
mem_region_read_t memread, mem_region_write_t memwrite,
@@ -390,6 +443,10 @@ vmm_emulate_instruction(void *vm, int vc
error = emulate_and(vm, vcpuid, gpa, vie,
memread, memwrite, memarg);
break;
+ case VIE_OP_TYPE_OR:
+ error = emulate_or(vm, vcpuid, gpa, vie,
+ memread, memwrite, memarg);
+ break;
default:
error = EINVAL;
break;
More information about the svn-src-head
mailing list