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

[Xen-changelog] add BT instruction support to VMX MMIO decoder.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 5487b11faafa6ef6782088ccb33ddce7c5d69c4f
# Parent  768b04d09dde761432186fbfd8c3fa02c826e2f0
add BT instruction support to VMX MMIO decoder.
Also extends TEST and OR instructions support for 16/32 bit operations,
these are needed for windows.

Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx>
Signed-off-by: Chengyuan Li <chengyuan.li@xxxxxxxxx>
Signed-off-by: Nakajima Jun <nakajima.jun@xxxxxxxxx>

diff -r 768b04d09dde -r 5487b11faafa xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c     Fri Oct 14 23:20:35 2005
+++ b/xen/arch/x86/vmx_io.c     Sat Oct 15 06:43:08 2005
@@ -624,6 +624,17 @@
         set_eflags_SF(size, diff, regs);
         set_eflags_PF(size, diff, regs);
         break;
+
+    case INSTR_BT:
+        index = operand_index(src);
+        value = get_reg_value(size, index, 0, regs);
+
+        if (p->u.data & (1 << (value & ((1 << 5) - 1))))
+            regs->eflags |= X86_EFLAGS_CF;
+        else
+            regs->eflags &= ~X86_EFLAGS_CF;
+
+        break;
     }
 
     load_cpu_user_regs(regs);
diff -r 768b04d09dde -r 5487b11faafa xen/arch/x86/vmx_platform.c
--- a/xen/arch/x86/vmx_platform.c       Fri Oct 14 23:20:35 2005
+++ b/xen/arch/x86/vmx_platform.c       Sat Oct 15 06:43:08 2005
@@ -371,7 +371,7 @@
     unsigned long eflags;
     int index, vm86 = 0;
     unsigned char rex = 0;
-    unsigned char tmp_size = 0;
+    unsigned char size_reg = 0;
 
     init_instruction(instr);
 
@@ -428,33 +428,47 @@
 
     case 0x80:
     case 0x81:
-        if (((opcode[1] >> 3) & 7) == 7) { /* cmp $imm, m32/16 */
-            instr->instr = INSTR_CMP;
-
-            if (opcode[0] == 0x80)
-                GET_OP_SIZE_FOR_BYTE(instr->op_size);
-            else
+        {
+            unsigned char ins_subtype = (opcode[1] >> 3) & 7;
+
+            if (opcode[0] == 0x80) {
+                GET_OP_SIZE_FOR_BYTE(size_reg);
+                instr->op_size = BYTE;
+            } else {
                 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
-
-            instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
-            instr->immediate = get_immediate(vm86, opcode+1, BYTE);
-            instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
-
-            return DECODE_success;
-        } else
-            return DECODE_failure;
+                size_reg = instr->op_size;
+            }
+
+            instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
+            instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
+            instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
+
+            switch (ins_subtype) {
+                case 7: /* cmp $imm, m32/16 */
+                    instr->instr = INSTR_CMP;
+                    return DECODE_success;
+
+                case 1: /* or $imm, m32/16 */
+                    instr->instr = INSTR_OR;
+                    return DECODE_success;
+
+                default:
+                    printf("%x, This opcode isn't handled yet!\n", *opcode);
+                    return DECODE_failure;
+            }
+        }
 
     case 0x84:  /* test m8, r8 */
         instr->instr = INSTR_TEST;
         instr->op_size = BYTE;
-        GET_OP_SIZE_FOR_BYTE(tmp_size);
-        return mem_reg(tmp_size, opcode, instr, rex);
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return mem_reg(size_reg, opcode, instr, rex);
 
     case 0x88: /* mov r8, m8 */
         instr->instr = INSTR_MOV;
         instr->op_size = BYTE;
-        GET_OP_SIZE_FOR_BYTE(tmp_size);
-        return reg_mem(tmp_size, opcode, instr, rex);
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return reg_mem(size_reg, opcode, instr, rex);
 
     case 0x89: /* mov r32/16, m32/16 */
         instr->instr = INSTR_MOV;
@@ -464,8 +478,8 @@
     case 0x8A: /* mov m8, r8 */
         instr->instr = INSTR_MOV;
         instr->op_size = BYTE;
-        GET_OP_SIZE_FOR_BYTE(tmp_size);
-        return mem_reg(tmp_size, opcode, instr, rex);
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return mem_reg(size_reg, opcode, instr, rex);
 
     case 0x8B: /* mov m32/16, r32/16 */
         instr->instr = INSTR_MOV;
