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