# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1169742739 0
# Node ID fec1a697558853ffc61e1d8047a5dc2fa965e6a8
# Parent 21b9416d2215bb6241ccb20957a2428eb1bbaa07
emulator: Emulate IN/OUT/INS/OUTS. Fix CLTS.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/x86_emulate.c | 72 ++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 68 insertions(+), 4 deletions(-)
diff -r 21b9416d2215 -r fec1a6975588 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Thu Jan 25 15:25:06 2007 +0000
+++ b/xen/arch/x86/x86_emulate.c Thu Jan 25 16:32:19 2007 +0000
@@ -105,7 +105,7 @@ static uint8_t opcode_table[256] = {
/* 0x68 - 0x6F */
ImplicitOps|Mov, DstMem|SrcImm|ModRM|Mov,
ImplicitOps|Mov, DstMem|SrcImmByte|ModRM|Mov,
- 0, 0, 0, 0,
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
/* 0x70 - 0x77 */
ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
@@ -155,9 +155,11 @@ static uint8_t opcode_table[256] = {
/* 0xD8 - 0xDF */
0, 0, 0, 0, 0, 0, 0, 0,
/* 0xE0 - 0xE7 */
- ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 0, 0, 0, 0,
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
/* 0xE8 - 0xEF */
- ImplicitOps, ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0,
+ ImplicitOps, ImplicitOps, 0, ImplicitOps,
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
/* 0xF0 - 0xF7 */
0, 0, 0, 0,
0, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM,
@@ -1724,6 +1726,34 @@ x86_emulate(
dst.mem.off = sp_pre_dec(dst.bytes);
break;
+ case 0x6c ... 0x6d: /* ins %dx,%es:%edi */
+ generate_exception_if(!mode_iopl(), EXC_GP);
+ dst.type = OP_MEM;
+ dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
+ dst.mem.seg = x86_seg_es;
+ dst.mem.off = truncate_ea(_regs.edi);
+ fail_if(ops->read_io == NULL);
+ if ( (rc = ops->read_io((uint16_t)_regs.edx, dst.bytes,
+ &dst.val, ctxt)) != 0 )
+ goto done;
+ register_address_increment(
+ _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
+ break;
+
+ case 0x6e ... 0x6f: /* outs %esi,%dx */
+ generate_exception_if(!mode_iopl(), EXC_GP);
+ dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
+ if ( (rc = ops->read(ea.mem.seg, truncate_ea(_regs.esi),
+ &dst.val, dst.bytes, ctxt)) != 0 )
+ goto done;
+ fail_if(ops->write_io == NULL);
+ if ( (rc = ops->write_io((uint16_t)_regs.edx, dst.bytes,
+ dst.val, ctxt)) != 0 )
+ goto done;
+ register_address_increment(
+ _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
+ break;
+
case 0x70 ... 0x7f: /* jcc (short) */ {
int rel = insn_fetch_type(int8_t);
if ( test_cc(b, _regs.eflags) )
@@ -1914,6 +1944,40 @@ x86_emulate(
break;
}
+ case 0xe4: /* in imm8,%al */
+ case 0xe5: /* in imm8,%eax */
+ case 0xe6: /* out %al,imm8 */
+ case 0xe7: /* out %eax,imm8 */
+ case 0xec: /* in %dx,%al */
+ case 0xed: /* in %dx,%eax */
+ case 0xee: /* out %al,%dx */
+ case 0xef: /* out %eax,%dx */ {
+ unsigned int port = ((b < 0xe8)
+ ? insn_fetch_type(uint8_t)
+ : (uint16_t)_regs.edx);
+ generate_exception_if(!mode_iopl(), EXC_GP);
+ op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
+ if ( b & 2 )
+ {
+ /* out */
+ fail_if(ops->write_io == NULL);
+ rc = ops->write_io(port, op_bytes, _regs.eax, ctxt);
+
+ }
+ else
+ {
+ /* in */
+ dst.type = OP_REG;
+ dst.bytes = op_bytes;
+ dst.reg = (unsigned long *)&_regs.eax;
+ fail_if(ops->read_io == NULL);
+ rc = ops->read_io(port, dst.bytes, &dst.val, ctxt);
+ }
+ if ( rc != 0 )
+ goto done;
+ break;
+ }
+
case 0xe8: /* call (near) */ {
int rel = (((op_bytes == 2) && !mode_64bit())
? (int32_t)insn_fetch_type(int16_t)
@@ -2122,7 +2186,7 @@ x86_emulate(
generate_exception_if(!mode_ring0(), EXC_GP);
fail_if((ops->read_cr == NULL) || (ops->write_cr == NULL));
if ( (rc = ops->read_cr(0, &dst.val, ctxt)) ||
- (rc = ops->write_cr(0, dst.val|8, ctxt)) )
+ (rc = ops->write_cr(0, dst.val&~8, ctxt)) )
goto done;
break;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|