diff --git a/util/vgabios/Makefile b/util/vgabios/Makefile index 4cebe1d542..1c0f3920fe 100644 --- a/util/vgabios/Makefile +++ b/util/vgabios/Makefile @@ -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 diff --git a/util/vgabios/helper_exec.c b/util/vgabios/helper_exec.c index cb3ede784a..5eb1d4b8f6 100644 --- a/util/vgabios/helper_exec.c +++ b/util/vgabios/helper_exec.c @@ -19,9 +19,7 @@ #include #include -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; diff --git a/util/vgabios/helper_mem.c b/util/vgabios/helper_mem.c index 3d1699596b..7ec147b8ee 100644 --- a/util/vgabios/helper_mem.c +++ b/util/vgabios/helper_mem.c @@ -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 diff --git a/util/vgabios/pci-userspace.c b/util/vgabios/pci-userspace.c index 2d6cbdc27e..b7e3a1eded 100644 --- a/util/vgabios/pci-userspace.c +++ b/util/vgabios/pci-userspace.c @@ -1,5 +1,10 @@ #include -#include "pci-userspace.h" +#include +#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=<ag; - pciVideoPtr dev; + PCITAG tag = <ag; - 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 } - diff --git a/util/vgabios/pci-userspace.h b/util/vgabios/pci-userspace.h index 5f42fe1c7c..094433070f 100644 --- a/util/vgabios/pci-userspace.h +++ b/util/vgabios/pci-userspace.h @@ -1,8 +1,38 @@ -#include +#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); diff --git a/util/vgabios/test.h b/util/vgabios/test.h index 042c0effa1..531bda6101 100644 --- a/util/vgabios/test.h +++ b/util/vgabios/test.h @@ -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; diff --git a/util/vgabios/testbios.c b/util/vgabios/testbios.c index b58947f7ae..e31eb63a01 100644 --- a/util/vgabios/testbios.c +++ b/util/vgabios/testbios.c @@ -1,30 +1,76 @@ #include #include #include +#include #include #include +#include + #define die(x) { perror(x); exit(1); } #include #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] ... \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 "); + 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; }