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