]> git.ipfire.org Git - u-boot.git/blame - board/MAI/bios_emulator/scitech/src/v86bios/x86emu.c
* Code cleanup:
[u-boot.git] / board / MAI / bios_emulator / scitech / src / v86bios / x86emu.c
CommitLineData
c7de829c
WD
1/*
2 * Copyright 1999 Egbert Eich
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the authors not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. The authors makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
13 *
14 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22#include "debug.h"
23
24#define IF_MASK 0x00000200
25#define VIF_MASK 0x00080000 /* virtual interrupt flag */
26#define VIP_MASK 0x00100000 /* virtual interrupt pending */
27
28#include </usr/include/unistd.h>
29#include <errno.h>
30#include <asm/unistd.h>
8bde7f77 31/*#include <syscall-list.h> */
c7de829c
WD
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <stdarg.h>
36#ifdef __alpha__
37#include <sys/io.h>
38#endif
39#include <signal.h>
40#include <setjmp.h>
41#include "AsmMacros.h"
42#include "v86bios.h"
43# define DEBUG
44#include "x86emu.h"
45#undef DEBUG
46
47#define M _X86EMU_env
48#define CPU_REG(reg) M.x86.R_##reg
49
50struct pio P;
51
52void
8bde7f77 53setup_io(void)
c7de829c
WD
54{
55 if (!Config.PrintPort && !Config.IoStatistics) {
8bde7f77 56
c7de829c
WD
57#if defined (__i386__)
58 P.inb = (u8(*)(u16))inb;
59 P.inw = (u16(*)(u16))inw;
60 P.outb = (void(*)(u16,u8))outb;
61 P.outw = (void(*)(u16,u16))outw;
62#else
63 P.inb = p_inb;
64 P.inw = p_inw;
65 P.outb = p_outb;
66 P.outw = p_outw;
67#endif
68#if defined (__i386__) && ! defined(NEED_PCI_IO)
69 P.inl = (u32(*)(u16))inl;
70 P.outl = (void(*)(u16,u32))outl;
71#else
72 P.inl = p_inl;
73 P.outl = p_outl;
74#endif
75 } else {
76 P.inb = p_inb;
77 P.inw = p_inw;
78 P.inl = p_inl;
79 P.outb = p_outb;
80 P.outw = p_outw;
81 P.outl = p_outl;
82 }
83}
84
85void
86x86emu_do_int(int num)
87{
88 struct regs86 regs;
8bde7f77 89
c7de829c
WD
90 i_printf("int 0x%x received: ax:0x%x",num,CPU_REG(AX));
91 if (Config.PrintIp)
8bde7f77 92 i_printf(" at: 0x%x\n",getIP());
c7de829c 93 else
8bde7f77
WD
94 i_printf("\n");
95
c7de829c 96 /* try to run bios interrupt */
8bde7f77 97
c7de829c
WD
98 /* if not installed fall back */
99#define COPY(x,y) regs.y = M.x86.x
100#define COPY_R(x,y) M.x86.x = regs.y
8bde7f77 101
c7de829c
WD
102 COPY(R_EAX,eax);
103 COPY(R_EBX,ebx);
104 COPY(R_ECX,ecx);
105 COPY(R_EDX,edx);
106 COPY(R_ESI,esi);
107 COPY(R_EDI,edi);
108 COPY(R_EBP,ebp);
109 COPY(R_EIP,eip);
110 COPY(R_ESP,esp);
111 COPY(R_CS,cs);
112 COPY(R_SS,ss);
113 COPY(R_DS,ds);
114 COPY(R_ES,es);
115 COPY(R_FS,fs);
116 COPY(R_GS,gs);
117 COPY(R_EFLG,eflags);
118
119 if (!(int_handler(num,&regs))) {
8bde7f77
WD
120 if (!run_bios_int(num,&regs))
121 goto unknown_int;
122 else
123 return;
c7de829c 124 }
8bde7f77 125
c7de829c
WD
126 COPY_R(R_EAX,eax);
127 COPY_R(R_EBX,ebx);
128 COPY_R(R_ECX,ecx);
129 COPY_R(R_EDX,edx);
130 COPY_R(R_ESI,esi);
131 COPY_R(R_EDI,edi);
132 COPY_R(R_EBP,ebp);
133 COPY_R(R_EIP,eip);
134 COPY_R(R_ESP,esp);
135 COPY_R(R_CS,cs);
136 COPY_R(R_SS,ss);
137 COPY_R(R_DS,ds);
138 COPY_R(R_ES,es);
139 COPY_R(R_FS,fs);
140 COPY_R(R_GS,gs);
141 COPY_R(R_EFLG,eflags);
142 return;
143
144 unknown_int:
145 fprintf(stderr,"\nUnknown vm86_int: %X\n\n",num);
146 X86EMU_halt_sys();
147 return;
8bde7f77 148
c7de829c
WD
149#undef COPY
150#undef COPY_R
151}
152
153void
154setup_x86emu(unsigned long bios_start, i86biosRegsPtr regs)
155{
156 int i;
157 CARD32 eip;
158 CARD16 cs;
159 X86EMU_intrFuncs intFuncs[256];
160
161 X86EMU_pioFuncs pioFuncs = {
8bde7f77
WD
162 (u8(*)(u16))P.inb,
163 (u16(*)(u16))P.inw,
164 (u32(*)(u16))P.inl,
165 (void(*)(u16,u8))P.outb,
166 (void(*)(u16,u16))P.outw,
167 (void(*)(u16,u32))P.outl
c7de829c
WD
168 };
169#ifdef __alpha__
170 X86EMU_memFuncs memFuncs = {
171 (u8(*)(u32))mem_rb,
172 (u16(*)(u32))mem_rw,
173 (u32(*)(u32))mem_rl,
174 (void(*)(u32,u8))mem_wb,
175 (void(*)(u32,u16))mem_ww,
176 (void(*)(u32,u32))mem_wl
177 };
178#endif
179 M.mem_base = 0;
180 M.mem_size = 1024*1024 + 1024;
8bde7f77
WD
181 /* M.x86.debug = DEBUG_DISASSEMBLE_F | DEBUG_TRACE_F | DEBUG_DECODE_F; */
182 /* M.x86.debug |= DEBUG_DECODE_F | DEBUG_TRACE_F; */
c7de829c
WD
183/*
184 * For single step tracing compile x86emu with option -DDEBUG
185 */
186 M.x86.debug = 0;
187 if (Config.PrintIp)
8bde7f77 188 M.x86.debug = DEBUG_SAVE_CS_IP;
c7de829c
WD
189
190 if (Config.Trace)
8bde7f77 191 X86EMU_trace_on();
c7de829c
WD
192
193 X86EMU_setupPioFuncs(&pioFuncs);
194#ifdef __alpha__
195 X86EMU_setupMemFuncs(&memFuncs);
196#endif
197 for (i=0;i<256;i++)
8bde7f77 198 intFuncs[i] = x86emu_do_int;
c7de829c
WD
199 X86EMU_setupIntrFuncs(intFuncs);
200
201 eip = bios_start & 0xFFFF;
202 cs = (bios_start & 0xFF0000) >> 4;
8bde7f77 203
c7de829c
WD
204 CPU_REG(EAX) = regs->ax;
205 CPU_REG(EBX) = regs->bx;
206 CPU_REG(ECX) = regs->cx;
207 CPU_REG(EDX) = regs->dx;
208 CPU_REG(ESI) = regs->si;
209 CPU_REG(EDI) = regs->di;
210 CPU_REG(EBP) = 0;
211 CPU_REG(EIP) = eip;
8bde7f77 212 CPU_REG(CS) = cs;
c7de829c
WD
213 CPU_REG(SP) = 0x100;
214 CPU_REG(SS) = 0x30; /* This is the standard pc bios stack */
215 CPU_REG(ES) = regs->es;
216 CPU_REG(DS) = regs->ds;
217 CPU_REG(FS) = 0;
218 CPU_REG(GS) = 0;
219 CPU_REG(EFLG) |= (VIF_MASK | VIP_MASK | IF_MASK | 0x2);
220}
221
222void
223collect_bios_regs(i86biosRegsPtr regs)
224{
225 regs->ax = CPU_REG(EAX);
226 regs->bx = CPU_REG(EBX);
227 regs->cx = CPU_REG(ECX);
228 regs->dx = CPU_REG(EDX);
229 regs->es = CPU_REG(ES);
230 regs->ds = CPU_REG(DS);
231 regs->di = CPU_REG(EDI);
232 regs->si = CPU_REG(ESI);
233}
234
235static void
236do_x86emu(void)
237{
238 X86EMU_exec();
239}
240
241static jmp_buf x86_esc;
242static void
243vmexit(int unused)
244{
245 longjmp(x86_esc,1);
246}
247
248void
249do_x86(unsigned long bios_start, i86biosRegsPtr regs)
250{
251 static void (*org_handler)(int);
252
253 setup_x86emu(bios_start,regs);
254 if (setjmp(x86_esc) == 0) {
8bde7f77
WD
255 org_handler = signal(2,vmexit);
256 do_x86emu();
257 signal(2,org_handler);
258 collect_bios_regs(regs);
c7de829c 259 } else {
8bde7f77
WD
260 signal(2,org_handler);
261 printf("interrupted at 0x%x\n",((CARD16)CPU_REG(CS)) << 4
262 | (CARD16)CPU_REG(EIP));
c7de829c
WD
263 }
264}
265
266int
267run_bios_int(int num, struct regs86 *regs)
268{
269#ifdef V86BIOS_DEBUG
270 static int firsttime = 1;
271#endif
272 /* check if bios vector is initialized */
273 if (((CARD16*)0)[(num<<1)+1] == 0x0000) { /* SYS_BIOS_SEG ?*/
274#ifdef V86BIOS_DEBUG
8bde7f77 275 i_printf("card BIOS not loaded\n");
c7de829c 276#endif
8bde7f77 277 return 0;
c7de829c 278 }
8bde7f77 279
c7de829c
WD
280#ifdef V86BIOS_DEBUG
281 if (firsttime) {
8bde7f77
WD
282 dprint(0,0x3D0);
283 firsttime = 0;
c7de829c
WD
284 }
285#endif
8bde7f77 286
c7de829c
WD
287 i_printf("calling card BIOS at: ");
288 i_printf("0x%x:%x\n",((CARD16 *) 0)[(num << 1) + 1],
8bde7f77 289 (CARD32)((CARD16 *) 0)[num << 1]);
c7de829c 290 X86EMU_prepareForInt(num);
8bde7f77 291
c7de829c
WD
292 return 1;
293}
294
295CARD32
296getIntVect(int num)
297{
298 return ((CARD32*)0)[num];
299}
300#if 0
301void
302printk(const char *fmt, ...)
303{
304 va_list argptr;
305 va_start(argptr, fmt);
306 vfprintf(stdout, fmt, argptr);
307 fflush(stdout);
308 va_end(argptr);
309}
310#endif
311
312CARD32
313getIP(void)
314{
315 return (M.x86.saved_cs << 4) + M.x86.saved_ip;
316}