Stefan's fixes
This commit is contained in:
parent
a7d074cfb1
commit
0db5c853be
7 changed files with 413 additions and 216 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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=<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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue