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