From: kfraser@localhost.localdomain Date: Tue, 31 Oct 2006 16:22:39 +0000 (+0000) Subject: [HVM] Add support for 'add r8,m8' instruction to memory-mapped I/O. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15567^2~162 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=342c7011f6dc7a04505846638f4dafcd50f533df;p=xen.git [HVM] Add support for 'add r8,m8' instruction to memory-mapped I/O. Signed-off-by: Kevin Tronkowski Signed-off-by: Ben Thomas --- diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c index 83fc5e8f00..22ea8b56e3 100644 --- a/tools/ioemu/target-i386-dm/helper2.c +++ b/tools/ioemu/target-i386-dm/helper2.c @@ -393,6 +393,21 @@ void cpu_ioreq_and(CPUState *env, ioreq_t *req) req->u.data = tmp1; } +void cpu_ioreq_add(CPUState *env, ioreq_t *req) +{ + unsigned long tmp1, tmp2; + + if (req->pdata_valid != 0) + hw_error("expected scalar value"); + + read_physical(req->addr, req->size, &tmp1); + if (req->dir == IOREQ_WRITE) { + tmp2 = tmp1 + (unsigned long) req->u.data; + write_physical(req->addr, req->size, &tmp2); + } + req->u.data = tmp1; +} + void cpu_ioreq_or(CPUState *env, ioreq_t *req) { unsigned long tmp1, tmp2; @@ -438,6 +453,9 @@ void __handle_ioreq(CPUState *env, ioreq_t *req) case IOREQ_TYPE_AND: cpu_ioreq_and(env, req); break; + case IOREQ_TYPE_ADD: + cpu_ioreq_add(env, req); + break; case IOREQ_TYPE_OR: cpu_ioreq_or(env, req); break; diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c index ea6f73a51d..8c20d9f23c 100644 --- a/xen/arch/x86/hvm/intercept.c +++ b/xen/arch/x86/hvm/intercept.c @@ -109,6 +109,15 @@ static inline void hvm_mmio_access(struct vcpu *v, p->u.data = tmp1; break; + case IOREQ_TYPE_ADD: + tmp1 = read_handler(v, p->addr, p->size); + if (p->dir == IOREQ_WRITE) { + tmp2 = tmp1 + (unsigned long) p->u.data; + write_handler(v, p->addr, p->size, tmp2); + } + p->u.data = tmp1; + break; + case IOREQ_TYPE_OR: tmp1 = read_handler(v, p->addr, p->size); if ( p->dir == IOREQ_WRITE ) { diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c index 28f06e66a0..8bf9afc470 100644 --- a/xen/arch/x86/hvm/io.c +++ b/xen/arch/x86/hvm/io.c @@ -532,6 +532,21 @@ static void hvm_mmio_assist(struct cpu_user_regs *regs, ioreq_t *p, set_reg_value(size, index, 0, regs, diff); } + case INSTR_ADD: + if (src & REGISTER) { + index = operand_index(src); + value = get_reg_value(size, index, 0, regs); + diff = (unsigned long) p->u.data + value; + } else if (src & IMMEDIATE) { + value = mmio_opp->immediate; + diff = (unsigned long) p->u.data + value; + } else if (src & MEMORY) { + index = operand_index(dst); + value = get_reg_value(size, index, 0, regs); + diff = (unsigned long) p->u.data + value; + set_reg_value(size, index, 0, regs, diff); + } + /* * The OF and CF flags are cleared; the SF, ZF, and PF * flags are set according to the result. The state of diff --git a/xen/arch/x86/hvm/platform.c b/xen/arch/x86/hvm/platform.c index 21b757be46..e26b3e96d0 100644 --- a/xen/arch/x86/hvm/platform.c +++ b/xen/arch/x86/hvm/platform.c @@ -370,6 +370,13 @@ static int hvm_decode(int realmode, unsigned char *opcode, /* the operands order in comments conforms to AT&T convention */ switch ( *opcode ) { + + case 0x00: /* add r8, m8 */ + mmio_op->instr = INSTR_ADD; + *op_size = BYTE; + GET_OP_SIZE_FOR_BYTE(size_reg); + return reg_mem(size_reg, opcode, mmio_op, rex); + case 0x0A: /* or m8, r8 */ mmio_op->instr = INSTR_OR; *op_size = BYTE; @@ -1040,6 +1047,10 @@ void handle_mmio(unsigned long gpa) mmio_operands(IOREQ_TYPE_AND, gpa, mmio_op, op_size); break; + case INSTR_ADD: + mmio_operands(IOREQ_TYPE_ADD, gpa, mmio_op, op_size); + break; + case INSTR_XOR: mmio_operands(IOREQ_TYPE_XOR, gpa, mmio_op, op_size); break; diff --git a/xen/include/asm-x86/hvm/io.h b/xen/include/asm-x86/hvm/io.h index 2e35ef79d9..98441ee260 100644 --- a/xen/include/asm-x86/hvm/io.h +++ b/xen/include/asm-x86/hvm/io.h @@ -64,6 +64,7 @@ #define INSTR_BT 13 #define INSTR_XCHG 14 #define INSTR_SUB 15 +#define INSTR_ADD 16 #define MAX_INST_LEN 15 /* Maximum instruction length = 15 bytes */ diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h index 992505e1c5..b7f68c1282 100644 --- a/xen/include/public/hvm/ioreq.h +++ b/xen/include/public/hvm/ioreq.h @@ -34,6 +34,7 @@ #define IOREQ_TYPE_OR 3 #define IOREQ_TYPE_XOR 4 #define IOREQ_TYPE_XCHG 5 +#define IOREQ_TYPE_ADD 6 /* * VMExit dispatcher should cooperate with instruction decoder to