xref: /OK3568_Linux_fs/u-boot/drivers/bios_emulator/besys.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /****************************************************************************
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun *                        BIOS emulator and interface
4*4882a593Smuzhiyun *                      to Realmode X86 Emulator Library
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun *  ========================================================================
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun *   Copyright (C) 2007 Freescale Semiconductor, Inc.
9*4882a593Smuzhiyun *   Jason Jin<Jason.jin@freescale.com>
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun *   Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun *   This file may be distributed and/or modified under the terms of the
14*4882a593Smuzhiyun *   GNU General Public License version 2.0 as published by the Free
15*4882a593Smuzhiyun *   Software Foundation and appearing in the file LICENSE.GPL included
16*4882a593Smuzhiyun *   in the packaging of this file.
17*4882a593Smuzhiyun *
18*4882a593Smuzhiyun *   Licensees holding a valid Commercial License for this product from
19*4882a593Smuzhiyun *   SciTech Software, Inc. may use this file in accordance with the
20*4882a593Smuzhiyun *   Commercial License Agreement provided with the Software.
21*4882a593Smuzhiyun *
22*4882a593Smuzhiyun *   This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
23*4882a593Smuzhiyun *   THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24*4882a593Smuzhiyun *   PURPOSE.
25*4882a593Smuzhiyun *
26*4882a593Smuzhiyun *   See http://www.scitechsoft.com/license/ for information about
27*4882a593Smuzhiyun *   the licensing options available and how to purchase a Commercial
28*4882a593Smuzhiyun *   License Agreement.
29*4882a593Smuzhiyun *
30*4882a593Smuzhiyun *   Contact license@scitechsoft.com if any conditions of this licensing
31*4882a593Smuzhiyun *   are not clear to you, or you have questions about licensing options.
32*4882a593Smuzhiyun *
33*4882a593Smuzhiyun *  ========================================================================
34*4882a593Smuzhiyun *
35*4882a593Smuzhiyun * Language:     ANSI C
36*4882a593Smuzhiyun * Environment:  Any
37*4882a593Smuzhiyun * Developer:    Kendall Bennett
38*4882a593Smuzhiyun *
39*4882a593Smuzhiyun * Description:  This file includes BIOS emulator I/O and memory access
40*4882a593Smuzhiyun *               functions.
41*4882a593Smuzhiyun *
42*4882a593Smuzhiyun *		Jason ported this file to u-boot to run the ATI video card
43*4882a593Smuzhiyun *		BIOS in u-boot. Removed some emulate functions such as the
44*4882a593Smuzhiyun *		timer port access. Made all the VGA port except reading 0x3c3
45*4882a593Smuzhiyun *		be emulated. Seems like reading 0x3c3 should return the high
46*4882a593Smuzhiyun *		16 bit of the io port.
47*4882a593Smuzhiyun *
48*4882a593Smuzhiyun ****************************************************************************/
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #define __io
51*4882a593Smuzhiyun #include <common.h>
52*4882a593Smuzhiyun #include <asm/io.h>
53*4882a593Smuzhiyun #include "biosemui.h"
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun /*------------------------- Global Variables ------------------------------*/
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun #ifndef CONFIG_X86EMU_RAW_IO
58*4882a593Smuzhiyun static char *BE_biosDate = "08/14/99";
59*4882a593Smuzhiyun static u8 BE_model = 0xFC;
60*4882a593Smuzhiyun static u8 BE_submodel = 0x00;
61*4882a593Smuzhiyun #endif
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun #undef DEBUG_IO_ACCESS
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun #ifdef DEBUG_IO_ACCESS
66*4882a593Smuzhiyun #define debug_io(fmt, ...)	printf(fmt, ##__VA_ARGS__)
67*4882a593Smuzhiyun #else
68*4882a593Smuzhiyun #define debug_io(x, b...)
69*4882a593Smuzhiyun #endif
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /*----------------------------- Implementation ----------------------------*/
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /****************************************************************************
74*4882a593Smuzhiyun PARAMETERS:
75*4882a593Smuzhiyun addr    - Emulator memory address to convert
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun RETURNS:
78*4882a593Smuzhiyun Actual memory address to read or write the data
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun REMARKS:
81*4882a593Smuzhiyun This function converts an emulator memory address in a 32-bit range to
82*4882a593Smuzhiyun a real memory address that we wish to access. It handles splitting up the
83*4882a593Smuzhiyun memory address space appropriately to access the emulator BIOS image, video
84*4882a593Smuzhiyun memory and system BIOS etc.
85*4882a593Smuzhiyun ****************************************************************************/
BE_memaddr(u32 addr)86*4882a593Smuzhiyun static u8 *BE_memaddr(u32 addr)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
89*4882a593Smuzhiyun 		return (u8*)(_BE_env.biosmem_base + addr - 0xC0000);
90*4882a593Smuzhiyun 	} else if (addr > _BE_env.biosmem_limit && addr < 0xD0000) {
91*4882a593Smuzhiyun 		DB(printf("BE_memaddr: address %#lx may be invalid!\n",
92*4882a593Smuzhiyun 			  (ulong)addr);)
93*4882a593Smuzhiyun 		return (u8 *)M.mem_base;
94*4882a593Smuzhiyun 	} else if (addr >= 0xA0000 && addr <= 0xBFFFF) {
95*4882a593Smuzhiyun 		return (u8*)(_BE_env.busmem_base + addr - 0xA0000);
96*4882a593Smuzhiyun 	}
97*4882a593Smuzhiyun #ifdef CONFIG_X86EMU_RAW_IO
98*4882a593Smuzhiyun 	else if (addr >= 0xD0000 && addr <= 0xFFFFF) {
99*4882a593Smuzhiyun 		/* We map the real System BIOS directly on real PC's */
100*4882a593Smuzhiyun 		DB(printf("BE_memaddr: System BIOS address %#lx\n",
101*4882a593Smuzhiyun 			  (ulong)addr);)
102*4882a593Smuzhiyun 		    return (u8 *)_BE_env.busmem_base + addr - 0xA0000;
103*4882a593Smuzhiyun 	}
104*4882a593Smuzhiyun #else
105*4882a593Smuzhiyun 	else if (addr >= 0xFFFF5 && addr < 0xFFFFE) {
106*4882a593Smuzhiyun 		/* Return a faked BIOS date string for non-x86 machines */
107*4882a593Smuzhiyun 		debug_io("BE_memaddr - Returning BIOS date\n");
108*4882a593Smuzhiyun 		return (u8 *)(BE_biosDate + addr - 0xFFFF5);
109*4882a593Smuzhiyun 	} else if (addr == 0xFFFFE) {
110*4882a593Smuzhiyun 		/* Return system model identifier for non-x86 machines */
111*4882a593Smuzhiyun 		debug_io("BE_memaddr - Returning model\n");
112*4882a593Smuzhiyun 		return &BE_model;
113*4882a593Smuzhiyun 	} else if (addr == 0xFFFFF) {
114*4882a593Smuzhiyun 		/* Return system submodel identifier for non-x86 machines */
115*4882a593Smuzhiyun 		debug_io("BE_memaddr - Returning submodel\n");
116*4882a593Smuzhiyun 		return &BE_submodel;
117*4882a593Smuzhiyun 	}
118*4882a593Smuzhiyun #endif
119*4882a593Smuzhiyun 	else if (addr > M.mem_size - 1) {
120*4882a593Smuzhiyun 		HALT_SYS();
121*4882a593Smuzhiyun 		return (u8 *)M.mem_base;
122*4882a593Smuzhiyun 	}
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	return (u8 *)(M.mem_base + addr);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun /****************************************************************************
128*4882a593Smuzhiyun PARAMETERS:
129*4882a593Smuzhiyun addr    - Emulator memory address to read
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun RETURNS:
132*4882a593Smuzhiyun Byte value read from emulator memory.
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun REMARKS:
135*4882a593Smuzhiyun Reads a byte value from the emulator memory. We have three distinct memory
136*4882a593Smuzhiyun regions that are handled differently, which this function handles.
137*4882a593Smuzhiyun ****************************************************************************/
BE_rdb(u32 addr)138*4882a593Smuzhiyun u8 X86API BE_rdb(u32 addr)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun 	if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)
141*4882a593Smuzhiyun 		return 0;
142*4882a593Smuzhiyun 	else {
143*4882a593Smuzhiyun 		u8 val = readb_le(BE_memaddr(addr));
144*4882a593Smuzhiyun 		return val;
145*4882a593Smuzhiyun 	}
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun /****************************************************************************
149*4882a593Smuzhiyun PARAMETERS:
150*4882a593Smuzhiyun addr    - Emulator memory address to read
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun RETURNS:
153*4882a593Smuzhiyun Word value read from emulator memory.
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun REMARKS:
156*4882a593Smuzhiyun Reads a word value from the emulator memory. We have three distinct memory
157*4882a593Smuzhiyun regions that are handled differently, which this function handles.
158*4882a593Smuzhiyun ****************************************************************************/
BE_rdw(u32 addr)159*4882a593Smuzhiyun u16 X86API BE_rdw(u32 addr)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun 	if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)
162*4882a593Smuzhiyun 		return 0;
163*4882a593Smuzhiyun 	else {
164*4882a593Smuzhiyun 		u8 *base = BE_memaddr(addr);
165*4882a593Smuzhiyun 		u16 val = readw_le(base);
166*4882a593Smuzhiyun 		return val;
167*4882a593Smuzhiyun 	}
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun /****************************************************************************
171*4882a593Smuzhiyun PARAMETERS:
172*4882a593Smuzhiyun addr    - Emulator memory address to read
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun RETURNS:
175*4882a593Smuzhiyun Long value read from emulator memory.
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun REMARKS:
178*4882a593Smuzhiyun Reads a 32-bit value from the emulator memory. We have three distinct memory
179*4882a593Smuzhiyun regions that are handled differently, which this function handles.
180*4882a593Smuzhiyun ****************************************************************************/
BE_rdl(u32 addr)181*4882a593Smuzhiyun u32 X86API BE_rdl(u32 addr)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun 	if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)
184*4882a593Smuzhiyun 		return 0;
185*4882a593Smuzhiyun 	else {
186*4882a593Smuzhiyun 		u8 *base = BE_memaddr(addr);
187*4882a593Smuzhiyun 		u32 val = readl_le(base);
188*4882a593Smuzhiyun 		return val;
189*4882a593Smuzhiyun 	}
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun /****************************************************************************
193*4882a593Smuzhiyun PARAMETERS:
194*4882a593Smuzhiyun addr    - Emulator memory address to read
195*4882a593Smuzhiyun val     - Value to store
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun REMARKS:
198*4882a593Smuzhiyun Writes a byte value to emulator memory. We have three distinct memory
199*4882a593Smuzhiyun regions that are handled differently, which this function handles.
200*4882a593Smuzhiyun ****************************************************************************/
BE_wrb(u32 addr,u8 val)201*4882a593Smuzhiyun void X86API BE_wrb(u32 addr, u8 val)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun 	if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) {
204*4882a593Smuzhiyun 		writeb_le(BE_memaddr(addr), val);
205*4882a593Smuzhiyun 	}
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun /****************************************************************************
209*4882a593Smuzhiyun PARAMETERS:
210*4882a593Smuzhiyun addr    - Emulator memory address to read
211*4882a593Smuzhiyun val     - Value to store
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun REMARKS:
214*4882a593Smuzhiyun Writes a word value to emulator memory. We have three distinct memory
215*4882a593Smuzhiyun regions that are handled differently, which this function handles.
216*4882a593Smuzhiyun ****************************************************************************/
BE_wrw(u32 addr,u16 val)217*4882a593Smuzhiyun void X86API BE_wrw(u32 addr, u16 val)
218*4882a593Smuzhiyun {
219*4882a593Smuzhiyun 	if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) {
220*4882a593Smuzhiyun 		u8 *base = BE_memaddr(addr);
221*4882a593Smuzhiyun 		writew_le(base, val);
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	}
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun /****************************************************************************
227*4882a593Smuzhiyun PARAMETERS:
228*4882a593Smuzhiyun addr    - Emulator memory address to read
229*4882a593Smuzhiyun val     - Value to store
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun REMARKS:
232*4882a593Smuzhiyun Writes a 32-bit value to emulator memory. We have three distinct memory
233*4882a593Smuzhiyun regions that are handled differently, which this function handles.
234*4882a593Smuzhiyun ****************************************************************************/
BE_wrl(u32 addr,u32 val)235*4882a593Smuzhiyun void X86API BE_wrl(u32 addr, u32 val)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun 	if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) {
238*4882a593Smuzhiyun 		u8 *base = BE_memaddr(addr);
239*4882a593Smuzhiyun 		writel_le(base, val);
240*4882a593Smuzhiyun 	}
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun #if !defined(CONFIG_X86EMU_RAW_IO)
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun /* For Non-Intel machines we may need to emulate some I/O port accesses that
246*4882a593Smuzhiyun  * the BIOS may try to access, such as the PCI config registers.
247*4882a593Smuzhiyun  */
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun #define IS_TIMER_PORT(port) (0x40 <= port && port <= 0x43)
250*4882a593Smuzhiyun #define IS_CMOS_PORT(port)  (0x70 <= port && port <= 0x71)
251*4882a593Smuzhiyun /*#define IS_VGA_PORT(port)   (_BE_env.emulateVGA && 0x3C0 <= port && port <= 0x3DA)*/
252*4882a593Smuzhiyun #define IS_VGA_PORT(port)   (0x3C0 <= port && port <= 0x3DA)
253*4882a593Smuzhiyun #define IS_PCI_PORT(port)   (0xCF8 <= port && port <= 0xCFF)
254*4882a593Smuzhiyun #define IS_SPKR_PORT(port)  (port == 0x61)
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun /****************************************************************************
257*4882a593Smuzhiyun PARAMETERS:
258*4882a593Smuzhiyun port    - Port to read from
259*4882a593Smuzhiyun type    - Type of access to perform
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun REMARKS:
262*4882a593Smuzhiyun Performs an emulated read from the Standard VGA I/O ports. If the target
263*4882a593Smuzhiyun hardware does not support mapping the VGA I/O and memory (such as some
264*4882a593Smuzhiyun PowerPC systems), we emulate the VGA so that the BIOS will still be able to
265*4882a593Smuzhiyun set NonVGA display modes such as on ATI hardware.
266*4882a593Smuzhiyun ****************************************************************************/
VGA_inpb(const int port)267*4882a593Smuzhiyun static u8 VGA_inpb (const int port)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun 	u8 val = 0xff;
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	debug_io("vga_inb.%04X -> ", (u16) port);
272*4882a593Smuzhiyun 	switch (port) {
273*4882a593Smuzhiyun 	case 0x3C0:
274*4882a593Smuzhiyun 		/* 3C0 has funky characteristics because it can act as either
275*4882a593Smuzhiyun 		   a data register or index register depending on the state
276*4882a593Smuzhiyun 		   of an internal flip flop in the hardware. Hence we have
277*4882a593Smuzhiyun 		   to emulate that functionality in here. */
278*4882a593Smuzhiyun 		if (_BE_env.flipFlop3C0 == 0) {
279*4882a593Smuzhiyun 			/* Access 3C0 as index register */
280*4882a593Smuzhiyun 			val = _BE_env.emu3C0;
281*4882a593Smuzhiyun 		} else {
282*4882a593Smuzhiyun 			/* Access 3C0 as data register */
283*4882a593Smuzhiyun 			if (_BE_env.emu3C0 < ATT_C)
284*4882a593Smuzhiyun 				val = _BE_env.emu3C1[_BE_env.emu3C0];
285*4882a593Smuzhiyun 		}
286*4882a593Smuzhiyun 		_BE_env.flipFlop3C0 ^= 1;
287*4882a593Smuzhiyun 		break;
288*4882a593Smuzhiyun 	case 0x3C1:
289*4882a593Smuzhiyun 		if (_BE_env.emu3C0 < ATT_C)
290*4882a593Smuzhiyun 			return _BE_env.emu3C1[_BE_env.emu3C0];
291*4882a593Smuzhiyun 		break;
292*4882a593Smuzhiyun 	case 0x3CC:
293*4882a593Smuzhiyun 		return _BE_env.emu3C2;
294*4882a593Smuzhiyun 	case 0x3C4:
295*4882a593Smuzhiyun 		return _BE_env.emu3C4;
296*4882a593Smuzhiyun 	case 0x3C5:
297*4882a593Smuzhiyun 		if (_BE_env.emu3C4 < ATT_C)
298*4882a593Smuzhiyun 			return _BE_env.emu3C5[_BE_env.emu3C4];
299*4882a593Smuzhiyun 		break;
300*4882a593Smuzhiyun 	case 0x3C6:
301*4882a593Smuzhiyun 		return _BE_env.emu3C6;
302*4882a593Smuzhiyun 	case 0x3C7:
303*4882a593Smuzhiyun 		return _BE_env.emu3C7;
304*4882a593Smuzhiyun 	case 0x3C8:
305*4882a593Smuzhiyun 		return _BE_env.emu3C8;
306*4882a593Smuzhiyun 	case 0x3C9:
307*4882a593Smuzhiyun 		if (_BE_env.emu3C7 < PAL_C)
308*4882a593Smuzhiyun 			return _BE_env.emu3C9[_BE_env.emu3C7++];
309*4882a593Smuzhiyun 		break;
310*4882a593Smuzhiyun 	case 0x3CE:
311*4882a593Smuzhiyun 		return _BE_env.emu3CE;
312*4882a593Smuzhiyun 	case 0x3CF:
313*4882a593Smuzhiyun 		if (_BE_env.emu3CE < GRA_C)
314*4882a593Smuzhiyun 			return _BE_env.emu3CF[_BE_env.emu3CE];
315*4882a593Smuzhiyun 		break;
316*4882a593Smuzhiyun 	case 0x3D4:
317*4882a593Smuzhiyun 		if (_BE_env.emu3C2 & 0x1)
318*4882a593Smuzhiyun 			return _BE_env.emu3D4;
319*4882a593Smuzhiyun 		break;
320*4882a593Smuzhiyun 	case 0x3D5:
321*4882a593Smuzhiyun 		if ((_BE_env.emu3C2 & 0x1) && (_BE_env.emu3D4 < CRT_C))
322*4882a593Smuzhiyun 			return _BE_env.emu3D5[_BE_env.emu3D4];
323*4882a593Smuzhiyun 		break;
324*4882a593Smuzhiyun 	case 0x3DA:
325*4882a593Smuzhiyun 		_BE_env.flipFlop3C0 = 0;
326*4882a593Smuzhiyun 		val = _BE_env.emu3DA;
327*4882a593Smuzhiyun 		_BE_env.emu3DA ^= 0x9;
328*4882a593Smuzhiyun 		break;
329*4882a593Smuzhiyun 	}
330*4882a593Smuzhiyun 	return val;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun /****************************************************************************
334*4882a593Smuzhiyun PARAMETERS:
335*4882a593Smuzhiyun port    - Port to write to
336*4882a593Smuzhiyun type    - Type of access to perform
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun REMARKS:
339*4882a593Smuzhiyun Performs an emulated write to one of the 8253 timer registers. For now
340*4882a593Smuzhiyun we only emulate timer 0 which is the only timer that the BIOS code appears
341*4882a593Smuzhiyun to use.
342*4882a593Smuzhiyun ****************************************************************************/
VGA_outpb(int port,u8 val)343*4882a593Smuzhiyun static void VGA_outpb (int port, u8 val)
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun 	switch (port) {
346*4882a593Smuzhiyun 	case 0x3C0:
347*4882a593Smuzhiyun 		/* 3C0 has funky characteristics because it can act as either
348*4882a593Smuzhiyun 		   a data register or index register depending on the state
349*4882a593Smuzhiyun 		   of an internal flip flop in the hardware. Hence we have
350*4882a593Smuzhiyun 		   to emulate that functionality in here. */
351*4882a593Smuzhiyun 		if (_BE_env.flipFlop3C0 == 0) {
352*4882a593Smuzhiyun 			/* Access 3C0 as index register */
353*4882a593Smuzhiyun 			_BE_env.emu3C0 = val;
354*4882a593Smuzhiyun 		} else {
355*4882a593Smuzhiyun 			/* Access 3C0 as data register */
356*4882a593Smuzhiyun 			if (_BE_env.emu3C0 < ATT_C)
357*4882a593Smuzhiyun 				_BE_env.emu3C1[_BE_env.emu3C0] = val;
358*4882a593Smuzhiyun 		}
359*4882a593Smuzhiyun 		_BE_env.flipFlop3C0 ^= 1;
360*4882a593Smuzhiyun 		break;
361*4882a593Smuzhiyun 	case 0x3C2:
362*4882a593Smuzhiyun 		_BE_env.emu3C2 = val;
363*4882a593Smuzhiyun 		break;
364*4882a593Smuzhiyun 	case 0x3C4:
365*4882a593Smuzhiyun 		_BE_env.emu3C4 = val;
366*4882a593Smuzhiyun 		break;
367*4882a593Smuzhiyun 	case 0x3C5:
368*4882a593Smuzhiyun 		if (_BE_env.emu3C4 < ATT_C)
369*4882a593Smuzhiyun 			_BE_env.emu3C5[_BE_env.emu3C4] = val;
370*4882a593Smuzhiyun 		break;
371*4882a593Smuzhiyun 	case 0x3C6:
372*4882a593Smuzhiyun 		_BE_env.emu3C6 = val;
373*4882a593Smuzhiyun 		break;
374*4882a593Smuzhiyun 	case 0x3C7:
375*4882a593Smuzhiyun 		_BE_env.emu3C7 = (int) val *3;
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 		break;
378*4882a593Smuzhiyun 	case 0x3C8:
379*4882a593Smuzhiyun 		_BE_env.emu3C8 = (int) val *3;
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 		break;
382*4882a593Smuzhiyun 	case 0x3C9:
383*4882a593Smuzhiyun 		if (_BE_env.emu3C8 < PAL_C)
384*4882a593Smuzhiyun 			_BE_env.emu3C9[_BE_env.emu3C8++] = val;
385*4882a593Smuzhiyun 		break;
386*4882a593Smuzhiyun 	case 0x3CE:
387*4882a593Smuzhiyun 		_BE_env.emu3CE = val;
388*4882a593Smuzhiyun 		break;
389*4882a593Smuzhiyun 	case 0x3CF:
390*4882a593Smuzhiyun 		if (_BE_env.emu3CE < GRA_C)
391*4882a593Smuzhiyun 			_BE_env.emu3CF[_BE_env.emu3CE] = val;
392*4882a593Smuzhiyun 		break;
393*4882a593Smuzhiyun 	case 0x3D4:
394*4882a593Smuzhiyun 		if (_BE_env.emu3C2 & 0x1)
395*4882a593Smuzhiyun 			_BE_env.emu3D4 = val;
396*4882a593Smuzhiyun 		break;
397*4882a593Smuzhiyun 	case 0x3D5:
398*4882a593Smuzhiyun 		if ((_BE_env.emu3C2 & 0x1) && (_BE_env.emu3D4 < CRT_C))
399*4882a593Smuzhiyun 			_BE_env.emu3D5[_BE_env.emu3D4] = val;
400*4882a593Smuzhiyun 		break;
401*4882a593Smuzhiyun 	}
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun /****************************************************************************
405*4882a593Smuzhiyun PARAMETERS:
406*4882a593Smuzhiyun regOffset   - Offset into register space for non-DWORD accesses
407*4882a593Smuzhiyun value       - Value to write to register for PCI_WRITE_* operations
408*4882a593Smuzhiyun func        - Function to perform (PCIAccessRegFlags)
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun RETURNS:
411*4882a593Smuzhiyun Value read from configuration register for PCI_READ_* operations
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun REMARKS:
414*4882a593Smuzhiyun Accesses a PCI configuration space register by decoding the value currently
415*4882a593Smuzhiyun stored in the _BE_env.configAddress variable and passing it through to the
416*4882a593Smuzhiyun portable PCI_accessReg function.
417*4882a593Smuzhiyun ****************************************************************************/
BE_accessReg(int regOffset,u32 value,int func)418*4882a593Smuzhiyun static u32 BE_accessReg(int regOffset, u32 value, int func)
419*4882a593Smuzhiyun {
420*4882a593Smuzhiyun #ifdef __KERNEL__
421*4882a593Smuzhiyun 	int function, device, bus;
422*4882a593Smuzhiyun 	u8 val8;
423*4882a593Smuzhiyun 	u16 val16;
424*4882a593Smuzhiyun 	u32 val32;
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	/* Decode the configuration register values for the register we wish to
428*4882a593Smuzhiyun 	 * access
429*4882a593Smuzhiyun 	 */
430*4882a593Smuzhiyun 	regOffset += (_BE_env.configAddress & 0xFF);
431*4882a593Smuzhiyun 	function = (_BE_env.configAddress >> 8) & 0x7;
432*4882a593Smuzhiyun 	device = (_BE_env.configAddress >> 11) & 0x1F;
433*4882a593Smuzhiyun 	bus = (_BE_env.configAddress >> 16) & 0xFF;
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	/* Ignore accesses to all devices other than the one we're POSTing */
436*4882a593Smuzhiyun 	if ((function == _BE_env.vgaInfo.function) &&
437*4882a593Smuzhiyun 	    (device == _BE_env.vgaInfo.device) &&
438*4882a593Smuzhiyun 	    (bus == _BE_env.vgaInfo.bus)) {
439*4882a593Smuzhiyun 		switch (func) {
440*4882a593Smuzhiyun 		case REG_READ_BYTE:
441*4882a593Smuzhiyun 			pci_read_config_byte(_BE_env.vgaInfo.pcidev, regOffset,
442*4882a593Smuzhiyun 					     &val8);
443*4882a593Smuzhiyun 			return val8;
444*4882a593Smuzhiyun 		case REG_READ_WORD:
445*4882a593Smuzhiyun 			pci_read_config_word(_BE_env.vgaInfo.pcidev, regOffset,
446*4882a593Smuzhiyun 					     &val16);
447*4882a593Smuzhiyun 			return val16;
448*4882a593Smuzhiyun 		case REG_READ_DWORD:
449*4882a593Smuzhiyun 			pci_read_config_dword(_BE_env.vgaInfo.pcidev, regOffset,
450*4882a593Smuzhiyun 					      &val32);
451*4882a593Smuzhiyun 			return val32;
452*4882a593Smuzhiyun 		case REG_WRITE_BYTE:
453*4882a593Smuzhiyun 			pci_write_config_byte(_BE_env.vgaInfo.pcidev, regOffset,
454*4882a593Smuzhiyun 					      value);
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 			return 0;
457*4882a593Smuzhiyun 		case REG_WRITE_WORD:
458*4882a593Smuzhiyun 			pci_write_config_word(_BE_env.vgaInfo.pcidev, regOffset,
459*4882a593Smuzhiyun 					      value);
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 			return 0;
462*4882a593Smuzhiyun 		case REG_WRITE_DWORD:
463*4882a593Smuzhiyun 			pci_write_config_dword(_BE_env.vgaInfo.pcidev,
464*4882a593Smuzhiyun 					       regOffset, value);
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 			return 0;
467*4882a593Smuzhiyun 		}
468*4882a593Smuzhiyun 	}
469*4882a593Smuzhiyun 	return 0;
470*4882a593Smuzhiyun #else
471*4882a593Smuzhiyun 	PCIDeviceInfo pciInfo;
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	pciInfo.mech1 = 1;
474*4882a593Smuzhiyun 	pciInfo.slot.i = 0;
475*4882a593Smuzhiyun 	pciInfo.slot.p.Function = (_BE_env.configAddress >> 8) & 0x7;
476*4882a593Smuzhiyun 	pciInfo.slot.p.Device = (_BE_env.configAddress >> 11) & 0x1F;
477*4882a593Smuzhiyun 	pciInfo.slot.p.Bus = (_BE_env.configAddress >> 16) & 0xFF;
478*4882a593Smuzhiyun 	pciInfo.slot.p.Enable = 1;
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 	/* Ignore accesses to all devices other than the one we're POSTing */
481*4882a593Smuzhiyun 	if ((pciInfo.slot.p.Function ==
482*4882a593Smuzhiyun 	     _BE_env.vgaInfo.pciInfo->slot.p.Function)
483*4882a593Smuzhiyun 	    && (pciInfo.slot.p.Device == _BE_env.vgaInfo.pciInfo->slot.p.Device)
484*4882a593Smuzhiyun 	    && (pciInfo.slot.p.Bus == _BE_env.vgaInfo.pciInfo->slot.p.Bus))
485*4882a593Smuzhiyun 		return PCI_accessReg((_BE_env.configAddress & 0xFF) + regOffset,
486*4882a593Smuzhiyun 				     value, func, &pciInfo);
487*4882a593Smuzhiyun 	return 0;
488*4882a593Smuzhiyun #endif
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun /****************************************************************************
492*4882a593Smuzhiyun PARAMETERS:
493*4882a593Smuzhiyun port    - Port to read from
494*4882a593Smuzhiyun type    - Type of access to perform
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun REMARKS:
497*4882a593Smuzhiyun Performs an emulated read from one of the PCI configuration space registers.
498*4882a593Smuzhiyun We emulate this using our PCI_accessReg function which will access the PCI
499*4882a593Smuzhiyun configuration space registers in a portable fashion.
500*4882a593Smuzhiyun ****************************************************************************/
PCI_inp(int port,int type)501*4882a593Smuzhiyun static u32 PCI_inp(int port, int type)
502*4882a593Smuzhiyun {
503*4882a593Smuzhiyun 	switch (type) {
504*4882a593Smuzhiyun 	case REG_READ_BYTE:
505*4882a593Smuzhiyun 		if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
506*4882a593Smuzhiyun 		    && port <= 0xCFF)
507*4882a593Smuzhiyun 			return BE_accessReg(port - 0xCFC, 0, REG_READ_BYTE);
508*4882a593Smuzhiyun 		break;
509*4882a593Smuzhiyun 	case REG_READ_WORD:
510*4882a593Smuzhiyun 		if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
511*4882a593Smuzhiyun 		    && port <= 0xCFF)
512*4882a593Smuzhiyun 			return BE_accessReg(port - 0xCFC, 0, REG_READ_WORD);
513*4882a593Smuzhiyun 		break;
514*4882a593Smuzhiyun 	case REG_READ_DWORD:
515*4882a593Smuzhiyun 		if (port == 0xCF8)
516*4882a593Smuzhiyun 			return _BE_env.configAddress;
517*4882a593Smuzhiyun 		else if ((_BE_env.configAddress & 0x80000000) && port == 0xCFC)
518*4882a593Smuzhiyun 			return BE_accessReg(0, 0, REG_READ_DWORD);
519*4882a593Smuzhiyun 		break;
520*4882a593Smuzhiyun 	}
521*4882a593Smuzhiyun 	return 0;
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun /****************************************************************************
525*4882a593Smuzhiyun PARAMETERS:
526*4882a593Smuzhiyun port    - Port to write to
527*4882a593Smuzhiyun type    - Type of access to perform
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun REMARKS:
530*4882a593Smuzhiyun Performs an emulated write to one of the PCI control registers.
531*4882a593Smuzhiyun ****************************************************************************/
PCI_outp(int port,u32 val,int type)532*4882a593Smuzhiyun static void PCI_outp(int port, u32 val, int type)
533*4882a593Smuzhiyun {
534*4882a593Smuzhiyun 	switch (type) {
535*4882a593Smuzhiyun 	case REG_WRITE_BYTE:
536*4882a593Smuzhiyun 		if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
537*4882a593Smuzhiyun 		    && port <= 0xCFF)
538*4882a593Smuzhiyun 			BE_accessReg(port - 0xCFC, val, REG_WRITE_BYTE);
539*4882a593Smuzhiyun 		break;
540*4882a593Smuzhiyun 	case REG_WRITE_WORD:
541*4882a593Smuzhiyun 		if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
542*4882a593Smuzhiyun 		    && port <= 0xCFF)
543*4882a593Smuzhiyun 			BE_accessReg(port - 0xCFC, val, REG_WRITE_WORD);
544*4882a593Smuzhiyun 		break;
545*4882a593Smuzhiyun 	case REG_WRITE_DWORD:
546*4882a593Smuzhiyun 		if (port == 0xCF8)
547*4882a593Smuzhiyun 		{
548*4882a593Smuzhiyun 			_BE_env.configAddress = val & 0x80FFFFFC;
549*4882a593Smuzhiyun 		}
550*4882a593Smuzhiyun 		else if ((_BE_env.configAddress & 0x80000000) && port == 0xCFC)
551*4882a593Smuzhiyun 			BE_accessReg(0, val, REG_WRITE_DWORD);
552*4882a593Smuzhiyun 		break;
553*4882a593Smuzhiyun 	}
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun #endif
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun /****************************************************************************
559*4882a593Smuzhiyun PARAMETERS:
560*4882a593Smuzhiyun port    - Port to write to
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun RETURNS:
563*4882a593Smuzhiyun Value read from the I/O port
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun REMARKS:
566*4882a593Smuzhiyun Performs an emulated 8-bit read from an I/O port. We handle special cases
567*4882a593Smuzhiyun that we need to emulate in here, and fall through to reflecting the write
568*4882a593Smuzhiyun through to the real hardware if we don't need to special case it.
569*4882a593Smuzhiyun ****************************************************************************/
BE_inb(X86EMU_pioAddr port)570*4882a593Smuzhiyun u8 X86API BE_inb(X86EMU_pioAddr port)
571*4882a593Smuzhiyun {
572*4882a593Smuzhiyun 	u8 val = 0;
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun #if !defined(CONFIG_X86EMU_RAW_IO)
575*4882a593Smuzhiyun 	if (IS_VGA_PORT(port)){
576*4882a593Smuzhiyun 		/*seems reading port 0x3c3 return the high 16 bit of io port*/
577*4882a593Smuzhiyun 		if(port == 0x3c3)
578*4882a593Smuzhiyun 			val = LOG_inpb(port);
579*4882a593Smuzhiyun 		else
580*4882a593Smuzhiyun 			val = VGA_inpb(port);
581*4882a593Smuzhiyun 	}
582*4882a593Smuzhiyun 	else if (IS_TIMER_PORT(port))
583*4882a593Smuzhiyun 		DB(printf("Can not interept TIMER port now!\n");)
584*4882a593Smuzhiyun 	else if (IS_SPKR_PORT(port))
585*4882a593Smuzhiyun 		DB(printf("Can not interept SPEAKER port now!\n");)
586*4882a593Smuzhiyun 	else if (IS_CMOS_PORT(port))
587*4882a593Smuzhiyun 		DB(printf("Can not interept CMOS port now!\n");)
588*4882a593Smuzhiyun 	else if (IS_PCI_PORT(port))
589*4882a593Smuzhiyun 		val = PCI_inp(port, REG_READ_BYTE);
590*4882a593Smuzhiyun 	else if (port < 0x100) {
591*4882a593Smuzhiyun 		DB(printf("WARN: INVALID inb.%04X -> %02X\n", (u16) port, val);)
592*4882a593Smuzhiyun 		val = LOG_inpb(port);
593*4882a593Smuzhiyun 	} else
594*4882a593Smuzhiyun #endif
595*4882a593Smuzhiyun 	{
596*4882a593Smuzhiyun 		debug_io("inb.%04X -> ", (u16) port);
597*4882a593Smuzhiyun 		val = LOG_inpb(port);
598*4882a593Smuzhiyun 		debug_io("%02X\n", val);
599*4882a593Smuzhiyun 	}
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 	return val;
602*4882a593Smuzhiyun }
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun /****************************************************************************
605*4882a593Smuzhiyun PARAMETERS:
606*4882a593Smuzhiyun port    - Port to write to
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun RETURNS:
609*4882a593Smuzhiyun Value read from the I/O port
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun REMARKS:
612*4882a593Smuzhiyun Performs an emulated 16-bit read from an I/O port. We handle special cases
613*4882a593Smuzhiyun that we need to emulate in here, and fall through to reflecting the write
614*4882a593Smuzhiyun through to the real hardware if we don't need to special case it.
615*4882a593Smuzhiyun ****************************************************************************/
BE_inw(X86EMU_pioAddr port)616*4882a593Smuzhiyun u16 X86API BE_inw(X86EMU_pioAddr port)
617*4882a593Smuzhiyun {
618*4882a593Smuzhiyun 	u16 val = 0;
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun #if !defined(CONFIG_X86EMU_RAW_IO)
621*4882a593Smuzhiyun 	if (IS_PCI_PORT(port))
622*4882a593Smuzhiyun 		val = PCI_inp(port, REG_READ_WORD);
623*4882a593Smuzhiyun 	else if (port < 0x100) {
624*4882a593Smuzhiyun 		DB(printf("WARN: Maybe INVALID inw.%04X -> %04X\n", (u16) port, val);)
625*4882a593Smuzhiyun 		val = LOG_inpw(port);
626*4882a593Smuzhiyun 	} else
627*4882a593Smuzhiyun #endif
628*4882a593Smuzhiyun 	{
629*4882a593Smuzhiyun 		debug_io("inw.%04X -> ", (u16) port);
630*4882a593Smuzhiyun 		val = LOG_inpw(port);
631*4882a593Smuzhiyun 		debug_io("%04X\n", val);
632*4882a593Smuzhiyun 	}
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	return val;
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun /****************************************************************************
638*4882a593Smuzhiyun PARAMETERS:
639*4882a593Smuzhiyun port    - Port to write to
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun RETURNS:
642*4882a593Smuzhiyun Value read from the I/O port
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun REMARKS:
645*4882a593Smuzhiyun Performs an emulated 32-bit read from an I/O port. We handle special cases
646*4882a593Smuzhiyun that we need to emulate in here, and fall through to reflecting the write
647*4882a593Smuzhiyun through to the real hardware if we don't need to special case it.
648*4882a593Smuzhiyun ****************************************************************************/
BE_inl(X86EMU_pioAddr port)649*4882a593Smuzhiyun u32 X86API BE_inl(X86EMU_pioAddr port)
650*4882a593Smuzhiyun {
651*4882a593Smuzhiyun 	u32 val = 0;
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun #if !defined(CONFIG_X86EMU_RAW_IO)
654*4882a593Smuzhiyun 	if (IS_PCI_PORT(port))
655*4882a593Smuzhiyun 		val = PCI_inp(port, REG_READ_DWORD);
656*4882a593Smuzhiyun 	else if (port < 0x100) {
657*4882a593Smuzhiyun 		val = LOG_inpd(port);
658*4882a593Smuzhiyun 	} else
659*4882a593Smuzhiyun #endif
660*4882a593Smuzhiyun 	{
661*4882a593Smuzhiyun 		debug_io("inl.%04X -> ", (u16) port);
662*4882a593Smuzhiyun 		val = LOG_inpd(port);
663*4882a593Smuzhiyun 		debug_io("%08X\n", val);
664*4882a593Smuzhiyun 	}
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun 	return val;
667*4882a593Smuzhiyun }
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun /****************************************************************************
670*4882a593Smuzhiyun PARAMETERS:
671*4882a593Smuzhiyun port    - Port to write to
672*4882a593Smuzhiyun val     - Value to write to port
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun REMARKS:
675*4882a593Smuzhiyun Performs an emulated 8-bit write to an I/O port. We handle special cases
676*4882a593Smuzhiyun that we need to emulate in here, and fall through to reflecting the write
677*4882a593Smuzhiyun through to the real hardware if we don't need to special case it.
678*4882a593Smuzhiyun ****************************************************************************/
BE_outb(X86EMU_pioAddr port,u8 val)679*4882a593Smuzhiyun void X86API BE_outb(X86EMU_pioAddr port, u8 val)
680*4882a593Smuzhiyun {
681*4882a593Smuzhiyun #if !defined(CONFIG_X86EMU_RAW_IO)
682*4882a593Smuzhiyun 	if (IS_VGA_PORT(port))
683*4882a593Smuzhiyun 		VGA_outpb(port, val);
684*4882a593Smuzhiyun 	else if (IS_TIMER_PORT(port))
685*4882a593Smuzhiyun 		DB(printf("Can not interept TIMER port now!\n");)
686*4882a593Smuzhiyun 	else if (IS_SPKR_PORT(port))
687*4882a593Smuzhiyun 		DB(printf("Can not interept SPEAKER port now!\n");)
688*4882a593Smuzhiyun 	else if (IS_CMOS_PORT(port))
689*4882a593Smuzhiyun 		DB(printf("Can not interept CMOS port now!\n");)
690*4882a593Smuzhiyun 	else if (IS_PCI_PORT(port))
691*4882a593Smuzhiyun 		PCI_outp(port, val, REG_WRITE_BYTE);
692*4882a593Smuzhiyun 	else if (port < 0x100) {
693*4882a593Smuzhiyun 		DB(printf("WARN:Maybe INVALID outb.%04X <- %02X\n", (u16) port, val);)
694*4882a593Smuzhiyun 		LOG_outpb(port, val);
695*4882a593Smuzhiyun 	} else
696*4882a593Smuzhiyun #endif
697*4882a593Smuzhiyun 	{
698*4882a593Smuzhiyun 		debug_io("outb.%04X <- %02X", (u16) port, val);
699*4882a593Smuzhiyun 		LOG_outpb(port, val);
700*4882a593Smuzhiyun 		debug_io("\n");
701*4882a593Smuzhiyun 	}
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun /****************************************************************************
705*4882a593Smuzhiyun PARAMETERS:
706*4882a593Smuzhiyun port    - Port to write to
707*4882a593Smuzhiyun val     - Value to write to port
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun REMARKS:
710*4882a593Smuzhiyun Performs an emulated 16-bit write to an I/O port. We handle special cases
711*4882a593Smuzhiyun that we need to emulate in here, and fall through to reflecting the write
712*4882a593Smuzhiyun through to the real hardware if we don't need to special case it.
713*4882a593Smuzhiyun ****************************************************************************/
BE_outw(X86EMU_pioAddr port,u16 val)714*4882a593Smuzhiyun void X86API BE_outw(X86EMU_pioAddr port, u16 val)
715*4882a593Smuzhiyun {
716*4882a593Smuzhiyun #if !defined(CONFIG_X86EMU_RAW_IO)
717*4882a593Smuzhiyun 	if (IS_VGA_PORT(port)) {
718*4882a593Smuzhiyun 		VGA_outpb(port, val);
719*4882a593Smuzhiyun 		VGA_outpb(port + 1, val >> 8);
720*4882a593Smuzhiyun 	} else if (IS_PCI_PORT(port)) {
721*4882a593Smuzhiyun 		PCI_outp(port, val, REG_WRITE_WORD);
722*4882a593Smuzhiyun 	} else if (port < 0x100) {
723*4882a593Smuzhiyun 		DB(printf("WARN: MAybe INVALID outw.%04X <- %04X\n", (u16)port,
724*4882a593Smuzhiyun 			  val);)
725*4882a593Smuzhiyun 		LOG_outpw(port, val);
726*4882a593Smuzhiyun 	} else
727*4882a593Smuzhiyun #endif
728*4882a593Smuzhiyun 	{
729*4882a593Smuzhiyun 		debug_io("outw.%04X <- %04X", (u16) port, val);
730*4882a593Smuzhiyun 		LOG_outpw(port, val);
731*4882a593Smuzhiyun 		debug_io("\n");
732*4882a593Smuzhiyun 	}
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun 
735*4882a593Smuzhiyun /****************************************************************************
736*4882a593Smuzhiyun PARAMETERS:
737*4882a593Smuzhiyun port    - Port to write to
738*4882a593Smuzhiyun val     - Value to write to port
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun REMARKS:
741*4882a593Smuzhiyun Performs an emulated 32-bit write to an I/O port. We handle special cases
742*4882a593Smuzhiyun that we need to emulate in here, and fall through to reflecting the write
743*4882a593Smuzhiyun through to the real hardware if we don't need to special case it.
744*4882a593Smuzhiyun ****************************************************************************/
BE_outl(X86EMU_pioAddr port,u32 val)745*4882a593Smuzhiyun void X86API BE_outl(X86EMU_pioAddr port, u32 val)
746*4882a593Smuzhiyun {
747*4882a593Smuzhiyun #if !defined(CONFIG_X86EMU_RAW_IO)
748*4882a593Smuzhiyun 	if (IS_PCI_PORT(port)) {
749*4882a593Smuzhiyun 		PCI_outp(port, val, REG_WRITE_DWORD);
750*4882a593Smuzhiyun 	} else if (port < 0x100) {
751*4882a593Smuzhiyun 		DB(printf("WARN: INVALID outl.%04X <- %08X\n", (u16) port,val);)
752*4882a593Smuzhiyun 		LOG_outpd(port, val);
753*4882a593Smuzhiyun 	} else
754*4882a593Smuzhiyun #endif
755*4882a593Smuzhiyun 	{
756*4882a593Smuzhiyun 		debug_io("outl.%04X <- %08X", (u16) port, val);
757*4882a593Smuzhiyun 		LOG_outpd(port, val);
758*4882a593Smuzhiyun 		debug_io("\n");
759*4882a593Smuzhiyun 	}
760*4882a593Smuzhiyun }
761