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