1 /**************************************************************************** 2 * 3 * BIOS emulator and interface 4 * to Realmode X86 Emulator Library 5 * 6 * ======================================================================== 7 * 8 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. 9 * Jason Jin<Jason.jin@freescale.com> 10 * 11 * Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. 12 * 13 * This file may be distributed and/or modified under the terms of the 14 * GNU General Public License version 2.0 as published by the Free 15 * Software Foundation and appearing in the file LICENSE.GPL included 16 * in the packaging of this file. 17 * 18 * Licensees holding a valid Commercial License for this product from 19 * SciTech Software, Inc. may use this file in accordance with the 20 * Commercial License Agreement provided with the Software. 21 * 22 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING 23 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE. 25 * 26 * See http://www.scitechsoft.com/license/ for information about 27 * the licensing options available and how to purchase a Commercial 28 * License Agreement. 29 * 30 * Contact license@scitechsoft.com if any conditions of this licensing 31 * are not clear to you, or you have questions about licensing options. 32 * 33 * ======================================================================== 34 * 35 * Language: ANSI C 36 * Environment: Any 37 * Developer: Kendall Bennett 38 * 39 * Description: This file includes BIOS emulator I/O and memory access 40 * functions. 41 * 42 * Jason ported this file to u-boot to run the ATI video card 43 * BIOS in u-boot. Removed some emulate functions such as the 44 * timer port access. Made all the VGA port except reading 0x3c3 45 * be emulated. Seems like reading 0x3c3 should return the high 46 * 16 bit of the io port. 47 * 48 ****************************************************************************/ 49 50 #if defined(CONFIG_BIOSEMU) 51 52 #include "biosemui.h" 53 54 /*------------------------- Global Variables ------------------------------*/ 55 56 #ifndef __i386__ 57 static char *BE_biosDate = "08/14/99"; 58 static u8 BE_model = 0xFC; 59 static u8 BE_submodel = 0x00; 60 #endif 61 62 /*----------------------------- Implementation ----------------------------*/ 63 64 /**************************************************************************** 65 PARAMETERS: 66 addr - Emulator memory address to convert 67 68 RETURNS: 69 Actual memory address to read or write the data 70 71 REMARKS: 72 This function converts an emulator memory address in a 32-bit range to 73 a real memory address that we wish to access. It handles splitting up the 74 memory address space appropriately to access the emulator BIOS image, video 75 memory and system BIOS etc. 76 ****************************************************************************/ 77 static 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 /**************************************************************************** 117 PARAMETERS: 118 addr - Emulator memory address to read 119 120 RETURNS: 121 Byte value read from emulator memory. 122 123 REMARKS: 124 Reads a byte value from the emulator memory. We have three distinct memory 125 regions that are handled differently, which this function handles. 126 ****************************************************************************/ 127 u8 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 /**************************************************************************** 138 PARAMETERS: 139 addr - Emulator memory address to read 140 141 RETURNS: 142 Word value read from emulator memory. 143 144 REMARKS: 145 Reads a word value from the emulator memory. We have three distinct memory 146 regions that are handled differently, which this function handles. 147 ****************************************************************************/ 148 u16 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 /**************************************************************************** 160 PARAMETERS: 161 addr - Emulator memory address to read 162 163 RETURNS: 164 Long value read from emulator memory. 165 166 REMARKS: 167 Reads a 32-bit value from the emulator memory. We have three distinct memory 168 regions that are handled differently, which this function handles. 169 ****************************************************************************/ 170 u32 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 /**************************************************************************** 182 PARAMETERS: 183 addr - Emulator memory address to read 184 val - Value to store 185 186 REMARKS: 187 Writes a byte value to emulator memory. We have three distinct memory 188 regions that are handled differently, which this function handles. 189 ****************************************************************************/ 190 void 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 /**************************************************************************** 198 PARAMETERS: 199 addr - Emulator memory address to read 200 val - Value to store 201 202 REMARKS: 203 Writes a word value to emulator memory. We have three distinct memory 204 regions that are handled differently, which this function handles. 205 ****************************************************************************/ 206 void 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 /**************************************************************************** 216 PARAMETERS: 217 addr - Emulator memory address to read 218 val - Value to store 219 220 REMARKS: 221 Writes a 32-bit value to emulator memory. We have three distinct memory 222 regions that are handled differently, which this function handles. 223 ****************************************************************************/ 224 void 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 /**************************************************************************** 246 PARAMETERS: 247 port - Port to read from 248 type - Type of access to perform 249 250 REMARKS: 251 Performs an emulated read from the Standard VGA I/O ports. If the target 252 hardware does not support mapping the VGA I/O and memory (such as some 253 PowerPC systems), we emulate the VGA so that the BIOS will still be able to 254 set NonVGA display modes such as on ATI hardware. 255 ****************************************************************************/ 256 static u8 VGA_inpb (const int port) 257 { 258 u8 val = 0xff; 259 260 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; 319 } 320 321 /**************************************************************************** 322 PARAMETERS: 323 port - Port to write to 324 type - Type of access to perform 325 326 REMARKS: 327 Performs an emulated write to one of the 8253 timer registers. For now 328 we only emulate timer 0 which is the only timer that the BIOS code appears 329 to use. 330 ****************************************************************************/ 331 static void VGA_outpb (int port, u8 val) 332 { 333 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 } 390 } 391 392 /**************************************************************************** 393 PARAMETERS: 394 regOffset - Offset into register space for non-DWORD accesses 395 value - Value to write to register for PCI_WRITE_* operations 396 func - Function to perform (PCIAccessRegFlags) 397 398 RETURNS: 399 Value read from configuration register for PCI_READ_* operations 400 401 REMARKS: 402 Accesses a PCI configuration space register by decoding the value currently 403 stored in the _BE_env.configAddress variable and passing it through to the 404 portable PCI_accessReg function. 405 ****************************************************************************/ 406 static 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 /**************************************************************************** 480 PARAMETERS: 481 port - Port to read from 482 type - Type of access to perform 483 484 REMARKS: 485 Performs an emulated read from one of the PCI configuration space registers. 486 We emulate this using our PCI_accessReg function which will access the PCI 487 configuration space registers in a portable fashion. 488 ****************************************************************************/ 489 static 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 /**************************************************************************** 513 PARAMETERS: 514 port - Port to write to 515 type - Type of access to perform 516 517 REMARKS: 518 Performs an emulated write to one of the PCI control registers. 519 ****************************************************************************/ 520 static 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 /**************************************************************************** 547 PARAMETERS: 548 port - Port to write to 549 550 RETURNS: 551 Value read from the I/O port 552 553 REMARKS: 554 Performs an emulated 8-bit read from an I/O port. We handle special cases 555 that we need to emulate in here, and fall through to reflecting the write 556 through to the real hardware if we don't need to special case it. 557 ****************************************************************************/ 558 u8 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 /**************************************************************************** 588 PARAMETERS: 589 port - Port to write to 590 591 RETURNS: 592 Value read from the I/O port 593 594 REMARKS: 595 Performs an emulated 16-bit read from an I/O port. We handle special cases 596 that we need to emulate in here, and fall through to reflecting the write 597 through to the real hardware if we don't need to special case it. 598 ****************************************************************************/ 599 u16 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 /**************************************************************************** 616 PARAMETERS: 617 port - Port to write to 618 619 RETURNS: 620 Value read from the I/O port 621 622 REMARKS: 623 Performs an emulated 32-bit read from an I/O port. We handle special cases 624 that we need to emulate in here, and fall through to reflecting the write 625 through to the real hardware if we don't need to special case it. 626 ****************************************************************************/ 627 u32 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 /**************************************************************************** 643 PARAMETERS: 644 port - Port to write to 645 val - Value to write to port 646 647 REMARKS: 648 Performs an emulated 8-bit write to an I/O port. We handle special cases 649 that we need to emulate in here, and fall through to reflecting the write 650 through to the real hardware if we don't need to special case it. 651 ****************************************************************************/ 652 void 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 /**************************************************************************** 674 PARAMETERS: 675 port - Port to write to 676 val - Value to write to port 677 678 REMARKS: 679 Performs an emulated 16-bit write to an I/O port. We handle special cases 680 that we need to emulate in here, and fall through to reflecting the write 681 through to the real hardware if we don't need to special case it. 682 ****************************************************************************/ 683 void 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 /**************************************************************************** 701 PARAMETERS: 702 port - Port to write to 703 val - Value to write to port 704 705 REMARKS: 706 Performs an emulated 32-bit write to an I/O port. We handle special cases 707 that we need to emulate in here, and fall through to reflecting the write 708 through to the real hardware if we don't need to special case it. 709 ****************************************************************************/ 710 void 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 } 722 #endif 723