mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
This is a BIOS emulator, porting from SciTech for u-boot, mainly for
ATI video card BIOS. and can be used for x86 code emulation by some modifications. Signed-off-by: Jason Jin <Jason.jin@freescale.com>
This commit is contained in:
parent
5072188aca
commit
ece92f8505
21 changed files with 16008 additions and 0 deletions
30
drivers/bios_emulator/Makefile
Normal file
30
drivers/bios_emulator/Makefile
Normal file
|
@ -0,0 +1,30 @@
|
|||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB := libatibiosemu.a
|
||||
|
||||
X86DIR = ./x86emu
|
||||
|
||||
OBJS = atibios.o biosemu.o besys.o bios.o \
|
||||
$(X86DIR)/decode.o \
|
||||
$(X86DIR)/ops2.o \
|
||||
$(X86DIR)/ops.o \
|
||||
$(X86DIR)/prim_ops.o \
|
||||
$(X86DIR)/sys.o \
|
||||
$(X86DIR)/debug.o
|
||||
|
||||
CFLAGS += -I. -I./include -I$(X86DIR) -I$(TOPDIR)/include \
|
||||
-D__PPC__ -D__BIG_ENDIAN__
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(AR) crv $@ $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(OBJS:.o=.c)
|
||||
$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
|
||||
|
||||
sinclude .depend
|
||||
|
||||
#########################################################################
|
340
drivers/bios_emulator/atibios.c
Normal file
340
drivers/bios_emulator/atibios.c
Normal file
|
@ -0,0 +1,340 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Video BOOT Graphics Card POST Module
|
||||
*
|
||||
* ========================================================================
|
||||
* 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: Linux Kernel
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Module to implement booting PCI/AGP controllers on the
|
||||
* bus. We use the x86 real mode emulator to run the BIOS on
|
||||
* graphics controllers to bring the cards up.
|
||||
*
|
||||
* Note that at present this module does *not* support
|
||||
* multiple controllers.
|
||||
*
|
||||
* The orignal name of this file is warmboot.c.
|
||||
* Jason ported this file to u-boot to run the ATI video card
|
||||
* BIOS in u-boot.
|
||||
****************************************************************************/
|
||||
#include <common.h>
|
||||
|
||||
#ifdef CONFIG_BIOSEMU
|
||||
|
||||
#include "biosemui.h"
|
||||
#include <malloc.h>
|
||||
|
||||
/* Length of the BIOS image */
|
||||
#define MAX_BIOSLEN (128 * 1024L)
|
||||
|
||||
/* Define some useful types and macros */
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
/* Place to save PCI BAR's that we change and later restore */
|
||||
static u32 saveROMBaseAddress;
|
||||
static u32 saveBaseAddress10;
|
||||
static u32 saveBaseAddress14;
|
||||
static u32 saveBaseAddress18;
|
||||
static u32 saveBaseAddress20;
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
pcidev - PCI device info for the video card on the bus to boot
|
||||
VGAInfo - BIOS emulator VGA info structure
|
||||
|
||||
REMARKS:
|
||||
This function executes the BIOS POST code on the controller. We assume that
|
||||
at this stage the controller has its I/O and memory space enabled and
|
||||
that all other controllers are in a disabled state.
|
||||
****************************************************************************/
|
||||
static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo * VGAInfo)
|
||||
{
|
||||
RMREGS regs;
|
||||
RMSREGS sregs;
|
||||
|
||||
/* Determine the value to store in AX for BIOS POST. Per the PCI specs,
|
||||
AH must contain the bus and AL must contain the devfn, encoded as
|
||||
(dev << 3) | fn
|
||||
*/
|
||||
memset(®s, 0, sizeof(regs));
|
||||
memset(&sregs, 0, sizeof(sregs));
|
||||
regs.x.ax = ((int)PCI_BUS(pcidev) << 8) |
|
||||
((int)PCI_DEV(pcidev) << 3) | (int)PCI_FUNC(pcidev);
|
||||
|
||||
/*Setup the X86 emulator for the VGA BIOS*/
|
||||
BE_setVGA(VGAInfo);
|
||||
|
||||
/*Execute the BIOS POST code*/
|
||||
BE_callRealMode(0xC000, 0x0003, ®s, &sregs);
|
||||
|
||||
/*Cleanup and exit*/
|
||||
BE_getVGA(VGAInfo);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
pcidev - PCI device info for the video card on the bus
|
||||
bar - Place to return the base address register offset to use
|
||||
|
||||
RETURNS:
|
||||
The address to use to map the secondary BIOS (AGP devices)
|
||||
|
||||
REMARKS:
|
||||
Searches all the PCI base address registers for the device looking for a
|
||||
memory mapping that is large enough to hold our ROM BIOS. We usually end up
|
||||
finding the framebuffer mapping (usually BAR 0x10), and we use this mapping
|
||||
to map the BIOS for the device into. We use a mapping that is already
|
||||
assigned to the device to ensure the memory range will be passed through
|
||||
by any PCI->PCI or AGP->PCI bridge that may be present.
|
||||
|
||||
NOTE: Usually this function is only used for AGP devices, but it may be
|
||||
used for PCI devices that have already been POST'ed and the BIOS
|
||||
ROM base address has been zero'ed out.
|
||||
|
||||
NOTE: This function leaves the original memory aperture disabled by leaving
|
||||
it programmed to all 1's. It must be restored to the correct value
|
||||
later.
|
||||
****************************************************************************/
|
||||
static u32 PCI_findBIOSAddr(pci_dev_t pcidev, int *bar)
|
||||
{
|
||||
u32 base, size;
|
||||
|
||||
for (*bar = 0x10; *bar <= 0x14; (*bar) += 4) {
|
||||
pci_read_config_dword(pcidev, *bar, &base);
|
||||
if (!(base & 0x1)) {
|
||||
pci_write_config_dword(pcidev, *bar, 0xFFFFFFFF);
|
||||
pci_read_config_dword(pcidev, *bar, &size);
|
||||
size = ~(size & ~0xFF) + 1;
|
||||
if (size >= MAX_BIOSLEN)
|
||||
return base & ~0xFF;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Some non-x86 Linux kernels map PCI relocateable I/O to values that
|
||||
are above 64K, which will not work with the BIOS image that requires
|
||||
the offset for the I/O ports to be a maximum of 16-bits. Ideally
|
||||
someone should fix the kernel to map the I/O ports for VGA compatible
|
||||
devices to a different location (or just all I/O ports since it is
|
||||
unlikely you can have enough devices in the machine to use up all
|
||||
64K of the I/O space - a total of more than 256 cards would be
|
||||
necessary).
|
||||
|
||||
Anyway to fix this we change all I/O mapped base registers and
|
||||
chop off the top bits.
|
||||
****************************************************************************/
|
||||
static void PCI_fixupIObase(pci_dev_t pcidev, int reg, u32 * base)
|
||||
{
|
||||
if ((*base & 0x1) && (*base > 0xFFFE)) {
|
||||
*base &= 0xFFFF;
|
||||
pci_write_config_dword(pcidev, reg, *base);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
pcidev - PCI device info for the video card on the bus
|
||||
|
||||
RETURNS:
|
||||
Pointers to the mapped BIOS image
|
||||
|
||||
REMARKS:
|
||||
Maps a pointer to the BIOS image on the graphics card on the PCI bus.
|
||||
****************************************************************************/
|
||||
void *PCI_mapBIOSImage(pci_dev_t pcidev)
|
||||
{
|
||||
u32 BIOSImagePhys;
|
||||
int BIOSImageBAR;
|
||||
u8 *BIOSImage;
|
||||
|
||||
/*Save PCI BAR registers that might get changed*/
|
||||
pci_read_config_dword(pcidev, PCI_ROM_ADDRESS, &saveROMBaseAddress);
|
||||
pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &saveBaseAddress10);
|
||||
pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_1, &saveBaseAddress14);
|
||||
pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_2, &saveBaseAddress18);
|
||||
pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_4, &saveBaseAddress20);
|
||||
|
||||
/*Fix up I/O base registers to less than 64K */
|
||||
if(saveBaseAddress14 != 0)
|
||||
PCI_fixupIObase(pcidev, PCI_BASE_ADDRESS_1, &saveBaseAddress14);
|
||||
else
|
||||
PCI_fixupIObase(pcidev, PCI_BASE_ADDRESS_4, &saveBaseAddress20);
|
||||
|
||||
/* Some cards have problems that stop us from being able to read the
|
||||
BIOS image from the ROM BAR. To fix this we have to do some chipset
|
||||
specific programming for different cards to solve this problem.
|
||||
*/
|
||||
|
||||
if ((BIOSImagePhys = PCI_findBIOSAddr(pcidev, &BIOSImageBAR)) == 0) {
|
||||
printf("Find bios addr error\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BIOSImage = (u8 *) BIOSImagePhys;
|
||||
|
||||
/*Change the PCI BAR registers to map it onto the bus.*/
|
||||
pci_write_config_dword(pcidev, BIOSImageBAR, 0);
|
||||
pci_write_config_dword(pcidev, PCI_ROM_ADDRESS, BIOSImagePhys | 0x1);
|
||||
|
||||
udelay(1);
|
||||
|
||||
/*Check that the BIOS image is valid. If not fail, or return the
|
||||
compiled in BIOS image if that option was enabled
|
||||
*/
|
||||
if (BIOSImage[0] != 0x55 || BIOSImage[1] != 0xAA || BIOSImage[2] == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return BIOSImage;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
pcidev - PCI device info for the video card on the bus
|
||||
|
||||
REMARKS:
|
||||
Unmaps the BIOS image for the device and restores framebuffer mappings
|
||||
****************************************************************************/
|
||||
void PCI_unmapBIOSImage(pci_dev_t pcidev, void *BIOSImage)
|
||||
{
|
||||
pci_write_config_dword(pcidev, PCI_ROM_ADDRESS, saveROMBaseAddress);
|
||||
pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_0, saveBaseAddress10);
|
||||
pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_1, saveBaseAddress14);
|
||||
pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_2, saveBaseAddress18);
|
||||
pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_4, saveBaseAddress20);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
pcidev - PCI device info for the video card on the bus to boot
|
||||
VGAInfo - BIOS emulator VGA info structure
|
||||
|
||||
RETURNS:
|
||||
True if successfully initialised, false if not.
|
||||
|
||||
REMARKS:
|
||||
Loads and POST's the display controllers BIOS, directly from the BIOS
|
||||
image we can extract over the PCI bus.
|
||||
****************************************************************************/
|
||||
static int PCI_postController(pci_dev_t pcidev, BE_VGAInfo * VGAInfo)
|
||||
{
|
||||
u32 BIOSImageLen;
|
||||
uchar *mappedBIOS;
|
||||
uchar *copyOfBIOS;
|
||||
|
||||
/*Allocate memory to store copy of BIOS from display controller*/
|
||||
if ((mappedBIOS = PCI_mapBIOSImage(pcidev)) == NULL) {
|
||||
printf("videoboot: Video ROM failed to map!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
BIOSImageLen = mappedBIOS[2] * 512;
|
||||
|
||||
if ((copyOfBIOS = malloc(BIOSImageLen)) == NULL) {
|
||||
printf("videoboot: Out of memory!\n");
|
||||
return false;
|
||||
}
|
||||
memcpy(copyOfBIOS, mappedBIOS, BIOSImageLen);
|
||||
|
||||
PCI_unmapBIOSImage(pcidev, mappedBIOS);
|
||||
|
||||
/*Save information in VGAInfo structure*/
|
||||
VGAInfo->function = PCI_FUNC(pcidev);
|
||||
VGAInfo->device = PCI_DEV(pcidev);
|
||||
VGAInfo->bus = PCI_BUS(pcidev);
|
||||
VGAInfo->pcidev = pcidev;
|
||||
VGAInfo->BIOSImage = copyOfBIOS;
|
||||
VGAInfo->BIOSImageLen = BIOSImageLen;
|
||||
|
||||
/*Now execute the BIOS POST for the device*/
|
||||
if (copyOfBIOS[0] != 0x55 || copyOfBIOS[1] != 0xAA) {
|
||||
printf("videoboot: Video ROM image is invalid!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
PCI_doBIOSPOST(pcidev, VGAInfo);
|
||||
|
||||
/*Reset the size of the BIOS image to the final size*/
|
||||
VGAInfo->BIOSImageLen = copyOfBIOS[2] * 512;
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
pcidev - PCI device info for the video card on the bus to boot
|
||||
pVGAInfo - Place to return VGA info structure is requested
|
||||
cleanUp - True to clean up on exit, false to leave emulator active
|
||||
|
||||
REMARKS:
|
||||
Boots the PCI/AGP video card on the bus using the Video ROM BIOS image
|
||||
and the X86 BIOS emulator module.
|
||||
****************************************************************************/
|
||||
int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp)
|
||||
{
|
||||
BE_VGAInfo *VGAInfo;
|
||||
|
||||
printf("videoboot: Booting PCI video card bus %d, function %d, device %d\n",
|
||||
PCI_BUS(pcidev), PCI_FUNC(pcidev), PCI_DEV(pcidev));
|
||||
|
||||
/*Initialise the x86 BIOS emulator*/
|
||||
if ((VGAInfo = malloc(sizeof(*VGAInfo))) == NULL) {
|
||||
printf("videoboot: Out of memory!\n");
|
||||
return false;
|
||||
}
|
||||
memset(VGAInfo, 0, sizeof(*VGAInfo));
|
||||
BE_init(0, 65536, VGAInfo, 0);
|
||||
|
||||
/*Post all the display controller BIOS'es*/
|
||||
PCI_postController(pcidev, VGAInfo);
|
||||
|
||||
/*Cleanup and exit the emulator if requested. If the BIOS emulator
|
||||
is needed after booting the card, we will not call BE_exit and
|
||||
leave it enabled for further use (ie: VESA driver etc).
|
||||
*/
|
||||
if (cleanUp) {
|
||||
BE_exit();
|
||||
if (VGAInfo->BIOSImage)
|
||||
free(VGAInfo->BIOSImage);
|
||||
free(VGAInfo);
|
||||
VGAInfo = NULL;
|
||||
}
|
||||
/*Return VGA info pointer if the caller requested it*/
|
||||
if (pVGAInfo)
|
||||
*pVGAInfo = VGAInfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
722
drivers/bios_emulator/besys.c
Normal file
722
drivers/bios_emulator/besys.c
Normal file
|
@ -0,0 +1,722 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* 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 "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 convert
|
||||
|
||||
RETURNS:
|
||||
Actual memory address to read or write the data
|
||||
|
||||
REMARKS:
|
||||
This function converts an emulator memory address in a 32-bit range to
|
||||
a real memory address that we wish to access. It handles splitting up the
|
||||
memory address space appropriately to access the emulator BIOS image, video
|
||||
memory 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 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 read
|
||||
|
||||
RETURNS:
|
||||
Byte value read from emulator memory.
|
||||
|
||||
REMARKS:
|
||||
Reads a byte value from the emulator memory. We have three distinct memory
|
||||
regions 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 read
|
||||
|
||||
RETURNS:
|
||||
Word value read from emulator memory.
|
||||
|
||||
REMARKS:
|
||||
Reads a word value from the emulator memory. We have three distinct memory
|
||||
regions 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 read
|
||||
|
||||
RETURNS:
|
||||
Long value read from emulator memory.
|
||||
|
||||
REMARKS:
|
||||
Reads a 32-bit value from the emulator memory. We have three distinct memory
|
||||
regions 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 read
|
||||
val - Value to store
|
||||
|
||||
REMARKS:
|
||||
Writes a byte value to emulator memory. We have three distinct memory
|
||||
regions 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 read
|
||||
val - Value to store
|
||||
|
||||
REMARKS:
|
||||
Writes a word value to emulator memory. We have three distinct memory
|
||||
regions 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 read
|
||||
val - Value to store
|
||||
|
||||
REMARKS:
|
||||
Writes a 32-bit value to emulator memory. We have three distinct memory
|
||||
regions 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 from
|
||||
type - Type of access to perform
|
||||
|
||||
REMARKS:
|
||||
Performs an emulated read from the Standard VGA I/O ports. If the target
|
||||
hardware does not support mapping the VGA I/O and memory (such as some
|
||||
PowerPC systems), we emulate the VGA so that the BIOS will still be able to
|
||||
set 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 to
|
||||
type - Type of access to perform
|
||||
|
||||
REMARKS:
|
||||
Performs an emulated write to one of the 8253 timer registers. For now
|
||||
we only emulate timer 0 which is the only timer that the BIOS code appears
|
||||
to 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;
|
||||
case 0x3C7:
|
||||
_BE_env.emu3C7 = (int)val * 3;
|
||||
break;
|
||||
case 0x3C8:
|
||||
_BE_env.emu3C8 = (int)val * 3;
|
||||
break;
|
||||
case 0x3C9:
|
||||
if (_BE_env.emu3C8 < PAL_C)
|
||||
_BE_env.emu3C9[_BE_env.emu3C8++] = val;
|
||||
break;
|
||||
case 0x3CE:
|
||||
_BE_env.emu3CE = val;
|
||||
break;
|
||||
case 0x3CF:
|
||||
if (_BE_env.emu3CE < GRA_C)
|
||||
_BE_env.emu3CF[_BE_env.emu3CE] = val;
|
||||
break;
|
||||
case 0x3D4:
|
||||
if (_BE_env.emu3C2 & 0x1)
|
||||
_BE_env.emu3D4 = val;
|
||||
break;
|
||||
case 0x3D5:
|
||||
if ((_BE_env.emu3C2 & 0x1) && (_BE_env.emu3D4 < CRT_C))
|
||||
_BE_env.emu3D5[_BE_env.emu3D4] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
regOffset - Offset into register space for non-DWORD accesses
|
||||
value - Value to write to register for PCI_WRITE_* operations
|
||||
func - Function to perform (PCIAccessRegFlags)
|
||||
|
||||
RETURNS:
|
||||
Value read from configuration register for PCI_READ_* operations
|
||||
|
||||
REMARKS:
|
||||
Accesses a PCI configuration space register by decoding the value currently
|
||||
stored in the _BE_env.configAddress variable and passing it through to the
|
||||
portable PCI_accessReg function.
|
||||
****************************************************************************/
|
||||
static u32 BE_accessReg(int regOffset, u32 value, int func)
|
||||
{
|
||||
#ifdef __KERNEL__
|
||||
int function, device, bus;
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
u32 val32;
|
||||
|
||||
|
||||
/* Decode the configuration register values for the register we wish to
|
||||
* access
|
||||
*/
|
||||
regOffset += (_BE_env.configAddress & 0xFF);
|
||||
function = (_BE_env.configAddress >> 8) & 0x7;
|
||||
device = (_BE_env.configAddress >> 11) & 0x1F;
|
||||
bus = (_BE_env.configAddress >> 16) & 0xFF;
|
||||
|
||||
/* Ignore accesses to all devices other than the one we're POSTing */
|
||||
if ((function == _BE_env.vgaInfo.function) &&
|
||||
(device == _BE_env.vgaInfo.device) &&
|
||||
(bus == _BE_env.vgaInfo.bus)) {
|
||||
switch (func) {
|
||||
case REG_READ_BYTE:
|
||||
pci_read_config_byte(_BE_env.vgaInfo.pcidev, regOffset,
|
||||
&val8);
|
||||
return val8;
|
||||
case REG_READ_WORD:
|
||||
pci_read_config_word(_BE_env.vgaInfo.pcidev, regOffset,
|
||||
&val16);
|
||||
return val16;
|
||||
case REG_READ_DWORD:
|
||||
pci_read_config_dword(_BE_env.vgaInfo.pcidev, regOffset,
|
||||
&val32);
|
||||
return val32;
|
||||
case REG_WRITE_BYTE:
|
||||
pci_write_config_byte(_BE_env.vgaInfo.pcidev, regOffset,
|
||||
value);
|
||||
|
||||
return 0;
|
||||
case REG_WRITE_WORD:
|
||||
pci_write_config_word(_BE_env.vgaInfo.pcidev, regOffset,
|
||||
value);
|
||||
|
||||
return 0;
|
||||
case REG_WRITE_DWORD:
|
||||
pci_write_config_dword(_BE_env.vgaInfo.pcidev,
|
||||
regOffset, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
PCIDeviceInfo pciInfo;
|
||||
|
||||
pciInfo.mech1 = 1;
|
||||
pciInfo.slot.i = 0;
|
||||
pciInfo.slot.p.Function = (_BE_env.configAddress >> 8) & 0x7;
|
||||
pciInfo.slot.p.Device = (_BE_env.configAddress >> 11) & 0x1F;
|
||||
pciInfo.slot.p.Bus = (_BE_env.configAddress >> 16) & 0xFF;
|
||||
pciInfo.slot.p.Enable = 1;
|
||||
|
||||
/* Ignore accesses to all devices other than the one we're POSTing */
|
||||
if ((pciInfo.slot.p.Function ==
|
||||
_BE_env.vgaInfo.pciInfo->slot.p.Function)
|
||||
&& (pciInfo.slot.p.Device == _BE_env.vgaInfo.pciInfo->slot.p.Device)
|
||||
&& (pciInfo.slot.p.Bus == _BE_env.vgaInfo.pciInfo->slot.p.Bus))
|
||||
return PCI_accessReg((_BE_env.configAddress & 0xFF) + regOffset,
|
||||
value, func, &pciInfo);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
port - Port to read from
|
||||
type - Type of access to perform
|
||||
|
||||
REMARKS:
|
||||
Performs an emulated read from one of the PCI configuration space registers.
|
||||
We emulate this using our PCI_accessReg function which will access the PCI
|
||||
configuration space registers in a portable fashion.
|
||||
****************************************************************************/
|
||||
static u32 PCI_inp(int port, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case REG_READ_BYTE:
|
||||
if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
|
||||
&& port <= 0xCFF)
|
||||
return BE_accessReg(port - 0xCFC, 0, REG_READ_BYTE);
|
||||
break;
|
||||
case REG_READ_WORD:
|
||||
if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
|
||||
&& port <= 0xCFF)
|
||||
return BE_accessReg(port - 0xCFC, 0, REG_READ_WORD);
|
||||
break;
|
||||
case REG_READ_DWORD:
|
||||
if (port == 0xCF8)
|
||||
return _BE_env.configAddress;
|
||||
else if ((_BE_env.configAddress & 0x80000000) && port == 0xCFC)
|
||||
return BE_accessReg(0, 0, REG_READ_DWORD);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
port - Port to write to
|
||||
type - Type of access to perform
|
||||
|
||||
REMARKS:
|
||||
Performs an emulated write to one of the PCI control registers.
|
||||
****************************************************************************/
|
||||
static void PCI_outp(int port, u32 val, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case REG_WRITE_BYTE:
|
||||
if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
|
||||
&& port <= 0xCFF)
|
||||
BE_accessReg(port - 0xCFC, val, REG_WRITE_BYTE);
|
||||
break;
|
||||
case REG_WRITE_WORD:
|
||||
if ((_BE_env.configAddress & 0x80000000) && 0xCFC <= port
|
||||
&& port <= 0xCFF)
|
||||
BE_accessReg(port - 0xCFC, val, REG_WRITE_WORD);
|
||||
break;
|
||||
case REG_WRITE_DWORD:
|
||||
if (port == 0xCF8)
|
||||
{
|
||||
_BE_env.configAddress = val & 0x80FFFFFC;
|
||||
}
|
||||
else if ((_BE_env.configAddress & 0x80000000) && port == 0xCFC)
|
||||
BE_accessReg(0, val, REG_WRITE_DWORD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
port - Port to write to
|
||||
|
||||
RETURNS:
|
||||
Value read from the I/O port
|
||||
|
||||
REMARKS:
|
||||
Performs an emulated 8-bit read from an I/O port. We handle special cases
|
||||
that we need to emulate in here, and fall through to reflecting the write
|
||||
through to the real hardware if we don't need to special case it.
|
||||
****************************************************************************/
|
||||
u8 X86API BE_inb(X86EMU_pioAddr port)
|
||||
{
|
||||
u8 val = 0;
|
||||
|
||||
#if defined(DEBUG) || !defined(__i386__)
|
||||
if (IS_VGA_PORT(port)){
|
||||
/*seems reading port 0x3c3 return the high 16 bit of io port*/
|
||||
if(port == 0x3c3)
|
||||
val = LOG_inpb(port);
|
||||
else
|
||||
val = VGA_inpb(port);
|
||||
}
|
||||
else if (IS_TIMER_PORT(port))
|
||||
DB(printf("Can not interept TIMER port now!\n");)
|
||||
else if (IS_SPKR_PORT(port))
|
||||
DB(printf("Can not interept SPEAKER port now!\n");)
|
||||
else if (IS_CMOS_PORT(port))
|
||||
DB(printf("Can not interept CMOS port now!\n");)
|
||||
else if (IS_PCI_PORT(port))
|
||||
val = PCI_inp(port, REG_READ_BYTE);
|
||||
else if (port < 0x100) {
|
||||
DB(printf("WARN: INVALID inb.%04X -> %02X\n", (u16) port, val);)
|
||||
val = LOG_inpb(port);
|
||||
} else
|
||||
#endif
|
||||
val = LOG_inpb(port);
|
||||
return val;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
port - Port to write to
|
||||
|
||||
RETURNS:
|
||||
Value read from the I/O port
|
||||
|
||||
REMARKS:
|
||||
Performs an emulated 16-bit read from an I/O port. We handle special cases
|
||||
that we need to emulate in here, and fall through to reflecting the write
|
||||
through to the real hardware if we don't need to special case it.
|
||||
****************************************************************************/
|
||||
u16 X86API BE_inw(X86EMU_pioAddr port)
|
||||
{
|
||||
u16 val = 0;
|
||||
|
||||
#if defined(DEBUG) || !defined(__i386__)
|
||||
if (IS_PCI_PORT(port))
|
||||
val = PCI_inp(port, REG_READ_WORD);
|
||||
else if (port < 0x100) {
|
||||
DB(printf("WARN: Maybe INVALID inw.%04X -> %04X\n", (u16) port, val);)
|
||||
val = LOG_inpw(port);
|
||||
} else
|
||||
#endif
|
||||
val = LOG_inpw(port);
|
||||
return val;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
port - Port to write to
|
||||
|
||||
RETURNS:
|
||||
Value read from the I/O port
|
||||
|
||||
REMARKS:
|
||||
Performs an emulated 32-bit read from an I/O port. We handle special cases
|
||||
that we need to emulate in here, and fall through to reflecting the write
|
||||
through to the real hardware if we don't need to special case it.
|
||||
****************************************************************************/
|
||||
u32 X86API BE_inl(X86EMU_pioAddr port)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
#if defined(DEBUG) || !defined(__i386__)
|
||||
if (IS_PCI_PORT(port))
|
||||
val = PCI_inp(port, REG_READ_DWORD);
|
||||
else if (port < 0x100) {
|
||||
val = LOG_inpd(port);
|
||||
} else
|
||||
#endif
|
||||
val = LOG_inpd(port);
|
||||
return val;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
port - Port to write to
|
||||
val - Value to write to port
|
||||
|
||||
REMARKS:
|
||||
Performs an emulated 8-bit write to an I/O port. We handle special cases
|
||||
that we need to emulate in here, and fall through to reflecting the write
|
||||
through to the real hardware if we don't need to special case it.
|
||||
****************************************************************************/
|
||||
void X86API BE_outb(X86EMU_pioAddr port, u8 val)
|
||||
{
|
||||
#if defined(DEBUG) || !defined(__i386__)
|
||||
if (IS_VGA_PORT(port))
|
||||
VGA_outpb(port, val);
|
||||
else if (IS_TIMER_PORT(port))
|
||||
DB(printf("Can not interept TIMER port now!\n");)
|
||||
else if (IS_SPKR_PORT(port))
|
||||
DB(printf("Can not interept SPEAKER port now!\n");)
|
||||
else if (IS_CMOS_PORT(port))
|
||||
DB(printf("Can not interept CMOS port now!\n");)
|
||||
else if (IS_PCI_PORT(port))
|
||||
PCI_outp(port, val, REG_WRITE_BYTE);
|
||||
else if (port < 0x100) {
|
||||
DB(printf("WARN:Maybe INVALID outb.%04X <- %02X\n", (u16) port, val);)
|
||||
LOG_outpb(port, val);
|
||||
} else
|
||||
#endif
|
||||
LOG_outpb(port, val);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
port - Port to write to
|
||||
val - Value to write to port
|
||||
|
||||
REMARKS:
|
||||
Performs an emulated 16-bit write to an I/O port. We handle special cases
|
||||
that we need to emulate in here, and fall through to reflecting the write
|
||||
through to the real hardware if we don't need to special case it.
|
||||
****************************************************************************/
|
||||
void X86API BE_outw(X86EMU_pioAddr port, u16 val)
|
||||
{
|
||||
#if defined(DEBUG) || !defined(__i386__)
|
||||
if (IS_VGA_PORT(port)) {
|
||||
VGA_outpb(port, val);
|
||||
VGA_outpb(port + 1, val >> 8);
|
||||
} else if (IS_PCI_PORT(port))
|
||||
PCI_outp(port, val, REG_WRITE_WORD);
|
||||
else if (port < 0x100) {
|
||||
DB(printf("WARN: MAybe INVALID outw.%04X <- %04X\n", (u16) port,
|
||||
val);)
|
||||
LOG_outpw(port, val);
|
||||
} else
|
||||
#endif
|
||||
LOG_outpw(port, val);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
port - Port to write to
|
||||
val - Value to write to port
|
||||
|
||||
REMARKS:
|
||||
Performs an emulated 32-bit write to an I/O port. We handle special cases
|
||||
that we need to emulate in here, and fall through to reflecting the write
|
||||
through to the real hardware if we don't need to special case it.
|
||||
****************************************************************************/
|
||||
void X86API BE_outl(X86EMU_pioAddr port, u32 val)
|
||||
{
|
||||
#if defined(DEBUG) || !defined(__i386__)
|
||||
if (IS_PCI_PORT(port))
|
||||
PCI_outp(port, val, REG_WRITE_DWORD);
|
||||
else if (port < 0x100) {
|
||||
DB(printf("WARN: INVALID outl.%04X <- %08X\n", (u16) port,val);)
|
||||
LOG_outpd(port, val);
|
||||
} else
|
||||
#endif
|
||||
LOG_outpd(port, val);
|
||||
}
|
321
drivers/bios_emulator/bios.c
Normal file
321
drivers/bios_emulator/bios.c
Normal file
|
@ -0,0 +1,321 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* 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) 1996-1999 SciTech Software, Inc.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Module implementing the BIOS specific functions.
|
||||
*
|
||||
* Jason ported this file to u-boot to run the ATI video card
|
||||
* video BIOS.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "biosemui.h"
|
||||
|
||||
/*----------------------------- Implementation ----------------------------*/
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
intno - Interrupt number being serviced
|
||||
|
||||
REMARKS:
|
||||
Handler for undefined interrupts.
|
||||
****************************************************************************/
|
||||
static void X86API undefined_intr(int intno)
|
||||
{
|
||||
if (BE_rdw(intno * 4 + 2) == BIOS_SEG) {
|
||||
DB(printf("biosEmu: undefined interrupt %xh called!\n", intno);)
|
||||
} else
|
||||
X86EMU_prepareForInt(intno);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
intno - Interrupt number being serviced
|
||||
|
||||
REMARKS:
|
||||
This function handles the default system BIOS Int 10h (the default is stored
|
||||
in the Int 42h vector by the system BIOS at bootup). We only need to handle
|
||||
a small number of special functions used by the BIOS during POST time.
|
||||
****************************************************************************/
|
||||
static void X86API int42(int intno)
|
||||
{
|
||||
if (M.x86.R_AH == 0x12 && M.x86.R_BL == 0x32) {
|
||||
if (M.x86.R_AL == 0) {
|
||||
/* Enable CPU accesses to video memory */
|
||||
PM_outpb(0x3c2, PM_inpb(0x3cc) | (u8) 0x02);
|
||||
return;
|
||||
} else if (M.x86.R_AL == 1) {
|
||||
/* Disable CPU accesses to video memory */
|
||||
PM_outpb(0x3c2, PM_inpb(0x3cc) & (u8) ~ 0x02);
|
||||
return;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
printf("int42: unknown function AH=0x12, BL=0x32, AL=%#02x\n",
|
||||
M.x86.R_AL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
printf("int42: unknown function AH=%#02x, AL=%#02x, BL=%#02x\n",
|
||||
M.x86.R_AH, M.x86.R_AL, M.x86.R_BL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
intno - Interrupt number being serviced
|
||||
|
||||
REMARKS:
|
||||
This function handles the default system BIOS Int 10h. If the POST code
|
||||
has not yet re-vectored the Int 10h BIOS interrupt vector, we handle this
|
||||
by simply calling the int42 interrupt handler above. Very early in the
|
||||
BIOS POST process, the vector gets replaced and we simply let the real
|
||||
mode interrupt handler process the interrupt.
|
||||
****************************************************************************/
|
||||
static void X86API int10(int intno)
|
||||
{
|
||||
if (BE_rdw(intno * 4 + 2) == BIOS_SEG)
|
||||
int42(intno);
|
||||
else
|
||||
X86EMU_prepareForInt(intno);
|
||||
}
|
||||
|
||||
/* Result codes returned by the PCI BIOS */
|
||||
|
||||
#define SUCCESSFUL 0x00
|
||||
#define FUNC_NOT_SUPPORT 0x81
|
||||
#define BAD_VENDOR_ID 0x83
|
||||
#define DEVICE_NOT_FOUND 0x86
|
||||
#define BAD_REGISTER_NUMBER 0x87
|
||||
#define SET_FAILED 0x88
|
||||
#define BUFFER_TOO_SMALL 0x89
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
intno - Interrupt number being serviced
|
||||
|
||||
REMARKS:
|
||||
This function handles the default Int 1Ah interrupt handler for the real
|
||||
mode code, which provides support for the PCI BIOS functions. Since we only
|
||||
want to allow the real mode BIOS code *only* see the PCI config space for
|
||||
its own device, we only return information for the specific PCI config
|
||||
space that we have passed in to the init function. This solves problems
|
||||
when using the BIOS to warm boot a secondary adapter when there is an
|
||||
identical adapter before it on the bus (some BIOS'es get confused in this
|
||||
case).
|
||||
****************************************************************************/
|
||||
static void X86API int1A(int unused)
|
||||
{
|
||||
u16 pciSlot;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
u8 interface, subclass, baseclass;
|
||||
|
||||
/* Initialise the PCI slot number */
|
||||
pciSlot = ((int)_BE_env.vgaInfo.bus << 8) |
|
||||
((int)_BE_env.vgaInfo.device << 3) | (int)_BE_env.vgaInfo.function;
|
||||
#else
|
||||
/* Fail if no PCI device information has been registered */
|
||||
if (!_BE_env.vgaInfo.pciInfo)
|
||||
return;
|
||||
|
||||
pciSlot = (u16) (_BE_env.vgaInfo.pciInfo->slot.i >> 8);
|
||||
#endif
|
||||
switch (M.x86.R_AX) {
|
||||
case 0xB101: /* PCI bios present? */
|
||||
M.x86.R_AL = 0x00; /* no config space/special cycle generation support */
|
||||
M.x86.R_EDX = 0x20494350; /* " ICP" */
|
||||
M.x86.R_BX = 0x0210; /* Version 2.10 */
|
||||
M.x86.R_CL = 0; /* Max bus number in system */
|
||||
CLEAR_FLAG(F_CF);
|
||||
break;
|
||||
case 0xB102: /* Find PCI device */
|
||||
M.x86.R_AH = DEVICE_NOT_FOUND;
|
||||
#ifdef __KERNEL__
|
||||
if (M.x86.R_DX == _BE_env.vgaInfo.VendorID &&
|
||||
M.x86.R_CX == _BE_env.vgaInfo.DeviceID && M.x86.R_SI == 0) {
|
||||
#else
|
||||
if (M.x86.R_DX == _BE_env.vgaInfo.pciInfo->VendorID &&
|
||||
M.x86.R_CX == _BE_env.vgaInfo.pciInfo->DeviceID &&
|
||||
M.x86.R_SI == 0) {
|
||||
#endif
|
||||
M.x86.R_AH = SUCCESSFUL;
|
||||
M.x86.R_BX = pciSlot;
|
||||
}
|
||||
CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
|
||||
break;
|
||||
case 0xB103: /* Find PCI class code */
|
||||
M.x86.R_AH = DEVICE_NOT_FOUND;
|
||||
#ifdef __KERNEL__
|
||||
pci_read_config_byte(_BE_env.vgaInfo.pcidev, PCI_CLASS_PROG,
|
||||
&interface);
|
||||
pci_read_config_byte(_BE_env.vgaInfo.pcidev, PCI_CLASS_DEVICE,
|
||||
&subclass);
|
||||
pci_read_config_byte(_BE_env.vgaInfo.pcidev,
|
||||
PCI_CLASS_DEVICE + 1, &baseclass);
|
||||
if (M.x86.R_CL == interface && M.x86.R_CH == subclass
|
||||
&& (u8) (M.x86.R_ECX >> 16) == baseclass) {
|
||||
#else
|
||||
if (M.x86.R_CL == _BE_env.vgaInfo.pciInfo->Interface &&
|
||||
M.x86.R_CH == _BE_env.vgaInfo.pciInfo->SubClass &&
|
||||
(u8) (M.x86.R_ECX >> 16) ==
|
||||
_BE_env.vgaInfo.pciInfo->BaseClass) {
|
||||
#endif
|
||||
M.x86.R_AH = SUCCESSFUL;
|
||||
M.x86.R_BX = pciSlot;
|
||||
}
|
||||
CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
|
||||
break;
|
||||
case 0xB108: /* Read configuration byte */
|
||||
M.x86.R_AH = BAD_REGISTER_NUMBER;
|
||||
if (M.x86.R_BX == pciSlot) {
|
||||
M.x86.R_AH = SUCCESSFUL;
|
||||
#ifdef __KERNEL__
|
||||
pci_read_config_byte(_BE_env.vgaInfo.pcidev, M.x86.R_DI,
|
||||
&M.x86.R_CL);
|
||||
#else
|
||||
M.x86.R_CL =
|
||||
(u8) PCI_accessReg(M.x86.R_DI, 0, PCI_READ_BYTE,
|
||||
_BE_env.vgaInfo.pciInfo);
|
||||
#endif
|
||||
}
|
||||
CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
|
||||
break;
|
||||
case 0xB109: /* Read configuration word */
|
||||
M.x86.R_AH = BAD_REGISTER_NUMBER;
|
||||
if (M.x86.R_BX == pciSlot) {
|
||||
M.x86.R_AH = SUCCESSFUL;
|
||||
#ifdef __KERNEL__
|
||||
pci_read_config_word(_BE_env.vgaInfo.pcidev, M.x86.R_DI,
|
||||
&M.x86.R_CX);
|
||||
#else
|
||||
M.x86.R_CX =
|
||||
(u16) PCI_accessReg(M.x86.R_DI, 0, PCI_READ_WORD,
|
||||
_BE_env.vgaInfo.pciInfo);
|
||||
#endif
|
||||
}
|
||||
CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
|
||||
break;
|
||||
case 0xB10A: /* Read configuration dword */
|
||||
M.x86.R_AH = BAD_REGISTER_NUMBER;
|
||||
if (M.x86.R_BX == pciSlot) {
|
||||
M.x86.R_AH = SUCCESSFUL;
|
||||
#ifdef __KERNEL__
|
||||
pci_read_config_dword(_BE_env.vgaInfo.pcidev,
|
||||
M.x86.R_DI, &M.x86.R_ECX);
|
||||
#else
|
||||
M.x86.R_ECX =
|
||||
(u32) PCI_accessReg(M.x86.R_DI, 0, PCI_READ_DWORD,
|
||||
_BE_env.vgaInfo.pciInfo);
|
||||
#endif
|
||||
}
|
||||
CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
|
||||
break;
|
||||
case 0xB10B: /* Write configuration byte */
|
||||
M.x86.R_AH = BAD_REGISTER_NUMBER;
|
||||
if (M.x86.R_BX == pciSlot) {
|
||||
M.x86.R_AH = SUCCESSFUL;
|
||||
#ifdef __KERNEL__
|
||||
pci_write_config_byte(_BE_env.vgaInfo.pcidev,
|
||||
M.x86.R_DI, M.x86.R_CL);
|
||||
#else
|
||||
PCI_accessReg(M.x86.R_DI, M.x86.R_CL, PCI_WRITE_BYTE,
|
||||
_BE_env.vgaInfo.pciInfo);
|
||||
#endif
|
||||
}
|
||||
CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
|
||||
break;
|
||||
case 0xB10C: /* Write configuration word */
|
||||
M.x86.R_AH = BAD_REGISTER_NUMBER;
|
||||
if (M.x86.R_BX == pciSlot) {
|
||||
M.x86.R_AH = SUCCESSFUL;
|
||||
#ifdef __KERNEL__
|
||||
pci_write_config_word(_BE_env.vgaInfo.pcidev,
|
||||
M.x86.R_DI, M.x86.R_CX);
|
||||
#else
|
||||
PCI_accessReg(M.x86.R_DI, M.x86.R_CX, PCI_WRITE_WORD,
|
||||
_BE_env.vgaInfo.pciInfo);
|
||||
#endif
|
||||
}
|
||||
CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
|
||||
break;
|
||||
case 0xB10D: /* Write configuration dword */
|
||||
M.x86.R_AH = BAD_REGISTER_NUMBER;
|
||||
if (M.x86.R_BX == pciSlot) {
|
||||
M.x86.R_AH = SUCCESSFUL;
|
||||
#ifdef __KERNEL__
|
||||
pci_write_config_dword(_BE_env.vgaInfo.pcidev,
|
||||
M.x86.R_DI, M.x86.R_ECX);
|
||||
#else
|
||||
PCI_accessReg(M.x86.R_DI, M.x86.R_ECX, PCI_WRITE_DWORD,
|
||||
_BE_env.vgaInfo.pciInfo);
|
||||
#endif
|
||||
}
|
||||
CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
|
||||
break;
|
||||
default:
|
||||
printf("biosEmu/bios.int1a: unknown function AX=%#04x\n",
|
||||
M.x86.R_AX);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
This function initialises the BIOS emulation functions for the specific
|
||||
PCI display device. We insulate the real mode BIOS from any other devices
|
||||
on the bus, so that it will work correctly thinking that it is the only
|
||||
device present on the bus (ie: avoiding any adapters present in from of
|
||||
the device we are trying to control).
|
||||
****************************************************************************/
|
||||
#define BE_constLE_32(v) ((((((v)&0xff00)>>8)|(((v)&0xff)<<8))<<16)|(((((v)&0xff000000)>>8)|(((v)&0x00ff0000)<<8))>>16))
|
||||
|
||||
void _BE_bios_init(u32 * intrTab)
|
||||
{
|
||||
int i;
|
||||
X86EMU_intrFuncs bios_intr_tab[256];
|
||||
|
||||
for (i = 0; i < 256; ++i) {
|
||||
intrTab[i] = BE_constLE_32(BIOS_SEG << 16);
|
||||
bios_intr_tab[i] = undefined_intr;
|
||||
}
|
||||
bios_intr_tab[0x10] = int10;
|
||||
bios_intr_tab[0x1A] = int1A;
|
||||
bios_intr_tab[0x42] = int42;
|
||||
bios_intr_tab[0x6D] = int10;
|
||||
X86EMU_setupIntrFuncs(bios_intr_tab);
|
||||
}
|
370
drivers/bios_emulator/biosemu.c
Normal file
370
drivers/bios_emulator/biosemu.c
Normal file
|
@ -0,0 +1,370 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* 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) 1996-1999 SciTech Software, Inc.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Module implementing the system specific functions. This
|
||||
* module is always compiled and linked in the OS depedent
|
||||
* libraries, and never in a binary portable driver.
|
||||
*
|
||||
* Jason ported this file to u-boot to run the ATI video card BIOS
|
||||
* in u-boot. Made all the video memory be emulated during the
|
||||
* BIOS runing process which may affect the VGA function but the
|
||||
* frambuffer function can work after run the BIOS.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "biosemui.h"
|
||||
#include <malloc.h>
|
||||
|
||||
BE_sysEnv _BE_env = {{0}};
|
||||
static X86EMU_memFuncs _BE_mem __attribute__((section(".got2"))) = {
|
||||
BE_rdb,
|
||||
BE_rdw,
|
||||
BE_rdl,
|
||||
BE_wrb,
|
||||
BE_wrw,
|
||||
BE_wrl,
|
||||
};
|
||||
|
||||
static X86EMU_pioFuncs _BE_pio __attribute__((section(".got2"))) = {
|
||||
BE_inb,
|
||||
BE_inw,
|
||||
BE_inl,
|
||||
BE_outb,
|
||||
BE_outw,
|
||||
BE_outl,
|
||||
};
|
||||
|
||||
#define OFF(addr) (u16)(((addr) >> 0) & 0xffff)
|
||||
#define SEG(addr) (u16)(((addr) >> 4) & 0xf000)
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
debugFlags - Flags to enable debugging options (debug builds only)
|
||||
memSize - Amount of memory to allocate for real mode machine
|
||||
info - Pointer to default VGA device information
|
||||
|
||||
REMARKS:
|
||||
This functions initialises the BElib, and uses the passed in
|
||||
BIOS image as the BIOS that is used and emulated at 0xC0000.
|
||||
****************************************************************************/
|
||||
int X86API BE_init(u32 debugFlags, int memSize, BE_VGAInfo * info, int shared)
|
||||
{
|
||||
#if !defined(__DRIVER__) && !defined(__KERNEL__)
|
||||
|
||||
PM_init();
|
||||
#endif
|
||||
memset(&M, 0, sizeof(M));
|
||||
if (memSize < 20480){
|
||||
printf("Emulator requires at least 20Kb of memory!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
M.mem_base = (unsigned long)malloc(memSize);
|
||||
|
||||
if (M.mem_base == NULL){
|
||||
printf("Biosemu:Out of memory!");
|
||||
return 0;
|
||||
}
|
||||
M.mem_size = memSize;
|
||||
|
||||
_BE_env.emulateVGA = 0;
|
||||
_BE_env.busmem_base = (unsigned long)malloc(128 * 1024);
|
||||
if (_BE_env.busmem_base == NULL){
|
||||
printf("Biosemu:Out of memory!");
|
||||
return 0;
|
||||
}
|
||||
M.x86.debug = debugFlags;
|
||||
_BE_bios_init((u32*)info->LowMem);
|
||||
X86EMU_setupMemFuncs(&_BE_mem);
|
||||
X86EMU_setupPioFuncs(&_BE_pio);
|
||||
BE_setVGA(info);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
info - Pointer to VGA device information to make current
|
||||
|
||||
REMARKS:
|
||||
This function sets the VGA BIOS functions in the emulator to point to the
|
||||
specific VGA BIOS in use. This includes swapping the BIOS interrupt
|
||||
vectors, BIOS image and BIOS data area to the new BIOS. This allows the
|
||||
real mode BIOS to be swapped without resetting the entire emulator.
|
||||
****************************************************************************/
|
||||
void X86API BE_setVGA(BE_VGAInfo * info)
|
||||
{
|
||||
|
||||
#ifdef __KERNEL__
|
||||
_BE_env.vgaInfo.function = info->function;
|
||||
_BE_env.vgaInfo.device = info->device;
|
||||
_BE_env.vgaInfo.bus = info->bus;
|
||||
_BE_env.vgaInfo.pcidev = info->pcidev;
|
||||
#else
|
||||
_BE_env.vgaInfo.pciInfo = info->pciInfo;
|
||||
#endif
|
||||
_BE_env.vgaInfo.BIOSImage = info->BIOSImage;
|
||||
if (info->BIOSImage) {
|
||||
_BE_env.biosmem_base = (ulong) info->BIOSImage;
|
||||
_BE_env.biosmem_limit = 0xC0000 + info->BIOSImageLen - 1;
|
||||
} else {
|
||||
_BE_env.biosmem_base = _BE_env.busmem_base + 0x20000;
|
||||
_BE_env.biosmem_limit = 0xC7FFF;
|
||||
}
|
||||
if (*((u32 *) info->LowMem) == 0)
|
||||
_BE_bios_init((u32 *) info->LowMem);
|
||||
memcpy((u8 *) M.mem_base, info->LowMem, sizeof(info->LowMem));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
info - Pointer to VGA device information to retrieve current
|
||||
|
||||
REMARKS:
|
||||
This function returns the VGA BIOS functions currently active in the
|
||||
emulator, so they can be restored at a later date.
|
||||
****************************************************************************/
|
||||
void X86API BE_getVGA(BE_VGAInfo * info)
|
||||
{
|
||||
#ifdef __KERNEL__
|
||||
info->function = _BE_env.vgaInfo.function;
|
||||
info->device = _BE_env.vgaInfo.device;
|
||||
info->bus = _BE_env.vgaInfo.bus;
|
||||
info->pcidev = _BE_env.vgaInfo.pcidev;
|
||||
#else
|
||||
info->pciInfo = _BE_env.vgaInfo.pciInfo;
|
||||
#endif
|
||||
info->BIOSImage = _BE_env.vgaInfo.BIOSImage;
|
||||
memcpy(info->LowMem, (u8 *) M.mem_base, sizeof(info->LowMem));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
r_seg - Segment for pointer to convert
|
||||
r_off - Offset for pointer to convert
|
||||
|
||||
REMARKS:
|
||||
This function maps a real mode pointer in the emulator memory to a protected
|
||||
mode pointer that can be used to directly access the memory.
|
||||
|
||||
NOTE: The memory is *always* in little endian format, son on non-x86
|
||||
systems you will need to do endian translations to access this
|
||||
memory.
|
||||
****************************************************************************/
|
||||
void *X86API BE_mapRealPointer(uint r_seg, uint r_off)
|
||||
{
|
||||
u32 addr = ((u32) r_seg << 4) + r_off;
|
||||
|
||||
if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
|
||||
return (void *)(_BE_env.biosmem_base + addr - 0xC0000);
|
||||
} else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
|
||||
return (void *)(_BE_env.busmem_base + addr - 0xA0000);
|
||||
}
|
||||
return (void *)(M.mem_base + addr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
len - Return the length of the VESA buffer
|
||||
rseg - Place to store VESA buffer segment
|
||||
roff - Place to store VESA buffer offset
|
||||
|
||||
REMARKS:
|
||||
This function returns the address of the VESA transfer buffer in real
|
||||
_BE_piomode emulator memory. The VESA transfer buffer is always 1024 bytes long,
|
||||
and located at 15Kb into the start of the real mode memory (16Kb is where
|
||||
we put the real mode code we execute for issuing interrupts).
|
||||
|
||||
NOTE: The memory is *always* in little endian format, son on non-x86
|
||||
systems you will need to do endian translations to access this
|
||||
memory.
|
||||
****************************************************************************/
|
||||
void *X86API BE_getVESABuf(uint * len, uint * rseg, uint * roff)
|
||||
{
|
||||
*len = 1024;
|
||||
*rseg = SEG(0x03C00);
|
||||
*roff = OFF(0x03C00);
|
||||
return (void *)(M.mem_base + ((u32) * rseg << 4) + *roff);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Cleans up and exits the emulator.
|
||||
****************************************************************************/
|
||||
void X86API BE_exit(void)
|
||||
{
|
||||
free(M.mem_base);
|
||||
free(_BE_env.busmem_base);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
seg - Segment of code to call
|
||||
off - Offset of code to call
|
||||
regs - Real mode registers to load
|
||||
sregs - Real mode segment registers to load
|
||||
|
||||
REMARKS:
|
||||
This functions calls a real mode far function at the specified address,
|
||||
and loads all the x86 registers from the passed in registers structure.
|
||||
On exit the registers returned from the call are returned in the same
|
||||
structures.
|
||||
****************************************************************************/
|
||||
void X86API BE_callRealMode(uint seg, uint off, RMREGS * regs, RMSREGS * sregs)
|
||||
{
|
||||
M.x86.R_EAX = regs->e.eax;
|
||||
M.x86.R_EBX = regs->e.ebx;
|
||||
M.x86.R_ECX = regs->e.ecx;
|
||||
M.x86.R_EDX = regs->e.edx;
|
||||
M.x86.R_ESI = regs->e.esi;
|
||||
M.x86.R_EDI = regs->e.edi;
|
||||
M.x86.R_DS = sregs->ds;
|
||||
M.x86.R_ES = sregs->es;
|
||||
M.x86.R_FS = sregs->fs;
|
||||
M.x86.R_GS = sregs->gs;
|
||||
|
||||
((u8 *) M.mem_base)[0x4000] = 0x9A;
|
||||
((u8 *) M.mem_base)[0x4001] = (u8) off;
|
||||
((u8 *) M.mem_base)[0x4002] = (u8) (off >> 8);
|
||||
((u8 *) M.mem_base)[0x4003] = (u8) seg;
|
||||
((u8 *) M.mem_base)[0x4004] = (u8) (seg >> 8);
|
||||
((u8 *) M.mem_base)[0x4005] = 0xF1; /* Illegal op-code */
|
||||
M.x86.R_CS = SEG(0x04000);
|
||||
M.x86.R_IP = OFF(0x04000);
|
||||
|
||||
M.x86.R_SS = SEG(M.mem_size - 2);
|
||||
M.x86.R_SP = OFF(M.mem_size - 2) + 2;
|
||||
|
||||
X86EMU_exec();
|
||||
|
||||
regs->e.cflag = M.x86.R_EFLG & F_CF;
|
||||
regs->e.eax = M.x86.R_EAX;
|
||||
regs->e.ebx = M.x86.R_EBX;
|
||||
regs->e.ecx = M.x86.R_ECX;
|
||||
regs->e.edx = M.x86.R_EDX;
|
||||
regs->e.esi = M.x86.R_ESI;
|
||||
regs->e.edi = M.x86.R_EDI;
|
||||
sregs->ds = M.x86.R_DS;
|
||||
sregs->es = M.x86.R_ES;
|
||||
sregs->fs = M.x86.R_FS;
|
||||
sregs->gs = M.x86.R_GS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
intno - Interrupt number to execute
|
||||
in - Real mode registers to load
|
||||
out - Place to store resulting real mode registers
|
||||
|
||||
REMARKS:
|
||||
This functions calls a real mode interrupt function at the specified address,
|
||||
and loads all the x86 registers from the passed in registers structure.
|
||||
On exit the registers returned from the call are returned in out stucture.
|
||||
****************************************************************************/
|
||||
int X86API BE_int86(int intno, RMREGS * in, RMREGS * out)
|
||||
{
|
||||
M.x86.R_EAX = in->e.eax;
|
||||
M.x86.R_EBX = in->e.ebx;
|
||||
M.x86.R_ECX = in->e.ecx;
|
||||
M.x86.R_EDX = in->e.edx;
|
||||
M.x86.R_ESI = in->e.esi;
|
||||
M.x86.R_EDI = in->e.edi;
|
||||
((u8 *) M.mem_base)[0x4000] = 0xCD;
|
||||
((u8 *) M.mem_base)[0x4001] = (u8) intno;
|
||||
((u8 *) M.mem_base)[0x4002] = 0xF1;
|
||||
M.x86.R_CS = SEG(0x04000);
|
||||
M.x86.R_IP = OFF(0x04000);
|
||||
|
||||
M.x86.R_SS = SEG(M.mem_size - 1);
|
||||
M.x86.R_SP = OFF(M.mem_size - 1) - 1;
|
||||
|
||||
X86EMU_exec();
|
||||
out->e.cflag = M.x86.R_EFLG & F_CF;
|
||||
out->e.eax = M.x86.R_EAX;
|
||||
out->e.ebx = M.x86.R_EBX;
|
||||
out->e.ecx = M.x86.R_ECX;
|
||||
out->e.edx = M.x86.R_EDX;
|
||||
out->e.esi = M.x86.R_ESI;
|
||||
out->e.edi = M.x86.R_EDI;
|
||||
return out->x.ax;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
intno - Interrupt number to execute
|
||||
in - Real mode registers to load
|
||||
out - Place to store resulting real mode registers
|
||||
sregs - Real mode segment registers to load
|
||||
|
||||
REMARKS:
|
||||
This functions calls a real mode interrupt function at the specified address,
|
||||
and loads all the x86 registers from the passed in registers structure.
|
||||
On exit the registers returned from the call are returned in out stucture.
|
||||
****************************************************************************/
|
||||
int X86API BE_int86x(int intno, RMREGS * in, RMREGS * out, RMSREGS * sregs)
|
||||
{
|
||||
M.x86.R_EAX = in->e.eax;
|
||||
M.x86.R_EBX = in->e.ebx;
|
||||
M.x86.R_ECX = in->e.ecx;
|
||||
M.x86.R_EDX = in->e.edx;
|
||||
M.x86.R_ESI = in->e.esi;
|
||||
M.x86.R_EDI = in->e.edi;
|
||||
M.x86.R_DS = sregs->ds;
|
||||
M.x86.R_ES = sregs->es;
|
||||
M.x86.R_FS = sregs->fs;
|
||||
M.x86.R_GS = sregs->gs;
|
||||
((u8 *) M.mem_base)[0x4000] = 0xCD;
|
||||
((u8 *) M.mem_base)[0x4001] = (u8) intno;
|
||||
((u8 *) M.mem_base)[0x4002] = 0xF1;
|
||||
M.x86.R_CS = SEG(0x04000);
|
||||
M.x86.R_IP = OFF(0x04000);
|
||||
|
||||
M.x86.R_SS = SEG(M.mem_size - 1);
|
||||
M.x86.R_SP = OFF(M.mem_size - 1) - 1;
|
||||
|
||||
X86EMU_exec();
|
||||
out->e.cflag = M.x86.R_EFLG & F_CF;
|
||||
out->e.eax = M.x86.R_EAX;
|
||||
out->e.ebx = M.x86.R_EBX;
|
||||
out->e.ecx = M.x86.R_ECX;
|
||||
out->e.edx = M.x86.R_EDX;
|
||||
out->e.esi = M.x86.R_ESI;
|
||||
out->e.edi = M.x86.R_EDI;
|
||||
sregs->ds = M.x86.R_DS;
|
||||
sregs->es = M.x86.R_ES;
|
||||
sregs->fs = M.x86.R_FS;
|
||||
sregs->gs = M.x86.R_GS;
|
||||
return out->x.ax;
|
||||
}
|
169
drivers/bios_emulator/biosemui.h
Normal file
169
drivers/bios_emulator/biosemui.h
Normal file
|
@ -0,0 +1,169 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* 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) 1996-1999 SciTech Software, Inc.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Internal header file for the BIOS emulator library.
|
||||
*
|
||||
* Jason ported this file to u-boot, Added some architecture
|
||||
* related Macro.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __BIOSEMUI_H
|
||||
#define __BIOSEMUI_H
|
||||
|
||||
#include "biosemu.h"
|
||||
#include <asm/io.h>
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DB(x) x
|
||||
#else
|
||||
#define DB(x) do{}while(0);
|
||||
#endif
|
||||
|
||||
#define BIOS_SEG 0xfff0
|
||||
extern X86EMU_sysEnv _X86EMU_env;
|
||||
#define M _X86EMU_env
|
||||
|
||||
/* Macros to read and write values to x86 emulator memory. Memory is always
|
||||
* considered to be little endian, so we use macros to do endian swapping
|
||||
* where necessary.
|
||||
*/
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
#define readb_le(base) *((u8*)(base))
|
||||
#define readw_le(base) ((u16)readb_le(base) | ((u16)readb_le((base) + 1) << 8))
|
||||
#define readl_le(base) ((u32)readb_le((base) + 0) | ((u32)readb_le((base) + 1) << 8) | \
|
||||
((u32)readb_le((base) + 2) << 16) | ((u32)readb_le((base) + 3) << 24))
|
||||
#define writeb_le(base, v) *((u8*)(base)) = (v)
|
||||
#define writew_le(base, v) writeb_le(base + 0, (v >> 0) & 0xff), \
|
||||
writeb_le(base + 1, (v >> 8) & 0xff)
|
||||
#define writel_le(base, v) writeb_le(base + 0, (v >> 0) & 0xff), \
|
||||
writeb_le(base + 1, (v >> 8) & 0xff), \
|
||||
writeb_le(base + 2, (v >> 16) & 0xff), \
|
||||
writeb_le(base + 3, (v >> 24) & 0xff)
|
||||
#else
|
||||
#define readb_le(base) *((u8*)(base))
|
||||
#define readw_le(base) *((u16*)(base))
|
||||
#define readl_le(base) *((u32*)(base))
|
||||
#define writeb_le(base, v) *((u8*)(base)) = (v)
|
||||
#define writew_le(base, v) *((u16*)(base)) = (v)
|
||||
#define writel_le(base, v) *((u32*)(base)) = (v)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Function codes passed to the emulated I/O port functions to determine the
|
||||
type of operation to perform.
|
||||
****************************************************************************/
|
||||
typedef enum {
|
||||
REG_READ_BYTE = 0,
|
||||
REG_READ_WORD = 1,
|
||||
REG_READ_DWORD = 2,
|
||||
REG_WRITE_BYTE = 3,
|
||||
REG_WRITE_WORD = 4,
|
||||
REG_WRITE_DWORD = 5
|
||||
} RegisterFlags;
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Function codes passed to the emulated I/O port functions to determine the
|
||||
type of operation to perform.
|
||||
****************************************************************************/
|
||||
typedef enum {
|
||||
PORT_BYTE = 1,
|
||||
PORT_WORD = 2,
|
||||
PORT_DWORD = 3,
|
||||
} PortInfoFlags;
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Data structure used to describe the details for the BIOS emulator system
|
||||
environment as used by the X86 emulator library.
|
||||
|
||||
HEADER:
|
||||
biosemu.h
|
||||
|
||||
MEMBERS:
|
||||
type - Type of port access (1 = byte, 2 = word, 3 = dword)
|
||||
defVal - Default power on value
|
||||
finalVal - Final value
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
u8 type;
|
||||
u32 defVal;
|
||||
u32 finalVal;
|
||||
} BE_portInfo;
|
||||
|
||||
#define PM_inpb(port) inb(port+VIDEO_IO_OFFSET)
|
||||
#define PM_inpw(port) inw(port+VIDEO_IO_OFFSET)
|
||||
#define PM_inpd(port) inl(port+VIDEO_IO_OFFSET)
|
||||
#define PM_outpb(port,val) outb(val,port+VIDEO_IO_OFFSET)
|
||||
#define PM_outpw(port,val) outw(val,port+VIDEO_IO_OFFSET)
|
||||
#define PM_outpd(port,val) outl(val,port+VIDEO_IO_OFFSET)
|
||||
|
||||
#define LOG_inpb(port) PM_inpb(port)
|
||||
#define LOG_inpw(port) PM_inpw(port)
|
||||
#define LOG_inpd(port) PM_inpd(port)
|
||||
#define LOG_outpb(port,val) PM_outpb(port,val)
|
||||
#define LOG_outpw(port,val) PM_outpw(port,val)
|
||||
#define LOG_outpd(port,val) PM_outpd(port,val)
|
||||
|
||||
/*-------------------------- Function Prototypes --------------------------*/
|
||||
|
||||
/* bios.c */
|
||||
|
||||
void _BE_bios_init(u32 * intrTab);
|
||||
void _BE_setup_funcs(void);
|
||||
|
||||
/* besys.c */
|
||||
#define DEBUG_IO() (M.x86.debug & DEBUG_IO_TRACE_F)
|
||||
|
||||
u8 X86API BE_rdb(u32 addr);
|
||||
u16 X86API BE_rdw(u32 addr);
|
||||
u32 X86API BE_rdl(u32 addr);
|
||||
void X86API BE_wrb(u32 addr, u8 val);
|
||||
void X86API BE_wrw(u32 addr, u16 val);
|
||||
void X86API BE_wrl(u32 addr, u32 val);
|
||||
|
||||
u8 X86API BE_inb(X86EMU_pioAddr port);
|
||||
u16 X86API BE_inw(X86EMU_pioAddr port);
|
||||
u32 X86API BE_inl(X86EMU_pioAddr port);
|
||||
void X86API BE_outb(X86EMU_pioAddr port, u8 val);
|
||||
void X86API BE_outw(X86EMU_pioAddr port, u16 val);
|
||||
void X86API BE_outl(X86EMU_pioAddr port, u32 val);
|
||||
#endif
|
||||
/* __BIOSEMUI_H */
|
392
drivers/bios_emulator/include/biosemu.h
Normal file
392
drivers/bios_emulator/include/biosemu.h
Normal file
|
@ -0,0 +1,392 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* BIOS emulator and interface
|
||||
* to Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for the real mode x86 BIOS emulator, which is
|
||||
* used to warmboot any number of VGA compatible PCI/AGP
|
||||
* controllers under any OS, on any processor family that
|
||||
* supports PCI. We also allow the user application to call
|
||||
* real mode BIOS functions and Int 10h functions (including
|
||||
* the VESA BIOS).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __BIOSEMU_H
|
||||
#define __BIOSEMU_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include "x86emu.h"
|
||||
#else
|
||||
#include "x86emu.h"
|
||||
#include "pmapi.h"
|
||||
#include "pcilib.h"
|
||||
#endif
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#ifndef __KERNEL__
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Data structure used to describe the details specific to a particular VGA
|
||||
controller. This information is used to allow the VGA controller to be
|
||||
swapped on the fly within the BIOS emulator.
|
||||
|
||||
HEADER:
|
||||
biosemu.h
|
||||
|
||||
MEMBERS:
|
||||
pciInfo - PCI device information block for the controller
|
||||
BIOSImage - Pointer to a read/write copy of the BIOS image
|
||||
BIOSImageLen - Length of the BIOS image
|
||||
LowMem - Copy of key low memory areas
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
PCIDeviceInfo *pciInfo;
|
||||
void *BIOSImage;
|
||||
ulong BIOSImageLen;
|
||||
uchar LowMem[1536];
|
||||
} BE_VGAInfo;
|
||||
#else
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Data structure used to describe the details for the BIOS emulator system
|
||||
environment as used by the X86 emulator library.
|
||||
|
||||
HEADER:
|
||||
biosemu.h
|
||||
|
||||
MEMBERS:
|
||||
vgaInfo - VGA BIOS information structure
|
||||
biosmem_base - Base of the BIOS image
|
||||
biosmem_limit - Limit of the BIOS image
|
||||
busmem_base - Base of the VGA bus memory
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
int function;
|
||||
int device;
|
||||
int bus;
|
||||
u32 VendorID;
|
||||
u32 DeviceID;
|
||||
pci_dev_t pcidev;
|
||||
void *BIOSImage;
|
||||
u32 BIOSImageLen;
|
||||
u8 LowMem[1536];
|
||||
} BE_VGAInfo;
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#define CRT_C 24 /* 24 CRT Controller Registers */
|
||||
#define ATT_C 21 /* 21 Attribute Controller Registers */
|
||||
#define GRA_C 9 /* 9 Graphics Controller Registers */
|
||||
#define SEQ_C 5 /* 5 Sequencer Registers */
|
||||
#define PAL_C 768 /* 768 Palette Registers */
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Data structure used to describe the details for the BIOS emulator system
|
||||
environment as used by the X86 emulator library.
|
||||
|
||||
HEADER:
|
||||
biosemu.h
|
||||
|
||||
MEMBERS:
|
||||
vgaInfo - VGA BIOS information structure
|
||||
biosmem_base - Base of the BIOS image
|
||||
biosmem_limit - Limit of the BIOS image
|
||||
busmem_base - Base of the VGA bus memory
|
||||
timer - Timer used to emulate PC timer ports
|
||||
timer0 - Latched value for timer 0
|
||||
timer0Latched - True if timer 0 value was just latched
|
||||
timer2 - Current value for timer 2
|
||||
emulateVGA - True to emulate VGA I/O and memory accesses
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
BE_VGAInfo vgaInfo;
|
||||
ulong biosmem_base;
|
||||
ulong biosmem_limit;
|
||||
ulong busmem_base;
|
||||
|
||||
u32 timer0;
|
||||
int timer0Latched;
|
||||
u32 timer1;
|
||||
int timer1Latched;
|
||||
u32 timer2;
|
||||
int timer2Latched;
|
||||
|
||||
int emulateVGA;
|
||||
u8 emu61;
|
||||
u8 emu70;
|
||||
int flipFlop3C0;
|
||||
u32 configAddress;
|
||||
u8 emu3C0;
|
||||
u8 emu3C1[ATT_C];
|
||||
u8 emu3C2;
|
||||
u8 emu3C4;
|
||||
u8 emu3C5[SEQ_C];
|
||||
u8 emu3C6;
|
||||
uint emu3C7;
|
||||
uint emu3C8;
|
||||
u8 emu3C9[PAL_C];
|
||||
u8 emu3CE;
|
||||
u8 emu3CF[GRA_C];
|
||||
u8 emu3D4;
|
||||
u8 emu3D5[CRT_C];
|
||||
u8 emu3DA;
|
||||
|
||||
} BE_sysEnv;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* Define some types when compiling for the Linux kernel that normally
|
||||
* come from the SciTech PM library.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Structure describing the 32-bit extended x86 CPU registers
|
||||
|
||||
HEADER:
|
||||
pmapi.h
|
||||
|
||||
MEMBERS:
|
||||
eax - Value of the EAX register
|
||||
ebx - Value of the EBX register
|
||||
ecx - Value of the ECX register
|
||||
edx - Value of the EDX register
|
||||
esi - Value of the ESI register
|
||||
edi - Value of the EDI register
|
||||
cflag - Value of the carry flag
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
u32 eax;
|
||||
u32 ebx;
|
||||
u32 ecx;
|
||||
u32 edx;
|
||||
u32 esi;
|
||||
u32 edi;
|
||||
u32 cflag;
|
||||
} RMDWORDREGS;
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Structure describing the 16-bit x86 CPU registers
|
||||
|
||||
HEADER:
|
||||
pmapi.h
|
||||
|
||||
MEMBERS:
|
||||
ax - Value of the AX register
|
||||
bx - Value of the BX register
|
||||
cx - Value of the CX register
|
||||
dx - Value of the DX register
|
||||
si - Value of the SI register
|
||||
di - Value of the DI register
|
||||
cflag - Value of the carry flag
|
||||
****************************************************************************/
|
||||
#ifdef __BIG_ENDIAN__
|
||||
typedef struct {
|
||||
u16 ax_hi, ax;
|
||||
u16 bx_hi, bx;
|
||||
u16 cx_hi, cx;
|
||||
u16 dx_hi, dx;
|
||||
u16 si_hi, si;
|
||||
u16 di_hi, di;
|
||||
u16 cflag_hi, cflag;
|
||||
} RMWORDREGS;
|
||||
#else
|
||||
typedef struct {
|
||||
u16 ax, ax_hi;
|
||||
u16 bx, bx_hi;
|
||||
u16 cx, cx_hi;
|
||||
u16 dx, dx_hi;
|
||||
u16 si, si_hi;
|
||||
u16 di, di_hi;
|
||||
u16 cflag, cflag_hi;
|
||||
} RMWORDREGS;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Structure describing the 8-bit x86 CPU registers
|
||||
|
||||
HEADER:
|
||||
pmapi.h
|
||||
|
||||
MEMBERS:
|
||||
al - Value of the AL register
|
||||
ah - Value of the AH register
|
||||
bl - Value of the BL register
|
||||
bh - Value of the BH register
|
||||
cl - Value of the CL register
|
||||
ch - Value of the CH register
|
||||
dl - Value of the DL register
|
||||
dh - Value of the DH register
|
||||
****************************************************************************/
|
||||
#ifdef __BIG_ENDIAN__
|
||||
typedef struct {
|
||||
u16 ax_hi;
|
||||
u8 ah, al;
|
||||
u16 bx_hi;
|
||||
u8 bh, bl;
|
||||
u16 cx_hi;
|
||||
u8 ch, cl;
|
||||
u16 dx_hi;
|
||||
u8 dh, dl;
|
||||
} RMBYTEREGS;
|
||||
#else
|
||||
typedef struct {
|
||||
u8 al;
|
||||
u8 ah;
|
||||
u16 ax_hi;
|
||||
u8 bl;
|
||||
u8 bh;
|
||||
u16 bx_hi;
|
||||
u8 cl;
|
||||
u8 ch;
|
||||
u16 cx_hi;
|
||||
u8 dl;
|
||||
u8 dh;
|
||||
u16 dx_hi;
|
||||
} RMBYTEREGS;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Structure describing all the x86 CPU registers
|
||||
|
||||
HEADER:
|
||||
pmapi.h
|
||||
|
||||
MEMBERS:
|
||||
e - Member to access registers as 32-bit values
|
||||
x - Member to access registers as 16-bit values
|
||||
h - Member to access registers as 8-bit values
|
||||
****************************************************************************/
|
||||
typedef union {
|
||||
RMDWORDREGS e;
|
||||
RMWORDREGS x;
|
||||
RMBYTEREGS h;
|
||||
} RMREGS;
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Structure describing all the x86 segment registers
|
||||
|
||||
HEADER:
|
||||
pmapi.h
|
||||
|
||||
MEMBERS:
|
||||
es - ES segment register
|
||||
cs - CS segment register
|
||||
ss - SS segment register
|
||||
ds - DS segment register
|
||||
fs - FS segment register
|
||||
gs - GS segment register
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
u16 es;
|
||||
u16 cs;
|
||||
u16 ss;
|
||||
u16 ds;
|
||||
u16 fs;
|
||||
u16 gs;
|
||||
} RMSREGS;
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Structure defining all the BIOS Emulator API functions as exported from
|
||||
the Binary Portable DLL.
|
||||
{secret}
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
ulong dwSize;
|
||||
ibool(PMAPIP BE_init) (u32 debugFlags, int memSize, BE_VGAInfo * info);
|
||||
void (PMAPIP BE_setVGA) (BE_VGAInfo * info);
|
||||
void (PMAPIP BE_getVGA) (BE_VGAInfo * info);
|
||||
void *(PMAPIP BE_mapRealPointer) (uint r_seg, uint r_off);
|
||||
void *(PMAPIP BE_getVESABuf) (uint * len, uint * rseg, uint * roff);
|
||||
void (PMAPIP BE_callRealMode) (uint seg, uint off, RMREGS * regs,
|
||||
RMSREGS * sregs);
|
||||
int (PMAPIP BE_int86) (int intno, RMREGS * in, RMREGS * out);
|
||||
int (PMAPIP BE_int86x) (int intno, RMREGS * in, RMREGS * out,
|
||||
RMSREGS * sregs);
|
||||
void *reserved1;
|
||||
void (PMAPIP BE_exit) (void);
|
||||
} BE_exports;
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Function pointer type for the Binary Portable DLL initialisation entry point.
|
||||
{secret}
|
||||
****************************************************************************/
|
||||
typedef BE_exports *(PMAPIP BE_initLibrary_t) (PM_imports * PMImp);
|
||||
#endif
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/*---------------------------- Global variables ---------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
/* {secret} Global BIOS emulator system environment */
|
||||
extern BE_sysEnv _BE_env;
|
||||
|
||||
/*-------------------------- Function Prototypes --------------------------*/
|
||||
|
||||
/* BIOS emulator library entry points */
|
||||
int X86API BE_init(u32 debugFlags, int memSize, BE_VGAInfo * info,
|
||||
int shared);
|
||||
void X86API BE_setVGA(BE_VGAInfo * info);
|
||||
void X86API BE_getVGA(BE_VGAInfo * info);
|
||||
void X86API BE_setDebugFlags(u32 debugFlags);
|
||||
void *X86API BE_mapRealPointer(uint r_seg, uint r_off);
|
||||
void *X86API BE_getVESABuf(uint * len, uint * rseg, uint * roff);
|
||||
void X86API BE_callRealMode(uint seg, uint off, RMREGS * regs,
|
||||
RMSREGS * sregs);
|
||||
int X86API BE_int86(int intno, RMREGS * in, RMREGS * out);
|
||||
int X86API BE_int86x(int intno, RMREGS * in, RMREGS * out,
|
||||
RMSREGS * sregs);
|
||||
void X86API BE_exit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __BIOSEMU_H */
|
191
drivers/bios_emulator/include/x86emu.h
Normal file
191
drivers/bios_emulator/include/x86emu.h
Normal file
|
@ -0,0 +1,191 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for public specific functions.
|
||||
* Any application linking against us should only
|
||||
* include this header
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_X86EMU_H
|
||||
#define __X86EMU_X86EMU_H
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <common.h>
|
||||
#include <pci.h>
|
||||
#include <asm/io.h>
|
||||
#define X86API
|
||||
#define X86APIP *
|
||||
typedef u16 X86EMU_pioAddr;
|
||||
|
||||
#include "x86emu/regs.h"
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Data structure containing ponters to programmed I/O functions used by the
|
||||
emulator. This is used so that the user program can hook all programmed
|
||||
I/O for the emulator to handled as necessary by the user program. By
|
||||
default the emulator contains simple functions that do not do access the
|
||||
hardware in any way. To allow the emualtor access the hardware, you will
|
||||
need to override the programmed I/O functions using the X86EMU_setupPioFuncs
|
||||
function.
|
||||
|
||||
HEADER:
|
||||
x86emu.h
|
||||
|
||||
MEMBERS:
|
||||
inb - Function to read a byte from an I/O port
|
||||
inw - Function to read a word from an I/O port
|
||||
inl - Function to read a dword from an I/O port
|
||||
outb - Function to write a byte to an I/O port
|
||||
outw - Function to write a word to an I/O port
|
||||
outl - Function to write a dword to an I/O port
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
u8(X86APIP inb) (X86EMU_pioAddr addr);
|
||||
u16(X86APIP inw) (X86EMU_pioAddr addr);
|
||||
u32(X86APIP inl) (X86EMU_pioAddr addr);
|
||||
void (X86APIP outb) (X86EMU_pioAddr addr, u8 val);
|
||||
void (X86APIP outw) (X86EMU_pioAddr addr, u16 val);
|
||||
void (X86APIP outl) (X86EMU_pioAddr addr, u32 val);
|
||||
} X86EMU_pioFuncs;
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Data structure containing ponters to memory access functions used by the
|
||||
emulator. This is used so that the user program can hook all memory
|
||||
access functions as necessary for the emulator. By default the emulator
|
||||
contains simple functions that only access the internal memory of the
|
||||
emulator. If you need specialised functions to handle access to different
|
||||
types of memory (ie: hardware framebuffer accesses and BIOS memory access
|
||||
etc), you will need to override this using the X86EMU_setupMemFuncs
|
||||
function.
|
||||
|
||||
HEADER:
|
||||
x86emu.h
|
||||
|
||||
MEMBERS:
|
||||
rdb - Function to read a byte from an address
|
||||
rdw - Function to read a word from an address
|
||||
rdl - Function to read a dword from an address
|
||||
wrb - Function to write a byte to an address
|
||||
wrw - Function to write a word to an address
|
||||
wrl - Function to write a dword to an address
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
u8(X86APIP rdb) (u32 addr);
|
||||
u16(X86APIP rdw) (u32 addr);
|
||||
u32(X86APIP rdl) (u32 addr);
|
||||
void (X86APIP wrb) (u32 addr, u8 val);
|
||||
void (X86APIP wrw) (u32 addr, u16 val);
|
||||
void (X86APIP wrl) (u32 addr, u32 val);
|
||||
} X86EMU_memFuncs;
|
||||
|
||||
/****************************************************************************
|
||||
Here are the default memory read and write
|
||||
function in case they are needed as fallbacks.
|
||||
***************************************************************************/
|
||||
extern u8 X86API rdb(u32 addr);
|
||||
extern u16 X86API rdw(u32 addr);
|
||||
extern u32 X86API rdl(u32 addr);
|
||||
extern void X86API wrb(u32 addr, u8 val);
|
||||
extern void X86API wrw(u32 addr, u16 val);
|
||||
extern void X86API wrl(u32 addr, u32 val);
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/*--------------------- type definitions -----------------------------------*/
|
||||
|
||||
typedef void (X86APIP X86EMU_intrFuncs) (int num);
|
||||
extern X86EMU_intrFuncs _X86EMU_intrTab[256];
|
||||
|
||||
/*-------------------------- Function Prototypes --------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
void X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs);
|
||||
void X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs);
|
||||
void X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[]);
|
||||
void X86EMU_prepareForInt(int num);
|
||||
|
||||
/* decode.c */
|
||||
|
||||
void X86EMU_exec(void);
|
||||
void X86EMU_halt_sys(void);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define HALT_SYS() \
|
||||
printf("halt_sys: file %s, line %d\n", __FILE__, __LINE__), \
|
||||
X86EMU_halt_sys()
|
||||
#else
|
||||
#define HALT_SYS() X86EMU_halt_sys()
|
||||
#endif
|
||||
|
||||
/* Debug options */
|
||||
|
||||
#define DEBUG_DECODE_F 0x0001 /* print decoded instruction */
|
||||
#define DEBUG_TRACE_F 0x0002 /* dump regs before/after execution */
|
||||
#define DEBUG_STEP_F 0x0004
|
||||
#define DEBUG_DISASSEMBLE_F 0x0008
|
||||
#define DEBUG_BREAK_F 0x0010
|
||||
#define DEBUG_SVC_F 0x0020
|
||||
#define DEBUG_SAVE_CS_IP 0x0040
|
||||
#define DEBUG_FS_F 0x0080
|
||||
#define DEBUG_PROC_F 0x0100
|
||||
#define DEBUG_SYSINT_F 0x0200 /* bios system interrupts. */
|
||||
#define DEBUG_TRACECALL_F 0x0400
|
||||
#define DEBUG_INSTRUMENT_F 0x0800
|
||||
#define DEBUG_MEM_TRACE_F 0x1000
|
||||
#define DEBUG_IO_TRACE_F 0x2000
|
||||
#define DEBUG_TRACECALL_REGS_F 0x4000
|
||||
#define DEBUG_DECODE_NOPRINT_F 0x8000
|
||||
#define DEBUG_EXIT 0x10000
|
||||
#define DEBUG_SYS_F (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F)
|
||||
|
||||
void X86EMU_trace_regs(void);
|
||||
void X86EMU_trace_xregs(void);
|
||||
void X86EMU_dump_memory(u16 seg, u16 off, u32 amt);
|
||||
int X86EMU_trace_on(void);
|
||||
int X86EMU_trace_off(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __X86EMU_X86EMU_H */
|
209
drivers/bios_emulator/include/x86emu/debug.h
Normal file
209
drivers/bios_emulator/include/x86emu/debug.h
Normal file
|
@ -0,0 +1,209 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1991-2004 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for debug definitions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_DEBUG_H
|
||||
#define __X86EMU_DEBUG_H
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
/* checks to be enabled for "runtime" */
|
||||
|
||||
#define CHECK_IP_FETCH_F 0x1
|
||||
#define CHECK_SP_ACCESS_F 0x2
|
||||
#define CHECK_MEM_ACCESS_F 0x4 /*using regular linear pointer */
|
||||
#define CHECK_DATA_ACCESS_F 0x8 /*using segment:offset */
|
||||
|
||||
#ifdef DEBUG
|
||||
# define CHECK_IP_FETCH() (M.x86.check & CHECK_IP_FETCH_F)
|
||||
# define CHECK_SP_ACCESS() (M.x86.check & CHECK_SP_ACCESS_F)
|
||||
# define CHECK_MEM_ACCESS() (M.x86.check & CHECK_MEM_ACCESS_F)
|
||||
# define CHECK_DATA_ACCESS() (M.x86.check & CHECK_DATA_ACCESS_F)
|
||||
#else
|
||||
# define CHECK_IP_FETCH()
|
||||
# define CHECK_SP_ACCESS()
|
||||
# define CHECK_MEM_ACCESS()
|
||||
# define CHECK_DATA_ACCESS()
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# define DEBUG_INSTRUMENT() (M.x86.debug & DEBUG_INSTRUMENT_F)
|
||||
# define DEBUG_DECODE() (M.x86.debug & DEBUG_DECODE_F)
|
||||
# define DEBUG_TRACE() (M.x86.debug & DEBUG_TRACE_F)
|
||||
# define DEBUG_STEP() (M.x86.debug & DEBUG_STEP_F)
|
||||
# define DEBUG_DISASSEMBLE() (M.x86.debug & DEBUG_DISASSEMBLE_F)
|
||||
# define DEBUG_BREAK() (M.x86.debug & DEBUG_BREAK_F)
|
||||
# define DEBUG_SVC() (M.x86.debug & DEBUG_SVC_F)
|
||||
# define DEBUG_SAVE_IP_CS() (M.x86.debug & DEBUG_SAVE_CS_IP)
|
||||
|
||||
# define DEBUG_FS() (M.x86.debug & DEBUG_FS_F)
|
||||
# define DEBUG_PROC() (M.x86.debug & DEBUG_PROC_F)
|
||||
# define DEBUG_SYSINT() (M.x86.debug & DEBUG_SYSINT_F)
|
||||
# define DEBUG_TRACECALL() (M.x86.debug & DEBUG_TRACECALL_F)
|
||||
# define DEBUG_TRACECALLREGS() (M.x86.debug & DEBUG_TRACECALL_REGS_F)
|
||||
# define DEBUG_SYS() (M.x86.debug & DEBUG_SYS_F)
|
||||
# define DEBUG_MEM_TRACE() (M.x86.debug & DEBUG_MEM_TRACE_F)
|
||||
# define DEBUG_IO_TRACE() (M.x86.debug & DEBUG_IO_TRACE_F)
|
||||
# define DEBUG_DECODE_NOPRINT() (M.x86.debug & DEBUG_DECODE_NOPRINT_F)
|
||||
#else
|
||||
# define DEBUG_INSTRUMENT() 0
|
||||
# define DEBUG_DECODE() 0
|
||||
# define DEBUG_TRACE() 0
|
||||
# define DEBUG_STEP() 0
|
||||
# define DEBUG_DISASSEMBLE() 0
|
||||
# define DEBUG_BREAK() 0
|
||||
# define DEBUG_SVC() 0
|
||||
# define DEBUG_SAVE_IP_CS() 0
|
||||
# define DEBUG_FS() 0
|
||||
# define DEBUG_PROC() 0
|
||||
# define DEBUG_SYSINT() 0
|
||||
# define DEBUG_TRACECALL() 0
|
||||
# define DEBUG_TRACECALLREGS() 0
|
||||
# define DEBUG_SYS() 0
|
||||
# define DEBUG_MEM_TRACE() 0
|
||||
# define DEBUG_IO_TRACE() 0
|
||||
# define DEBUG_DECODE_NOPRINT() 0
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
# define DECODE_PRINTF(x) if (DEBUG_DECODE()) \
|
||||
x86emu_decode_printf(x)
|
||||
# define DECODE_PRINTF2(x,y) if (DEBUG_DECODE()) \
|
||||
x86emu_decode_printf2(x,y)
|
||||
|
||||
/*
|
||||
* The following allow us to look at the bytes of an instruction. The
|
||||
* first INCR_INSTRN_LEN, is called everytime bytes are consumed in
|
||||
* the decoding process. The SAVE_IP_CS is called initially when the
|
||||
* major opcode of the instruction is accessed.
|
||||
*/
|
||||
#define INC_DECODED_INST_LEN(x) \
|
||||
if (DEBUG_DECODE()) \
|
||||
x86emu_inc_decoded_inst_len(x)
|
||||
|
||||
#define SAVE_IP_CS(x,y) \
|
||||
if (DEBUG_DECODE() | DEBUG_TRACECALL() | DEBUG_BREAK() \
|
||||
| DEBUG_IO_TRACE() | DEBUG_SAVE_IP_CS()) { \
|
||||
M.x86.saved_cs = x; \
|
||||
M.x86.saved_ip = y; \
|
||||
}
|
||||
#else
|
||||
# define INC_DECODED_INST_LEN(x)
|
||||
# define DECODE_PRINTF(x)
|
||||
# define DECODE_PRINTF2(x,y)
|
||||
# define SAVE_IP_CS(x,y)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define TRACE_REGS() \
|
||||
if (DEBUG_DISASSEMBLE()) { \
|
||||
x86emu_just_disassemble(); \
|
||||
goto EndOfTheInstructionProcedure; \
|
||||
} \
|
||||
if (DEBUG_TRACE() || DEBUG_DECODE()) X86EMU_trace_regs()
|
||||
#else
|
||||
# define TRACE_REGS()
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# define SINGLE_STEP() if (DEBUG_STEP()) x86emu_single_step()
|
||||
#else
|
||||
# define SINGLE_STEP()
|
||||
#endif
|
||||
|
||||
#define TRACE_AND_STEP() \
|
||||
TRACE_REGS(); \
|
||||
SINGLE_STEP()
|
||||
|
||||
#ifdef DEBUG
|
||||
# define START_OF_INSTR()
|
||||
# define END_OF_INSTR() EndOfTheInstructionProcedure: x86emu_end_instr();
|
||||
# define END_OF_INSTR_NO_TRACE() x86emu_end_instr();
|
||||
#else
|
||||
# define START_OF_INSTR()
|
||||
# define END_OF_INSTR()
|
||||
# define END_OF_INSTR_NO_TRACE()
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# define CALL_TRACE(u,v,w,x,s) \
|
||||
if (DEBUG_TRACECALLREGS()) \
|
||||
x86emu_dump_regs(); \
|
||||
if (DEBUG_TRACECALL()) \
|
||||
printk("%04x:%04x: CALL %s%04x:%04x\n", u , v, s, w, x);
|
||||
# define RETURN_TRACE(n,u,v) \
|
||||
if (DEBUG_TRACECALLREGS()) \
|
||||
x86emu_dump_regs(); \
|
||||
if (DEBUG_TRACECALL()) \
|
||||
printk("%04x:%04x: %s\n",u,v,n);
|
||||
#else
|
||||
# define CALL_TRACE(u,v,w,x,s)
|
||||
# define RETURN_TRACE(n,u,v)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DB(x) x
|
||||
#else
|
||||
#define DB(x)
|
||||
#endif
|
||||
|
||||
/*-------------------------- Function Prototypes --------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
extern void x86emu_inc_decoded_inst_len(int x);
|
||||
extern void x86emu_decode_printf(char *x);
|
||||
extern void x86emu_decode_printf2(char *x, int y);
|
||||
extern void x86emu_just_disassemble(void);
|
||||
extern void x86emu_single_step(void);
|
||||
extern void x86emu_end_instr(void);
|
||||
extern void x86emu_dump_regs(void);
|
||||
extern void x86emu_dump_xregs(void);
|
||||
extern void x86emu_print_int_vect(u16 iv);
|
||||
extern void x86emu_instrument_instruction(void);
|
||||
extern void x86emu_check_ip_access(void);
|
||||
extern void x86emu_check_sp_access(void);
|
||||
extern void x86emu_check_mem_access(u32 p);
|
||||
extern void x86emu_check_data_access(uint s, uint o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __X86EMU_DEBUG_H */
|
88
drivers/bios_emulator/include/x86emu/decode.h
Normal file
88
drivers/bios_emulator/include/x86emu/decode.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1991-2004 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for instruction decoding logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_DECODE_H
|
||||
#define __X86EMU_DECODE_H
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
/* Instruction Decoding Stuff */
|
||||
|
||||
#define FETCH_DECODE_MODRM(mod,rh,rl) fetch_decode_modrm(&mod,&rh,&rl)
|
||||
#define DECODE_RM_BYTE_REGISTER(r) decode_rm_byte_register(r)
|
||||
#define DECODE_RM_WORD_REGISTER(r) decode_rm_word_register(r)
|
||||
#define DECODE_RM_LONG_REGISTER(r) decode_rm_long_register(r)
|
||||
#define DECODE_CLEAR_SEGOVR() M.x86.mode &= ~SYSMODE_CLRMASK
|
||||
|
||||
/*-------------------------- Function Prototypes --------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
void x86emu_intr_raise (u8 type);
|
||||
void fetch_decode_modrm (int *mod,int *regh,int *regl);
|
||||
u8 fetch_byte_imm (void);
|
||||
u16 fetch_word_imm (void);
|
||||
u32 fetch_long_imm (void);
|
||||
u8 fetch_data_byte (uint offset);
|
||||
u8 fetch_data_byte_abs (uint segment, uint offset);
|
||||
u16 fetch_data_word (uint offset);
|
||||
u16 fetch_data_word_abs (uint segment, uint offset);
|
||||
u32 fetch_data_long (uint offset);
|
||||
u32 fetch_data_long_abs (uint segment, uint offset);
|
||||
void store_data_byte (uint offset, u8 val);
|
||||
void store_data_byte_abs (uint segment, uint offset, u8 val);
|
||||
void store_data_word (uint offset, u16 val);
|
||||
void store_data_word_abs (uint segment, uint offset, u16 val);
|
||||
void store_data_long (uint offset, u32 val);
|
||||
void store_data_long_abs (uint segment, uint offset, u32 val);
|
||||
u8* decode_rm_byte_register(int reg);
|
||||
u16* decode_rm_word_register(int reg);
|
||||
u32* decode_rm_long_register(int reg);
|
||||
u16* decode_rm_seg_register(int reg);
|
||||
unsigned decode_rm00_address(int rm);
|
||||
unsigned decode_rm01_address(int rm);
|
||||
unsigned decode_rm10_address(int rm);
|
||||
unsigned decode_rmXX_address(int mod, int rm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
|
||||
#endif /* __X86EMU_DECODE_H */
|
45
drivers/bios_emulator/include/x86emu/ops.h
Normal file
45
drivers/bios_emulator/include/x86emu/ops.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1991-2004 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for operand decoding functions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_OPS_H
|
||||
#define __X86EMU_OPS_H
|
||||
|
||||
extern void (*x86emu_optab[0x100])(u8 op1);
|
||||
extern void (*x86emu_optab2[0x100])(u8 op2);
|
||||
|
||||
#endif /* __X86EMU_OPS_H */
|
970
drivers/bios_emulator/include/x86emu/prim_asm.h
Normal file
970
drivers/bios_emulator/include/x86emu/prim_asm.h
Normal file
|
@ -0,0 +1,970 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1991-2004 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: Watcom C++ 10.6 or later
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Inline assembler versions of the primitive operand
|
||||
* functions for faster performance. At the moment this is
|
||||
* x86 inline assembler, but these functions could be replaced
|
||||
* with native inline assembler for each supported processor
|
||||
* platform.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_PRIM_ASM_H
|
||||
#define __X86EMU_PRIM_ASM_H
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
|
||||
#ifndef VALIDATE
|
||||
#define __HAVE_INLINE_ASSEMBLER__
|
||||
#endif
|
||||
|
||||
u32 get_flags_asm(void);
|
||||
#pragma aux get_flags_asm = \
|
||||
"pushf" \
|
||||
"pop eax" \
|
||||
value [eax] \
|
||||
modify exact [eax];
|
||||
|
||||
u16 aaa_word_asm(u32 * flags, u16 d);
|
||||
#pragma aux aaa_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"aaa" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] \
|
||||
value [ax] \
|
||||
modify exact [ax];
|
||||
|
||||
u16 aas_word_asm(u32 * flags, u16 d);
|
||||
#pragma aux aas_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"aas" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] \
|
||||
value [ax] \
|
||||
modify exact [ax];
|
||||
|
||||
u16 aad_word_asm(u32 * flags, u16 d);
|
||||
#pragma aux aad_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"aad" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] \
|
||||
value [ax] \
|
||||
modify exact [ax];
|
||||
|
||||
u16 aam_word_asm(u32 * flags, u8 d);
|
||||
#pragma aux aam_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"aam" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] \
|
||||
value [ax] \
|
||||
modify exact [ax];
|
||||
|
||||
u8 adc_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux adc_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"adc al,bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [bl] \
|
||||
value [al] \
|
||||
modify exact [al bl];
|
||||
|
||||
u16 adc_word_asm(u32 * flags, u16 d, u16 s);
|
||||
#pragma aux adc_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"adc ax,bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [bx] \
|
||||
value [ax] \
|
||||
modify exact [ax bx];
|
||||
|
||||
u32 adc_long_asm(u32 * flags, u32 d, u32 s);
|
||||
#pragma aux adc_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"adc eax,ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [ebx] \
|
||||
value [eax] \
|
||||
modify exact [eax ebx];
|
||||
|
||||
u8 add_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux add_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"add al,bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [bl] \
|
||||
value [al] \
|
||||
modify exact [al bl];
|
||||
|
||||
u16 add_word_asm(u32 * flags, u16 d, u16 s);
|
||||
#pragma aux add_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"add ax,bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [bx] \
|
||||
value [ax] \
|
||||
modify exact [ax bx];
|
||||
|
||||
u32 add_long_asm(u32 * flags, u32 d, u32 s);
|
||||
#pragma aux add_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"add eax,ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [ebx] \
|
||||
value [eax] \
|
||||
modify exact [eax ebx];
|
||||
|
||||
u8 and_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux and_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"and al,bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [bl] \
|
||||
value [al] \
|
||||
modify exact [al bl];
|
||||
|
||||
u16 and_word_asm(u32 * flags, u16 d, u16 s);
|
||||
#pragma aux and_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"and ax,bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [bx] \
|
||||
value [ax] \
|
||||
modify exact [ax bx];
|
||||
|
||||
u32 and_long_asm(u32 * flags, u32 d, u32 s);
|
||||
#pragma aux and_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"and eax,ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [ebx] \
|
||||
value [eax] \
|
||||
modify exact [eax ebx];
|
||||
|
||||
u8 cmp_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux cmp_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"cmp al,bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [bl] \
|
||||
value [al] \
|
||||
modify exact [al bl];
|
||||
|
||||
u16 cmp_word_asm(u32 * flags, u16 d, u16 s);
|
||||
#pragma aux cmp_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"cmp ax,bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [bx] \
|
||||
value [ax] \
|
||||
modify exact [ax bx];
|
||||
|
||||
u32 cmp_long_asm(u32 * flags, u32 d, u32 s);
|
||||
#pragma aux cmp_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"cmp eax,ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [ebx] \
|
||||
value [eax] \
|
||||
modify exact [eax ebx];
|
||||
|
||||
u8 daa_byte_asm(u32 * flags, u8 d);
|
||||
#pragma aux daa_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"daa" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] \
|
||||
value [al] \
|
||||
modify exact [al];
|
||||
|
||||
u8 das_byte_asm(u32 * flags, u8 d);
|
||||
#pragma aux das_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"das" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] \
|
||||
value [al] \
|
||||
modify exact [al];
|
||||
|
||||
u8 dec_byte_asm(u32 * flags, u8 d);
|
||||
#pragma aux dec_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"dec al" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] \
|
||||
value [al] \
|
||||
modify exact [al];
|
||||
|
||||
u16 dec_word_asm(u32 * flags, u16 d);
|
||||
#pragma aux dec_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"dec ax" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] \
|
||||
value [ax] \
|
||||
modify exact [ax];
|
||||
|
||||
u32 dec_long_asm(u32 * flags, u32 d);
|
||||
#pragma aux dec_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"dec eax" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] \
|
||||
value [eax] \
|
||||
modify exact [eax];
|
||||
|
||||
u8 inc_byte_asm(u32 * flags, u8 d);
|
||||
#pragma aux inc_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"inc al" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] \
|
||||
value [al] \
|
||||
modify exact [al];
|
||||
|
||||
u16 inc_word_asm(u32 * flags, u16 d);
|
||||
#pragma aux inc_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"inc ax" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] \
|
||||
value [ax] \
|
||||
modify exact [ax];
|
||||
|
||||
u32 inc_long_asm(u32 * flags, u32 d);
|
||||
#pragma aux inc_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"inc eax" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] \
|
||||
value [eax] \
|
||||
modify exact [eax];
|
||||
|
||||
u8 or_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux or_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"or al,bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [bl] \
|
||||
value [al] \
|
||||
modify exact [al bl];
|
||||
|
||||
u16 or_word_asm(u32 * flags, u16 d, u16 s);
|
||||
#pragma aux or_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"or ax,bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [bx] \
|
||||
value [ax] \
|
||||
modify exact [ax bx];
|
||||
|
||||
u32 or_long_asm(u32 * flags, u32 d, u32 s);
|
||||
#pragma aux or_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"or eax,ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [ebx] \
|
||||
value [eax] \
|
||||
modify exact [eax ebx];
|
||||
|
||||
u8 neg_byte_asm(u32 * flags, u8 d);
|
||||
#pragma aux neg_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"neg al" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] \
|
||||
value [al] \
|
||||
modify exact [al];
|
||||
|
||||
u16 neg_word_asm(u32 * flags, u16 d);
|
||||
#pragma aux neg_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"neg ax" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] \
|
||||
value [ax] \
|
||||
modify exact [ax];
|
||||
|
||||
u32 neg_long_asm(u32 * flags, u32 d);
|
||||
#pragma aux neg_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"neg eax" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] \
|
||||
value [eax] \
|
||||
modify exact [eax];
|
||||
|
||||
u8 not_byte_asm(u32 * flags, u8 d);
|
||||
#pragma aux not_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"not al" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] \
|
||||
value [al] \
|
||||
modify exact [al];
|
||||
|
||||
u16 not_word_asm(u32 * flags, u16 d);
|
||||
#pragma aux not_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"not ax" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] \
|
||||
value [ax] \
|
||||
modify exact [ax];
|
||||
|
||||
u32 not_long_asm(u32 * flags, u32 d);
|
||||
#pragma aux not_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"not eax" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] \
|
||||
value [eax] \
|
||||
modify exact [eax];
|
||||
|
||||
u8 rcl_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux rcl_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"rcl al,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [cl] \
|
||||
value [al] \
|
||||
modify exact [al cl];
|
||||
|
||||
u16 rcl_word_asm(u32 * flags, u16 d, u8 s);
|
||||
#pragma aux rcl_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"rcl ax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [cl] \
|
||||
value [ax] \
|
||||
modify exact [ax cl];
|
||||
|
||||
u32 rcl_long_asm(u32 * flags, u32 d, u8 s);
|
||||
#pragma aux rcl_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"rcl eax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [cl] \
|
||||
value [eax] \
|
||||
modify exact [eax cl];
|
||||
|
||||
u8 rcr_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux rcr_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"rcr al,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [cl] \
|
||||
value [al] \
|
||||
modify exact [al cl];
|
||||
|
||||
u16 rcr_word_asm(u32 * flags, u16 d, u8 s);
|
||||
#pragma aux rcr_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"rcr ax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [cl] \
|
||||
value [ax] \
|
||||
modify exact [ax cl];
|
||||
|
||||
u32 rcr_long_asm(u32 * flags, u32 d, u8 s);
|
||||
#pragma aux rcr_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"rcr eax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [cl] \
|
||||
value [eax] \
|
||||
modify exact [eax cl];
|
||||
|
||||
u8 rol_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux rol_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"rol al,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [cl] \
|
||||
value [al] \
|
||||
modify exact [al cl];
|
||||
|
||||
u16 rol_word_asm(u32 * flags, u16 d, u8 s);
|
||||
#pragma aux rol_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"rol ax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [cl] \
|
||||
value [ax] \
|
||||
modify exact [ax cl];
|
||||
|
||||
u32 rol_long_asm(u32 * flags, u32 d, u8 s);
|
||||
#pragma aux rol_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"rol eax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [cl] \
|
||||
value [eax] \
|
||||
modify exact [eax cl];
|
||||
|
||||
u8 ror_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux ror_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"ror al,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [cl] \
|
||||
value [al] \
|
||||
modify exact [al cl];
|
||||
|
||||
u16 ror_word_asm(u32 * flags, u16 d, u8 s);
|
||||
#pragma aux ror_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"ror ax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [cl] \
|
||||
value [ax] \
|
||||
modify exact [ax cl];
|
||||
|
||||
u32 ror_long_asm(u32 * flags, u32 d, u8 s);
|
||||
#pragma aux ror_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"ror eax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [cl] \
|
||||
value [eax] \
|
||||
modify exact [eax cl];
|
||||
|
||||
u8 shl_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux shl_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"shl al,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [cl] \
|
||||
value [al] \
|
||||
modify exact [al cl];
|
||||
|
||||
u16 shl_word_asm(u32 * flags, u16 d, u8 s);
|
||||
#pragma aux shl_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"shl ax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [cl] \
|
||||
value [ax] \
|
||||
modify exact [ax cl];
|
||||
|
||||
u32 shl_long_asm(u32 * flags, u32 d, u8 s);
|
||||
#pragma aux shl_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"shl eax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [cl] \
|
||||
value [eax] \
|
||||
modify exact [eax cl];
|
||||
|
||||
u8 shr_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux shr_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"shr al,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [cl] \
|
||||
value [al] \
|
||||
modify exact [al cl];
|
||||
|
||||
u16 shr_word_asm(u32 * flags, u16 d, u8 s);
|
||||
#pragma aux shr_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"shr ax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [cl] \
|
||||
value [ax] \
|
||||
modify exact [ax cl];
|
||||
|
||||
u32 shr_long_asm(u32 * flags, u32 d, u8 s);
|
||||
#pragma aux shr_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"shr eax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [cl] \
|
||||
value [eax] \
|
||||
modify exact [eax cl];
|
||||
|
||||
u8 sar_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux sar_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"sar al,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [cl] \
|
||||
value [al] \
|
||||
modify exact [al cl];
|
||||
|
||||
u16 sar_word_asm(u32 * flags, u16 d, u8 s);
|
||||
#pragma aux sar_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"sar ax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [cl] \
|
||||
value [ax] \
|
||||
modify exact [ax cl];
|
||||
|
||||
u32 sar_long_asm(u32 * flags, u32 d, u8 s);
|
||||
#pragma aux sar_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"sar eax,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [cl] \
|
||||
value [eax] \
|
||||
modify exact [eax cl];
|
||||
|
||||
u16 shld_word_asm(u32 * flags, u16 d, u16 fill, u8 s);
|
||||
#pragma aux shld_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"shld ax,dx,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [dx] [cl] \
|
||||
value [ax] \
|
||||
modify exact [ax dx cl];
|
||||
|
||||
u32 shld_long_asm(u32 * flags, u32 d, u32 fill, u8 s);
|
||||
#pragma aux shld_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"shld eax,edx,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [edx] [cl] \
|
||||
value [eax] \
|
||||
modify exact [eax edx cl];
|
||||
|
||||
u16 shrd_word_asm(u32 * flags, u16 d, u16 fill, u8 s);
|
||||
#pragma aux shrd_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"shrd ax,dx,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [dx] [cl] \
|
||||
value [ax] \
|
||||
modify exact [ax dx cl];
|
||||
|
||||
u32 shrd_long_asm(u32 * flags, u32 d, u32 fill, u8 s);
|
||||
#pragma aux shrd_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"shrd eax,edx,cl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [edx] [cl] \
|
||||
value [eax] \
|
||||
modify exact [eax edx cl];
|
||||
|
||||
u8 sbb_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux sbb_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"sbb al,bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [bl] \
|
||||
value [al] \
|
||||
modify exact [al bl];
|
||||
|
||||
u16 sbb_word_asm(u32 * flags, u16 d, u16 s);
|
||||
#pragma aux sbb_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"sbb ax,bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [bx] \
|
||||
value [ax] \
|
||||
modify exact [ax bx];
|
||||
|
||||
u32 sbb_long_asm(u32 * flags, u32 d, u32 s);
|
||||
#pragma aux sbb_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"sbb eax,ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [ebx] \
|
||||
value [eax] \
|
||||
modify exact [eax ebx];
|
||||
|
||||
u8 sub_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux sub_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"sub al,bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [bl] \
|
||||
value [al] \
|
||||
modify exact [al bl];
|
||||
|
||||
u16 sub_word_asm(u32 * flags, u16 d, u16 s);
|
||||
#pragma aux sub_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"sub ax,bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [bx] \
|
||||
value [ax] \
|
||||
modify exact [ax bx];
|
||||
|
||||
u32 sub_long_asm(u32 * flags, u32 d, u32 s);
|
||||
#pragma aux sub_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"sub eax,ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [ebx] \
|
||||
value [eax] \
|
||||
modify exact [eax ebx];
|
||||
|
||||
void test_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux test_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"test al,bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [bl] \
|
||||
modify exact [al bl];
|
||||
|
||||
void test_word_asm(u32 * flags, u16 d, u16 s);
|
||||
#pragma aux test_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"test ax,bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [bx] \
|
||||
modify exact [ax bx];
|
||||
|
||||
void test_long_asm(u32 * flags, u32 d, u32 s);
|
||||
#pragma aux test_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"test eax,ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [ebx] \
|
||||
modify exact [eax ebx];
|
||||
|
||||
u8 xor_byte_asm(u32 * flags, u8 d, u8 s);
|
||||
#pragma aux xor_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"xor al,bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [al] [bl] \
|
||||
value [al] \
|
||||
modify exact [al bl];
|
||||
|
||||
u16 xor_word_asm(u32 * flags, u16 d, u16 s);
|
||||
#pragma aux xor_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"xor ax,bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [ax] [bx] \
|
||||
value [ax] \
|
||||
modify exact [ax bx];
|
||||
|
||||
u32 xor_long_asm(u32 * flags, u32 d, u32 s);
|
||||
#pragma aux xor_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"xor eax,ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
parm [edi] [eax] [ebx] \
|
||||
value [eax] \
|
||||
modify exact [eax ebx];
|
||||
|
||||
void imul_byte_asm(u32 * flags, u16 * ax, u8 d, u8 s);
|
||||
#pragma aux imul_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"imul bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],ax" \
|
||||
parm [edi] [esi] [al] [bl] \
|
||||
modify exact [esi ax bl];
|
||||
|
||||
void imul_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 d, u16 s);
|
||||
#pragma aux imul_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"imul bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],ax" \
|
||||
"mov [ecx],dx" \
|
||||
parm [edi] [esi] [ecx] [ax] [bx]\
|
||||
modify exact [esi edi ax bx dx];
|
||||
|
||||
void imul_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 d, u32 s);
|
||||
#pragma aux imul_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"imul ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],eax" \
|
||||
"mov [ecx],edx" \
|
||||
parm [edi] [esi] [ecx] [eax] [ebx] \
|
||||
modify exact [esi edi eax ebx edx];
|
||||
|
||||
void mul_byte_asm(u32 * flags, u16 * ax, u8 d, u8 s);
|
||||
#pragma aux mul_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"mul bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],ax" \
|
||||
parm [edi] [esi] [al] [bl] \
|
||||
modify exact [esi ax bl];
|
||||
|
||||
void mul_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 d, u16 s);
|
||||
#pragma aux mul_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"mul bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],ax" \
|
||||
"mov [ecx],dx" \
|
||||
parm [edi] [esi] [ecx] [ax] [bx]\
|
||||
modify exact [esi edi ax bx dx];
|
||||
|
||||
void mul_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 d, u32 s);
|
||||
#pragma aux mul_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"mul ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],eax" \
|
||||
"mov [ecx],edx" \
|
||||
parm [edi] [esi] [ecx] [eax] [ebx] \
|
||||
modify exact [esi edi eax ebx edx];
|
||||
|
||||
void idiv_byte_asm(u32 * flags, u8 * al, u8 * ah, u16 d, u8 s);
|
||||
#pragma aux idiv_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"idiv bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],al" \
|
||||
"mov [ecx],ah" \
|
||||
parm [edi] [esi] [ecx] [ax] [bl]\
|
||||
modify exact [esi edi ax bl];
|
||||
|
||||
void idiv_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 dlo, u16 dhi, u16 s);
|
||||
#pragma aux idiv_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"idiv bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],ax" \
|
||||
"mov [ecx],dx" \
|
||||
parm [edi] [esi] [ecx] [ax] [dx] [bx]\
|
||||
modify exact [esi edi ax dx bx];
|
||||
|
||||
void idiv_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 dlo, u32 dhi, u32 s);
|
||||
#pragma aux idiv_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"idiv ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],eax" \
|
||||
"mov [ecx],edx" \
|
||||
parm [edi] [esi] [ecx] [eax] [edx] [ebx]\
|
||||
modify exact [esi edi eax edx ebx];
|
||||
|
||||
void div_byte_asm(u32 * flags, u8 * al, u8 * ah, u16 d, u8 s);
|
||||
#pragma aux div_byte_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"div bl" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],al" \
|
||||
"mov [ecx],ah" \
|
||||
parm [edi] [esi] [ecx] [ax] [bl]\
|
||||
modify exact [esi edi ax bl];
|
||||
|
||||
void div_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 dlo, u16 dhi, u16 s);
|
||||
#pragma aux div_word_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"div bx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],ax" \
|
||||
"mov [ecx],dx" \
|
||||
parm [edi] [esi] [ecx] [ax] [dx] [bx]\
|
||||
modify exact [esi edi ax dx bx];
|
||||
|
||||
void div_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 dlo, u32 dhi, u32 s);
|
||||
#pragma aux div_long_asm = \
|
||||
"push [edi]" \
|
||||
"popf" \
|
||||
"div ebx" \
|
||||
"pushf" \
|
||||
"pop [edi]" \
|
||||
"mov [esi],eax" \
|
||||
"mov [ecx],edx" \
|
||||
parm [edi] [esi] [ecx] [eax] [edx] [ebx]\
|
||||
modify exact [esi edi eax edx ebx];
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __X86EMU_PRIM_ASM_H */
|
142
drivers/bios_emulator/include/x86emu/prim_ops.h
Normal file
142
drivers/bios_emulator/include/x86emu/prim_ops.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1991-2004 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for primitive operation functions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_PRIM_OPS_H
|
||||
#define __X86EMU_PRIM_OPS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
u16 aaa_word (u16 d);
|
||||
u16 aas_word (u16 d);
|
||||
u16 aad_word (u16 d);
|
||||
u16 aam_word (u8 d);
|
||||
u8 adc_byte (u8 d, u8 s);
|
||||
u16 adc_word (u16 d, u16 s);
|
||||
u32 adc_long (u32 d, u32 s);
|
||||
u8 add_byte (u8 d, u8 s);
|
||||
u16 add_word (u16 d, u16 s);
|
||||
u32 add_long (u32 d, u32 s);
|
||||
u8 and_byte (u8 d, u8 s);
|
||||
u16 and_word (u16 d, u16 s);
|
||||
u32 and_long (u32 d, u32 s);
|
||||
u8 cmp_byte (u8 d, u8 s);
|
||||
u16 cmp_word (u16 d, u16 s);
|
||||
u32 cmp_long (u32 d, u32 s);
|
||||
u8 daa_byte (u8 d);
|
||||
u8 das_byte (u8 d);
|
||||
u8 dec_byte (u8 d);
|
||||
u16 dec_word (u16 d);
|
||||
u32 dec_long (u32 d);
|
||||
u8 inc_byte (u8 d);
|
||||
u16 inc_word (u16 d);
|
||||
u32 inc_long (u32 d);
|
||||
u8 or_byte (u8 d, u8 s);
|
||||
u16 or_word (u16 d, u16 s);
|
||||
u32 or_long (u32 d, u32 s);
|
||||
u8 neg_byte (u8 s);
|
||||
u16 neg_word (u16 s);
|
||||
u32 neg_long (u32 s);
|
||||
u8 not_byte (u8 s);
|
||||
u16 not_word (u16 s);
|
||||
u32 not_long (u32 s);
|
||||
u8 rcl_byte (u8 d, u8 s);
|
||||
u16 rcl_word (u16 d, u8 s);
|
||||
u32 rcl_long (u32 d, u8 s);
|
||||
u8 rcr_byte (u8 d, u8 s);
|
||||
u16 rcr_word (u16 d, u8 s);
|
||||
u32 rcr_long (u32 d, u8 s);
|
||||
u8 rol_byte (u8 d, u8 s);
|
||||
u16 rol_word (u16 d, u8 s);
|
||||
u32 rol_long (u32 d, u8 s);
|
||||
u8 ror_byte (u8 d, u8 s);
|
||||
u16 ror_word (u16 d, u8 s);
|
||||
u32 ror_long (u32 d, u8 s);
|
||||
u8 shl_byte (u8 d, u8 s);
|
||||
u16 shl_word (u16 d, u8 s);
|
||||
u32 shl_long (u32 d, u8 s);
|
||||
u8 shr_byte (u8 d, u8 s);
|
||||
u16 shr_word (u16 d, u8 s);
|
||||
u32 shr_long (u32 d, u8 s);
|
||||
u8 sar_byte (u8 d, u8 s);
|
||||
u16 sar_word (u16 d, u8 s);
|
||||
u32 sar_long (u32 d, u8 s);
|
||||
u16 shld_word (u16 d, u16 fill, u8 s);
|
||||
u32 shld_long (u32 d, u32 fill, u8 s);
|
||||
u16 shrd_word (u16 d, u16 fill, u8 s);
|
||||
u32 shrd_long (u32 d, u32 fill, u8 s);
|
||||
u8 sbb_byte (u8 d, u8 s);
|
||||
u16 sbb_word (u16 d, u16 s);
|
||||
u32 sbb_long (u32 d, u32 s);
|
||||
u8 sub_byte (u8 d, u8 s);
|
||||
u16 sub_word (u16 d, u16 s);
|
||||
u32 sub_long (u32 d, u32 s);
|
||||
void test_byte (u8 d, u8 s);
|
||||
void test_word (u16 d, u16 s);
|
||||
void test_long (u32 d, u32 s);
|
||||
u8 xor_byte (u8 d, u8 s);
|
||||
u16 xor_word (u16 d, u16 s);
|
||||
u32 xor_long (u32 d, u32 s);
|
||||
void imul_byte (u8 s);
|
||||
void imul_word (u16 s);
|
||||
void imul_long (u32 s);
|
||||
void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s);
|
||||
void mul_byte (u8 s);
|
||||
void mul_word (u16 s);
|
||||
void mul_long (u32 s);
|
||||
void idiv_byte (u8 s);
|
||||
void idiv_word (u16 s);
|
||||
void idiv_long (u32 s);
|
||||
void div_byte (u8 s);
|
||||
void div_word (u16 s);
|
||||
void div_long (u32 s);
|
||||
void ins (int size);
|
||||
void outs (int size);
|
||||
u16 mem_access_word (int addr);
|
||||
void push_word (u16 w);
|
||||
void push_long (u32 w);
|
||||
u16 pop_word (void);
|
||||
u32 pop_long (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
|
||||
#endif /* __X86EMU_PRIM_OPS_H */
|
||||
|
340
drivers/bios_emulator/include/x86emu/regs.h
Normal file
340
drivers/bios_emulator/include/x86emu/regs.h
Normal file
|
@ -0,0 +1,340 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1991-2004 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for x86 register definitions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_REGS_H
|
||||
#define __X86EMU_REGS_H
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/*
|
||||
* General EAX, EBX, ECX, EDX type registers. Note that for
|
||||
* portability, and speed, the issue of byte swapping is not addressed
|
||||
* in the registers. All registers are stored in the default format
|
||||
* available on the host machine. The only critical issue is that the
|
||||
* registers should line up EXACTLY in the same manner as they do in
|
||||
* the 386. That is:
|
||||
*
|
||||
* EAX & 0xff === AL
|
||||
* EAX & 0xffff == AX
|
||||
*
|
||||
* etc. The result is that alot of the calculations can then be
|
||||
* done using the native instruction set fully.
|
||||
*/
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
|
||||
typedef struct {
|
||||
u32 e_reg;
|
||||
} I32_reg_t;
|
||||
|
||||
typedef struct {
|
||||
u16 filler0, x_reg;
|
||||
} I16_reg_t;
|
||||
|
||||
typedef struct {
|
||||
u8 filler0, filler1, h_reg, l_reg;
|
||||
} I8_reg_t;
|
||||
|
||||
#else /* !__BIG_ENDIAN__ */
|
||||
|
||||
typedef struct {
|
||||
u32 e_reg;
|
||||
} I32_reg_t;
|
||||
|
||||
typedef struct {
|
||||
u16 x_reg;
|
||||
} I16_reg_t;
|
||||
|
||||
typedef struct {
|
||||
u8 l_reg, h_reg;
|
||||
} I8_reg_t;
|
||||
|
||||
#endif /* BIG_ENDIAN */
|
||||
|
||||
typedef union {
|
||||
I32_reg_t I32_reg;
|
||||
I16_reg_t I16_reg;
|
||||
I8_reg_t I8_reg;
|
||||
} i386_general_register;
|
||||
|
||||
struct i386_general_regs {
|
||||
i386_general_register A, B, C, D;
|
||||
};
|
||||
|
||||
typedef struct i386_general_regs Gen_reg_t;
|
||||
|
||||
struct i386_special_regs {
|
||||
i386_general_register SP, BP, SI, DI, IP;
|
||||
u32 FLAGS;
|
||||
};
|
||||
|
||||
/*
|
||||
* Segment registers here represent the 16 bit quantities
|
||||
* CS, DS, ES, SS.
|
||||
*/
|
||||
|
||||
#undef CS
|
||||
#undef DS
|
||||
#undef SS
|
||||
#undef ES
|
||||
#undef FS
|
||||
#undef GS
|
||||
|
||||
struct i386_segment_regs {
|
||||
u16 CS, DS, SS, ES, FS, GS;
|
||||
};
|
||||
|
||||
/* 8 bit registers */
|
||||
#define R_AH gen.A.I8_reg.h_reg
|
||||
#define R_AL gen.A.I8_reg.l_reg
|
||||
#define R_BH gen.B.I8_reg.h_reg
|
||||
#define R_BL gen.B.I8_reg.l_reg
|
||||
#define R_CH gen.C.I8_reg.h_reg
|
||||
#define R_CL gen.C.I8_reg.l_reg
|
||||
#define R_DH gen.D.I8_reg.h_reg
|
||||
#define R_DL gen.D.I8_reg.l_reg
|
||||
|
||||
/* 16 bit registers */
|
||||
#define R_AX gen.A.I16_reg.x_reg
|
||||
#define R_BX gen.B.I16_reg.x_reg
|
||||
#define R_CX gen.C.I16_reg.x_reg
|
||||
#define R_DX gen.D.I16_reg.x_reg
|
||||
|
||||
/* 32 bit extended registers */
|
||||
#define R_EAX gen.A.I32_reg.e_reg
|
||||
#define R_EBX gen.B.I32_reg.e_reg
|
||||
#define R_ECX gen.C.I32_reg.e_reg
|
||||
#define R_EDX gen.D.I32_reg.e_reg
|
||||
|
||||
/* special registers */
|
||||
#define R_SP spc.SP.I16_reg.x_reg
|
||||
#define R_BP spc.BP.I16_reg.x_reg
|
||||
#define R_SI spc.SI.I16_reg.x_reg
|
||||
#define R_DI spc.DI.I16_reg.x_reg
|
||||
#define R_IP spc.IP.I16_reg.x_reg
|
||||
#define R_FLG spc.FLAGS
|
||||
|
||||
/* special registers */
|
||||
#define R_SP spc.SP.I16_reg.x_reg
|
||||
#define R_BP spc.BP.I16_reg.x_reg
|
||||
#define R_SI spc.SI.I16_reg.x_reg
|
||||
#define R_DI spc.DI.I16_reg.x_reg
|
||||
#define R_IP spc.IP.I16_reg.x_reg
|
||||
#define R_FLG spc.FLAGS
|
||||
|
||||
/* special registers */
|
||||
#define R_ESP spc.SP.I32_reg.e_reg
|
||||
#define R_EBP spc.BP.I32_reg.e_reg
|
||||
#define R_ESI spc.SI.I32_reg.e_reg
|
||||
#define R_EDI spc.DI.I32_reg.e_reg
|
||||
#define R_EIP spc.IP.I32_reg.e_reg
|
||||
#define R_EFLG spc.FLAGS
|
||||
|
||||
/* segment registers */
|
||||
#define R_CS seg.CS
|
||||
#define R_DS seg.DS
|
||||
#define R_SS seg.SS
|
||||
#define R_ES seg.ES
|
||||
#define R_FS seg.FS
|
||||
#define R_GS seg.GS
|
||||
|
||||
/* flag conditions */
|
||||
#define FB_CF 0x0001 /* CARRY flag */
|
||||
#define FB_PF 0x0004 /* PARITY flag */
|
||||
#define FB_AF 0x0010 /* AUX flag */
|
||||
#define FB_ZF 0x0040 /* ZERO flag */
|
||||
#define FB_SF 0x0080 /* SIGN flag */
|
||||
#define FB_TF 0x0100 /* TRAP flag */
|
||||
#define FB_IF 0x0200 /* INTERRUPT ENABLE flag */
|
||||
#define FB_DF 0x0400 /* DIR flag */
|
||||
#define FB_OF 0x0800 /* OVERFLOW flag */
|
||||
|
||||
/* 80286 and above always have bit#1 set */
|
||||
#define F_ALWAYS_ON (0x0002) /* flag bits always on */
|
||||
|
||||
/*
|
||||
* Define a mask for only those flag bits we will ever pass back
|
||||
* (via PUSHF)
|
||||
*/
|
||||
#define F_MSK (FB_CF|FB_PF|FB_AF|FB_ZF|FB_SF|FB_TF|FB_IF|FB_DF|FB_OF)
|
||||
|
||||
/* following bits masked in to a 16bit quantity */
|
||||
|
||||
#define F_CF 0x0001 /* CARRY flag */
|
||||
#define F_PF 0x0004 /* PARITY flag */
|
||||
#define F_AF 0x0010 /* AUX flag */
|
||||
#define F_ZF 0x0040 /* ZERO flag */
|
||||
#define F_SF 0x0080 /* SIGN flag */
|
||||
#define F_TF 0x0100 /* TRAP flag */
|
||||
#define F_IF 0x0200 /* INTERRUPT ENABLE flag */
|
||||
#define F_DF 0x0400 /* DIR flag */
|
||||
#define F_OF 0x0800 /* OVERFLOW flag */
|
||||
|
||||
#define TOGGLE_FLAG(flag) (M.x86.R_FLG ^= (flag))
|
||||
#define SET_FLAG(flag) (M.x86.R_FLG |= (flag))
|
||||
#define CLEAR_FLAG(flag) (M.x86.R_FLG &= ~(flag))
|
||||
#define ACCESS_FLAG(flag) (M.x86.R_FLG & (flag))
|
||||
#define CLEARALL_FLAG(m) (M.x86.R_FLG = 0)
|
||||
|
||||
#define CONDITIONAL_SET_FLAG(COND,FLAG) \
|
||||
if (COND) SET_FLAG(FLAG); else CLEAR_FLAG(FLAG)
|
||||
|
||||
#define F_PF_CALC 0x010000 /* PARITY flag has been calced */
|
||||
#define F_ZF_CALC 0x020000 /* ZERO flag has been calced */
|
||||
#define F_SF_CALC 0x040000 /* SIGN flag has been calced */
|
||||
|
||||
#define F_ALL_CALC 0xff0000 /* All have been calced */
|
||||
|
||||
/*
|
||||
* Emulator machine state.
|
||||
* Segment usage control.
|
||||
*/
|
||||
#define SYSMODE_SEG_DS_SS 0x00000001
|
||||
#define SYSMODE_SEGOVR_CS 0x00000002
|
||||
#define SYSMODE_SEGOVR_DS 0x00000004
|
||||
#define SYSMODE_SEGOVR_ES 0x00000008
|
||||
#define SYSMODE_SEGOVR_FS 0x00000010
|
||||
#define SYSMODE_SEGOVR_GS 0x00000020
|
||||
#define SYSMODE_SEGOVR_SS 0x00000040
|
||||
#define SYSMODE_PREFIX_REPE 0x00000080
|
||||
#define SYSMODE_PREFIX_REPNE 0x00000100
|
||||
#define SYSMODE_PREFIX_DATA 0x00000200
|
||||
#define SYSMODE_PREFIX_ADDR 0x00000400
|
||||
#define SYSMODE_INTR_PENDING 0x10000000
|
||||
#define SYSMODE_EXTRN_INTR 0x20000000
|
||||
#define SYSMODE_HALTED 0x40000000
|
||||
|
||||
#define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS | \
|
||||
SYSMODE_SEGOVR_CS | \
|
||||
SYSMODE_SEGOVR_DS | \
|
||||
SYSMODE_SEGOVR_ES | \
|
||||
SYSMODE_SEGOVR_FS | \
|
||||
SYSMODE_SEGOVR_GS | \
|
||||
SYSMODE_SEGOVR_SS)
|
||||
#define SYSMODE_CLRMASK (SYSMODE_SEG_DS_SS | \
|
||||
SYSMODE_SEGOVR_CS | \
|
||||
SYSMODE_SEGOVR_DS | \
|
||||
SYSMODE_SEGOVR_ES | \
|
||||
SYSMODE_SEGOVR_FS | \
|
||||
SYSMODE_SEGOVR_GS | \
|
||||
SYSMODE_SEGOVR_SS | \
|
||||
SYSMODE_PREFIX_DATA | \
|
||||
SYSMODE_PREFIX_ADDR)
|
||||
|
||||
#define INTR_SYNCH 0x1
|
||||
#define INTR_ASYNCH 0x2
|
||||
#define INTR_HALTED 0x4
|
||||
|
||||
typedef struct {
|
||||
struct i386_general_regs gen;
|
||||
struct i386_special_regs spc;
|
||||
struct i386_segment_regs seg;
|
||||
/*
|
||||
* MODE contains information on:
|
||||
* REPE prefix 2 bits repe,repne
|
||||
* SEGMENT overrides 5 bits normal,DS,SS,CS,ES
|
||||
* Delayed flag set 3 bits (zero, signed, parity)
|
||||
* reserved 6 bits
|
||||
* interrupt # 8 bits instruction raised interrupt
|
||||
* BIOS video segregs 4 bits
|
||||
* Interrupt Pending 1 bits
|
||||
* Extern interrupt 1 bits
|
||||
* Halted 1 bits
|
||||
*/
|
||||
long mode;
|
||||
u8 intno;
|
||||
volatile int intr; /* mask of pending interrupts */
|
||||
int debug;
|
||||
#ifdef DEBUG
|
||||
int check;
|
||||
u16 saved_ip;
|
||||
u16 saved_cs;
|
||||
int enc_pos;
|
||||
int enc_str_pos;
|
||||
char decode_buf[32]; /* encoded byte stream */
|
||||
char decoded_buf[256]; /* disassembled strings */
|
||||
#endif
|
||||
} X86EMU_regs;
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Structure maintaining the emulator machine state.
|
||||
|
||||
MEMBERS:
|
||||
x86 - X86 registers
|
||||
mem_base - Base real mode memory for the emulator
|
||||
mem_size - Size of the real mode memory block for the emulator
|
||||
****************************************************************************/
|
||||
#undef x86
|
||||
typedef struct {
|
||||
X86EMU_regs x86;
|
||||
u8 *mem_base;
|
||||
u32 mem_size;
|
||||
void *private;
|
||||
} X86EMU_sysEnv;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/*----------------------------- Global Variables --------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
/* Global emulator machine state.
|
||||
*
|
||||
* We keep it global to avoid pointer dereferences in the code for speed.
|
||||
*/
|
||||
|
||||
extern X86EMU_sysEnv _X86EMU_env;
|
||||
#define M _X86EMU_env
|
||||
|
||||
/*-------------------------- Function Prototypes --------------------------*/
|
||||
|
||||
/* Function to log information at runtime */
|
||||
|
||||
#ifndef __KERNEL__
|
||||
void printk(const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __X86EMU_REGS_H */
|
101
drivers/bios_emulator/include/x86emu/x86emui.h
Normal file
101
drivers/bios_emulator/include/x86emu/x86emui.h
Normal file
|
@ -0,0 +1,101 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1991-2004 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: Header file for system specific functions. These functions
|
||||
* are always compiled and linked in the OS depedent libraries,
|
||||
* and never in a binary portable driver.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __X86EMU_X86EMUI_H
|
||||
#define __X86EMU_X86EMUI_H
|
||||
|
||||
/* If we are compiling in C++ mode, we can compile some functions as
|
||||
* inline to increase performance (however the code size increases quite
|
||||
* dramatically in this case).
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus) && !defined(_NO_INLINE)
|
||||
#define _INLINE inline
|
||||
#else
|
||||
#define _INLINE static
|
||||
#endif
|
||||
|
||||
/* Get rid of unused parameters in C++ compilation mode */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define X86EMU_UNUSED(v)
|
||||
#else
|
||||
#define X86EMU_UNUSED(v) v
|
||||
#endif
|
||||
|
||||
#include "x86emu.h"
|
||||
#include "x86emu/regs.h"
|
||||
#include "x86emu/debug.h"
|
||||
#include "x86emu/decode.h"
|
||||
#include "x86emu/ops.h"
|
||||
#include "x86emu/prim_ops.h"
|
||||
#ifndef __KERNEL__
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#define printk printf
|
||||
|
||||
|
||||
/*--------------------------- Inline Functions ----------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||
#endif
|
||||
|
||||
extern u8(X86APIP sys_rdb) (u32 addr);
|
||||
extern u16(X86APIP sys_rdw) (u32 addr);
|
||||
extern u32(X86APIP sys_rdl) (u32 addr);
|
||||
extern void (X86APIP sys_wrb) (u32 addr, u8 val);
|
||||
extern void (X86APIP sys_wrw) (u32 addr, u16 val);
|
||||
extern void (X86APIP sys_wrl) (u32 addr, u32 val);
|
||||
|
||||
extern u8(X86APIP sys_inb) (X86EMU_pioAddr addr);
|
||||
extern u16(X86APIP sys_inw) (X86EMU_pioAddr addr);
|
||||
extern u32(X86APIP sys_inl) (X86EMU_pioAddr addr);
|
||||
extern void (X86APIP sys_outb) (X86EMU_pioAddr addr, u8 val);
|
||||
extern void (X86APIP sys_outw) (X86EMU_pioAddr addr, u16 val);
|
||||
extern void (X86APIP sys_outl) (X86EMU_pioAddr addr, u32 val);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of "C" linkage for C++ */
|
||||
#endif
|
||||
#endif /* __X86EMU_X86EMUI_H */
|
461
drivers/bios_emulator/x86emu/debug.c
Normal file
461
drivers/bios_emulator/x86emu/debug.c
Normal file
|
@ -0,0 +1,461 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1991-2004 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: This file contains the code to handle debugging of the
|
||||
* emulator.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "x86emu/x86emui.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/*----------------------------- Implementation ----------------------------*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static void print_encoded_bytes(u16 s, u16 o);
|
||||
static void print_decoded_instruction(void);
|
||||
static int parse_line(char *s, int *ps, int *n);
|
||||
|
||||
/* should look something like debug's output. */
|
||||
void X86EMU_trace_regs(void)
|
||||
{
|
||||
if (DEBUG_TRACE()) {
|
||||
x86emu_dump_regs();
|
||||
}
|
||||
if (DEBUG_DECODE() && !DEBUG_DECODE_NOPRINT()) {
|
||||
printk("%04x:%04x ", M.x86.saved_cs, M.x86.saved_ip);
|
||||
print_encoded_bytes(M.x86.saved_cs, M.x86.saved_ip);
|
||||
print_decoded_instruction();
|
||||
}
|
||||
}
|
||||
|
||||
void X86EMU_trace_xregs(void)
|
||||
{
|
||||
if (DEBUG_TRACE()) {
|
||||
x86emu_dump_xregs();
|
||||
}
|
||||
}
|
||||
|
||||
void x86emu_just_disassemble(void)
|
||||
{
|
||||
/*
|
||||
* This routine called if the flag DEBUG_DISASSEMBLE is set kind
|
||||
* of a hack!
|
||||
*/
|
||||
printk("%04x:%04x ", M.x86.saved_cs, M.x86.saved_ip);
|
||||
print_encoded_bytes(M.x86.saved_cs, M.x86.saved_ip);
|
||||
print_decoded_instruction();
|
||||
}
|
||||
|
||||
static void disassemble_forward(u16 seg, u16 off, int n)
|
||||
{
|
||||
X86EMU_sysEnv tregs;
|
||||
int i;
|
||||
u8 op1;
|
||||
/*
|
||||
* hack, hack, hack. What we do is use the exact machinery set up
|
||||
* for execution, except that now there is an additional state
|
||||
* flag associated with the "execution", and we are using a copy
|
||||
* of the register struct. All the major opcodes, once fully
|
||||
* decoded, have the following two steps: TRACE_REGS(r,m);
|
||||
* SINGLE_STEP(r,m); which disappear if DEBUG is not defined to
|
||||
* the preprocessor. The TRACE_REGS macro expands to:
|
||||
*
|
||||
* if (debug&DEBUG_DISASSEMBLE)
|
||||
* {just_disassemble(); goto EndOfInstruction;}
|
||||
* if (debug&DEBUG_TRACE) trace_regs(r,m);
|
||||
*
|
||||
* ...... and at the last line of the routine.
|
||||
*
|
||||
* EndOfInstruction: end_instr();
|
||||
*
|
||||
* Up to the point where TRACE_REG is expanded, NO modifications
|
||||
* are done to any register EXCEPT the IP register, for fetch and
|
||||
* decoding purposes.
|
||||
*
|
||||
* This was done for an entirely different reason, but makes a
|
||||
* nice way to get the system to help debug codes.
|
||||
*/
|
||||
tregs = M;
|
||||
tregs.x86.R_IP = off;
|
||||
tregs.x86.R_CS = seg;
|
||||
|
||||
/* reset the decoding buffers */
|
||||
tregs.x86.enc_str_pos = 0;
|
||||
tregs.x86.enc_pos = 0;
|
||||
|
||||
/* turn on the "disassemble only, no execute" flag */
|
||||
tregs.x86.debug |= DEBUG_DISASSEMBLE_F;
|
||||
|
||||
/* DUMP NEXT n instructions to screen in straight_line fashion */
|
||||
/*
|
||||
* This looks like the regular instruction fetch stream, except
|
||||
* that when this occurs, each fetched opcode, upon seeing the
|
||||
* DEBUG_DISASSEMBLE flag set, exits immediately after decoding
|
||||
* the instruction. XXX --- CHECK THAT MEM IS NOT AFFECTED!!!
|
||||
* Note the use of a copy of the register structure...
|
||||
*/
|
||||
for (i = 0; i < n; i++) {
|
||||
op1 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
|
||||
(x86emu_optab[op1]) (op1);
|
||||
}
|
||||
/* end major hack mode. */
|
||||
}
|
||||
|
||||
void x86emu_check_ip_access(void)
|
||||
{
|
||||
/* NULL as of now */
|
||||
}
|
||||
|
||||
void x86emu_check_sp_access(void)
|
||||
{
|
||||
}
|
||||
|
||||
void x86emu_check_mem_access(u32 dummy)
|
||||
{
|
||||
/* check bounds, etc */
|
||||
}
|
||||
|
||||
void x86emu_check_data_access(uint dummy1, uint dummy2)
|
||||
{
|
||||
/* check bounds, etc */
|
||||
}
|
||||
|
||||
void x86emu_inc_decoded_inst_len(int x)
|
||||
{
|
||||
M.x86.enc_pos += x;
|
||||
}
|
||||
|
||||
void x86emu_decode_printf(char *x)
|
||||
{
|
||||
sprintf(M.x86.decoded_buf + M.x86.enc_str_pos, "%s", x);
|
||||
M.x86.enc_str_pos += strlen(x);
|
||||
}
|
||||
|
||||
void x86emu_decode_printf2(char *x, int y)
|
||||
{
|
||||
char temp[100];
|
||||
sprintf(temp, x, y);
|
||||
sprintf(M.x86.decoded_buf + M.x86.enc_str_pos, "%s", temp);
|
||||
M.x86.enc_str_pos += strlen(temp);
|
||||
}
|
||||
|
||||
void x86emu_end_instr(void)
|
||||
{
|
||||
M.x86.enc_str_pos = 0;
|
||||
M.x86.enc_pos = 0;
|
||||
}
|
||||
|
||||
static void print_encoded_bytes(u16 s, u16 o)
|
||||
{
|
||||
int i;
|
||||
char buf1[64];
|
||||
for (i = 0; i < M.x86.enc_pos; i++) {
|
||||
sprintf(buf1 + 2 * i, "%02x", fetch_data_byte_abs(s, o + i));
|
||||
}
|
||||
printk("%-20s", buf1);
|
||||
}
|
||||
|
||||
static void print_decoded_instruction(void)
|
||||
{
|
||||
printk("%s", M.x86.decoded_buf);
|
||||
}
|
||||
|
||||
void x86emu_print_int_vect(u16 iv)
|
||||
{
|
||||
u16 seg, off;
|
||||
|
||||
if (iv > 256)
|
||||
return;
|
||||
seg = fetch_data_word_abs(0, iv * 4);
|
||||
off = fetch_data_word_abs(0, iv * 4 + 2);
|
||||
printk("%04x:%04x ", seg, off);
|
||||
}
|
||||
|
||||
void X86EMU_dump_memory(u16 seg, u16 off, u32 amt)
|
||||
{
|
||||
u32 start = off & 0xfffffff0;
|
||||
u32 end = (off + 16) & 0xfffffff0;
|
||||
u32 i;
|
||||
u32 current;
|
||||
|
||||
current = start;
|
||||
while (end <= off + amt) {
|
||||
printk("%04x:%04x ", seg, start);
|
||||
for (i = start; i < off; i++)
|
||||
printk(" ");
|
||||
for (; i < end; i++)
|
||||
printk("%02x ", fetch_data_byte_abs(seg, i));
|
||||
printk("\n");
|
||||
start = end;
|
||||
end = start + 16;
|
||||
}
|
||||
}
|
||||
|
||||
void x86emu_single_step(void)
|
||||
{
|
||||
char s[1024];
|
||||
int ps[10];
|
||||
int ntok;
|
||||
int cmd;
|
||||
int done;
|
||||
int segment;
|
||||
int offset;
|
||||
static int breakpoint;
|
||||
static int noDecode = 1;
|
||||
|
||||
char *p;
|
||||
|
||||
if (DEBUG_BREAK()) {
|
||||
if (M.x86.saved_ip != breakpoint) {
|
||||
return;
|
||||
} else {
|
||||
M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
|
||||
M.x86.debug |= DEBUG_TRACE_F;
|
||||
M.x86.debug &= ~DEBUG_BREAK_F;
|
||||
print_decoded_instruction();
|
||||
X86EMU_trace_regs();
|
||||
}
|
||||
}
|
||||
done = 0;
|
||||
offset = M.x86.saved_ip;
|
||||
while (!done) {
|
||||
printk("-");
|
||||
cmd = parse_line(s, ps, &ntok);
|
||||
switch (cmd) {
|
||||
case 'u':
|
||||
disassemble_forward(M.x86.saved_cs, (u16) offset, 10);
|
||||
break;
|
||||
case 'd':
|
||||
if (ntok == 2) {
|
||||
segment = M.x86.saved_cs;
|
||||
offset = ps[1];
|
||||
X86EMU_dump_memory(segment, (u16) offset, 16);
|
||||
offset += 16;
|
||||
} else if (ntok == 3) {
|
||||
segment = ps[1];
|
||||
offset = ps[2];
|
||||
X86EMU_dump_memory(segment, (u16) offset, 16);
|
||||
offset += 16;
|
||||
} else {
|
||||
segment = M.x86.saved_cs;
|
||||
X86EMU_dump_memory(segment, (u16) offset, 16);
|
||||
offset += 16;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
M.x86.debug ^= DEBUG_TRACECALL_F;
|
||||
break;
|
||||
case 's':
|
||||
M.x86.debug ^=
|
||||
DEBUG_SVC_F | DEBUG_SYS_F | DEBUG_SYSINT_F;
|
||||
break;
|
||||
case 'r':
|
||||
X86EMU_trace_regs();
|
||||
break;
|
||||
case 'x':
|
||||
X86EMU_trace_xregs();
|
||||
break;
|
||||
case 'g':
|
||||
if (ntok == 2) {
|
||||
breakpoint = ps[1];
|
||||
if (noDecode) {
|
||||
M.x86.debug |= DEBUG_DECODE_NOPRINT_F;
|
||||
} else {
|
||||
M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
|
||||
}
|
||||
M.x86.debug &= ~DEBUG_TRACE_F;
|
||||
M.x86.debug |= DEBUG_BREAK_F;
|
||||
done = 1;
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
M.x86.debug |= DEBUG_EXIT;
|
||||
return;
|
||||
case 'P':
|
||||
noDecode = (noDecode) ? 0 : 1;
|
||||
printk("Toggled decoding to %s\n",
|
||||
(noDecode) ? "FALSE" : "TRUE");
|
||||
break;
|
||||
case 't':
|
||||
case 0:
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int X86EMU_trace_on(void)
|
||||
{
|
||||
return M.x86.debug |= DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F;
|
||||
}
|
||||
|
||||
int X86EMU_trace_off(void)
|
||||
{
|
||||
return M.x86.debug &= ~(DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F);
|
||||
}
|
||||
|
||||
static int parse_line(char *s, int *ps, int *n)
|
||||
{
|
||||
int cmd;
|
||||
|
||||
*n = 0;
|
||||
while (*s == ' ' || *s == '\t')
|
||||
s++;
|
||||
ps[*n] = *s;
|
||||
switch (*s) {
|
||||
case '\n':
|
||||
*n += 1;
|
||||
return 0;
|
||||
default:
|
||||
cmd = *s;
|
||||
*n += 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
while (*s != ' ' && *s != '\t' && *s != '\n')
|
||||
s++;
|
||||
|
||||
if (*s == '\n')
|
||||
return cmd;
|
||||
|
||||
while (*s == ' ' || *s == '\t')
|
||||
s++;
|
||||
|
||||
*n += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
void x86emu_dump_regs(void)
|
||||
{
|
||||
printk("\tAX=%04x ", M.x86.R_AX);
|
||||
printk("BX=%04x ", M.x86.R_BX);
|
||||
printk("CX=%04x ", M.x86.R_CX);
|
||||
printk("DX=%04x ", M.x86.R_DX);
|
||||
printk("SP=%04x ", M.x86.R_SP);
|
||||
printk("BP=%04x ", M.x86.R_BP);
|
||||
printk("SI=%04x ", M.x86.R_SI);
|
||||
printk("DI=%04x\n", M.x86.R_DI);
|
||||
printk("\tDS=%04x ", M.x86.R_DS);
|
||||
printk("ES=%04x ", M.x86.R_ES);
|
||||
printk("SS=%04x ", M.x86.R_SS);
|
||||
printk("CS=%04x ", M.x86.R_CS);
|
||||
printk("IP=%04x ", M.x86.R_IP);
|
||||
if (ACCESS_FLAG(F_OF))
|
||||
printk("OV "); /* CHECKED... */
|
||||
else
|
||||
printk("NV ");
|
||||
if (ACCESS_FLAG(F_DF))
|
||||
printk("DN ");
|
||||
else
|
||||
printk("UP ");
|
||||
if (ACCESS_FLAG(F_IF))
|
||||
printk("EI ");
|
||||
else
|
||||
printk("DI ");
|
||||
if (ACCESS_FLAG(F_SF))
|
||||
printk("NG ");
|
||||
else
|
||||
printk("PL ");
|
||||
if (ACCESS_FLAG(F_ZF))
|
||||
printk("ZR ");
|
||||
else
|
||||
printk("NZ ");
|
||||
if (ACCESS_FLAG(F_AF))
|
||||
printk("AC ");
|
||||
else
|
||||
printk("NA ");
|
||||
if (ACCESS_FLAG(F_PF))
|
||||
printk("PE ");
|
||||
else
|
||||
printk("PO ");
|
||||
if (ACCESS_FLAG(F_CF))
|
||||
printk("CY ");
|
||||
else
|
||||
printk("NC ");
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
void x86emu_dump_xregs(void)
|
||||
{
|
||||
printk("\tEAX=%08x ", M.x86.R_EAX);
|
||||
printk("EBX=%08x ", M.x86.R_EBX);
|
||||
printk("ECX=%08x ", M.x86.R_ECX);
|
||||
printk("EDX=%08x \n", M.x86.R_EDX);
|
||||
printk("\tESP=%08x ", M.x86.R_ESP);
|
||||
printk("EBP=%08x ", M.x86.R_EBP);
|
||||
printk("ESI=%08x ", M.x86.R_ESI);
|
||||
printk("EDI=%08x\n", M.x86.R_EDI);
|
||||
printk("\tDS=%04x ", M.x86.R_DS);
|
||||
printk("ES=%04x ", M.x86.R_ES);
|
||||
printk("SS=%04x ", M.x86.R_SS);
|
||||
printk("CS=%04x ", M.x86.R_CS);
|
||||
printk("EIP=%08x\n\t", M.x86.R_EIP);
|
||||
if (ACCESS_FLAG(F_OF))
|
||||
printk("OV "); /* CHECKED... */
|
||||
else
|
||||
printk("NV ");
|
||||
if (ACCESS_FLAG(F_DF))
|
||||
printk("DN ");
|
||||
else
|
||||
printk("UP ");
|
||||
if (ACCESS_FLAG(F_IF))
|
||||
printk("EI ");
|
||||
else
|
||||
printk("DI ");
|
||||
if (ACCESS_FLAG(F_SF))
|
||||
printk("NG ");
|
||||
else
|
||||
printk("PL ");
|
||||
if (ACCESS_FLAG(F_ZF))
|
||||
printk("ZR ");
|
||||
else
|
||||
printk("NZ ");
|
||||
if (ACCESS_FLAG(F_AF))
|
||||
printk("AC ");
|
||||
else
|
||||
printk("NA ");
|
||||
if (ACCESS_FLAG(F_PF))
|
||||
printk("PE ");
|
||||
else
|
||||
printk("PO ");
|
||||
if (ACCESS_FLAG(F_CF))
|
||||
printk("CY ");
|
||||
else
|
||||
printk("NC ");
|
||||
printk("\n");
|
||||
}
|
1148
drivers/bios_emulator/x86emu/decode.c
Normal file
1148
drivers/bios_emulator/x86emu/decode.c
Normal file
File diff suppressed because it is too large
Load diff
5431
drivers/bios_emulator/x86emu/ops.c
Normal file
5431
drivers/bios_emulator/x86emu/ops.c
Normal file
File diff suppressed because it is too large
Load diff
1770
drivers/bios_emulator/x86emu/ops2.c
Normal file
1770
drivers/bios_emulator/x86emu/ops2.c
Normal file
File diff suppressed because it is too large
Load diff
2446
drivers/bios_emulator/x86emu/prim_ops.c
Normal file
2446
drivers/bios_emulator/x86emu/prim_ops.c
Normal file
File diff suppressed because it is too large
Load diff
322
drivers/bios_emulator/x86emu/sys.c
Normal file
322
drivers/bios_emulator/x86emu/sys.c
Normal file
|
@ -0,0 +1,322 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* Realmode X86 Emulator Library
|
||||
*
|
||||
* Copyright (C) 1991-2004 SciTech Software, Inc.
|
||||
* Copyright (C) David Mosberger-Tang
|
||||
* Copyright (C) 1999 Egbert Eich
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of the authors not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The authors makes no
|
||||
* representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ========================================================================
|
||||
*
|
||||
* Language: ANSI C
|
||||
* Environment: Any
|
||||
* Developer: Kendall Bennett
|
||||
*
|
||||
* Description: This file includes subroutines which are related to
|
||||
* programmed I/O and memory access. Included in this module
|
||||
* are default functions that do nothing. For real uses these
|
||||
* functions will have to be overriden by the user library.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "x86emu/x86emui.h"
|
||||
|
||||
/*------------------------- Global Variables ------------------------------*/
|
||||
|
||||
X86EMU_sysEnv _X86EMU_env; /* Global emulator machine state */
|
||||
X86EMU_intrFuncs _X86EMU_intrTab[256];
|
||||
|
||||
int debug_intr;
|
||||
|
||||
/*----------------------------- Implementation ----------------------------*/
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
|
||||
RETURNS:
|
||||
Byte value read from emulator memory.
|
||||
|
||||
REMARKS:
|
||||
Reads a byte value from the emulator memory.
|
||||
****************************************************************************/
|
||||
u8 X86API rdb(u32 addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
|
||||
RETURNS:
|
||||
Word value read from emulator memory.
|
||||
|
||||
REMARKS:
|
||||
Reads a word value from the emulator memory.
|
||||
****************************************************************************/
|
||||
u16 X86API rdw(u32 addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
|
||||
RETURNS:
|
||||
Long value read from emulator memory.
|
||||
REMARKS:
|
||||
Reads a long value from the emulator memory.
|
||||
****************************************************************************/
|
||||
u32 X86API rdl(u32 addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
val - Value to store
|
||||
|
||||
REMARKS:
|
||||
Writes a byte value to emulator memory.
|
||||
****************************************************************************/
|
||||
void X86API wrb(u32 addr, u8 val)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
val - Value to store
|
||||
|
||||
REMARKS:
|
||||
Writes a word value to emulator memory.
|
||||
****************************************************************************/
|
||||
void X86API wrw(u32 addr, u16 val)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - Emulator memory address to read
|
||||
val - Value to store
|
||||
|
||||
REMARKS:
|
||||
Writes a long value to emulator memory.
|
||||
****************************************************************************/
|
||||
void X86API wrl(u32 addr, u32 val)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to read
|
||||
RETURN:
|
||||
0
|
||||
REMARKS:
|
||||
Default PIO byte read function. Doesn't perform real inb.
|
||||
****************************************************************************/
|
||||
static u8 X86API p_inb(X86EMU_pioAddr addr)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("inb %#04x \n", addr);)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to read
|
||||
RETURN:
|
||||
0
|
||||
REMARKS:
|
||||
Default PIO word read function. Doesn't perform real inw.
|
||||
****************************************************************************/
|
||||
static u16 X86API p_inw(X86EMU_pioAddr addr)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("inw %#04x \n", addr);)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to read
|
||||
RETURN:
|
||||
0
|
||||
REMARKS:
|
||||
Default PIO long read function. Doesn't perform real inl.
|
||||
****************************************************************************/
|
||||
static u32 X86API p_inl(X86EMU_pioAddr addr)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("inl %#04x \n", addr);)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to write
|
||||
val - Value to store
|
||||
REMARKS:
|
||||
Default PIO byte write function. Doesn't perform real outb.
|
||||
****************************************************************************/
|
||||
static void X86API p_outb(X86EMU_pioAddr addr, u8 val)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("outb %#02x -> %#04x \n", val, addr);)
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to write
|
||||
val - Value to store
|
||||
REMARKS:
|
||||
Default PIO word write function. Doesn't perform real outw.
|
||||
****************************************************************************/
|
||||
static void X86API p_outw(X86EMU_pioAddr addr, u16 val)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("outw %#04x -> %#04x \n", val, addr);)
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
addr - PIO address to write
|
||||
val - Value to store
|
||||
REMARKS:
|
||||
Default PIO ;ong write function. Doesn't perform real outl.
|
||||
****************************************************************************/
|
||||
static void X86API p_outl(X86EMU_pioAddr addr, u32 val)
|
||||
{
|
||||
DB(if (DEBUG_IO_TRACE())
|
||||
printk("outl %#08x -> %#04x \n", val, addr);)
|
||||
return;
|
||||
}
|
||||
|
||||
/*------------------------- Global Variables ------------------------------*/
|
||||
|
||||
u8(X86APIP sys_rdb) (u32 addr) = rdb;
|
||||
u16(X86APIP sys_rdw) (u32 addr) = rdw;
|
||||
u32(X86APIP sys_rdl) (u32 addr) = rdl;
|
||||
void (X86APIP sys_wrb) (u32 addr, u8 val) = wrb;
|
||||
void (X86APIP sys_wrw) (u32 addr, u16 val) = wrw;
|
||||
void (X86APIP sys_wrl) (u32 addr, u32 val) = wrl;
|
||||
u8(X86APIP sys_inb) (X86EMU_pioAddr addr) = p_inb;
|
||||
u16(X86APIP sys_inw) (X86EMU_pioAddr addr) = p_inw;
|
||||
u32(X86APIP sys_inl) (X86EMU_pioAddr addr) = p_inl;
|
||||
void (X86APIP sys_outb) (X86EMU_pioAddr addr, u8 val) = p_outb;
|
||||
void (X86APIP sys_outw) (X86EMU_pioAddr addr, u16 val) = p_outw;
|
||||
void (X86APIP sys_outl) (X86EMU_pioAddr addr, u32 val) = p_outl;
|
||||
|
||||
/*----------------------------- Setup -------------------------------------*/
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
funcs - New memory function pointers to make active
|
||||
|
||||
REMARKS:
|
||||
This function is used to set the pointers to functions which access
|
||||
memory space, allowing the user application to override these functions
|
||||
and hook them out as necessary for their application.
|
||||
****************************************************************************/
|
||||
void X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs)
|
||||
{
|
||||
sys_rdb = funcs->rdb;
|
||||
sys_rdw = funcs->rdw;
|
||||
sys_rdl = funcs->rdl;
|
||||
sys_wrb = funcs->wrb;
|
||||
sys_wrw = funcs->wrw;
|
||||
sys_wrl = funcs->wrl;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
funcs - New programmed I/O function pointers to make active
|
||||
|
||||
REMARKS:
|
||||
This function is used to set the pointers to functions which access
|
||||
I/O space, allowing the user application to override these functions
|
||||
and hook them out as necessary for their application.
|
||||
****************************************************************************/
|
||||
void X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs)
|
||||
{
|
||||
sys_inb = funcs->inb;
|
||||
sys_inw = funcs->inw;
|
||||
sys_inl = funcs->inl;
|
||||
sys_outb = funcs->outb;
|
||||
sys_outw = funcs->outw;
|
||||
sys_outl = funcs->outl;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
funcs - New interrupt vector table to make active
|
||||
|
||||
REMARKS:
|
||||
This function is used to set the pointers to functions which handle
|
||||
interrupt processing in the emulator, allowing the user application to
|
||||
hook interrupts as necessary for their application. Any interrupts that
|
||||
are not hooked by the user application, and reflected and handled internally
|
||||
in the emulator via the interrupt vector table. This allows the application
|
||||
to get control when the code being emulated executes specific software
|
||||
interrupts.
|
||||
****************************************************************************/
|
||||
void X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
_X86EMU_intrTab[i] = NULL;
|
||||
if (funcs) {
|
||||
for (i = 0; i < 256; i++)
|
||||
_X86EMU_intrTab[i] = funcs[i];
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
PARAMETERS:
|
||||
int - New software interrupt to prepare for
|
||||
|
||||
REMARKS:
|
||||
This function is used to set up the emulator state to exceute a software
|
||||
interrupt. This can be used by the user application code to allow an
|
||||
interrupt to be hooked, examined and then reflected back to the emulator
|
||||
so that the code in the emulator will continue processing the software
|
||||
interrupt as per normal. This essentially allows system code to actively
|
||||
hook and handle certain software interrupts as necessary.
|
||||
****************************************************************************/
|
||||
void X86EMU_prepareForInt(int num)
|
||||
{
|
||||
push_word((u16) M.x86.R_FLG);
|
||||
CLEAR_FLAG(F_IF);
|
||||
CLEAR_FLAG(F_TF);
|
||||
push_word(M.x86.R_CS);
|
||||
M.x86.R_CS = mem_access_word(num * 4 + 2);
|
||||
push_word(M.x86.R_IP);
|
||||
M.x86.R_IP = mem_access_word(num * 4);
|
||||
M.x86.intr = 0;
|
||||
}
|
Loading…
Reference in a new issue