[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [HVM] Add support for 'add r8, m8' instruction to memory-mapped I/O.



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.