# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID d93280670c3f315e2d48200564ed2220c1542209
# Parent b6de597411610bb9b9ac5077e23a68e22085884e
[HVM] Add support for 'add r8,m8' instruction to memory-mapped I/O.
Signed-off-by: Kevin Tronkowski <ktronkowski@xxxxxxxxxxxxxxx>
Signed-off-by: Ben Thomas <bthomas@xxxxxxxxxxxxxxx>
---
tools/ioemu/target-i386-dm/helper2.c | 18 ++++++++++++++++++
xen/arch/x86/hvm/intercept.c | 9 +++++++++
xen/arch/x86/hvm/io.c | 15 +++++++++++++++
xen/arch/x86/hvm/platform.c | 11 +++++++++++
xen/include/asm-x86/hvm/io.h | 1 +
xen/include/public/hvm/ioreq.h | 1 +
6 files changed, 55 insertions(+)
diff -r b6de59741161 -r d93280670c3f tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c Tue Oct 31 16:18:07 2006 +0000
+++ b/tools/ioemu/target-i386-dm/helper2.c Tue Oct 31 16:22:39 2006 +0000
@@ -393,6 +393,21 @@ void cpu_ioreq_and(CPUState *env, ioreq_
req->u.data = tmp1;
}
+void cpu_ioreq_add(CPUState *env, ioreq_t *req)
+{
+ unsigned long tmp1, tmp2;
+
+ if (req->pdata_valid != 0)
+ hw_error("expected scalar value");
+
+ read_physical(req->addr, req->size, &tmp1);
+ if (req->dir == IOREQ_WRITE) {
+ tmp2 = tmp1 + (unsigned long) req->u.data;
+ write_physical(req->addr, req->size, &tmp2);
+ }
+ req->u.data = tmp1;
+}
+
void cpu_ioreq_or(CPUState *env, ioreq_t *req)
{
unsigned long tmp1, tmp2;
@@ -437,6 +452,9 @@ void __handle_ioreq(CPUState *env, ioreq
break;
case IOREQ_TYPE_AND:
cpu_ioreq_and(env, req);
+ break;
+ case IOREQ_TYPE_ADD:
+ cpu_ioreq_add(env, req);
break;
case IOREQ_TYPE_OR:
cpu_ioreq_or(env, req);
diff -r b6de59741161 -r d93280670c3f xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c Tue Oct 31 16:18:07 2006 +0000
+++ b/xen/arch/x86/hvm/intercept.c Tue Oct 31 16:22:39 2006 +0000
@@ -109,6 +109,15 @@ static inline void hvm_mmio_access(struc
p->u.data = tmp1;
break;
+ case IOREQ_TYPE_ADD:
+ tmp1 = read_handler(v, p->addr, p->size);
+ if (p->dir == IOREQ_WRITE) {
+ tmp2 = tmp1 + (unsigned long) p->u.data;
+ write_handler(v, p->addr, p->size, tmp2);
+ }
+ p->u.data = tmp1;
+ break;
+
case IOREQ_TYPE_OR:
tmp1 = read_handler(v, p->addr, p->size);
if ( p->dir == IOREQ_WRITE ) {
diff -r b6de59741161 -r d93280670c3f xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Tue Oct 31 16:18:07 2006 +0000
+++ b/xen/arch/x86/hvm/io.c Tue Oct 31 16:22:39 2006 +0000
@@ -532,6 +532,21 @@ static void hvm_mmio_assist(struct cpu_u
set_reg_value(size, index, 0, regs, diff);
}
+ case INSTR_ADD:
+ if (src & REGISTER) {
+ index = operand_index(src);
+ value = get_reg_value(size, index, 0, regs);
+ diff = (unsigned long) p->u.data + value;
+ } else if (src & IMMEDIATE) {
+ value = mmio_opp->immediate;
+ diff = (unsigned long) p->u.data + value;
+ } else if (src & MEMORY) {
+ index = operand_index(dst);
+ value = get_reg_value(size, index, 0, regs);
+ diff = (unsigned long) p->u.data + value;
+ set_reg_value(size, index, 0, regs, diff);
+ }
+
/*
* The OF and CF flags are cleared; the SF, ZF, and PF
* flags are set according to the result. The state of
diff -r b6de59741161 -r d93280670c3f xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Tue Oct 31 16:18:07 2006 +0000
+++ b/xen/arch/x86/hvm/platform.c Tue Oct 31 16:22:39 2006 +0000
@@ -370,6 +370,13 @@ static int hvm_decode(int realmode, unsi
/* the operands order in comments conforms to AT&T convention */
switch ( *opcode ) {
+
+ case 0x00: /* add r8, m8 */
+ mmio_op->instr = INSTR_ADD;
+ *op_size = BYTE;
+ GET_OP_SIZE_FOR_BYTE(size_reg);
+ return reg_mem(size_reg, opcode, mmio_op, rex);
+
case 0x0A: /* or m8, r8 */
mmio_op->instr = INSTR_OR;
*op_size = BYTE;
@@ -1038,6 +1045,10 @@ void handle_mmio(unsigned long gpa)
case INSTR_AND:
mmio_operands(IOREQ_TYPE_AND, gpa, mmio_op, op_size);
+ break;
+
+ case INSTR_ADD:
+ mmio_operands(IOREQ_TYPE_ADD, gpa, mmio_op, op_size);
break;
case INSTR_XOR:
diff -r b6de59741161 -r d93280670c3f xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h Tue Oct 31 16:18:07 2006 +0000
+++ b/xen/include/asm-x86/hvm/io.h Tue Oct 31 16:22:39 2006 +0000
@@ -64,6 +64,7 @@
#define INSTR_BT 13
#define INSTR_XCHG 14
#define INSTR_SUB 15
+#define INSTR_ADD 16
#define MAX_INST_LEN 15 /* Maximum instruction length = 15 bytes */
diff -r b6de59741161 -r d93280670c3f xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h Tue Oct 31 16:18:07 2006 +0000
+++ b/xen/include/public/hvm/ioreq.h Tue Oct 31 16:22:39 2006 +0000
@@ -34,6 +34,7 @@
#define IOREQ_TYPE_OR 3
#define IOREQ_TYPE_XOR 4
#define IOREQ_TYPE_XCHG 5
+#define IOREQ_TYPE_ADD 6
/*
* VMExit dispatcher should cooperate with instruction decoder to
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|