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