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