[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |