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