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