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#define __io
  51#include <common.h>
  52#include <asm/io.h>
  53#include "biosemui.h"
  54
  55/*------------------------- Global Variables ------------------------------*/
  56
  57#ifndef CONFIG_X86EMU_RAW_IO
  58static char *BE_biosDate = "08/14/99";
  59static u8 BE_model = 0xFC;
  60static 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/****************************************************************************
  74PARAMETERS:
  75addr    - Emulator memory address to convert
  76
  77RETURNS:
  78Actual memory address to read or write the data
  79
  80REMARKS:
  81This function converts an emulator memory address in a 32-bit range to
  82a real memory address that we wish to access. It handles splitting up the
  83memory address space appropriately to access the emulator BIOS image, video
  84memory and system BIOS etc.
  85****************************************************************************/
  86static 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/****************************************************************************
 128PARAMETERS:
 129addr    - Emulator memory address to read
 130
 131RETURNS:
 132Byte value read from emulator memory.
 133
 134REMARKS:
 135Reads a byte value from the emulator memory. We have three distinct memory
 136regions that are handled differently, which this function handles.
 137****************************************************************************/
 138u8 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/****************************************************************************
 149PARAMETERS:
 150addr    - Emulator memory address to read
 151
 152RETURNS:
 153Word value read from emulator memory.
 154
 155REMARKS:
 156Reads a word value from the emulator memory. We have three distinct memory
 157regions that are handled differently, which this function handles.
 158****************************************************************************/
 159u16 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/****************************************************************************
 171PARAMETERS:
 172addr    - Emulator memory address to read
 173
 174RETURNS:
 175Long value read from emulator memory.
 176
 177REMARKS:
 178Reads a 32-bit value from the emulator memory. We have three distinct memory
 179regions that are handled differently, which this function handles.
 180****************************************************************************/
 181u32 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/****************************************************************************
 193PARAMETERS:
 194addr    - Emulator memory address to read
 195val     - Value to store
 196
 197REMARKS:
 198Writes a byte value to emulator memory. We have three distinct memory
 199regions that are handled differently, which this function handles.
 200****************************************************************************/
 201void 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/****************************************************************************
 209PARAMETERS:
 210addr    - Emulator memory address to read
 211val     - Value to store
 212
 213REMARKS:
 214Writes a word value to emulator memory. We have three distinct memory
 215regions that are handled differently, which this function handles.
 216****************************************************************************/
 217void 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/****************************************************************************
 227PARAMETERS:
 228addr    - Emulator memory address to read
 229val     - Value to store
 230
 231REMARKS:
 232Writes a 32-bit value to emulator memory. We have three distinct memory
 233regions that are handled differently, which this function handles.
 234****************************************************************************/
 235void 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/****************************************************************************
 257PARAMETERS:
 258port    - Port to read from
 259type    - Type of access to perform
 260
 261REMARKS:
 262Performs an emulated read from the Standard VGA I/O ports. If the target
 263hardware does not support mapping the VGA I/O and memory (such as some
 264PowerPC systems), we emulate the VGA so that the BIOS will still be able to
 265set NonVGA display modes such as on ATI hardware.
 266****************************************************************************/
 267static 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/****************************************************************************
 334PARAMETERS:
 335port    - Port to write to
 336type    - Type of access to perform
 337
 338REMARKS:
 339Performs an emulated write to one of the 8253 timer registers. For now
 340we only emulate timer 0 which is the only timer that the BIOS code appears
 341to use.
 342****************************************************************************/
 343static 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/****************************************************************************
 405PARAMETERS:
 406regOffset   - Offset into register space for non-DWORD accesses
 407value       - Value to write to register for PCI_WRITE_* operations
 408func        - Function to perform (PCIAccessRegFlags)
 409
 410RETURNS:
 411Value read from configuration register for PCI_READ_* operations
 412
 413REMARKS:
 414Accesses a PCI configuration space register by decoding the value currently
 415stored in the _BE_env.configAddress variable and passing it through to the
 416portable PCI_accessReg function.
 417****************************************************************************/
 418static 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/****************************************************************************
 492PARAMETERS:
 493port    - Port to read from
 494type    - Type of access to perform
 495
 496REMARKS:
 497Performs an emulated read from one of the PCI configuration space registers.
 498We emulate this using our PCI_accessReg function which will access the PCI
 499configuration space registers in a portable fashion.
 500****************************************************************************/
 501static 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/****************************************************************************
 525PARAMETERS:
 526port    - Port to write to
 527type    - Type of access to perform
 528
 529REMARKS:
 530Performs an emulated write to one of the PCI control registers.
 531****************************************************************************/
 532static 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/****************************************************************************
 559PARAMETERS:
 560port    - Port to write to
 561
 562RETURNS:
 563Value read from the I/O port
 564
 565REMARKS:
 566Performs an emulated 8-bit read from an I/O port. We handle special cases
 567that we need to emulate in here, and fall through to reflecting the write
 568through to the real hardware if we don't need to special case it.
 569****************************************************************************/
 570u8 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/****************************************************************************
 605PARAMETERS:
 606port    - Port to write to
 607
 608RETURNS:
 609Value read from the I/O port
 610
 611REMARKS:
 612Performs an emulated 16-bit read from an I/O port. We handle special cases
 613that we need to emulate in here, and fall through to reflecting the write
 614through to the real hardware if we don't need to special case it.
 615****************************************************************************/
 616u16 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/****************************************************************************
 638PARAMETERS:
 639port    - Port to write to
 640
 641RETURNS:
 642Value read from the I/O port
 643
 644REMARKS:
 645Performs an emulated 32-bit read from an I/O port. We handle special cases
 646that we need to emulate in here, and fall through to reflecting the write
 647through to the real hardware if we don't need to special case it.
 648****************************************************************************/
 649u32 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/****************************************************************************
 670PARAMETERS:
 671port    - Port to write to
 672val     - Value to write to port
 673
 674REMARKS:
 675Performs an emulated 8-bit write to an I/O port. We handle special cases
 676that we need to emulate in here, and fall through to reflecting the write
 677through to the real hardware if we don't need to special case it.
 678****************************************************************************/
 679void 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/****************************************************************************
 705PARAMETERS:
 706port    - Port to write to
 707val     - Value to write to port
 708
 709REMARKS:
 710Performs an emulated 16-bit write to an I/O port. We handle special cases
 711that we need to emulate in here, and fall through to reflecting the write
 712through to the real hardware if we don't need to special case it.
 713****************************************************************************/
 714void 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/****************************************************************************
 736PARAMETERS:
 737port    - Port to write to
 738val     - Value to write to port
 739
 740REMARKS:
 741Performs an emulated 32-bit write to an I/O port. We handle special cases
 742that we need to emulate in here, and fall through to reflecting the write
 743through to the real hardware if we don't need to special case it.
 744****************************************************************************/
 745void 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