]> git.ipfire.org Git - ipfire-2.x.git/blob - src/hwinfo/src/int10/emu_vm86.c
Zwischencommit Installer...
[ipfire-2.x.git] / src / hwinfo / src / int10 / emu_vm86.c
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