mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 14:41:31 +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…
Add table
Reference in a new issue