Stefan's fixes

This commit is contained in:
Ronald G. Minnich 2002-04-23 20:45:28 +00:00
commit 0db5c853be
7 changed files with 413 additions and 216 deletions

View file

@ -1,13 +1,19 @@
CFLAGS = -Ix86emu/include -O2 -g
CC = gcc
CFLAGS = -Wall -Ix86emu/include -O2 -g
INTOBJS = int10.o int15.o int16.o int1a.o inte6.o
OBJECTS = testbios.o helper_exec.o helper_mem.o $(INTOBJS)
OBJECTS = testbios.o helper_exec.o inthandler.o pci-userspace.o
LIBS = x86emu/src/x86emu/libx86emu.a
# user space pci is the only option right now.
OBJECTS += pci-userspace.o
LIBS += /usr/lib/libpci.a
all: testbios
testbios: $(OBJECTS) $(LIBS)
cc -o testbios $(OBJECTS) $(LIBS)
$(CC) -o testbios $(OBJECTS) $(LIBS)
helper_exec.o: helper_exec.c test.h

View file

@ -19,9 +19,7 @@
#include <asm/io.h>
#include <sys/time.h>
int
port_rep_inb(ptr pInt,
u16 port, u32 base, int d_f, u32 count);
int port_rep_inb(u16 port, u32 base, int d_f, u32 count);
u8 x_inb(u16 port);
u16 x_inw(u16 port);
void x_outb(u16 port, u8 val);
@ -30,113 +28,98 @@ u32 x_inl(u16 port);
void x_outl(u16 port, u32 val);
/* general software interrupt handler */
u32
getIntVect(ptr pInt,int num)
u32 getIntVect(int num)
{
return MEM_RW(pInt, num << 2) + (MEM_RW(pInt, (num << 2) + 2) << 4);
return MEM_RW(num << 2) + (MEM_RW((num << 2) + 2) << 4);
}
void
pushw(ptr pInt, u16 val)
pushw(u16 val)
{
X86_ESP -= 2;
MEM_WW(pInt, ((u32) X86_SS << 4) + X86_SP, val);
MEM_WW(((u32) X86_SS << 4) + X86_SP, val);
}
int
run_bios_int(int num, ptr pInt)
int run_bios_int(int num)
{
u32 eflags;
eflags = X86_EFLAGS;
pushw(pInt, eflags);
pushw(pInt, X86_CS);
pushw(pInt, X86_IP);
X86_CS = MEM_RW(pInt, (num << 2) + 2);
X86_IP = MEM_RW(pInt, num << 2);
pushw(eflags);
pushw(X86_CS);
pushw(X86_IP);
X86_CS = MEM_RW( (num << 2) + 2);
X86_IP = MEM_RW( num << 2);
return 1;
}
int
port_rep_inb(ptr pInt,
u16 port, u32 base, int d_f, u32 count)
int port_rep_inb(u16 port, u32 base, int d_f, u32 count)
{
register int inc = d_f ? -1 : 1;
u32 dst = base;
while (count--) {
MEM_WB(pInt, dst, x_inb(port));
MEM_WB(dst, x_inb(port));
dst += inc;
}
return dst - base;
}
int
port_rep_inw(ptr pInt,
u16 port, u32 base, int d_f, u32 count)
int port_rep_inw(u16 port, u32 base, int d_f, u32 count)
{
register int inc = d_f ? -2 : 2;
u32 dst = base;
while (count--) {
MEM_WW(pInt, dst, x_inw(port));
MEM_WW(dst, x_inw(port));
dst += inc;
}
return dst - base;
}
int
port_rep_inl(ptr pInt,
u16 port, u32 base, int d_f, u32 count)
int port_rep_inl(u16 port, u32 base, int d_f, u32 count)
{
register int inc = d_f ? -4 : 4;
u32 dst = base;
while (count--) {
MEM_WL(pInt, dst, x_inl(port));
MEM_WL(dst, x_inl(port));
dst += inc;
}
return dst - base;
}
int
port_rep_outb(ptr pInt,
u16 port, u32 base, int d_f, u32 count)
int port_rep_outb(u16 port, u32 base, int d_f, u32 count)
{
register int inc = d_f ? -1 : 1;
u32 dst = base;
while (count--) {
x_outb(port, MEM_RB(pInt, dst));
x_outb(port, MEM_RB(dst));
dst += inc;
}
return dst - base;
}
int
port_rep_outw(ptr pInt,
u16 port, u32 base, int d_f, u32 count)
int port_rep_outw(u16 port, u32 base, int d_f, u32 count)
{
register int inc = d_f ? -2 : 2;
u32 dst = base;
while (count--) {
x_outw(port, MEM_RW(pInt, dst));
x_outw(port, MEM_RW(dst));
dst += inc;
}
return dst - base;
}
int
port_rep_outl(ptr pInt,
u16 port, u32 base, int d_f, u32 count)
int port_rep_outl(u16 port, u32 base, int d_f, u32 count)
{
register int inc = d_f ? -4 : 4;
u32 dst = base;
while (count--) {
x_outl(port, MEM_RL(pInt, dst));
x_outl(port, MEM_RL(dst));
dst += inc;
}
return dst - base;
}
u8
x_inb(u16 port)
u8 x_inb(u16 port)
{
u8 val;
@ -152,16 +135,15 @@ x_inb(u16 port)
return val;
}
void
getsecs(unsigned long *sec, unsigned long *usec)
void getsecs(unsigned long *sec, unsigned long *usec)
{
struct timeval tv;
gettimeofday(&tv, 0);
*sec = tv.tv_sec;
*usec = tv.tv_usec;
}
u16
x_inw(u16 port)
u16 x_inw(u16 port)
{
u16 val;
@ -175,8 +157,7 @@ x_inw(u16 port)
return val;
}
void
x_outb(u16 port, u8 val)
void x_outb(u16 port, u8 val)
{
if ((port == 0x43) && (val == 0)) {
/*
@ -193,15 +174,13 @@ x_outb(u16 port, u8 val)
}
}
void
x_outw(u16 port, u16 val)
void x_outw(u16 port, u16 val)
{
outw(port, val);
}
u32
x_inl(u16 port)
u32 x_inl(u16 port)
{
u32 val;
@ -210,44 +189,37 @@ x_inl(u16 port)
return val;
}
void
x_outl(u16 port, u32 val)
void x_outl(u16 port, u32 val)
{
outl(port, val);
}
u8
Mem_rb(int addr)
u8 Mem_rb(int addr)
{
return (*current->mem->rb)(current, addr);
}
u16
Mem_rw(int addr)
u16 Mem_rw(int addr)
{
return (*current->mem->rw)(current, addr);
}
u32
Mem_rl(int addr)
u32 Mem_rl(int addr)
{
return (*current->mem->rl)(current, addr);
}
void
Mem_wb(int addr, u8 val)
void Mem_wb(int addr, u8 val)
{
(*current->mem->wb)(current, addr, val);
}
void
Mem_ww(int addr, u16 val)
void Mem_ww(int addr, u16 val)
{
(*current->mem->ww)(current, addr, val);
}
void
Mem_wl(int addr, u32 val)
void Mem_wl(int addr, u32 val)
{
(*current->mem->wl)(current, addr, val);
}
@ -256,8 +228,7 @@ Mem_wl(int addr, u32 val)
#define TAG(Cfg1Addr) (Cfg1Addr & 0xffff00)
#define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff)
u8
bios_checksum(u8 *start, int size)
u8 bios_checksum(u8 *start, int size)
{
u8 sum = 0;

View file

@ -4,11 +4,10 @@
* execute BIOS int 10h calls in x86 real mode environment
* Copyright 1999 Egbert Eich
*/
#if 0
#define _INT10_PRIVATE
#define REG pInt
#if 0
typedef enum {
OPT_NOINT10,
OPT_INIT_PRIMARY,
@ -21,81 +20,79 @@ static const OptionInfoRec INT10Options[] = {
{OPT_BIOS_LOCATION, "BiosLocation", OPTV_STRING, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE },
};
#endif
#ifdef DEBUG
void
dprint(unsigned long start, unsigned long size)
void dprint(unsigned long start, unsigned long size)
{
int i,j;
char *c = (char *)start;
for (j = 0; j < (size >> 4); j++) {
char *d = c;
ErrorF("\n0x%lx: ",(unsigned long)c);
printf("\n0x%lx: ",(unsigned long)c);
for (i = 0; i<16; i++)
ErrorF("%2.2x ",(unsigned char) (*(c++)));
printf("%2.2x ",(unsigned char) (*(c++)));
c = d;
for (i = 0; i<16; i++) {
ErrorF("%c",((((CARD8)(*c)) > 32) && (((CARD8)(*c)) < 128)) ?
printf("%c",((((u8)(*c)) > 32) && (((u8)(*c)) < 128)) ?
(unsigned char) (*(c)): '.');
c++;
}
}
ErrorF("\n");
printf("\n");
}
#endif
#if 0
#ifndef _PC
/*
* here we are really paranoid about faking a "real"
* BIOS. Most of this information was pulled from
* dosemu.
*/
void
setup_int_vect(xf86Int10InfoPtr pInt)
void setup_int_vect(void)
{
int i;
/* let the int vects point to the SYS_BIOS seg */
for (i = 0; i < 0x80; i++) {
MEM_WW(pInt, i << 2, 0);
MEM_WW(pInt, (i << 2) + 2, SYS_BIOS >> 4);
MEM_WW( i << 2, 0);
MEM_WW( (i << 2) + 2, SYS_BIOS >> 4);
}
reset_int_vect(pInt);
reset_int_vect(current);
/* font tables default location (int 1F) */
MEM_WW(pInt,0x1f<<2,0xfa6e);
MEM_WW(0x1f<<2,0xfa6e);
/* int 11 default location (Get Equipment Configuration) */
MEM_WW(pInt, 0x11 << 2, 0xf84d);
MEM_WW( 0x11 << 2, 0xf84d);
/* int 12 default location (Get Conventional Memory Size) */
MEM_WW(pInt, 0x12 << 2, 0xf841);
MEM_WW( 0x12 << 2, 0xf841);
/* int 15 default location (I/O System Extensions) */
MEM_WW(pInt, 0x15 << 2, 0xf859);
MEM_WW( 0x15 << 2, 0xf859);
/* int 1A default location (RTC, PCI and others) */
MEM_WW(pInt, 0x1a << 2, 0xff6e);
MEM_WW( 0x1a << 2, 0xff6e);
/* int 05 default location (Bound Exceeded) */
MEM_WW(pInt, 0x05 << 2, 0xff54);
MEM_WW( 0x05 << 2, 0xff54);
/* int 08 default location (Double Fault) */
MEM_WW(pInt, 0x08 << 2, 0xfea5);
MEM_WW( 0x08 << 2, 0xfea5);
/* int 13 default location (Disk) */
MEM_WW(pInt, 0x13 << 2, 0xec59);
MEM_WW( 0x13 << 2, 0xec59);
/* int 0E default location (Page Fault) */
MEM_WW(pInt, 0x0e << 2, 0xef57);
MEM_WW( 0x0e << 2, 0xef57);
/* int 17 default location (Parallel Port) */
MEM_WW(pInt, 0x17 << 2, 0xefd2);
MEM_WW( 0x17 << 2, 0xefd2);
/* fdd table default location (int 1e) */
MEM_WW(pInt, 0x1e << 2, 0xefc7);
MEM_WW( 0x1e << 2, 0xefc7);
/* Set Equipment flag to VGA */
i = MEM_RB(pInt, 0x0410) & 0xCF;
MEM_WB(pInt, 0x0410, i);
i = MEM_RB( 0x0410) & 0xCF;
MEM_WB( 0x0410, i);
/* XXX Perhaps setup more of the BDA here. See also int42(0x00). */
}
#endif
int
setup_system_bios(void *base_addr)
int setup_system_bios(void *base_addr)
{
char *base = (char *) base_addr;
@ -116,8 +113,7 @@ setup_system_bios(void *base_addr)
return 1;
}
void
reset_int_vect(xf86Int10InfoPtr pInt)
void reset_int_vect(void)
{
/*
* This table is normally located at 0xF000:0xF0A4. However, int 0x42,
@ -125,7 +121,7 @@ reset_int_vect(xf86Int10InfoPtr pInt)
* 64kB. Note that because this data doesn't survive POST, int 0x42 should
* only be used during EGA/VGA BIOS initialisation.
*/
static const CARD8 VideoParms[] = {
static const u8 VideoParms[] = {
/* Timing for modes 0x00 & 0x01 */
0x38, 0x28, 0x2d, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
@ -153,31 +149,30 @@ reset_int_vect(xf86Int10InfoPtr pInt)
int i;
for (i = 0; i < sizeof(VideoParms); i++)
MEM_WB(pInt, i + (0x1000 - sizeof(VideoParms)), VideoParms[i]);
MEM_WW(pInt, 0x1d << 2, 0x1000 - sizeof(VideoParms));
MEM_WW(pInt, (0x1d << 2) + 2, 0);
MEM_WB( i + (0x1000 - sizeof(VideoParms)), VideoParms[i]);
MEM_WW( 0x1d << 2, 0x1000 - sizeof(VideoParms));
MEM_WW( (0x1d << 2) + 2, 0);
MEM_WW(pInt, 0x10 << 2, 0xf065);
MEM_WW(pInt, (0x10 << 2) + 2, SYS_BIOS >> 4);
MEM_WW(pInt, 0x42 << 2, 0xf065);
MEM_WW(pInt, (0x42 << 2) + 2, SYS_BIOS >> 4);
MEM_WW(pInt, 0x6D << 2, 0xf065);
MEM_WW(pInt, (0x6D << 2) + 2, SYS_BIOS >> 4);
MEM_WW( 0x10 << 2, 0xf065);
MEM_WW( (0x10 << 2) + 2, SYS_BIOS >> 4);
MEM_WW( 0x42 << 2, 0xf065);
MEM_WW( (0x42 << 2) + 2, SYS_BIOS >> 4);
MEM_WW( 0x6D << 2, 0xf065);
MEM_WW( (0x6D << 2) + 2, SYS_BIOS >> 4);
}
void
set_return_trap(xf86Int10InfoPtr pInt)
void set_return_trap(void)
{
/*
* Here we set the exit condition: We return when we encounter
* 'hlt' (=0xf4), which we locate at address 0x600 in x86 memory.
*/
MEM_WB(pInt, 0x0600, 0xf4);
MEM_WB( 0x0600, 0xf4);
/*
* Allocate a segment for the stack
*/
xf86Int10AllocPages(pInt, 1, &pInt->stackseg);
xf86Int10AllocPages( 1, current->stackseg);
}
void *
@ -314,5 +309,4 @@ xf86int10ParseBiosLocation(void* options,
}
#endif

View file

@ -1,5 +1,10 @@
#include <stdio.h>
#include "pci-userspace.h"
#include <pci/pci.h>
#include "pci.h"
#define PCITAG struct pci_filter *
#define DEBUG_PCI 1
struct pci_access *pacc;
struct pci_dev *dev;
@ -7,7 +12,7 @@ struct pci_dev *dev;
struct pci_filter ltag;
int pciNumBuses=0;
int pciNumBuses = 0;
int pciInit(void)
{
@ -15,7 +20,9 @@ int pciInit(void)
pci_init(pacc);
pci_scan_bus(pacc);
for (dev = pacc->devices; dev; dev = dev->next) {
pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES);
}
return 0;
}
@ -24,67 +31,103 @@ int pciExit(void)
pci_cleanup(pacc);
return 0;
}
#if 0
pciReadLong()
{
int c;
pci_get_dev(struct pci_access *acc, int bus, int dev, int func);
pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES);
c=pci_read_dword(dev, regnum);
}
#endif
PCITAG findPci(unsigned short bx)
{
PCITAG tag=&ltag;
pciVideoPtr dev;
PCITAG tag = &ltag;
int bus = (bx >> 8) & 0xFF;
int slot = (bx >> 3) & 0x1F;
int func = bx & 0x7;
int bus = (bx >> 8) & 0xFF;
int slot = (bx >> 3) & 0x1F;
int func = bx & 0x7;
tag->bus=bus; tag->slot=slot; tag->func=func;
tag->bus = bus;
tag->slot = slot;
tag->func = func;
if (pci_get_dev(pacc, bus, slot, func))
return tag;
if (pci_get_dev(pacc, bus, slot, func))
return tag;
return NULL;
return NULL;
}
CARD32 pciSlotBX(pciVideoPtr pvp)
u32 pciSlotBX(PCITAG tag)
{
return (pvp->bus << 8) | (pvp->dev << 3) | (pvp->func);
return (tag->bus << 8) | (tag->slot << 3) | (tag->func);
}
CARD8 pciReadByte(PCITAG tag, CARD32 idx)
u8 pciReadByte(PCITAG tag, u32 idx)
{
printf("pciReadByte: idx=%x\n",idx);
struct pci_dev *d;
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
return pci_read_byte(d, idx);
#ifdef DEBUG_PCI
printf("PCI: device not found while read byte (%x:%x.%x)\n",
tag->bus, tag->slot, tag->func);
#endif
return 0;
}
CARD16 pciReadWord(PCITAG tag, CARD32 idx)
u16 pciReadWord(PCITAG tag, u32 idx)
{
printf("pciReadWord: idx=%x\n",idx);
struct pci_dev *d;
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
return pci_read_word(d, idx);
#ifdef DEBUG_PCI
printf("PCI: device not found while read word (%x:%x.%x)\n",
tag->bus, tag->slot, tag->func);
#endif
return 0;
}
CARD32 pciReadLong(PCITAG tag, CARD32 idx)
u32 pciReadLong(PCITAG tag, u32 idx)
{
printf("pciReadWord: idx=%x\n",idx);
struct pci_dev *d;
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
return pci_read_long(d, idx);
#ifdef DEBUG_PCI
printf("PCI: device not found while read long (%x:%x.%x)\n",
tag->bus, tag->slot, tag->func);
#endif
return 0;
}
void pciWriteLong(PCITAG tag, CARD32 idx, CARD32 data)
void pciWriteLong(PCITAG tag, u32 idx, u32 data)
{
printf("pciWriteLong: idx=%x, data=%x\n",idx,data);
struct pci_dev *d;
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
pci_write_long(d, idx, data);
#ifdef DEBUG_PCI
else
printf
("PCI: device not found while write long (%x:%x.%x)\n",
tag->bus, tag->slot, tag->func);
#endif
}
void pciWriteWord(PCITAG tag, CARD32 idx, CARD16 data)
void pciWriteWord(PCITAG tag, u32 idx, u16 data)
{
printf("pciWriteWord: idx=%x, data=%x\n",idx,data);
struct pci_dev *d;
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
pci_write_word(d, idx, data);
#ifdef DEBUG_PCI
else
printf
("PCI: device not found while write word (%x:%x.%x)\n",
tag->bus, tag->slot, tag->func);
#endif
}
void pciWriteByte(PCITAG tag, CARD32 idx, CARD8 data)
void pciWriteByte(PCITAG tag, u32 idx, u8 data)
{
printf("pciWriteByte: idx=%x, data=%x\n",idx,data);
struct pci_dev *d;
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
pci_write_long(d, idx, data);
#ifdef DEBUG_PCI
else
printf
("PCI: device not found while write long (%x:%x.%x)\n",
tag->bus, tag->slot, tag->func);
#endif
}

View file

@ -1,8 +1,38 @@
#include <pci/pci.h>
#include "pci.h"
typedef unsigned long pciaddr_t;
typedef u8 byte;
typedef u16 word;
struct pci_dev {
struct pci_dev *next; /* Next device in the chain */
word bus; /* Higher byte can select host bridges */
byte dev, func; /* Device and function */
/* These fields are set by pci_fill_info() */
int known_fields; /* Set of info fields already known */
word vendor_id, device_id; /* Identity of the device */
int irq; /* IRQ number */
pciaddr_t base_addr[6]; /* Base addresses */
pciaddr_t size[6]; /* Region sizes */
pciaddr_t rom_base_addr; /* Expansion ROM base address */
pciaddr_t rom_size; /* Expansion ROM size */
/* Fields used internally: */
void *access;
void *methods;
byte *cache; /* Cached information */
int cache_len;
int hdrtype; /* Direct methods: header type */
void *aux; /* Auxillary data */
};
struct pci_filter {
int bus, slot, func; /* -1 = ANY */
int vendor, device;
};
#define CARD8 unsigned char
#define CARD16 unsigned short
#define CARD32 unsigned long
#define PCITAG struct pci_filter *
#define pciVideoPtr struct pci_dev *
@ -14,14 +44,12 @@ int pciExit(void);
PCITAG findPci(unsigned short bx);
CARD32 pciSlotBX(pciVideoPtr pvp);
void pciWriteLong(PCITAG tag, CARD32 idx, CARD32 data);
void pciWriteWord(PCITAG tag, CARD32 idx, CARD16 data);
void pciWriteByte(PCITAG tag, CARD32 idx, CARD8 data);
CARD32 pciReadLong(PCITAG tag, CARD32 idx);
CARD16 pciReadWord(PCITAG tag, CARD32 idx);
CARD8 pciReadByte(PCITAG tag, CARD32 idx);
u32 pciSlotBX(pciVideoPtr pvp);
void pciWriteLong(PCITAG tag, u32 idx, u32 data);
void pciWriteWord(PCITAG tag, u32 idx, u16 data);
void pciWriteByte(PCITAG tag, u32 idx, u8 data);
u32 pciReadLong(PCITAG tag, u32 idx);
u16 pciReadWord(PCITAG tag, u32 idx);
u8 pciReadByte(PCITAG tag, u32 idx);

View file

@ -76,25 +76,13 @@ typedef struct _mem {
void(*wl)(ptr, int, u32);
} mem;
// I don't know why they did it this way. So I won't change it for now
// RGM
#if 0
#define MEM_WB(pint, where, what) (pint)->mem->wb(pint, where, what)
#define MEM_WW(pint, where, what) (pint)->mem->ww(pint, where, what)
#define MEM_WL(pint, where, what) (pint)->mem->wl(pint, where, what)
#define MEM_WB(where, what) wrb(where,what)
#define MEM_WW(where, what) wrw(where, what)
#define MEM_WL(where, what) wrl(where, what)
#define MEM_RB(pint, where) (pint)->mem->rb(pint, where)
#define MEM_RW(pint, where) (pint)->mem->rw(pint, where)
#define MEM_RL(pint, where) (pint)->mem->rl(pint, where)
#endif
#define MEM_WB(pint, where, what) wrb(where,what)
#define MEM_WW(pint, where, what) wrw(where, what)
#define MEM_WL(pint, where, what) wrl(where, what)
#define MEM_RB(pint, where) rdb(where)
#define MEM_RW(pint, where) rdw(where)
#define MEM_RL(pint, where) rdl(where)
#define MEM_RB(where) rdb(where)
#define MEM_RW(where) rdw(where)
#define MEM_RL(where) rdl(where)
extern ptr current;

View file

@ -1,30 +1,76 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <getopt.h>
#define die(x) { perror(x); exit(1); }
#include <x86emu.h>
#include "test.h"
#include "pci-userspace.h"
void x86emu_dump_xregs (void);
int int15_handler(void);
int int16_handler(void);
int int1A_handler(void);
#ifndef _PC
int int42_handler(void);
#endif
int intE6_handler(void);
void pushw(u16 val);
extern int teststart, testend;
_ptr p;
ptr current = 0;
extern int teststart, testend;
#if 0
void
test()
{
__asm__ __volatile__(".code16\nteststart:movb $4, %al\n outb %al, $0x80\n.code32\nhlt\ntestend:");
}
#endif
void do_int(int num);
void setup_int(void);
void exit_int(void);
unsigned char biosmem[1024*1024];
int verbose=0;
/* Interrupt multiplexer */
void do_int(int num)
{
int ret = 0;
/* This is a pInt leftover */
current->num=num;
switch (num) {
#ifndef _PC
case 0x10:
case 0x42:
case 0x6D:
ret = int42_handler();
break;
#endif
case 0x15:
ret = int15_handler();
break;
case 0x16:
ret = int16_handler();
break;
case 0x1A:
ret = int1A_handler();
break;
case 0xe6:
ret = intE6_handler();
break;
default:
break;
}
if (!ret) {
printf("\nint%x: not implemented\n",num);
x86emu_dump_xregs();
}
}
unsigned char *mapitin(char *file, size_t size)
{
void * z;
@ -58,27 +104,118 @@ X86EMU_pioFuncs myfuncs = {
};
int
main(int argc, char **argv)
void usage(char *name)
{
int i;
printf("Usage: %s [-c codesegment] [-s size] [-b base] [-i ip] [-t] <filename> ... \n",name);
}
int main(int argc, char **argv)
{
int i,c,trace=0;
unsigned char *cp;
char *filename;
size_t size, howmuch;
int base;
unsigned short initialip, initialcs;
size_t size=0;
int base=0;
int have_size=0, have_base=0, have_ip=0, have_cs=0;
int parse_rom=0;
unsigned short initialip=0, initialcs=0, devfn=0;
X86EMU_intrFuncs intFuncs[256];
void X86EMU_setMemBase(void *base, size_t size);
void x86emu_dump_xregs (void);
if (argc < 4)
die("Usage: testbios <file> <size> <base> <initial IP> <initial CS>");
const char *optstring="vh?b:i:c:s:tpd:";
while (1) {
int option_index = 0;
static struct option long_options[] = {
{ "verbose", 0, 0, 'v' },
{ "help", 0, 0, 'h' },
{ "trace", 0, 0, 't' },
{ "base", 1, 0, 'b' },
{ "instructionpointer", 1, 0, 'i' },
{ "codesegment", 1, 0, 'c' },
{ "size", 1, 0, 's' },
{ "parserom", 0, 0, 'p' },
{ "device", 1, 0, 'd' },
{ 0, 0, 0, 0 }
};
c = getopt_long (argc, argv, optstring,
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'v':
verbose=1;
break;
case 'h':
case '?':
usage(argv[0]);
return 0;
case 't':
trace=1;
break;
case 'b':
base = strtol(optarg, 0, 0);
have_base=1;
break;
case 'i':
initialip=strtol(optarg, 0, 0);
have_ip=1;
break;
case 'c':
initialcs=strtol(optarg, 0, 0);
have_cs=1;
break;
case 's':
size=strtol(optarg, 0, 0);
have_size=1;
break;
case 'p':
printf("Parsing rom images not implemented.\n");
parse_rom=1;
break;
case 'd':
devfn=strtol(optarg, 0, 0);
break;
default:
printf("Unknown option \n");
usage(argv[0]);
return 1;
}
}
filename = argv[1];
size = strtol(argv[2], 0, 0);
base = strtol(argv[3], 0, 0);
initialip = strtol(argv[4], 0, 0);
initialcs = strtol(argv[5], 0, 0);
if (optind >= argc) {
printf("Filename missing.\n");
usage(argv[0]);
return 1;
}
while (optind < argc) {
printf("running file %s\n",argv[optind]);
filename=argv[optind];
optind++;
/* normally we would do continue, but for
* now only one filename is supported.
*/
/* continue; */
break;
}
if (!have_size) {
printf("No size specified. defaulting to 32k\n");
size=32*1024;
}
if (!have_base) {
printf("No base specified. defaulting to 0xc0000\n");
base=0xc0000;
}
if (!have_cs) {
printf("No initial code segment specified. defaulting to 0xc000\n");
initialcs=0xc000;
}
if (!have_ip) {
printf("No initial instruction pointer specified. defaulting to 0x0003\n");
initialip=0x0003;
}
current = &p;
X86EMU_setMemBase(biosmem, sizeof(biosmem));
@ -87,28 +224,58 @@ main(int argc, char **argv)
if (iopl(3) < 0)
die("iopl");
setup_int();
/* Emergency sync ;-) */
sync();
sync();
/* Setting up interrupt environment.
* basically this means initializing PCI and
* intXX handlers.
*/
pciInit();
for (i=0;i<256;i++)
intFuncs[i] = do_int;
X86EMU_setupIntrFuncs(intFuncs);
cp = mapitin(filename, size);
current->ax = 0xff;
current->ax = devfn?devfn:0xff;
current->dx = 0x80;
// current->ip = 0;
for(i = 0; i < size; i++)
wrb(base + i, cp[i]);
/* cpu setup */
X86_AX = devfn?devfn:0xff;
X86_DX = 0x80;
X86_EIP = initialip;
X86_CS = initialcs;
// M.x86.saved_cs = 0;
// M.x86.saved_ip = 0;
// X86EMU_trace_on();
X86_CS = initialcs;
/* Initialize stack and data segment */
X86_SS = 0x0030;
X86_DS = 0x0040;
X86_SP = 0xfffe;
/* We need a sane way to return from bios
* execution. A hlt instruction and a pointer
* to it, both kept on the stack, will do.
*/
pushw(0xf4f4); /* hlt; hlt */
pushw(X86_SS);
pushw(X86_SP+2);
X86_ES = 0x0000;
if (trace) {
printf("Switching to single step mode.\n");
X86EMU_trace_on();
}
X86EMU_exec();
exit_int();
/* Cleaning up */
pciExit();
return 0;
}