xref: /openbmc/u-boot/drivers/bios_emulator/besys.c (revision b9206e61f3d87535ac4f4b0b858e674fd1edfeaf)
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 <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  ****************************************************************************/
BE_memaddr(u32 addr)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  ****************************************************************************/
BE_rdb(u32 addr)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  ****************************************************************************/
BE_rdw(u32 addr)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  ****************************************************************************/
BE_rdl(u32 addr)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  ****************************************************************************/
BE_wrb(u32 addr,u8 val)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  ****************************************************************************/
BE_wrw(u32 addr,u16 val)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  ****************************************************************************/
BE_wrl(u32 addr,u32 val)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  ****************************************************************************/
VGA_inpb(const int port)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  ****************************************************************************/
VGA_outpb(int port,u8 val)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  ****************************************************************************/
BE_accessReg(int regOffset,u32 value,int func)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  ****************************************************************************/
PCI_inp(int port,int type)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  ****************************************************************************/
PCI_outp(int port,u32 val,int type)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  ****************************************************************************/
BE_inb(X86EMU_pioAddr port)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  ****************************************************************************/
BE_inw(X86EMU_pioAddr port)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  ****************************************************************************/
BE_inl(X86EMU_pioAddr port)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  ****************************************************************************/
BE_outb(X86EMU_pioAddr port,u8 val)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  ****************************************************************************/
BE_outw(X86EMU_pioAddr port,u16 val)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  ****************************************************************************/
BE_outl(X86EMU_pioAddr port,u32 val)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