#include #include #include "vm86_struct.h" #define INT2PTR(a) ((a) + (unsigned char *) 0) #include "../x86emu/include/x86emu.h" #include "AsmMacros.h" int emu_vm86_ret; static u8 Mem_rb(u32 addr) { return *(u8 *)(INT2PTR(addr)); } static void Mem_wb(u32 addr, u8 val) { *(u8 *)INT2PTR(addr) = val; } #ifdef __ia64__ static u16 Mem_rw(u32 addr) { return *(u8 *)INT2PTR(addr) | *(u8 *)INT2PTR(addr + 1) << 8; } static u32 Mem_rl(u32 addr) { return *(u8 *)INT2PTR(addr) | *(u8 *)INT2PTR(addr + 1) << 8 | *(u8 *)INT2PTR(addr + 2) << 16 | *(u8 *)INT2PTR(addr + 3) << 24; } static void Mem_ww(u32 addr, u16 val) { *(u8 *)INT2PTR(addr) = val; *(u8 *)INT2PTR(addr + 1) = val >> 8; } static void Mem_wl(u32 addr, u32 val) { *(u8 *)INT2PTR(addr) = val; *(u8 *)INT2PTR(addr + 1) = val >> 8; *(u8 *)INT2PTR(addr + 2) = val >> 16; *(u8 *)INT2PTR(addr + 3) = val >> 24; } #else static u16 Mem_rw(u32 addr) { return *(u16 *)INT2PTR(addr); } static u32 Mem_rl(u32 addr) { return *(u32 *)INT2PTR(addr); } static void Mem_ww(u32 addr, u16 val) { *(u16 *)INT2PTR(addr) = val; } static void Mem_wl(u32 addr, u32 val) { *(u32 *)INT2PTR(addr) = val; } #endif static void do_int(int num) { emu_vm86_ret = VM86_INTx | (num << 8); M.x86.intr = INTR_HALTED; } int emu_vm86(struct vm86_struct *vm) { int i; X86EMU_memFuncs memFuncs; X86EMU_intrFuncs intFuncs[256]; X86EMU_pioFuncs pioFuncs; memFuncs.rdb = Mem_rb; memFuncs.rdw = Mem_rw; memFuncs.rdl = Mem_rl; memFuncs.wrb = Mem_wb; memFuncs.wrw = Mem_ww; memFuncs.wrl = Mem_wl; X86EMU_setupMemFuncs(&memFuncs); pioFuncs.inb = (u8(*)(u16))inb; pioFuncs.inw = (u16(*)(u16))inw; pioFuncs.inl = (u32(*)(u16))inl; pioFuncs.outb = (void(*)(u16, u8))outb; pioFuncs.outw = (void(*)(u16, u16))outw; pioFuncs.outl = (void(*)(u16, u32))outl; X86EMU_setupPioFuncs(&pioFuncs); for (i=0;i<256;i++) intFuncs[i] = do_int; X86EMU_setupIntrFuncs(intFuncs); M.mem_base = 0; M.mem_size = 1024*1024 + 1024; M.x86.R_EAX = vm->regs.eax; M.x86.R_EBX = vm->regs.ebx; M.x86.R_ECX = vm->regs.ecx; M.x86.R_EDX = vm->regs.edx; M.x86.R_ESP = vm->regs.esp; M.x86.R_EBP = vm->regs.ebp; M.x86.R_ESI = vm->regs.esi; M.x86.R_EDI = vm->regs.edi; M.x86.R_EIP = vm->regs.eip; M.x86.R_EFLG = vm->regs.eflags; M.x86.R_CS = vm->regs.cs; M.x86.R_DS = vm->regs.ds; M.x86.R_SS = vm->regs.ss; M.x86.R_ES = vm->regs.es; M.x86.R_FS = vm->regs.fs; M.x86.R_GS = vm->regs.gs; emu_vm86_ret = 0; X86EMU_exec(); vm->regs.eax = M.x86.R_EAX; vm->regs.ebx = M.x86.R_EBX; vm->regs.ecx = M.x86.R_ECX; vm->regs.edx = M.x86.R_EDX; vm->regs.esp = M.x86.R_ESP; vm->regs.ebp = M.x86.R_EBP; vm->regs.esi = M.x86.R_ESI; vm->regs.edi = M.x86.R_EDI; vm->regs.eip = M.x86.R_EIP; vm->regs.eflags = M.x86.R_EFLG; vm->regs.cs = M.x86.R_CS; vm->regs.ds = M.x86.R_DS; vm->regs.ss = M.x86.R_SS; vm->regs.es = M.x86.R_ES; vm->regs.fs = M.x86.R_FS; vm->regs.gs = M.x86.R_GS; if (emu_vm86_ret == 0 && *(unsigned char *)INT2PTR(((u32)M.x86.R_CS << 4) + (M.x86.R_IP - 1)) == 0xf4) { vm->regs.eip--; return VM86_UNKNOWN; } return emu_vm86_ret ? emu_vm86_ret : -1; } void printk(const char *fmt, ...) { va_list argptr; va_start(argptr, fmt); vfprintf(stderr, fmt, argptr); va_end(argptr); }