[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM][MMIO] Emulate more instructions: or/and/xor with byte width,
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 7d37df6c324721647d5d6c930af09101f1165e23 # Parent 2fd2fd4b7c6a93e80b107dab9241d5790ba12f6f [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/arch/x86/hvm/io.c | 7 +++ xen/arch/x86/hvm/platform.c | 79 ++++++++++++++++++++++++++++++++----------- xen/include/asm-x86/hvm/io.h | 7 ++- 3 files changed, 70 insertions(+), 23 deletions(-) diff -r 2fd2fd4b7c6a -r 7d37df6c3247 xen/arch/x86/hvm/io.c --- a/xen/arch/x86/hvm/io.c Wed Jun 07 14:13:22 2006 +0100 +++ b/xen/arch/x86/hvm/io.c Wed Jun 07 14:20:29 2006 +0100 @@ -507,6 +507,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 2fd2fd4b7c6a -r 7d37df6c3247 xen/arch/x86/hvm/platform.c --- a/xen/arch/x86/hvm/platform.c Wed Jun 07 14:13:22 2006 +0100 +++ b/xen/arch/x86/hvm/platform.c Wed Jun 07 14:20:29 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); @@ -395,6 +407,12 @@ static int hvm_decode(int realmode, unsi instr->instr = INSTR_XOR; 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; @@ -513,6 +531,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 +934,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 +993,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 2fd2fd4b7c6a -r 7d37df6c3247 xen/include/asm-x86/hvm/io.h --- a/xen/include/asm-x86/hvm/io.h Wed Jun 07 14:13:22 2006 +0100 +++ b/xen/include/asm-x86/hvm/io.h Wed Jun 07 14:20:29 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |