1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48#include <malloc.h>
49#include <common.h>
50#include "biosemui.h"
51
52BE_sysEnv _BE_env = {{0}};
53static X86EMU_memFuncs _BE_mem __attribute__((section(GOT2_TYPE))) = {
54 BE_rdb,
55 BE_rdw,
56 BE_rdl,
57 BE_wrb,
58 BE_wrw,
59 BE_wrl,
60 };
61
62static X86EMU_pioFuncs _BE_pio __attribute__((section(GOT2_TYPE))) = {
63 BE_inb,
64 BE_inw,
65 BE_inl,
66 BE_outb,
67 BE_outw,
68 BE_outl,
69 };
70
71#define OFF(addr) (u16)(((addr) >> 0) & 0xffff)
72#define SEG(addr) (u16)(((addr) >> 4) & 0xf000)
73
74
75
76
77
78
79
80
81
82
83
84int X86API BE_init(u32 debugFlags, int memSize, BE_VGAInfo * info, int shared)
85{
86#if !defined(__DRIVER__) && !defined(__KERNEL__)
87
88 PM_init();
89#endif
90 memset(&M, 0, sizeof(M));
91 if (memSize < 20480){
92 printf("Emulator requires at least 20Kb of memory!\n");
93 return 0;
94 }
95
96 M.mem_base = malloc(memSize);
97
98 if (M.mem_base == NULL){
99 printf("Biosemu:Out of memory!");
100 return 0;
101 }
102 M.mem_size = memSize;
103
104 _BE_env.emulateVGA = 0;
105 _BE_env.busmem_base = (unsigned long)malloc(128 * 1024);
106 if ((void *)_BE_env.busmem_base == NULL){
107 printf("Biosemu:Out of memory!");
108 return 0;
109 }
110 M.x86.debug = debugFlags;
111 _BE_bios_init((u32*)info->LowMem);
112 X86EMU_setupMemFuncs(&_BE_mem);
113 X86EMU_setupPioFuncs(&_BE_pio);
114 BE_setVGA(info);
115 return 1;
116}
117
118
119
120
121
122
123
124
125
126
127
128void X86API BE_setVGA(BE_VGAInfo * info)
129{
130
131#ifdef __KERNEL__
132 _BE_env.vgaInfo.function = info->function;
133 _BE_env.vgaInfo.device = info->device;
134 _BE_env.vgaInfo.bus = info->bus;
135 _BE_env.vgaInfo.pcidev = info->pcidev;
136#else
137 _BE_env.vgaInfo.pciInfo = info->pciInfo;
138#endif
139 _BE_env.vgaInfo.BIOSImage = info->BIOSImage;
140 if (info->BIOSImage) {
141 _BE_env.biosmem_base = (ulong) info->BIOSImage;
142 _BE_env.biosmem_limit = 0xC0000 + info->BIOSImageLen - 1;
143 } else {
144 _BE_env.biosmem_base = _BE_env.busmem_base + 0x20000;
145 _BE_env.biosmem_limit = 0xC7FFF;
146 }
147 if ((info->LowMem[0] == 0) && (info->LowMem[1] == 0) &&
148 (info->LowMem[2] == 0) && (info->LowMem[3] == 0))
149 _BE_bios_init((u32 *) info->LowMem);
150 memcpy((u8 *) M.mem_base, info->LowMem, sizeof(info->LowMem));
151}
152
153
154
155
156
157
158
159
160
161void X86API BE_getVGA(BE_VGAInfo * info)
162{
163#ifdef __KERNEL__
164 info->function = _BE_env.vgaInfo.function;
165 info->device = _BE_env.vgaInfo.device;
166 info->bus = _BE_env.vgaInfo.bus;
167 info->pcidev = _BE_env.vgaInfo.pcidev;
168#else
169 info->pciInfo = _BE_env.vgaInfo.pciInfo;
170#endif
171 info->BIOSImage = _BE_env.vgaInfo.BIOSImage;
172 memcpy(info->LowMem, (u8 *) M.mem_base, sizeof(info->LowMem));
173}
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188void *X86API BE_mapRealPointer(uint r_seg, uint r_off)
189{
190 u32 addr = ((u32) r_seg << 4) + r_off;
191
192 if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
193 return (void *)(_BE_env.biosmem_base + addr - 0xC0000);
194 } else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
195 return (void *)(_BE_env.busmem_base + addr - 0xA0000);
196 }
197 return (void *)(M.mem_base + addr);
198}
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216void *X86API BE_getVESABuf(uint * len, uint * rseg, uint * roff)
217{
218 *len = 1024;
219 *rseg = SEG(0x03C00);
220 *roff = OFF(0x03C00);
221 return (void *)(M.mem_base + ((u32) * rseg << 4) + *roff);
222}
223
224
225
226
227
228void X86API BE_exit(void)
229{
230 free(M.mem_base);
231 free((void *)_BE_env.busmem_base);
232}
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247void X86API BE_callRealMode(uint seg, uint off, RMREGS * regs, RMSREGS * sregs)
248{
249 M.x86.R_EAX = regs->e.eax;
250 M.x86.R_EBX = regs->e.ebx;
251 M.x86.R_ECX = regs->e.ecx;
252 M.x86.R_EDX = regs->e.edx;
253 M.x86.R_ESI = regs->e.esi;
254 M.x86.R_EDI = regs->e.edi;
255 M.x86.R_DS = sregs->ds;
256 M.x86.R_ES = sregs->es;
257 M.x86.R_FS = sregs->fs;
258 M.x86.R_GS = sregs->gs;
259
260 ((u8 *) M.mem_base)[0x4000] = 0x9A;
261 ((u8 *) M.mem_base)[0x4001] = (u8) off;
262 ((u8 *) M.mem_base)[0x4002] = (u8) (off >> 8);
263 ((u8 *) M.mem_base)[0x4003] = (u8) seg;
264 ((u8 *) M.mem_base)[0x4004] = (u8) (seg >> 8);
265 ((u8 *) M.mem_base)[0x4005] = 0xF1;
266 M.x86.R_CS = SEG(0x04000);
267 M.x86.R_IP = OFF(0x04000);
268
269 M.x86.R_SS = SEG(M.mem_size - 2);
270 M.x86.R_SP = OFF(M.mem_size - 2) + 2;
271
272 X86EMU_exec();
273
274 regs->e.cflag = M.x86.R_EFLG & F_CF;
275 regs->e.eax = M.x86.R_EAX;
276 regs->e.ebx = M.x86.R_EBX;
277 regs->e.ecx = M.x86.R_ECX;
278 regs->e.edx = M.x86.R_EDX;
279 regs->e.esi = M.x86.R_ESI;
280 regs->e.edi = M.x86.R_EDI;
281 sregs->ds = M.x86.R_DS;
282 sregs->es = M.x86.R_ES;
283 sregs->fs = M.x86.R_FS;
284 sregs->gs = M.x86.R_GS;
285}
286
287
288
289
290
291
292
293
294
295
296
297
298int X86API BE_int86(int intno, RMREGS * in, RMREGS * out)
299{
300 M.x86.R_EAX = in->e.eax;
301 M.x86.R_EBX = in->e.ebx;
302 M.x86.R_ECX = in->e.ecx;
303 M.x86.R_EDX = in->e.edx;
304 M.x86.R_ESI = in->e.esi;
305 M.x86.R_EDI = in->e.edi;
306 ((u8 *) M.mem_base)[0x4000] = 0xCD;
307 ((u8 *) M.mem_base)[0x4001] = (u8) intno;
308 ((u8 *) M.mem_base)[0x4002] = 0xF1;
309 M.x86.R_CS = SEG(0x04000);
310 M.x86.R_IP = OFF(0x04000);
311
312 M.x86.R_SS = SEG(M.mem_size - 1);
313 M.x86.R_SP = OFF(M.mem_size - 1) - 1;
314
315 X86EMU_exec();
316 out->e.cflag = M.x86.R_EFLG & F_CF;
317 out->e.eax = M.x86.R_EAX;
318 out->e.ebx = M.x86.R_EBX;
319 out->e.ecx = M.x86.R_ECX;
320 out->e.edx = M.x86.R_EDX;
321 out->e.esi = M.x86.R_ESI;
322 out->e.edi = M.x86.R_EDI;
323 return out->x.ax;
324}
325
326
327
328
329
330
331
332
333
334
335
336
337
338int X86API BE_int86x(int intno, RMREGS * in, RMREGS * out, RMSREGS * sregs)
339{
340 M.x86.R_EAX = in->e.eax;
341 M.x86.R_EBX = in->e.ebx;
342 M.x86.R_ECX = in->e.ecx;
343 M.x86.R_EDX = in->e.edx;
344 M.x86.R_ESI = in->e.esi;
345 M.x86.R_EDI = in->e.edi;
346 M.x86.R_DS = sregs->ds;
347 M.x86.R_ES = sregs->es;
348 M.x86.R_FS = sregs->fs;
349 M.x86.R_GS = sregs->gs;
350 ((u8 *) M.mem_base)[0x4000] = 0xCD;
351 ((u8 *) M.mem_base)[0x4001] = (u8) intno;
352 ((u8 *) M.mem_base)[0x4002] = 0xF1;
353 M.x86.R_CS = SEG(0x04000);
354 M.x86.R_IP = OFF(0x04000);
355
356 M.x86.R_SS = SEG(M.mem_size - 1);
357 M.x86.R_SP = OFF(M.mem_size - 1) - 1;
358
359 X86EMU_exec();
360 out->e.cflag = M.x86.R_EFLG & F_CF;
361 out->e.eax = M.x86.R_EAX;
362 out->e.ebx = M.x86.R_EBX;
363 out->e.ecx = M.x86.R_ECX;
364 out->e.edx = M.x86.R_EDX;
365 out->e.esi = M.x86.R_ESI;
366 out->e.edi = M.x86.R_EDI;
367 sregs->ds = M.x86.R_DS;
368 sregs->es = M.x86.R_ES;
369 sregs->fs = M.x86.R_FS;
370 sregs->gs = M.x86.R_GS;
371 return out->x.ax;
372}
373