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