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