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