[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] emulator: Emulate IN/OUT/INS/OUTS. Fix CLTS.



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.