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