Overview   API Reference  

io_page_fault.hpp

00001 #if !defined(__IO_PAGE_FAULT_HPP__)
00002 #define __IO_PAGE_FAULT_HPP__
00003 
00004 //
00005 // local includes
00006 //
00007 #include "core/machine/arch/x86/emulation/in_out.hpp"
00008 
00009 //
00010 // handle all x86 I/O space instructions
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     // decode prefixes: can be REP,OPSIZE as well as OPSIZE,REP
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     // emulate instruction
00027     //
00028     int err=0;
00029     switch (ctx.opcode<uint8_t>(ins_size++)) {
00030         case 0xe4:      // inb i8, al
00031             err=x86_in<uint8_t>(*this, ctx, ctx.opcode<uint8_t>(ins_size++));
00032             break;
00033         case 0xe5:      // in{w,l} i8, {e}ax
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:      // inb dx, al
00038             err=x86_in<uint8_t>(*this, ctx, ctx.edx() & 0xffff);
00039             break;
00040         case 0xed:      // in{w,l} dx, {e}ax
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:      // outb al, i8
00046             err=x86_out<uint8_t>(*this, ctx, ctx.opcode<uint8_t>(ins_size++));
00047             break;
00048         case 0xe7:      // out{w,l} {e}ax, i8
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:      // outb al, dx
00053             err=x86_out<uint8_t>(*this, ctx, ctx.edx() & 0xffff);
00054             break;
00055         case 0xef:      // out{w,l} {e}ax, dx
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:      // insb
00061             err=x86_ins<uint8_t>(*this, ctx, rep);
00062             break;
00063         case 0x6d:      // ins{w,l}
00064             err=(opsize) ? x86_ins<uint16_t>(*this, ctx, rep) :
00065                            x86_ins<uint32_t>(*this, ctx, rep);
00066             break;
00067 
00068         case 0x6e:      // outsb
00069             err=x86_outs<uint8_t>(*this, ctx, rep);
00070             break;
00071         case 0x6f:      // outs{w,l}
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     // skip instruction
00084     ctx.ip()+=ins_size;
00085     return 0;
00086 }
00087 
00088 #endif
00089 
00090 // ***** end of source ***** //
00091 

L4vmm Reference Manual, written by Mario Schwalbe  © 2006-2008