io_page_fault.hpp
00001 #if !defined(__IO_PAGE_FAULT_HPP__)
00002 #define __IO_PAGE_FAULT_HPP__
00003
00004
00005
00006
00007 #include "core/machine/arch/x86/emulation/in_out.hpp"
00008
00009
00010
00011
00012 inline int x86_machine::handle_io_page_fault(x86_context &ctx)
00013 {
00014 logd(L4VMM_DEBUG_X86 >= 2, L4VMM_DEBUG": emulating I/O space instruction at "l4_gva_fmt"\n", ctx.ip());
00015
00016
00017
00018
00019 bool rep=false, opsize=false;
00020 uint8_t ins_size=0;
00021 if (ctx.opcode<uint8_t>(ins_size) == 0x66) ins_size++, opsize=true;
00022 if (ctx.opcode<uint8_t>(ins_size) == 0xf3) ins_size++, rep=true;
00023 if (ctx.opcode<uint8_t>(ins_size) == 0x66) ins_size++, opsize=true;
00024
00025
00026
00027
00028 int err=0;
00029 switch (ctx.opcode<uint8_t>(ins_size++)) {
00030 case 0xe4:
00031 err=x86_in<uint8_t>(*this, ctx, ctx.opcode<uint8_t>(ins_size++));
00032 break;
00033 case 0xe5:
00034 err=(opsize) ? x86_in<uint16_t>(*this, ctx, ctx.opcode<uint8_t>(ins_size++)) :
00035 x86_in<uint32_t>(*this, ctx, ctx.opcode<uint8_t>(ins_size++));
00036 break;
00037 case 0xec:
00038 err=x86_in<uint8_t>(*this, ctx, ctx.edx() & 0xffff);
00039 break;
00040 case 0xed:
00041 err=(opsize) ? x86_in<uint16_t>(*this, ctx, ctx.edx() & 0xffff) :
00042 x86_in<uint32_t>(*this, ctx, ctx.edx() & 0xffff);
00043 break;
00044
00045 case 0xe6:
00046 err=x86_out<uint8_t>(*this, ctx, ctx.opcode<uint8_t>(ins_size++));
00047 break;
00048 case 0xe7:
00049 err=(opsize) ? x86_out<uint16_t>(*this, ctx, ctx.opcode<uint8_t>(ins_size++)) :
00050 x86_out<uint32_t>(*this, ctx, ctx.opcode<uint8_t>(ins_size++));
00051 break;
00052 case 0xee:
00053 err=x86_out<uint8_t>(*this, ctx, ctx.edx() & 0xffff);
00054 break;
00055 case 0xef:
00056 err=(opsize) ? x86_out<uint16_t>(*this, ctx, ctx.edx() & 0xffff) :
00057 x86_out<uint32_t>(*this, ctx, ctx.edx() & 0xffff);
00058 break;
00059
00060 case 0x6c:
00061 err=x86_ins<uint8_t>(*this, ctx, rep);
00062 break;
00063 case 0x6d:
00064 err=(opsize) ? x86_ins<uint16_t>(*this, ctx, rep) :
00065 x86_ins<uint32_t>(*this, ctx, rep);
00066 break;
00067
00068 case 0x6e:
00069 err=x86_outs<uint8_t>(*this, ctx, rep);
00070 break;
00071 case 0x6f:
00072 err=(opsize) ? x86_outs<uint16_t>(*this, ctx, rep) :
00073 x86_outs<uint32_t>(*this, ctx, rep);
00074 break;
00075
00076 default:
00077 log::error("bad instruction at "l4_gva_fmt"\n"
00078 " expected in/out or ins/outs\n", ctx.ip());
00079 return -L4_ENOTSUPP;
00080 }
00081
00082 if (err) return err;
00083
00084 ctx.ip()+=ins_size;
00085 return 0;
00086 }
00087
00088 #endif
00089
00090
00091