@@ -475,8 +489,8 @@
     case 0xA0: /* mov <addr>, al */
         instr->instr = INSTR_MOV;
         instr->op_size = BYTE;
-        GET_OP_SIZE_FOR_BYTE(tmp_size);
-        return mem_acc(tmp_size, instr);
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return mem_acc(size_reg, instr);
 
     case 0xA1: /* mov <addr>, ax/eax */
         instr->instr = INSTR_MOV;
@@ -486,8 +500,8 @@
     case 0xA2: /* mov al, <addr> */
         instr->instr = INSTR_MOV;
         instr->op_size = BYTE;
-        GET_OP_SIZE_FOR_BYTE(tmp_size);
-        return acc_mem(tmp_size, instr);
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return acc_mem(size_reg, instr);
 
     case 0xA3: /* mov ax/eax, <addr> */
         instr->instr = INSTR_MOV;
@@ -541,13 +555,21 @@
             return DECODE_failure;
 
     case 0xF6:
-        if (((opcode[1] >> 3) & 7) == 0) { /* testb $imm8, m8 */
+    case 0xF7:
+        if (((opcode[1] >> 3) & 7) == 0) { /* test $imm8/16/32, m8/16/32 */
             instr->instr = INSTR_TEST;
-            instr->op_size = BYTE;
-
-            instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
+
+            if (opcode[0] == 0xF6) {
+                GET_OP_SIZE_FOR_BYTE(size_reg);
+                instr->op_size = BYTE;
+            } else {
+                GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+                size_reg = instr->op_size;
+            }
+
+            instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
             instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
-            instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
+            instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
 
             return DECODE_success;
         } else
@@ -581,6 +603,14 @@
             instr->operand[1] = mk_operand(LONG, index, 0, REGISTER);
         }
         instr->operand[0] = mk_operand(instr->op_size, 0, 0, MEMORY);
+        return DECODE_success;
+
+    case 0xA3: /* bt r32, m32 */
+        instr->instr = INSTR_BT;
+        index = get_index(opcode + 1, rex);
+        instr->op_size = LONG;
+        instr->operand[0] = mk_operand(instr->op_size, index, 0, REGISTER);
+        instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
         return DECODE_success;
 
     default:
@@ -843,8 +873,27 @@
         mmio_opp->immediate = mmio_inst.immediate;
 
         /* send the request and wait for the value */
-        send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, mmio_inst.op_size, 0, 
IOREQ_READ, 0);
-        break;
+        send_mmio_req(IOREQ_TYPE_COPY, gpa, 1,
+                      mmio_inst.op_size, 0, IOREQ_READ, 0);
+        break;
+
+    case INSTR_BT:
+        {
+            unsigned long value = 0;
+            int index, size;
+
+            mmio_opp->instr = mmio_inst.instr;
+            mmio_opp->operand[0] = mmio_inst.operand[0]; /* bit offset */
+            mmio_opp->operand[1] = mmio_inst.operand[1]; /* bit base */
+
+            index = operand_index(mmio_inst.operand[0]);
+            size = operand_size(mmio_inst.operand[0]);
+            value = get_reg_value(size, index, 0, regs);
+
+            send_mmio_req(IOREQ_TYPE_COPY, gpa + (value >> 5), 1,
+                          mmio_inst.op_size, 0, IOREQ_READ, 0);
+            break;
+        }
 
     default:
         printf("Unhandled MMIO instruction\n");
diff -r 768b04d09dde -r 5487b11faafa xen/include/asm-x86/vmx_platform.h
--- a/xen/include/asm-x86/vmx_platform.h        Fri Oct 14 23:20:35 2005
+++ b/xen/include/asm-x86/vmx_platform.h        Sat Oct 15 06:43:08 2005
@@ -27,8 +27,8 @@
 
 #define MAX_OPERAND_NUM 2
 
-#define mk_operand(size, index, seg, flag) \
-    (((size) << 24) | ((index) << 16) | ((seg) << 8) | (flag))
+#define mk_operand(size_reg, index, seg, flag) \
+    (((size_reg) << 24) | ((index) << 16) | ((seg) << 8) | (flag))
 
 #define operand_size(operand)   \
       ((operand >> 24) & 0xFF)
@@ -63,6 +63,7 @@
 #define INSTR_MOVZ 8
 #define INSTR_STOS 9
 #define INSTR_TEST 10
+#define INSTR_BT 11
 
 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®.