xref: /OK3568_Linux_fs/external/xserver/hw/xfree86/x86emu/sys.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /****************************************************************************
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun *						Realmode X86 Emulator Library
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun *            	Copyright (C) 1996-1999 SciTech Software, Inc.
6*4882a593Smuzhiyun * 				     Copyright (C) David Mosberger-Tang
7*4882a593Smuzhiyun * 					   Copyright (C) 1999 Egbert Eich
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun *  ========================================================================
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun *  Permission to use, copy, modify, distribute, and sell this software and
12*4882a593Smuzhiyun *  its documentation for any purpose is hereby granted without fee,
13*4882a593Smuzhiyun *  provided that the above copyright notice appear in all copies and that
14*4882a593Smuzhiyun *  both that copyright notice and this permission notice appear in
15*4882a593Smuzhiyun *  supporting documentation, and that the name of the authors not be used
16*4882a593Smuzhiyun *  in advertising or publicity pertaining to distribution of the software
17*4882a593Smuzhiyun *  without specific, written prior permission.  The authors makes no
18*4882a593Smuzhiyun *  representations about the suitability of this software for any purpose.
19*4882a593Smuzhiyun *  It is provided "as is" without express or implied warranty.
20*4882a593Smuzhiyun *
21*4882a593Smuzhiyun *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22*4882a593Smuzhiyun *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23*4882a593Smuzhiyun *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24*4882a593Smuzhiyun *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25*4882a593Smuzhiyun *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26*4882a593Smuzhiyun *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27*4882a593Smuzhiyun *  PERFORMANCE OF THIS SOFTWARE.
28*4882a593Smuzhiyun *
29*4882a593Smuzhiyun *  ========================================================================
30*4882a593Smuzhiyun *
31*4882a593Smuzhiyun * Language:		ANSI C
32*4882a593Smuzhiyun * Environment:	Any
33*4882a593Smuzhiyun * Developer:    Kendall Bennett
34*4882a593Smuzhiyun *
35*4882a593Smuzhiyun * Description:  This file includes subroutines which are related to
36*4882a593Smuzhiyun *				programmed I/O and memory access. Included in this module
37*4882a593Smuzhiyun *				are default functions with limited usefulness. For real
38*4882a593Smuzhiyun *				uses these functions will most likely be overriden by the
39*4882a593Smuzhiyun *				user library.
40*4882a593Smuzhiyun *
41*4882a593Smuzhiyun ****************************************************************************/
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #include "x86emu.h"
44*4882a593Smuzhiyun #include "x86emu/x86emui.h"
45*4882a593Smuzhiyun #include "x86emu/regs.h"
46*4882a593Smuzhiyun #include "x86emu/debug.h"
47*4882a593Smuzhiyun #include "x86emu/prim_ops.h"
48*4882a593Smuzhiyun #ifndef NO_SYS_HEADERS
49*4882a593Smuzhiyun #include <string.h>
50*4882a593Smuzhiyun #endif
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun #ifdef __GNUC__
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /* Define some packed structures to use with unaligned accesses */
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun struct __una_u64 {
57*4882a593Smuzhiyun     u64 x __attribute__ ((packed));
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun struct __una_u32 {
60*4882a593Smuzhiyun     u32 x __attribute__ ((packed));
61*4882a593Smuzhiyun };
62*4882a593Smuzhiyun struct __una_u16 {
63*4882a593Smuzhiyun     u16 x __attribute__ ((packed));
64*4882a593Smuzhiyun };
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun /* Elemental unaligned loads */
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun static __inline__ u64
ldq_u(u64 * p)69*4882a593Smuzhiyun ldq_u(u64 * p)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun     const struct __una_u64 *ptr = (const struct __una_u64 *) p;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun     return ptr->x;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun static __inline__ u32
ldl_u(u32 * p)77*4882a593Smuzhiyun ldl_u(u32 * p)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun     const struct __una_u32 *ptr = (const struct __una_u32 *) p;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun     return ptr->x;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun static __inline__ u16
ldw_u(u16 * p)85*4882a593Smuzhiyun ldw_u(u16 * p)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun     const struct __una_u16 *ptr = (const struct __una_u16 *) p;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun     return ptr->x;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun /* Elemental unaligned stores */
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun static __inline__ void
stq_u(u64 val,u64 * p)95*4882a593Smuzhiyun stq_u(u64 val, u64 * p)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun     struct __una_u64 *ptr = (struct __una_u64 *) p;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun     ptr->x = val;
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun static __inline__ void
stl_u(u32 val,u32 * p)103*4882a593Smuzhiyun stl_u(u32 val, u32 * p)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun     struct __una_u32 *ptr = (struct __una_u32 *) p;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun     ptr->x = val;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun static __inline__ void
stw_u(u16 val,u16 * p)111*4882a593Smuzhiyun stw_u(u16 val, u16 * p)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun     struct __una_u16 *ptr = (struct __una_u16 *) p;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun     ptr->x = val;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun #else                           /* !__GNUC__ */
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun static __inline__ u64
ldq_u(u64 * p)120*4882a593Smuzhiyun ldq_u(u64 * p)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun     u64 ret;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun     memmove(&ret, p, sizeof(*p));
125*4882a593Smuzhiyun     return ret;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun static __inline__ u32
ldl_u(u32 * p)129*4882a593Smuzhiyun ldl_u(u32 * p)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun     u32 ret;
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun     memmove(&ret, p, sizeof(*p));
134*4882a593Smuzhiyun     return ret;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun static __inline__ u16
ldw_u(u16 * p)138*4882a593Smuzhiyun ldw_u(u16 * p)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun     u16 ret;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun     memmove(&ret, p, sizeof(*p));
143*4882a593Smuzhiyun     return ret;
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun static __inline__ void
stq_u(u64 val,u64 * p)147*4882a593Smuzhiyun stq_u(u64 val, u64 * p)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun     u64 tmp = val;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun     memmove(p, &tmp, sizeof(*p));
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun static __inline__ void
stl_u(u32 val,u32 * p)155*4882a593Smuzhiyun stl_u(u32 val, u32 * p)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun     u32 tmp = val;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun     memmove(p, &tmp, sizeof(*p));
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun static __inline__ void
stw_u(u16 val,u16 * p)163*4882a593Smuzhiyun stw_u(u16 val, u16 * p)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun     u16 tmp = val;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun     memmove(p, &tmp, sizeof(*p));
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun #endif                          /* __GNUC__ */
171*4882a593Smuzhiyun /*------------------------- Global Variables ------------------------------*/
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun X86EMU_sysEnv _X86EMU_env;      /* Global emulator machine state */
174*4882a593Smuzhiyun X86EMU_intrFuncs _X86EMU_intrTab[256];
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun /*----------------------------- Implementation ----------------------------*/
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun /****************************************************************************
179*4882a593Smuzhiyun PARAMETERS:
180*4882a593Smuzhiyun addr	- Emulator memory address to read
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun RETURNS:
183*4882a593Smuzhiyun Byte value read from emulator memory.
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun REMARKS:
186*4882a593Smuzhiyun Reads a byte value from the emulator memory.
187*4882a593Smuzhiyun ****************************************************************************/
188*4882a593Smuzhiyun u8 X86API
rdb(u32 addr)189*4882a593Smuzhiyun rdb(u32 addr)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun     u8 val;
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun     if (addr > M.mem_size - 1) {
194*4882a593Smuzhiyun         DB(printk("mem_read: address %#" PRIx32 " out of range!\n", addr);
195*4882a593Smuzhiyun             )
196*4882a593Smuzhiyun             HALT_SYS();
197*4882a593Smuzhiyun     }
198*4882a593Smuzhiyun     val = *(u8 *) (M.mem_base + addr);
199*4882a593Smuzhiyun     DB(if (DEBUG_MEM_TRACE())
200*4882a593Smuzhiyun        printk("%#08x 1 -> %#x\n", addr, val);)
201*4882a593Smuzhiyun         return val;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun /****************************************************************************
205*4882a593Smuzhiyun PARAMETERS:
206*4882a593Smuzhiyun addr	- Emulator memory address to read
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun RETURNS:
209*4882a593Smuzhiyun Word value read from emulator memory.
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun REMARKS:
212*4882a593Smuzhiyun Reads a word value from the emulator memory.
213*4882a593Smuzhiyun ****************************************************************************/
214*4882a593Smuzhiyun u16 X86API
rdw(u32 addr)215*4882a593Smuzhiyun rdw(u32 addr)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun     u16 val = 0;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun     if (addr > M.mem_size - 2) {
220*4882a593Smuzhiyun         DB(printk("mem_read: address %#" PRIx32 " out of range!\n", addr);
221*4882a593Smuzhiyun             )
222*4882a593Smuzhiyun             HALT_SYS();
223*4882a593Smuzhiyun     }
224*4882a593Smuzhiyun #ifdef __BIG_ENDIAN__
225*4882a593Smuzhiyun     if (addr & 0x1) {
226*4882a593Smuzhiyun         val = (*(u8 *) (M.mem_base + addr) |
227*4882a593Smuzhiyun                (*(u8 *) (M.mem_base + addr + 1) << 8));
228*4882a593Smuzhiyun     }
229*4882a593Smuzhiyun     else
230*4882a593Smuzhiyun #endif
231*4882a593Smuzhiyun         val = ldw_u((u16 *) (M.mem_base + addr));
232*4882a593Smuzhiyun     DB(if (DEBUG_MEM_TRACE())
233*4882a593Smuzhiyun        printk("%#08x 2 -> %#x\n", addr, val);)
234*4882a593Smuzhiyun         return val;
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun /****************************************************************************
238*4882a593Smuzhiyun PARAMETERS:
239*4882a593Smuzhiyun addr	- Emulator memory address to read
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun RETURNS:
242*4882a593Smuzhiyun Long value read from emulator memory.
243*4882a593Smuzhiyun REMARKS:
244*4882a593Smuzhiyun Reads a long value from the emulator memory.
245*4882a593Smuzhiyun ****************************************************************************/
246*4882a593Smuzhiyun u32 X86API
rdl(u32 addr)247*4882a593Smuzhiyun rdl(u32 addr)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun     u32 val = 0;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun     if (addr > M.mem_size - 4) {
252*4882a593Smuzhiyun         DB(printk("mem_read: address %#" PRIx32 " out of range!\n", addr);
253*4882a593Smuzhiyun             )
254*4882a593Smuzhiyun             HALT_SYS();
255*4882a593Smuzhiyun     }
256*4882a593Smuzhiyun #ifdef __BIG_ENDIAN__
257*4882a593Smuzhiyun     if (addr & 0x3) {
258*4882a593Smuzhiyun         val = (*(u8 *) (M.mem_base + addr + 0) |
259*4882a593Smuzhiyun                (*(u8 *) (M.mem_base + addr + 1) << 8) |
260*4882a593Smuzhiyun                (*(u8 *) (M.mem_base + addr + 2) << 16) |
261*4882a593Smuzhiyun                (*(u8 *) (M.mem_base + addr + 3) << 24));
262*4882a593Smuzhiyun     }
263*4882a593Smuzhiyun     else
264*4882a593Smuzhiyun #endif
265*4882a593Smuzhiyun         val = ldl_u((u32 *) (M.mem_base + addr));
266*4882a593Smuzhiyun     DB(if (DEBUG_MEM_TRACE())
267*4882a593Smuzhiyun        printk("%#08x 4 -> %#x\n", addr, val);)
268*4882a593Smuzhiyun         return val;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun /****************************************************************************
272*4882a593Smuzhiyun PARAMETERS:
273*4882a593Smuzhiyun addr	- Emulator memory address to read
274*4882a593Smuzhiyun val		- Value to store
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun REMARKS:
277*4882a593Smuzhiyun Writes a byte value to emulator memory.
278*4882a593Smuzhiyun ****************************************************************************/
279*4882a593Smuzhiyun void X86API
wrb(u32 addr,u8 val)280*4882a593Smuzhiyun wrb(u32 addr, u8 val)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun     DB(if (DEBUG_MEM_TRACE())
283*4882a593Smuzhiyun        printk("%#08x 1 <- %#x\n", addr, val);)
284*4882a593Smuzhiyun         if (addr > M.mem_size - 1) {
285*4882a593Smuzhiyun             DB(printk("mem_write: address %#" PRIx32 " out of range!\n",addr);
286*4882a593Smuzhiyun                 )
287*4882a593Smuzhiyun                 HALT_SYS();
288*4882a593Smuzhiyun         }
289*4882a593Smuzhiyun     *(u8 *) (M.mem_base + addr) = val;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun /****************************************************************************
293*4882a593Smuzhiyun PARAMETERS:
294*4882a593Smuzhiyun addr	- Emulator memory address to read
295*4882a593Smuzhiyun val		- Value to store
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun REMARKS:
298*4882a593Smuzhiyun Writes a word value to emulator memory.
299*4882a593Smuzhiyun ****************************************************************************/
300*4882a593Smuzhiyun void X86API
wrw(u32 addr,u16 val)301*4882a593Smuzhiyun wrw(u32 addr, u16 val)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun     DB(if (DEBUG_MEM_TRACE())
304*4882a593Smuzhiyun        printk("%#08x 2 <- %#x\n", addr, val);)
305*4882a593Smuzhiyun         if (addr > M.mem_size - 2) {
306*4882a593Smuzhiyun             DB(printk("mem_write: address %#" PRIx32 " out of range!\n",addr);
307*4882a593Smuzhiyun                 )
308*4882a593Smuzhiyun                 HALT_SYS();
309*4882a593Smuzhiyun         }
310*4882a593Smuzhiyun #ifdef __BIG_ENDIAN__
311*4882a593Smuzhiyun     if (addr & 0x1) {
312*4882a593Smuzhiyun         *(u8 *) (M.mem_base + addr + 0) = (val >> 0) & 0xff;
313*4882a593Smuzhiyun         *(u8 *) (M.mem_base + addr + 1) = (val >> 8) & 0xff;
314*4882a593Smuzhiyun     }
315*4882a593Smuzhiyun     else
316*4882a593Smuzhiyun #endif
317*4882a593Smuzhiyun         stw_u(val, (u16 *) (M.mem_base + addr));
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun /****************************************************************************
321*4882a593Smuzhiyun PARAMETERS:
322*4882a593Smuzhiyun addr	- Emulator memory address to read
323*4882a593Smuzhiyun val		- Value to store
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun REMARKS:
326*4882a593Smuzhiyun Writes a long value to emulator memory.
327*4882a593Smuzhiyun ****************************************************************************/
328*4882a593Smuzhiyun void X86API
wrl(u32 addr,u32 val)329*4882a593Smuzhiyun wrl(u32 addr, u32 val)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun     DB(if (DEBUG_MEM_TRACE())
332*4882a593Smuzhiyun        printk("%#08x 4 <- %#x\n", addr, val);)
333*4882a593Smuzhiyun         if (addr > M.mem_size - 4) {
334*4882a593Smuzhiyun             DB(printk("mem_write: address %#" PRIx32 " out of range!\n",addr);
335*4882a593Smuzhiyun                 )
336*4882a593Smuzhiyun                 HALT_SYS();
337*4882a593Smuzhiyun         }
338*4882a593Smuzhiyun #ifdef __BIG_ENDIAN__
339*4882a593Smuzhiyun     if (addr & 0x1) {
340*4882a593Smuzhiyun         *(u8 *) (M.mem_base + addr + 0) = (val >> 0) & 0xff;
341*4882a593Smuzhiyun         *(u8 *) (M.mem_base + addr + 1) = (val >> 8) & 0xff;
342*4882a593Smuzhiyun         *(u8 *) (M.mem_base + addr + 2) = (val >> 16) & 0xff;
343*4882a593Smuzhiyun         *(u8 *) (M.mem_base + addr + 3) = (val >> 24) & 0xff;
344*4882a593Smuzhiyun     }
345*4882a593Smuzhiyun     else
346*4882a593Smuzhiyun #endif
347*4882a593Smuzhiyun         stl_u(val, (u32 *) (M.mem_base + addr));
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun /****************************************************************************
351*4882a593Smuzhiyun PARAMETERS:
352*4882a593Smuzhiyun addr	- PIO address to read
353*4882a593Smuzhiyun RETURN:
354*4882a593Smuzhiyun 0
355*4882a593Smuzhiyun REMARKS:
356*4882a593Smuzhiyun Default PIO byte read function. Doesn't perform real inb.
357*4882a593Smuzhiyun ****************************************************************************/
358*4882a593Smuzhiyun static u8 X86API
p_inb(X86EMU_pioAddr addr)359*4882a593Smuzhiyun p_inb(X86EMU_pioAddr addr)
360*4882a593Smuzhiyun {
361*4882a593Smuzhiyun     DB(if (DEBUG_IO_TRACE())
362*4882a593Smuzhiyun        printk("inb %#04x \n", addr);)
363*4882a593Smuzhiyun         return 0;
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun /****************************************************************************
367*4882a593Smuzhiyun PARAMETERS:
368*4882a593Smuzhiyun addr	- PIO address to read
369*4882a593Smuzhiyun RETURN:
370*4882a593Smuzhiyun 0
371*4882a593Smuzhiyun REMARKS:
372*4882a593Smuzhiyun Default PIO word read function. Doesn't perform real inw.
373*4882a593Smuzhiyun ****************************************************************************/
374*4882a593Smuzhiyun static u16 X86API
p_inw(X86EMU_pioAddr addr)375*4882a593Smuzhiyun p_inw(X86EMU_pioAddr addr)
376*4882a593Smuzhiyun {
377*4882a593Smuzhiyun     DB(if (DEBUG_IO_TRACE())
378*4882a593Smuzhiyun        printk("inw %#04x \n", addr);)
379*4882a593Smuzhiyun         return 0;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun /****************************************************************************
383*4882a593Smuzhiyun PARAMETERS:
384*4882a593Smuzhiyun addr	- PIO address to read
385*4882a593Smuzhiyun RETURN:
386*4882a593Smuzhiyun 0
387*4882a593Smuzhiyun REMARKS:
388*4882a593Smuzhiyun Default PIO long read function. Doesn't perform real inl.
389*4882a593Smuzhiyun ****************************************************************************/
390*4882a593Smuzhiyun static u32 X86API
p_inl(X86EMU_pioAddr addr)391*4882a593Smuzhiyun p_inl(X86EMU_pioAddr addr)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun     DB(if (DEBUG_IO_TRACE())
394*4882a593Smuzhiyun        printk("inl %#04x \n", addr);)
395*4882a593Smuzhiyun         return 0;
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun /****************************************************************************
399*4882a593Smuzhiyun PARAMETERS:
400*4882a593Smuzhiyun addr	- PIO address to write
401*4882a593Smuzhiyun val     - Value to store
402*4882a593Smuzhiyun REMARKS:
403*4882a593Smuzhiyun Default PIO byte write function. Doesn't perform real outb.
404*4882a593Smuzhiyun ****************************************************************************/
405*4882a593Smuzhiyun static void X86API
p_outb(X86EMU_pioAddr addr,u8 val)406*4882a593Smuzhiyun p_outb(X86EMU_pioAddr addr, u8 val)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun     DB(if (DEBUG_IO_TRACE())
409*4882a593Smuzhiyun        printk("outb %#02x -> %#04x \n", val, addr);)
410*4882a593Smuzhiyun         return;
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun /****************************************************************************
414*4882a593Smuzhiyun PARAMETERS:
415*4882a593Smuzhiyun addr	- PIO address to write
416*4882a593Smuzhiyun val     - Value to store
417*4882a593Smuzhiyun REMARKS:
418*4882a593Smuzhiyun Default PIO word write function. Doesn't perform real outw.
419*4882a593Smuzhiyun ****************************************************************************/
420*4882a593Smuzhiyun static void X86API
p_outw(X86EMU_pioAddr addr,u16 val)421*4882a593Smuzhiyun p_outw(X86EMU_pioAddr addr, u16 val)
422*4882a593Smuzhiyun {
423*4882a593Smuzhiyun     DB(if (DEBUG_IO_TRACE())
424*4882a593Smuzhiyun        printk("outw %#04x -> %#04x \n", val, addr);)
425*4882a593Smuzhiyun         return;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun /****************************************************************************
429*4882a593Smuzhiyun PARAMETERS:
430*4882a593Smuzhiyun addr	- PIO address to write
431*4882a593Smuzhiyun val     - Value to store
432*4882a593Smuzhiyun REMARKS:
433*4882a593Smuzhiyun Default PIO ;ong write function. Doesn't perform real outl.
434*4882a593Smuzhiyun ****************************************************************************/
435*4882a593Smuzhiyun static void X86API
p_outl(X86EMU_pioAddr addr,u32 val)436*4882a593Smuzhiyun p_outl(X86EMU_pioAddr addr, u32 val)
437*4882a593Smuzhiyun {
438*4882a593Smuzhiyun     DB(if (DEBUG_IO_TRACE())
439*4882a593Smuzhiyun        printk("outl %#08x -> %#04x \n", val, addr);)
440*4882a593Smuzhiyun         return;
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun /*------------------------- Global Variables ------------------------------*/
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun u8(X86APIP sys_rdb) (u32 addr) = rdb;
446*4882a593Smuzhiyun u16(X86APIP sys_rdw) (u32 addr) = rdw;
447*4882a593Smuzhiyun u32(X86APIP sys_rdl) (u32 addr) = rdl;
448*4882a593Smuzhiyun void (X86APIP sys_wrb) (u32 addr, u8 val) = wrb;
449*4882a593Smuzhiyun void (X86APIP sys_wrw) (u32 addr, u16 val) = wrw;
450*4882a593Smuzhiyun void (X86APIP sys_wrl) (u32 addr, u32 val) = wrl;
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun u8(X86APIP sys_inb) (X86EMU_pioAddr addr) = p_inb;
453*4882a593Smuzhiyun u16(X86APIP sys_inw) (X86EMU_pioAddr addr) = p_inw;
454*4882a593Smuzhiyun u32(X86APIP sys_inl) (X86EMU_pioAddr addr) = p_inl;
455*4882a593Smuzhiyun void (X86APIP sys_outb) (X86EMU_pioAddr addr, u8 val) = p_outb;
456*4882a593Smuzhiyun void (X86APIP sys_outw) (X86EMU_pioAddr addr, u16 val) = p_outw;
457*4882a593Smuzhiyun void (X86APIP sys_outl) (X86EMU_pioAddr addr, u32 val) = p_outl;
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun /*----------------------------- Setup -------------------------------------*/
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun /****************************************************************************
462*4882a593Smuzhiyun PARAMETERS:
463*4882a593Smuzhiyun funcs	- New memory function pointers to make active
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun REMARKS:
466*4882a593Smuzhiyun This function is used to set the pointers to functions which access
467*4882a593Smuzhiyun memory space, allowing the user application to override these functions
468*4882a593Smuzhiyun and hook them out as necessary for their application.
469*4882a593Smuzhiyun ****************************************************************************/
470*4882a593Smuzhiyun void
X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs)471*4882a593Smuzhiyun X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs)
472*4882a593Smuzhiyun {
473*4882a593Smuzhiyun     sys_rdb = funcs->rdb;
474*4882a593Smuzhiyun     sys_rdw = funcs->rdw;
475*4882a593Smuzhiyun     sys_rdl = funcs->rdl;
476*4882a593Smuzhiyun     sys_wrb = funcs->wrb;
477*4882a593Smuzhiyun     sys_wrw = funcs->wrw;
478*4882a593Smuzhiyun     sys_wrl = funcs->wrl;
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun /****************************************************************************
482*4882a593Smuzhiyun PARAMETERS:
483*4882a593Smuzhiyun funcs	- New programmed I/O function pointers to make active
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun REMARKS:
486*4882a593Smuzhiyun This function is used to set the pointers to functions which access
487*4882a593Smuzhiyun I/O space, allowing the user application to override these functions
488*4882a593Smuzhiyun and hook them out as necessary for their application.
489*4882a593Smuzhiyun ****************************************************************************/
490*4882a593Smuzhiyun void
X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs)491*4882a593Smuzhiyun X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs)
492*4882a593Smuzhiyun {
493*4882a593Smuzhiyun     sys_inb = funcs->inb;
494*4882a593Smuzhiyun     sys_inw = funcs->inw;
495*4882a593Smuzhiyun     sys_inl = funcs->inl;
496*4882a593Smuzhiyun     sys_outb = funcs->outb;
497*4882a593Smuzhiyun     sys_outw = funcs->outw;
498*4882a593Smuzhiyun     sys_outl = funcs->outl;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun /****************************************************************************
502*4882a593Smuzhiyun PARAMETERS:
503*4882a593Smuzhiyun funcs	- New interrupt vector table to make active
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun REMARKS:
506*4882a593Smuzhiyun This function is used to set the pointers to functions which handle
507*4882a593Smuzhiyun interrupt processing in the emulator, allowing the user application to
508*4882a593Smuzhiyun hook interrupts as necessary for their application. Any interrupts that
509*4882a593Smuzhiyun are not hooked by the user application, and reflected and handled internally
510*4882a593Smuzhiyun in the emulator via the interrupt vector table. This allows the application
511*4882a593Smuzhiyun to get control when the code being emulated executes specific software
512*4882a593Smuzhiyun interrupts.
513*4882a593Smuzhiyun ****************************************************************************/
514*4882a593Smuzhiyun void
X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[])515*4882a593Smuzhiyun X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[])
516*4882a593Smuzhiyun {
517*4882a593Smuzhiyun     int i;
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun     for (i = 0; i < 256; i++)
520*4882a593Smuzhiyun         _X86EMU_intrTab[i] = NULL;
521*4882a593Smuzhiyun     if (funcs) {
522*4882a593Smuzhiyun         for (i = 0; i < 256; i++)
523*4882a593Smuzhiyun             _X86EMU_intrTab[i] = funcs[i];
524*4882a593Smuzhiyun     }
525*4882a593Smuzhiyun }
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun /****************************************************************************
528*4882a593Smuzhiyun PARAMETERS:
529*4882a593Smuzhiyun int	- New software interrupt to prepare for
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun REMARKS:
532*4882a593Smuzhiyun This function is used to set up the emulator state to exceute a software
533*4882a593Smuzhiyun interrupt. This can be used by the user application code to allow an
534*4882a593Smuzhiyun interrupt to be hooked, examined and then reflected back to the emulator
535*4882a593Smuzhiyun so that the code in the emulator will continue processing the software
536*4882a593Smuzhiyun interrupt as per normal. This essentially allows system code to actively
537*4882a593Smuzhiyun hook and handle certain software interrupts as necessary.
538*4882a593Smuzhiyun ****************************************************************************/
539*4882a593Smuzhiyun void
X86EMU_prepareForInt(int num)540*4882a593Smuzhiyun X86EMU_prepareForInt(int num)
541*4882a593Smuzhiyun {
542*4882a593Smuzhiyun     push_word((u16) M.x86.R_FLG);
543*4882a593Smuzhiyun     CLEAR_FLAG(F_IF);
544*4882a593Smuzhiyun     CLEAR_FLAG(F_TF);
545*4882a593Smuzhiyun     push_word(M.x86.R_CS);
546*4882a593Smuzhiyun     M.x86.R_CS = mem_access_word(num * 4 + 2);
547*4882a593Smuzhiyun     push_word(M.x86.R_IP);
548*4882a593Smuzhiyun     M.x86.R_IP = mem_access_word(num * 4);
549*4882a593Smuzhiyun     M.x86.intr = 0;
550*4882a593Smuzhiyun }
551