6
#include "vm86_struct.h"
9
#define INT2PTR(a) ((a) + (unsigned char *) 0)
11
#include "../x86emu/include/x86emu.h"
12
#include "AsmMacros.h"
16
static u8 Mem_rb(u32 addr) {
17
return *(u8 *)(INT2PTR(addr));
19
static void Mem_wb(u32 addr, u8 val) {
20
*(u8 *)INT2PTR(addr) = val;
24
static u16 Mem_rw(u32 addr) {
25
return *(u8 *)INT2PTR(addr) | *(u8 *)INT2PTR(addr + 1) << 8;
27
static u32 Mem_rl(u32 addr) {
28
return *(u8 *)INT2PTR(addr) | *(u8 *)INT2PTR(addr + 1) << 8 |
29
*(u8 *)INT2PTR(addr + 2) << 16 | *(u8 *)INT2PTR(addr + 3) << 24;
31
static void Mem_ww(u32 addr, u16 val) {
32
*(u8 *)INT2PTR(addr) = val;
33
*(u8 *)INT2PTR(addr + 1) = val >> 8;
35
static void Mem_wl(u32 addr, u32 val) {
36
*(u8 *)INT2PTR(addr) = val;
37
*(u8 *)INT2PTR(addr + 1) = val >> 8;
38
*(u8 *)INT2PTR(addr + 2) = val >> 16;
39
*(u8 *)INT2PTR(addr + 3) = val >> 24;
44
static u16 Mem_rw(u32 addr) {
45
return *(u16 *)INT2PTR(addr);
47
static u32 Mem_rl(u32 addr) {
48
return *(u32 *)INT2PTR(addr);
50
static void Mem_ww(u32 addr, u16 val) {
51
*(u16 *)INT2PTR(addr) = val;
53
static void Mem_wl(u32 addr, u32 val) {
54
*(u32 *)INT2PTR(addr) = val;
59
static void do_int(int num) {
60
emu_vm86_ret = VM86_INTx | (num << 8);
61
M.x86.intr = INTR_HALTED;
65
static u8 deb_inb(X86EMU_pioAddr addr)
70
fprintf(stderr, "%04x:%04x inb %04x = %02x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, u);
75
static u16 deb_inw(X86EMU_pioAddr addr)
80
fprintf(stderr, "%04x:%04x inw %04x = %04x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, u);
85
static u32 deb_inl(X86EMU_pioAddr addr)
90
fprintf(stderr, "%04x:%04x inl %04x = %08x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, (unsigned) u);
95
static void deb_outb(X86EMU_pioAddr addr, u8 val)
97
fprintf(stderr, "%04x:%04x outb %04x, %02x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, val);
101
static void deb_outw(X86EMU_pioAddr addr, u16 val)
103
fprintf(stderr, "%04x:%04x outw %04x, %04x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, val);
107
static void deb_outl(X86EMU_pioAddr addr, u32 val)
109
fprintf(stderr, "%04x:%04x outl %04x, %08x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, (unsigned) val);
114
emu_vm86(struct vm86_struct *vm, unsigned debug)
119
X86EMU_memFuncs memFuncs;
120
X86EMU_intrFuncs intFuncs[256];
121
X86EMU_pioFuncs pioFuncs;
123
memFuncs.rdb = Mem_rb;
124
memFuncs.rdw = Mem_rw;
125
memFuncs.rdl = Mem_rl;
126
memFuncs.wrb = Mem_wb;
127
memFuncs.wrw = Mem_ww;
128
memFuncs.wrl = Mem_wl;
129
X86EMU_setupMemFuncs(&memFuncs);
132
pioFuncs.inb = deb_inb;
133
pioFuncs.inw = deb_inw;
134
pioFuncs.inl = deb_inl;
135
pioFuncs.outb = deb_outb;
136
pioFuncs.outw = deb_outw;
137
pioFuncs.outl = deb_outl;
139
pioFuncs.inb = (u8(*)(u16))inb;
140
pioFuncs.inw = (u16(*)(u16))inw;
141
pioFuncs.inl = (u32(*)(u16))inl;
142
pioFuncs.outb = (void(*)(u16, u8))outb;
143
pioFuncs.outw = (void(*)(u16, u16))outw;
144
pioFuncs.outl = (void(*)(u16, u32))outl;
146
X86EMU_setupPioFuncs(&pioFuncs);
149
intFuncs[i] = do_int;
150
X86EMU_setupIntrFuncs(intFuncs);
153
M.mem_size = 1024*1024 + 1024;
155
M.x86.R_EAX = vm->regs.eax;
156
M.x86.R_EBX = vm->regs.ebx;
157
M.x86.R_ECX = vm->regs.ecx;
158
M.x86.R_EDX = vm->regs.edx;
160
M.x86.R_ESP = vm->regs.esp;
161
M.x86.R_EBP = vm->regs.ebp;
162
M.x86.R_ESI = vm->regs.esi;
163
M.x86.R_EDI = vm->regs.edi;
164
M.x86.R_EIP = vm->regs.eip;
165
M.x86.R_EFLG = vm->regs.eflags;
167
M.x86.R_CS = vm->regs.cs;
168
M.x86.R_DS = vm->regs.ds;
169
M.x86.R_SS = vm->regs.ss;
170
M.x86.R_ES = vm->regs.es;
171
M.x86.R_FS = vm->regs.fs;
172
M.x86.R_GS = vm->regs.gs;
175
/* set timeout, 20s normal, 60s for debugging */
176
timeout = debug ? (1 << 31) + 60 : 20;
177
X86EMU_exec(timeout);
179
vm->regs.eax = M.x86.R_EAX;
180
vm->regs.ebx = M.x86.R_EBX;
181
vm->regs.ecx = M.x86.R_ECX;
182
vm->regs.edx = M.x86.R_EDX;
184
vm->regs.esp = M.x86.R_ESP;
185
vm->regs.ebp = M.x86.R_EBP;
186
vm->regs.esi = M.x86.R_ESI;
187
vm->regs.edi = M.x86.R_EDI;
188
vm->regs.eip = M.x86.R_EIP;
189
vm->regs.eflags = M.x86.R_EFLG;
191
vm->regs.cs = M.x86.R_CS;
192
vm->regs.ds = M.x86.R_DS;
193
vm->regs.ss = M.x86.R_SS;
194
vm->regs.es = M.x86.R_ES;
195
vm->regs.fs = M.x86.R_FS;
196
vm->regs.gs = M.x86.R_GS;
198
if (emu_vm86_ret == 0 && *(unsigned char *)INT2PTR(((u32)M.x86.R_CS << 4) + (M.x86.R_IP - 1)) == 0xf4)
203
return emu_vm86_ret ? emu_vm86_ret : -1;
207
printk(const char *fmt, ...)
210
va_start(argptr, fmt);
211
vfprintf(stderr, fmt, argptr);