Coding style cleanup
[platform/kernel/u-boot.git] / board / MAI / bios_emulator / scitech / src / v86bios / x86emu.c
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>
31 /*#include <syscall-list.h> */
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
50 struct pio P;
51
52 void
53 setup_io(void)
54 {
55     if (!Config.PrintPort && !Config.IoStatistics) {
56
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
85 void
86 x86emu_do_int(int num)
87 {
88     struct regs86 regs;
89
90     i_printf("int 0x%x received: ax:0x%x",num,CPU_REG(AX));
91     if (Config.PrintIp)
92         i_printf(" at: 0x%x\n",getIP());
93     else
94         i_printf("\n");
95
96     /* try to run bios interrupt */
97
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
101
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))) {
120         if (!run_bios_int(num,&regs))
121             goto unknown_int;
122         else
123             return;
124     }
125
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;
148
149 #undef COPY
150 #undef COPY_R
151 }
152
153 void
154 setup_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 = {
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
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;
181     /*  M.x86.debug = DEBUG_DISASSEMBLE_F | DEBUG_TRACE_F | DEBUG_DECODE_F; */
182     /*  M.x86.debug |= DEBUG_DECODE_F |  DEBUG_TRACE_F; */
183 /*
184  * For single step tracing compile x86emu with option -DDEBUG
185  */
186     M.x86.debug = 0;
187     if (Config.PrintIp)
188         M.x86.debug = DEBUG_SAVE_CS_IP;
189
190     if (Config.Trace)
191         X86EMU_trace_on();
192
193     X86EMU_setupPioFuncs(&pioFuncs);
194 #ifdef __alpha__
195     X86EMU_setupMemFuncs(&memFuncs);
196 #endif
197     for (i=0;i<256;i++)
198         intFuncs[i] = x86emu_do_int;
199     X86EMU_setupIntrFuncs(intFuncs);
200
201     eip = bios_start & 0xFFFF;
202     cs = (bios_start & 0xFF0000) >> 4;
203
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;
212     CPU_REG(CS) = cs;
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
222 void
223 collect_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
235 static void
236 do_x86emu(void)
237 {
238     X86EMU_exec();
239 }
240
241 static jmp_buf x86_esc;
242 static void
243 vmexit(int unused)
244 {
245     longjmp(x86_esc,1);
246 }
247
248 void
249 do_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) {
255         org_handler = signal(2,vmexit);
256         do_x86emu();
257         signal(2,org_handler);
258         collect_bios_regs(regs);
259     } else {
260         signal(2,org_handler);
261         printf("interrupted at 0x%x\n",((CARD16)CPU_REG(CS)) << 4
262                | (CARD16)CPU_REG(EIP));
263     }
264 }
265
266 int
267 run_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
275         i_printf("card BIOS not loaded\n");
276 #endif
277         return 0;
278     }
279
280 #ifdef V86BIOS_DEBUG
281     if (firsttime) {
282         dprint(0,0x3D0);
283         firsttime = 0;
284     }
285 #endif
286
287     i_printf("calling card BIOS at: ");
288     i_printf("0x%x:%x\n",((CARD16 *) 0)[(num << 1) + 1],
289              (CARD32)((CARD16 *) 0)[num << 1]);
290     X86EMU_prepareForInt(num);
291
292     return 1;
293 }
294
295 CARD32
296 getIntVect(int num)
297 {
298   return ((CARD32*)0)[num];
299 }
300 #if 0
301 void
302 printk(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
312 CARD32
313 getIP(void)
314 {
315     return (M.x86.saved_cs << 4) + M.x86.saved_ip;
316 }