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

[Xen-changelog] [xen-3.0-testing] [HVM][MMIO] Emulate more instructions: or/and/xor with byte width,



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 05f07acd3be2fac0c66ef6e9a94b129f7f7e37b5
# Parent  11a431a8b3d98f991d4d22b47baa226b1cd12e2a
[HVM][MMIO] Emulate more instructions: or/and/xor with byte width,
and load string (LODS) instructions.

Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx>
Signed-off-by: Yunfeng zhao <yunfeng.zhao@xxxxxxxxx>
Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx>
xen-unstable changeset:   10292:7d37df6c324721647d5d6c930af09101f1165e23
xen-unstable date:        Wed Jun  7 14:20:29 2006 +0100

[HVM][MMIO] Support decode of 0x83 opcode (or imm8,m32/64').
This instruction is used by both WinXP during an SMP installation and by
Sun Solaris.  With this patch Sun Solaris UP is able to boot.  Windows
SMP gets a bit further but still has issues.

Signed-off-by: Tom Woller <thomas.woller@xxxxxxx>
Signed-off-by: Travis Betak <tbetak.woller@xxxxxxx>
xen-unstable changeset:   10293:2049467adee349ad576e8afee5de77e23d8928d8
xen-unstable date:        Wed Jun  7 14:21:49 2006 +0100
---
 xen/arch/x86/hvm/io.c        |    7 +++
 xen/arch/x86/hvm/platform.c  |   94 ++++++++++++++++++++++++++++++++-----------
 xen/include/asm-x86/hvm/io.h |    7 +--
 3 files changed, 83 insertions(+), 25 deletions(-)

diff -r 11a431a8b3d9 -r 05f07acd3be2 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Wed Jun 07 14:17:26 2006 +0100
+++ b/xen/arch/x86/hvm/io.c     Wed Jun 07 14:24:14 2006 +0100
@@ -505,6 +505,13 @@ static void hvm_mmio_assist(struct vcpu 
             regs->ecx -= p->count;
         break;
 
+    case INSTR_LODS:
+        sign = p->df ? -1 : 1;
+        regs->esi += sign * p->count * p->size;
+        if (mmio_opp->flags & REPZ)
+            regs->ecx -= p->count;
+        break;
+
     case INSTR_AND:
         if (src & REGISTER) {
             index = operand_index(src);
diff -r 11a431a8b3d9 -r 05f07acd3be2 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Wed Jun 07 14:17:26 2006 +0100
+++ b/xen/arch/x86/hvm/platform.c       Wed Jun 07 14:24:14 2006 +0100
@@ -364,6 +364,12 @@ static int hvm_decode(int realmode, unsi
     }
 
     switch (*opcode) {
+    case 0x0A: /* or r8, m8 */
+        instr->instr = INSTR_OR;
+        instr->op_size = BYTE;
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return mem_reg(size_reg, opcode, instr, rex);
+
     case 0x0B: /* or m32/16, r32/16 */
         instr->instr = INSTR_OR;
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
@@ -380,6 +386,12 @@ static int hvm_decode(int realmode, unsi
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
         return reg_mem(instr->op_size, opcode, instr, rex);
 
+    case 0x22: /* and m8, r8 */
+        instr->instr = INSTR_AND;
+        instr->op_size = BYTE;
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return mem_reg(size_reg, opcode, instr, rex);
+
     case 0x23: /* and m32/16, r32/16 */
         instr->instr = INSTR_AND;
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
@@ -396,6 +408,12 @@ static int hvm_decode(int realmode, unsi
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
         return reg_mem(instr->op_size, opcode, instr, rex);
 
+    case 0x32: /* xor m8, r8*/
+        instr->instr = INSTR_XOR;
+        instr->op_size = BYTE;
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return mem_reg(size_reg, opcode, instr, rex);
+
     case 0x39: /* cmp r32/16, m32/16 */
         instr->instr = INSTR_CMP;
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
@@ -408,19 +426,30 @@ static int hvm_decode(int realmode, unsi
 
     case 0x80:
     case 0x81:
+    case 0x83:
         {
             unsigned char ins_subtype = (opcode[1] >> 3) & 7;
 
             if (opcode[0] == 0x80) {
                 GET_OP_SIZE_FOR_BYTE(size_reg);
                 instr->op_size = BYTE;
-            } else {
+            } else if (opcode[0] == 0x81) {
                 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
                 size_reg = instr->op_size;
+            } else if (opcode[0] == 0x83) {
+                GET_OP_SIZE_FOR_NONEBYTE(size_reg);
+                instr->op_size = size_reg;
             }
+           
+            /* opcode 0x83 always has a single byte operand */
+            if (opcode[0] == 0x83)
+                instr->immediate = 
+                    (signed char)get_immediate(realmode, opcode+1, BYTE);
+            else
+                instr->immediate = 
+                    get_immediate(realmode, opcode+1, instr->op_size);
 
             instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
-            instr->immediate = get_immediate(realmode, opcode+1, 
instr->op_size);
             instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
 
             switch (ins_subtype) {
@@ -513,6 +542,16 @@ static int hvm_decode(int realmode, unsi
 
     case 0xAB: /* stosw/stosl */
         instr->instr = INSTR_STOS;
+        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+        return DECODE_success;
+
+    case 0xAC: /* lodsb */
+        instr->instr = INSTR_LODS;
+        instr->op_size = BYTE;
+        return DECODE_success;
+
+    case 0xAD: /* lodsw/lodsl */
+        instr->instr = INSTR_LODS;
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
         return DECODE_success;
 
@@ -906,6 +945,17 @@ void handle_mmio(unsigned long va, unsig
                       GET_REPEAT_COUNT(), mmio_inst.op_size, regs->eax, 
IOREQ_WRITE, 0);
         break;
 
+    case INSTR_LODS:
+        /*
+         * Since the source is always in (contiguous) mmio space we don't
+         * need to break it up into pages.
+         */
+        mmio_opp->flags = mmio_inst.flags;
+        mmio_opp->instr = mmio_inst.instr;
+        send_mmio_req(IOREQ_TYPE_COPY, gpa,
+                      GET_REPEAT_COUNT(), mmio_inst.op_size, 0, IOREQ_READ, 0);
+        break;
+
     case INSTR_OR:
         mmio_operands(IOREQ_TYPE_OR, gpa, &mmio_inst, mmio_opp, regs);
         break;
@@ -954,26 +1004,26 @@ void handle_mmio(unsigned long va, unsig
         mmio_opp->instr = mmio_inst.instr;
         mmio_opp->operand[0] = mmio_inst.operand[0]; /* source */
         mmio_opp->operand[1] = mmio_inst.operand[1]; /* destination */
-       if (mmio_inst.operand[0] & REGISTER) {
-               long value;
-               unsigned long operand = mmio_inst.operand[0];
-               value = get_reg_value(operand_size(operand), 
-                                     operand_index(operand), 0,
-                                     mmio_opp->inst_decoder_regs);
-               /* send the request and wait for the value */
-               send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
-                      mmio_inst.op_size, value, IOREQ_WRITE, 0);
-       } else {
-               /* the destination is a register */
-               long value;
-               unsigned long operand = mmio_inst.operand[1];
-               value = get_reg_value(operand_size(operand), 
-                                     operand_index(operand), 0,
-                                     mmio_opp->inst_decoder_regs);
-               /* send the request and wait for the value */
-               send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
-                      mmio_inst.op_size, value, IOREQ_WRITE, 0);
-       }
+        if ( mmio_inst.operand[0] & REGISTER ) {
+            long value;
+            unsigned long operand = mmio_inst.operand[0];
+            value = get_reg_value(operand_size(operand),
+                                  operand_index(operand), 0,
+                                  mmio_opp->inst_decoder_regs);
+            /* send the request and wait for the value */
+            send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
+                          mmio_inst.op_size, value, IOREQ_WRITE, 0);
+        } else {
+            /* the destination is a register */
+            long value;
+            unsigned long operand = mmio_inst.operand[1];
+            value = get_reg_value(operand_size(operand),
+                                  operand_index(operand), 0,
+                                  mmio_opp->inst_decoder_regs);
+            /* send the request and wait for the value */
+            send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
+                          mmio_inst.op_size, value, IOREQ_WRITE, 0);
+        }
         break;
 
     default:
diff -r 11a431a8b3d9 -r 05f07acd3be2 xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h      Wed Jun 07 14:17:26 2006 +0100
+++ b/xen/include/asm-x86/hvm/io.h      Wed Jun 07 14:24:14 2006 +0100
@@ -64,9 +64,10 @@
 #define INSTR_MOVZX 8
 #define INSTR_MOVSX 9
 #define INSTR_STOS  10
-#define INSTR_TEST  11
-#define INSTR_BT    12
-#define INSTR_XCHG  13
+#define INSTR_LODS  11
+#define INSTR_TEST  12
+#define INSTR_BT    13
+#define INSTR_XCHG  14
 
 struct instruction {
     __s8    instr;        /* instruction type */

_______________________________________________
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®.