# 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
|