debuggers.hg
changeset 13648:fec1a6975588
emulator: Emulate IN/OUT/INS/OUTS. Fix CLTS.
Signed-off-by: Keir Fraser <keir@xensource.com>
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