]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/hwinfo/src/int10/emu_vm86.c
Kleiner netter neuer Versuch.
[people/pmueller/ipfire-2.x.git] / src / hwinfo / src / int10 / emu_vm86.c
CommitLineData
a6316ce4
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
14int emu_vm86_ret;
15
16static u8 Mem_rb(u32 addr) {
17 return *(u8 *)(INT2PTR(addr));
18}
19static void Mem_wb(u32 addr, u8 val) {
20 *(u8 *)INT2PTR(addr) = val;
21}
22#ifdef __ia64__
23
24static u16 Mem_rw(u32 addr) {
25 return *(u8 *)INT2PTR(addr) | *(u8 *)INT2PTR(addr + 1) << 8;
26}
27static 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}
31static void Mem_ww(u32 addr, u16 val) {
32 *(u8 *)INT2PTR(addr) = val;
33 *(u8 *)INT2PTR(addr + 1) = val >> 8;
34}
35static 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
44static u16 Mem_rw(u32 addr) {
45 return *(u16 *)INT2PTR(addr);
46}
47static u32 Mem_rl(u32 addr) {
48 return *(u32 *)INT2PTR(addr);
49}
50static void Mem_ww(u32 addr, u16 val) {
51 *(u16 *)INT2PTR(addr) = val;
52}
53static void Mem_wl(u32 addr, u32 val) {
54 *(u32 *)INT2PTR(addr) = val;
55}
56
57#endif
58
59static void do_int(int num) {
60 emu_vm86_ret = VM86_INTx | (num << 8);
61 M.x86.intr = INTR_HALTED;
62}
63
64
65static 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
75static 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
85static 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
95static 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
101static 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
107static 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
113int
114emu_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
131if(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
206void
207printk(const char *fmt, ...)
208{
209 va_list argptr;
210 va_start(argptr, fmt);
211 vfprintf(stderr, fmt, argptr);
212 va_end(argptr);
213}
214