📄 besys.c
字号:
/****************************************************************************** BIOS emulator and interface* to Realmode X86 Emulator Library** ========================================================================** Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.* Jason Jin<Jason.jin@freescale.com>** Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.** This file may be distributed and/or modified under the terms of the* GNU General Public License version 2.0 as published by the Free* Software Foundation and appearing in the file LICENSE.GPL included* in the packaging of this file.** Licensees holding a valid Commercial License for this product from* SciTech Software, Inc. may use this file in accordance with the* Commercial License Agreement provided with the Software.** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR* PURPOSE.** See http://www.scitechsoft.com/license/ for information about* the licensing options available and how to purchase a Commercial* License Agreement.** Contact license@scitechsoft.com if any conditions of this licensing* are not clear to you, or you have questions about licensing options.** ========================================================================** Language: ANSI C* Environment: Any* Developer: Kendall Bennett** Description: This file includes BIOS emulator I/O and memory access* functions.** Jason ported this file to u-boot to run the ATI video card* BIOS in u-boot. Removed some emulate functions such as the* timer port access. Made all the VGA port except reading 0x3c3* be emulated. Seems like reading 0x3c3 should return the high* 16 bit of the io port.*****************************************************************************/#include <common.h>#if defined(CONFIG_BIOSEMU)#include "biosemui.h"/*------------------------- Global Variables ------------------------------*/#ifndef __i386__static char *BE_biosDate = "08/14/99";static u8 BE_model = 0xFC;static u8 BE_submodel = 0x00;#endif/*----------------------------- Implementation ----------------------------*//****************************************************************************PARAMETERS:addr - Emulator memory address to convertRETURNS:Actual memory address to read or write the dataREMARKS:This function converts an emulator memory address in a 32-bit range toa real memory address that we wish to access. It handles splitting up thememory address space appropriately to access the emulator BIOS image, videomemory and system BIOS etc.****************************************************************************/static u8 *BE_memaddr(u32 addr){ if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) { return (u8*)(_BE_env.biosmem_base + addr - 0xC0000); } else if (addr > _BE_env.biosmem_limit && addr < 0xD0000) { DB(printf("BE_memaddr: address %#lx may be invalid!\n", addr);) return M.mem_base; } else if (addr >= 0xA0000 && addr <= 0xBFFFF) { return (u8*)(_BE_env.busmem_base + addr - 0xA0000); }#ifdef __i386__ else if (addr >= 0xD0000 && addr <= 0xFFFFF) { /* We map the real System BIOS directly on real PC's */ DB(printf("BE_memaddr: System BIOS address %#lx\n", addr);) return _BE_env.busmem_base + addr - 0xA0000; }#else else if (addr >= 0xFFFF5 && addr < 0xFFFFE) { /* Return a faked BIOS date string for non-x86 machines */ DB(printf("BE_memaddr - Returning BIOS date\n");) return (u8 *)(BE_biosDate + addr - 0xFFFF5); } else if (addr == 0xFFFFE) { /* Return system model identifier for non-x86 machines */ DB(printf("BE_memaddr - Returning model\n");) return &BE_model; } else if (addr == 0xFFFFF) { /* Return system submodel identifier for non-x86 machines */ DB(printf("BE_memaddr - Returning submodel\n");) return &BE_submodel; }#endif else if (addr > M.mem_size - 1) { HALT_SYS(); return M.mem_base; } return M.mem_base + addr;}/****************************************************************************PARAMETERS:addr - Emulator memory address to readRETURNS:Byte value read from emulator memory.REMARKS:Reads a byte value from the emulator memory. We have three distinct memoryregions that are handled differently, which this function handles.****************************************************************************/u8 X86API BE_rdb(u32 addr){ if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF) return 0; else { u8 val = readb_le(BE_memaddr(addr)); return val; }}/****************************************************************************PARAMETERS:addr - Emulator memory address to readRETURNS:Word value read from emulator memory.REMARKS:Reads a word value from the emulator memory. We have three distinct memoryregions that are handled differently, which this function handles.****************************************************************************/u16 X86API BE_rdw(u32 addr){ if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF) return 0; else { u8 *base = BE_memaddr(addr); u16 val = readw_le(base); return val; }}/****************************************************************************PARAMETERS:addr - Emulator memory address to readRETURNS:Long value read from emulator memory.REMARKS:Reads a 32-bit value from the emulator memory. We have three distinct memoryregions that are handled differently, which this function handles.****************************************************************************/u32 X86API BE_rdl(u32 addr){ if (_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF) return 0; else { u8 *base = BE_memaddr(addr); u32 val = readl_le(base); return val; }}/****************************************************************************PARAMETERS:addr - Emulator memory address to readval - Value to storeREMARKS:Writes a byte value to emulator memory. We have three distinct memoryregions that are handled differently, which this function handles.****************************************************************************/void X86API BE_wrb(u32 addr, u8 val){ if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) { writeb_le(BE_memaddr(addr), val); }}/****************************************************************************PARAMETERS:addr - Emulator memory address to readval - Value to storeREMARKS:Writes a word value to emulator memory. We have three distinct memoryregions that are handled differently, which this function handles.****************************************************************************/void X86API BE_wrw(u32 addr, u16 val){ if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) { u8 *base = BE_memaddr(addr); writew_le(base, val); }}/****************************************************************************PARAMETERS:addr - Emulator memory address to readval - Value to storeREMARKS:Writes a 32-bit value to emulator memory. We have three distinct memoryregions that are handled differently, which this function handles.****************************************************************************/void X86API BE_wrl(u32 addr, u32 val){ if (!(_BE_env.emulateVGA && addr >= 0xA0000 && addr <= 0xBFFFF)) { u8 *base = BE_memaddr(addr); writel_le(base, val); }}#if defined(DEBUG) || !defined(__i386__)/* For Non-Intel machines we may need to emulate some I/O port accesses that * the BIOS may try to access, such as the PCI config registers. */#define IS_TIMER_PORT(port) (0x40 <= port && port <= 0x43)#define IS_CMOS_PORT(port) (0x70 <= port && port <= 0x71)/*#define IS_VGA_PORT(port) (_BE_env.emulateVGA && 0x3C0 <= port && port <= 0x3DA)*/#define IS_VGA_PORT(port) (0x3C0 <= port && port <= 0x3DA)#define IS_PCI_PORT(port) (0xCF8 <= port && port <= 0xCFF)#define IS_SPKR_PORT(port) (port == 0x61)/****************************************************************************PARAMETERS:port - Port to read fromtype - Type of access to performREMARKS:Performs an emulated read from the Standard VGA I/O ports. If the targethardware does not support mapping the VGA I/O and memory (such as somePowerPC systems), we emulate the VGA so that the BIOS will still be able toset NonVGA display modes such as on ATI hardware.****************************************************************************/static u8 VGA_inpb (const int port){ u8 val = 0xff; switch (port) { case 0x3C0: /* 3C0 has funky characteristics because it can act as either a data register or index register depending on the state of an internal flip flop in the hardware. Hence we have to emulate that functionality in here. */ if (_BE_env.flipFlop3C0 == 0) { /* Access 3C0 as index register */ val = _BE_env.emu3C0; } else { /* Access 3C0 as data register */ if (_BE_env.emu3C0 < ATT_C) val = _BE_env.emu3C1[_BE_env.emu3C0]; } _BE_env.flipFlop3C0 ^= 1; break; case 0x3C1: if (_BE_env.emu3C0 < ATT_C) return _BE_env.emu3C1[_BE_env.emu3C0]; break; case 0x3CC: return _BE_env.emu3C2; case 0x3C4: return _BE_env.emu3C4; case 0x3C5: if (_BE_env.emu3C4 < ATT_C) return _BE_env.emu3C5[_BE_env.emu3C4]; break; case 0x3C6: return _BE_env.emu3C6; case 0x3C7: return _BE_env.emu3C7; case 0x3C8: return _BE_env.emu3C8; case 0x3C9: if (_BE_env.emu3C7 < PAL_C) return _BE_env.emu3C9[_BE_env.emu3C7++]; break; case 0x3CE: return _BE_env.emu3CE; case 0x3CF: if (_BE_env.emu3CE < GRA_C) return _BE_env.emu3CF[_BE_env.emu3CE]; break; case 0x3D4: if (_BE_env.emu3C2 & 0x1) return _BE_env.emu3D4; break; case 0x3D5: if ((_BE_env.emu3C2 & 0x1) && (_BE_env.emu3D4 < CRT_C)) return _BE_env.emu3D5[_BE_env.emu3D4]; break; case 0x3DA: _BE_env.flipFlop3C0 = 0; val = _BE_env.emu3DA; _BE_env.emu3DA ^= 0x9; break; } return val;}/****************************************************************************PARAMETERS:port - Port to write totype - Type of access to performREMARKS:Performs an emulated write to one of the 8253 timer registers. For nowwe only emulate timer 0 which is the only timer that the BIOS code appearsto use.****************************************************************************/static void VGA_outpb (int port, u8 val){ switch (port) { case 0x3C0: /* 3C0 has funky characteristics because it can act as either a data register or index register depending on the state of an internal flip flop in the hardware. Hence we have to emulate that functionality in here. */ if (_BE_env.flipFlop3C0 == 0) { /* Access 3C0 as index register */ _BE_env.emu3C0 = val; } else { /* Access 3C0 as data register */ if (_BE_env.emu3C0 < ATT_C) _BE_env.emu3C1[_BE_env.emu3C0] = val; } _BE_env.flipFlop3C0 ^= 1; break; case 0x3C2: _BE_env.emu3C2 = val; break; case 0x3C4: _BE_env.emu3C4 = val; break; case 0x3C5: if (_BE_env.emu3C4 < ATT_C) _BE_env.emu3C5[_BE_env.emu3C4] = val; break; case 0x3C6: _BE_env.emu3C6 = val; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -