]>
Commit | Line | Data |
---|---|---|
93afd047 MT |
1 | #include <stdio.h> |
2 | #include <stdarg.h> | |
3 | #ifdef __i386__ | |
4 | #include <sys/vm86.h> | |
5 | #else | |
6 | #include "vm86_struct.h" | |
7 | #endif | |
8 | ||
9 | #define INT2PTR(a) ((a) + (unsigned char *) 0) | |
10 | ||
11 | #include "../x86emu/include/x86emu.h" | |
12 | #include "AsmMacros.h" | |
13 | ||
14 | int emu_vm86_ret; | |
15 | ||
16 | static u8 Mem_rb(u32 addr) { | |
17 | return *(u8 *)(INT2PTR(addr)); | |
18 | } | |
19 | static void Mem_wb(u32 addr, u8 val) { | |
20 | *(u8 *)INT2PTR(addr) = val; | |
21 | } | |
22 | #ifdef __ia64__ | |
23 | ||
24 | static u16 Mem_rw(u32 addr) { | |
25 | return *(u8 *)INT2PTR(addr) | *(u8 *)INT2PTR(addr + 1) << 8; | |
26 | } | |
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; | |
30 | } | |
31 | static void Mem_ww(u32 addr, u16 val) { | |
32 | *(u8 *)INT2PTR(addr) = val; | |
33 | *(u8 *)INT2PTR(addr + 1) = val >> 8; | |
34 | } | |
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; | |
40 | } | |
41 | ||
42 | #else | |
43 | ||
44 | static u16 Mem_rw(u32 addr) { | |
45 | return *(u16 *)INT2PTR(addr); | |
46 | } | |
47 | static u32 Mem_rl(u32 addr) { | |
48 | return *(u32 *)INT2PTR(addr); | |
49 | } | |
50 | static void Mem_ww(u32 addr, u16 val) { | |
51 | *(u16 *)INT2PTR(addr) = val; | |
52 | } | |
53 | static void Mem_wl(u32 addr, u32 val) { | |
54 | *(u32 *)INT2PTR(addr) = val; | |
55 | } | |
56 | ||
57 | #endif | |
58 | ||
59 | static void do_int(int num) { | |
60 | emu_vm86_ret = VM86_INTx | (num << 8); | |
61 | M.x86.intr = INTR_HALTED; | |
62 | } | |
63 | ||
64 | ||
65 | static u8 deb_inb(X86EMU_pioAddr addr) | |
66 | { | |
67 | u8 u; | |
68 | ||
69 | u = inb(addr); | |
70 | fprintf(stderr, "%04x:%04x inb %04x = %02x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, u); | |
71 | ||
72 | return u; | |
73 | } | |
74 | ||
75 | static u16 deb_inw(X86EMU_pioAddr addr) | |
76 | { | |
77 | u16 u; | |
78 | ||
79 | u = inw(addr); | |
80 | fprintf(stderr, "%04x:%04x inw %04x = %04x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, u); | |
81 | ||
82 | return u; | |
83 | } | |
84 | ||
85 | static u32 deb_inl(X86EMU_pioAddr addr) | |
86 | { | |
87 | u32 u; | |
88 | ||
89 | u = inl(addr); | |
90 | fprintf(stderr, "%04x:%04x inl %04x = %08x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, (unsigned) u); | |
91 | ||
92 | return u; | |
93 | } | |
94 | ||
95 | static void deb_outb(X86EMU_pioAddr addr, u8 val) | |
96 | { | |
97 | fprintf(stderr, "%04x:%04x outb %04x, %02x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, val); | |
98 | outb(addr, val); | |
99 | } | |
100 | ||
101 | static void deb_outw(X86EMU_pioAddr addr, u16 val) | |
102 | { | |
103 | fprintf(stderr, "%04x:%04x outw %04x, %04x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, val); | |
104 | outw(addr, val); | |
105 | } | |
106 | ||
107 | static void deb_outl(X86EMU_pioAddr addr, u32 val) | |
108 | { | |
109 | fprintf(stderr, "%04x:%04x outl %04x, %08x\n", M.x86.R_CS, (unsigned) M.x86.R_EIP, addr, (unsigned) val); | |
110 | outl(addr, val); | |
111 | } | |
112 | ||
113 | int | |
114 | emu_vm86(struct vm86_struct *vm, unsigned debug) | |
115 | { | |
116 | int i; | |
117 | unsigned timeout; | |
118 | ||
119 | X86EMU_memFuncs memFuncs; | |
120 | X86EMU_intrFuncs intFuncs[256]; | |
121 | X86EMU_pioFuncs pioFuncs; | |
122 | ||
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); | |
130 | ||
131 | if(debug) { | |
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; | |
138 | } else { | |
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; | |
145 | } | |
146 | X86EMU_setupPioFuncs(&pioFuncs); | |
147 | ||
148 | for (i=0;i<256;i++) | |
149 | intFuncs[i] = do_int; | |
150 | X86EMU_setupIntrFuncs(intFuncs); | |
151 | ||
152 | M.mem_base = 0; | |
153 | M.mem_size = 1024*1024 + 1024; | |
154 | ||
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; | |
159 | ||
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; | |
166 | ||
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; | |
173 | ||
174 | emu_vm86_ret = 0; | |
175 | /* set timeout, 20s normal, 60s for debugging */ | |
176 | timeout = debug ? (1 << 31) + 60 : 20; | |
177 | X86EMU_exec(timeout); | |
178 | ||
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; | |
183 | ||
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; | |
190 | ||
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; | |
197 | ||
198 | if (emu_vm86_ret == 0 && *(unsigned char *)INT2PTR(((u32)M.x86.R_CS << 4) + (M.x86.R_IP - 1)) == 0xf4) | |
199 | { | |
200 | vm->regs.eip--; | |
201 | return VM86_UNKNOWN; | |
202 | } | |
203 | return emu_vm86_ret ? emu_vm86_ret : -1; | |
204 | } | |
205 | ||
206 | void | |
207 | printk(const char *fmt, ...) | |
208 | { | |
209 | va_list argptr; | |
210 | va_start(argptr, fmt); | |
211 | vfprintf(stderr, fmt, argptr); | |
212 | va_end(argptr); | |
213 | } | |
214 |