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