ia64/xen-unstable

changeset 13624:fec1a6975588

emulator: Emulate IN/OUT/INS/OUTS. Fix CLTS.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Jan 25 16:32:19 2007 +0000 (2007-01-25)
parents 21b9416d2215
children e19f9d6a2ff5
files xen/arch/x86/x86_emulate.c
line diff
     1.1 --- a/xen/arch/x86/x86_emulate.c	Thu Jan 25 15:25:06 2007 +0000
     1.2 +++ b/xen/arch/x86/x86_emulate.c	Thu Jan 25 16:32:19 2007 +0000
     1.3 @@ -105,7 +105,7 @@ static uint8_t opcode_table[256] = {
     1.4      /* 0x68 - 0x6F */
     1.5      ImplicitOps|Mov, DstMem|SrcImm|ModRM|Mov,
     1.6      ImplicitOps|Mov, DstMem|SrcImmByte|ModRM|Mov,
     1.7 -    0, 0, 0, 0,
     1.8 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
     1.9      /* 0x70 - 0x77 */
    1.10      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
    1.11      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
    1.12 @@ -155,9 +155,11 @@ static uint8_t opcode_table[256] = {
    1.13      /* 0xD8 - 0xDF */
    1.14      0, 0, 0, 0, 0, 0, 0, 0,
    1.15      /* 0xE0 - 0xE7 */
    1.16 -    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 0, 0, 0, 0,
    1.17 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
    1.18 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
    1.19      /* 0xE8 - 0xEF */
    1.20 -    ImplicitOps, ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0,
    1.21 +    ImplicitOps, ImplicitOps, 0, ImplicitOps,
    1.22 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
    1.23      /* 0xF0 - 0xF7 */
    1.24      0, 0, 0, 0,
    1.25      0, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM,
    1.26 @@ -1724,6 +1726,34 @@ x86_emulate(
    1.27          dst.mem.off = sp_pre_dec(dst.bytes);
    1.28          break;
    1.29  
    1.30 +    case 0x6c ... 0x6d: /* ins %dx,%es:%edi */
    1.31 +        generate_exception_if(!mode_iopl(), EXC_GP);
    1.32 +        dst.type  = OP_MEM;
    1.33 +        dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
    1.34 +        dst.mem.seg = x86_seg_es;
    1.35 +        dst.mem.off = truncate_ea(_regs.edi);
    1.36 +        fail_if(ops->read_io == NULL);
    1.37 +        if ( (rc = ops->read_io((uint16_t)_regs.edx, dst.bytes,
    1.38 +                                &dst.val, ctxt)) != 0 )
    1.39 +            goto done;
    1.40 +        register_address_increment(
    1.41 +            _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
    1.42 +        break;
    1.43 +
    1.44 +    case 0x6e ... 0x6f: /* outs %esi,%dx */
    1.45 +        generate_exception_if(!mode_iopl(), EXC_GP);
    1.46 +        dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
    1.47 +        if ( (rc = ops->read(ea.mem.seg, truncate_ea(_regs.esi),
    1.48 +                             &dst.val, dst.bytes, ctxt)) != 0 )
    1.49 +            goto done;
    1.50 +        fail_if(ops->write_io == NULL);
    1.51 +        if ( (rc = ops->write_io((uint16_t)_regs.edx, dst.bytes,
    1.52 +                                 dst.val, ctxt)) != 0 )
    1.53 +            goto done;
    1.54 +        register_address_increment(
    1.55 +            _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
    1.56 +        break;
    1.57 +
    1.58      case 0x70 ... 0x7f: /* jcc (short) */ {
    1.59          int rel = insn_fetch_type(int8_t);
    1.60          if ( test_cc(b, _regs.eflags) )
    1.61 @@ -1914,6 +1944,40 @@ x86_emulate(
    1.62          break;
    1.63      }
    1.64  
    1.65 +    case 0xe4: /* in imm8,%al */
    1.66 +    case 0xe5: /* in imm8,%eax */
    1.67 +    case 0xe6: /* out %al,imm8 */
    1.68 +    case 0xe7: /* out %eax,imm8 */
    1.69 +    case 0xec: /* in %dx,%al */
    1.70 +    case 0xed: /* in %dx,%eax */
    1.71 +    case 0xee: /* out %al,%dx */
    1.72 +    case 0xef: /* out %eax,%dx */ {
    1.73 +        unsigned int port = ((b < 0xe8)
    1.74 +                             ? insn_fetch_type(uint8_t)
    1.75 +                             : (uint16_t)_regs.edx);
    1.76 +        generate_exception_if(!mode_iopl(), EXC_GP);
    1.77 +        op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
    1.78 +        if ( b & 2 )
    1.79 +        {
    1.80 +            /* out */
    1.81 +            fail_if(ops->write_io == NULL);
    1.82 +            rc = ops->write_io(port, op_bytes, _regs.eax, ctxt);
    1.83 +            
    1.84 +        }
    1.85 +        else
    1.86 +        {
    1.87 +            /* in */
    1.88 +            dst.type  = OP_REG;
    1.89 +            dst.bytes = op_bytes;
    1.90 +            dst.reg   = (unsigned long *)&_regs.eax;
    1.91 +            fail_if(ops->read_io == NULL);
    1.92 +            rc = ops->read_io(port, dst.bytes, &dst.val, ctxt);
    1.93 +        }
    1.94 +        if ( rc != 0 )
    1.95 +            goto done;
    1.96 +        break;
    1.97 +    }
    1.98 +
    1.99      case 0xe8: /* call (near) */ {
   1.100          int rel = (((op_bytes == 2) && !mode_64bit())
   1.101                     ? (int32_t)insn_fetch_type(int16_t)
   1.102 @@ -2122,7 +2186,7 @@ x86_emulate(
   1.103          generate_exception_if(!mode_ring0(), EXC_GP);
   1.104          fail_if((ops->read_cr == NULL) || (ops->write_cr == NULL));
   1.105          if ( (rc = ops->read_cr(0, &dst.val, ctxt)) ||
   1.106 -             (rc = ops->write_cr(0, dst.val|8, ctxt)) )
   1.107 +             (rc = ops->write_cr(0, dst.val&~8, ctxt)) )
   1.108              goto done;
   1.109          break;
   1.110