added setjmp()/longjmp() (used by NetBSD x86 emulator)
modified x86pcibios.c to work with NetBSD x86 emulator
This commit is contained in:
@@ -202,3 +202,7 @@ x86emu/x86biosemu.c
|
|||||||
x86emu/x86emu.c
|
x86emu/x86emu.c
|
||||||
x86emu/x86pcibios.c
|
x86emu/x86pcibios.c
|
||||||
util/libgcc_helper.S
|
util/libgcc_helper.S
|
||||||
|
util/setjmp.c
|
||||||
|
util/setjmp.S
|
||||||
|
include/x86emu_regs.h
|
||||||
|
x86emu/x86emu_util.c
|
||||||
|
|||||||
@@ -138,6 +138,9 @@ CSRCS= \
|
|||||||
fnt_st_8x16.c \
|
fnt_st_8x16.c \
|
||||||
\
|
\
|
||||||
x86emu.c \
|
x86emu.c \
|
||||||
|
x86pcibios.c \
|
||||||
|
x86biosemu.c \
|
||||||
|
x86emu_util.c \
|
||||||
\
|
\
|
||||||
basflash.c \
|
basflash.c \
|
||||||
basflash_start.c
|
basflash_start.c
|
||||||
@@ -147,6 +150,7 @@ ASRCS= \
|
|||||||
startcf.S \
|
startcf.S \
|
||||||
printf_helper.S \
|
printf_helper.S \
|
||||||
exceptions.S \
|
exceptions.S \
|
||||||
|
setjmp.S \
|
||||||
xhdi_vec.S \
|
xhdi_vec.S \
|
||||||
pci_wrappers.S
|
pci_wrappers.S
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ SECTIONS
|
|||||||
#endif /* MACHINE_FIREBEE */
|
#endif /* MACHINE_FIREBEE */
|
||||||
OBJDIR/wait.o(.text)
|
OBJDIR/wait.o(.text)
|
||||||
OBJDIR/exceptions.o(.text)
|
OBJDIR/exceptions.o(.text)
|
||||||
|
OBJDIR/setjmp.o(.text)
|
||||||
OBJDIR/driver_vec.o(.text)
|
OBJDIR/driver_vec.o(.text)
|
||||||
OBJDIR/interrupts.o(.text)
|
OBJDIR/interrupts.o(.text)
|
||||||
OBJDIR/mmu.o(.text)
|
OBJDIR/mmu.o(.text)
|
||||||
@@ -97,6 +98,7 @@ SECTIONS
|
|||||||
OBJDIR/offscreen.o(.text)
|
OBJDIR/offscreen.o(.text)
|
||||||
|
|
||||||
OBJDIR/x86emu.o(.text)
|
OBJDIR/x86emu.o(.text)
|
||||||
|
OBJDIR/x86emu_util.o(.text)
|
||||||
|
|
||||||
OBJDIR/radeon_base.o(.text)
|
OBJDIR/radeon_base.o(.text)
|
||||||
OBJDIR/radeon_accel.o(.text)
|
OBJDIR/radeon_accel.o(.text)
|
||||||
|
|||||||
@@ -106,43 +106,44 @@ struct X86EMU_regs {
|
|||||||
* Halted 1 bits
|
* Halted 1 bits
|
||||||
*/
|
*/
|
||||||
uint32_t mode;
|
uint32_t mode;
|
||||||
volatile int intr; /* mask of pending interrupts */
|
volatile int intr; /* mask of pending interrupts */
|
||||||
uint8_t intno;
|
uint8_t intno;
|
||||||
uint8_t __pad[3];
|
uint8_t __pad[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef uint32_t label_t;
|
typedef uint32_t label_t;
|
||||||
|
|
||||||
struct X86EMU {
|
struct X86EMU
|
||||||
char *mem_base;
|
{
|
||||||
size_t mem_size;
|
char *mem_base;
|
||||||
void *sys_private;
|
size_t mem_size;
|
||||||
struct X86EMU_regs x86;
|
void *sys_private;
|
||||||
|
struct X86EMU_regs x86;
|
||||||
|
|
||||||
label_t exec_state;
|
label_t exec_state;
|
||||||
|
|
||||||
uint64_t cur_cycles;
|
uint64_t cur_cycles;
|
||||||
|
|
||||||
unsigned int cur_mod:2;
|
unsigned int cur_mod:2;
|
||||||
unsigned int cur_rl:3;
|
unsigned int cur_rl:3;
|
||||||
unsigned int cur_rh:3;
|
unsigned int cur_rh:3;
|
||||||
uint32_t cur_offset;
|
uint32_t cur_offset;
|
||||||
|
|
||||||
uint8_t (*emu_rdb)(struct X86EMU *, uint32_t addr);
|
uint8_t (*emu_rdb)(struct X86EMU *, uint32_t addr);
|
||||||
uint16_t (*emu_rdw)(struct X86EMU *, uint32_t addr);
|
uint16_t (*emu_rdw)(struct X86EMU *, uint32_t addr);
|
||||||
uint32_t (*emu_rdl)(struct X86EMU *, uint32_t addr);
|
uint32_t (*emu_rdl)(struct X86EMU *, uint32_t addr);
|
||||||
void (*emu_wrb)(struct X86EMU *, uint32_t addr,uint8_t val);
|
void (*emu_wrb)(struct X86EMU *, uint32_t addr,uint8_t val);
|
||||||
void (*emu_wrw)(struct X86EMU *, uint32_t addr, uint16_t val);
|
void (*emu_wrw)(struct X86EMU *, uint32_t addr, uint16_t val);
|
||||||
void (*emu_wrl)(struct X86EMU *, uint32_t addr, uint32_t val);
|
void (*emu_wrl)(struct X86EMU *, uint32_t addr, uint32_t val);
|
||||||
|
|
||||||
uint8_t (*emu_inb)(struct X86EMU *, uint16_t addr);
|
uint8_t (*emu_inb)(struct X86EMU *, uint16_t addr);
|
||||||
uint16_t (*emu_inw)(struct X86EMU *, uint16_t addr);
|
uint16_t (*emu_inw)(struct X86EMU *, uint16_t addr);
|
||||||
uint32_t (*emu_inl)(struct X86EMU *, uint16_t addr);
|
uint32_t (*emu_inl)(struct X86EMU *, uint16_t addr);
|
||||||
void (*emu_outb)(struct X86EMU *, uint16_t addr, uint8_t val);
|
void (*emu_outb)(struct X86EMU *, uint16_t addr, uint8_t val);
|
||||||
void (*emu_outw)(struct X86EMU *, uint16_t addr, uint16_t val);
|
void (*emu_outw)(struct X86EMU *, uint16_t addr, uint16_t val);
|
||||||
void (*emu_outl)(struct X86EMU *, uint16_t addr, uint32_t val);
|
void (*emu_outl)(struct X86EMU *, uint16_t addr, uint32_t val);
|
||||||
|
|
||||||
void (*_X86EMU_intrTab[256])(struct X86EMU *, int);
|
void (*_X86EMU_intrTab[256])(struct X86EMU *, int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,27 +2,27 @@
|
|||||||
#define PCI_BIOS_H
|
#define PCI_BIOS_H
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PCI_BIOS_PRESENT = 0xB101,
|
PCI_BIOS_PRESENT = 0xB101,
|
||||||
FIND_PCI_DEVICE = 0xB102,
|
FIND_PCI_DEVICE = 0xB102,
|
||||||
FIND_PCI_CLASS_CODE = 0xB103,
|
FIND_PCI_CLASS_CODE = 0xB103,
|
||||||
GENERATE_SPECIAL_CYCLE = 0xB106,
|
GENERATE_SPECIAL_CYCLE = 0xB106,
|
||||||
READ_CONFIG_BYTE = 0xB108,
|
READ_CONFIG_BYTE = 0xB108,
|
||||||
READ_CONFIG_WORD = 0xB109,
|
READ_CONFIG_WORD = 0xB109,
|
||||||
READ_CONFIG_DWORD = 0xB10A,
|
READ_CONFIG_DWORD = 0xB10A,
|
||||||
WRITE_CONFIG_BYTE = 0xB10B,
|
WRITE_CONFIG_BYTE = 0xB10B,
|
||||||
WRITE_CONFIG_WORD = 0xB10C,
|
WRITE_CONFIG_WORD = 0xB10C,
|
||||||
WRITE_CONFIG_DWORD = 0xB10D,
|
WRITE_CONFIG_DWORD = 0xB10D,
|
||||||
GET_IRQ_ROUTING_OPTIONS = 0xB10E,
|
GET_IRQ_ROUTING_OPTIONS = 0xB10E,
|
||||||
SET_PCI_IRQ = 0xB10F
|
SET_PCI_IRQ = 0xB10F
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SUCCESSFUL = 0x00,
|
SUCCESSFUL = 0x00,
|
||||||
FUNC_NOT_SUPPORTED = 0x81,
|
FUNC_NOT_SUPPORTED = 0x81,
|
||||||
BAD_VENDOR_ID = 0x83,
|
BAD_VENDOR_ID = 0x83,
|
||||||
DEVICE_NOT_FOUND = 0x86,
|
DEVICE_NOT_FOUND = 0x86,
|
||||||
BAD_REGISTER_NUMBER = 0x87,
|
BAD_REGISTER_NUMBER = 0x87,
|
||||||
SET_FAILED = 0x88,
|
SET_FAILED = 0x88,
|
||||||
BUFFER_TOO_SMALL = 0x89
|
BUFFER_TOO_SMALL = 0x89
|
||||||
};
|
};
|
||||||
#endif /* PCI_BIOS_H */
|
#endif /* PCI_BIOS_H */
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
#else
|
#else
|
||||||
#define dbg(format, arg...) do {;} while (0)
|
#define dbg(format, arg...) do {;} while (0)
|
||||||
#endif /* DBG_MMU */
|
#endif /* DBG_MMU */
|
||||||
#define err(format, arg...) do { xprintf("ERROR (%s()): " format, __FUNCTION__, ##arg); } while(0);
|
#define err(format, arg...) do { xprintf("ERROR (%s()): " format, __FUNCTION__, ##arg); } while(0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set ASID register
|
* set ASID register
|
||||||
|
|||||||
16
BaS_gcc/util/setjmp.S
Normal file
16
BaS_gcc/util/setjmp.S
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
.globl _setjmp
|
||||||
|
.globl _longjmp
|
||||||
|
|
||||||
|
_setjmp: move.l 4(sp),a0 // address of jmp_buf[]
|
||||||
|
move.l (sp),(a0) // save return address
|
||||||
|
movem.l d2-d7/a2-a7,4(a0) // save registers to jmp_buf
|
||||||
|
clr.l d0
|
||||||
|
rts
|
||||||
|
|
||||||
|
_longjmp: move.l 4(sp),a0 // address of jmp_buf[]
|
||||||
|
move.l 8(sp),d0 // value to return
|
||||||
|
jne not_0 // value may not be 0
|
||||||
|
moveq.l #1,d0
|
||||||
|
not_0: movem.l 4(a0),d2-d7/a2-a7 // restore registers
|
||||||
|
move.l (a0),(sp) // restore saved return address
|
||||||
|
rts
|
||||||
@@ -274,8 +274,7 @@ void run_bios(struct radeonfb_info *rinfo)
|
|||||||
|
|
||||||
if ((rinfo->mmio_base == NULL) || (rinfo->io_base == NULL))
|
if ((rinfo->mmio_base == NULL) || (rinfo->io_base == NULL))
|
||||||
{
|
{
|
||||||
dbg("%s: rinfo->mmio_base = %p, rinfo->io_base = %p\r\n",
|
dbg("rinfo->mmio_base = %p, rinfo->io_base = %p\r\n", rinfo->mmio_base, rinfo->io_base);
|
||||||
__FUNCTION__, rinfo->mmio_base, rinfo->io_base);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
149
BaS_gcc/x86emu/x86emu_util.c
Normal file
149
BaS_gcc/x86emu/x86emu_util.c
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
/* $NetBSD: x86emu_util.c,v 1.1 2007/11/30 20:02:50 joerg Exp $ */
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Realmode X86 Emulator Library
|
||||||
|
*
|
||||||
|
* Copyright (C) 1996-1999 SciTech Software, Inc.
|
||||||
|
* Copyright (C) David Mosberger-Tang
|
||||||
|
* Copyright (C) 1999 Egbert Eich
|
||||||
|
* Copyright (C) 2007 Joerg Sonnenberger
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "x86emu.h"
|
||||||
|
#include "x86emu_regs.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
PARAMETERS:
|
||||||
|
addr - Emulator memory address to read
|
||||||
|
|
||||||
|
RETURNS:
|
||||||
|
Byte value read from emulator memory.
|
||||||
|
|
||||||
|
REMARKS:
|
||||||
|
Reads a byte value from the emulator memory.
|
||||||
|
****************************************************************************/
|
||||||
|
static uint8_t
|
||||||
|
rdb(struct X86EMU *emu, uint32_t addr)
|
||||||
|
{
|
||||||
|
if (addr > emu->mem_size - 1)
|
||||||
|
X86EMU_halt_sys(emu);
|
||||||
|
return emu->mem_base[addr];
|
||||||
|
}
|
||||||
|
/****************************************************************************
|
||||||
|
PARAMETERS:
|
||||||
|
addr - Emulator memory address to read
|
||||||
|
|
||||||
|
RETURNS:
|
||||||
|
Word value read from emulator memory.
|
||||||
|
|
||||||
|
REMARKS:
|
||||||
|
Reads a word value from the emulator memory.
|
||||||
|
****************************************************************************/
|
||||||
|
static uint16_t
|
||||||
|
rdw(struct X86EMU *emu, uint32_t addr)
|
||||||
|
{
|
||||||
|
if (addr > emu->mem_size - 2)
|
||||||
|
X86EMU_halt_sys(emu);
|
||||||
|
return le16dec(emu->mem_base + addr);
|
||||||
|
}
|
||||||
|
/****************************************************************************
|
||||||
|
PARAMETERS:
|
||||||
|
addr - Emulator memory address to read
|
||||||
|
|
||||||
|
RETURNS:
|
||||||
|
Long value read from emulator memory.
|
||||||
|
REMARKS:
|
||||||
|
Reads a long value from the emulator memory.
|
||||||
|
****************************************************************************/
|
||||||
|
static uint32_t
|
||||||
|
rdl(struct X86EMU *emu, uint32_t addr)
|
||||||
|
{
|
||||||
|
if (addr > emu->mem_size - 4)
|
||||||
|
X86EMU_halt_sys(emu);
|
||||||
|
return le32dec(emu->mem_base + addr);
|
||||||
|
}
|
||||||
|
/****************************************************************************
|
||||||
|
PARAMETERS:
|
||||||
|
addr - Emulator memory address to read
|
||||||
|
val - Value to store
|
||||||
|
|
||||||
|
REMARKS:
|
||||||
|
Writes a byte value to emulator memory.
|
||||||
|
****************************************************************************/
|
||||||
|
static void
|
||||||
|
wrb(struct X86EMU *emu, uint32_t addr, uint8_t val)
|
||||||
|
{
|
||||||
|
if (addr > emu->mem_size - 1)
|
||||||
|
X86EMU_halt_sys(emu);
|
||||||
|
emu->mem_base[addr] = val;
|
||||||
|
}
|
||||||
|
/****************************************************************************
|
||||||
|
PARAMETERS:
|
||||||
|
addr - Emulator memory address to read
|
||||||
|
val - Value to store
|
||||||
|
|
||||||
|
REMARKS:
|
||||||
|
Writes a word value to emulator memory.
|
||||||
|
****************************************************************************/
|
||||||
|
static void
|
||||||
|
wrw(struct X86EMU *emu, uint32_t addr, uint16_t val)
|
||||||
|
{
|
||||||
|
if (addr > emu->mem_size - 2)
|
||||||
|
X86EMU_halt_sys(emu);
|
||||||
|
le16enc(emu->mem_base + addr, val);
|
||||||
|
}
|
||||||
|
/****************************************************************************
|
||||||
|
PARAMETERS:
|
||||||
|
addr - Emulator memory address to read
|
||||||
|
val - Value to store
|
||||||
|
|
||||||
|
REMARKS:
|
||||||
|
Writes a long value to emulator memory.
|
||||||
|
****************************************************************************/
|
||||||
|
static void
|
||||||
|
wrl(struct X86EMU *emu, uint32_t addr, uint32_t val)
|
||||||
|
{
|
||||||
|
if (addr > emu->mem_size - 4)
|
||||||
|
X86EMU_halt_sys(emu);
|
||||||
|
le32enc(emu->mem_base + addr, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------- Setup -------------------------------------*/
|
||||||
|
|
||||||
|
void
|
||||||
|
X86EMU_init_default(struct X86EMU *emu)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
emu->emu_rdb = rdb;
|
||||||
|
emu->emu_rdw = rdw;
|
||||||
|
emu->emu_rdl = rdl;
|
||||||
|
emu->emu_wrb = wrb;
|
||||||
|
emu->emu_wrw = wrw;
|
||||||
|
emu->emu_wrl = wrl;
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
emu->_X86EMU_intrTab[i] = NULL;
|
||||||
|
}
|
||||||
@@ -2,161 +2,173 @@
|
|||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
#include "x86emu.h"
|
#include "x86emu.h"
|
||||||
#include "x86pcibios.h"
|
#include "x86pcibios.h"
|
||||||
|
#include "x86emu_regs.h"
|
||||||
|
#include "bas_printf.h"
|
||||||
extern unsigned short offset_port;
|
extern unsigned short offset_port;
|
||||||
|
|
||||||
int x86_pcibios_emulator()
|
#define DBG_PCIBIOS
|
||||||
|
#ifdef DBG_PCIBIOS
|
||||||
|
#define dbg(format, arg...) do { xprintf("DEBUG (%s()): " format, __FUNCTION__, ##arg);} while(0)
|
||||||
|
#else
|
||||||
|
#define dbg(format, arg...) do {;} while (0)
|
||||||
|
#endif /* DBG_PCIBIOS */
|
||||||
|
#define err(format, arg...) do { xprintf("ERROR (%s()): " format, __FUNCTION__, ##arg); } while(0);
|
||||||
|
|
||||||
|
|
||||||
|
int x86_pcibios_handler(struct X86EMU *emu)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned long dev;
|
unsigned long dev;
|
||||||
|
|
||||||
switch (X86_AX)
|
switch (emu->x86.R_AX)
|
||||||
{
|
{
|
||||||
case PCI_BIOS_PRESENT:
|
case PCI_BIOS_PRESENT:
|
||||||
dbg("%s: PCI_BIOS_PRESENT\r\n", __FUNCTION__);
|
dbg("PCI_BIOS_PRESENT\r\n");
|
||||||
X86_AH = 0x00; /* no config space/special cycle support */
|
emu->x86.R_AH = 0x00; /* no config space/special cycle support */
|
||||||
X86_AL = 0x01; /* config mechanism 1 */
|
emu->x86.R_AL = 0x01; /* config mechanism 1 */
|
||||||
X86_EDX = 'P' | 'C' << 8 | 'I' << 16 | ' ' << 24;
|
emu->x86.R_EDX = 'P' | 'C' << 8 | 'I' << 16 | ' ' << 24;
|
||||||
X86_EBX = 0x0210; /* Version 2.10 */
|
emu->x86.R_EBX = 0x0210; /* Version 2.10 */
|
||||||
X86_ECX = 0xFF00; /* FixME: Max bus number */
|
emu->x86.R_ECX = 0xFF00; /* FixME: Max bus number */
|
||||||
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
|
emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FIND_PCI_DEVICE:
|
case FIND_PCI_DEVICE:
|
||||||
dbg("%s: FIND_PCI_DEVICE vendor = %04x, device = %04x\r\n", __FUNCTION__, X86_DX, X86_CX);
|
dbg("FIND_PCI_DEVICE vendor = %04x, device = %04x\r\n", emu->x86.R_DX, emu->x86.R_CX);
|
||||||
dev = pci_find_device((unsigned long) X86_DX, ((unsigned long) X86_CX), 0);
|
dev = pci_find_device((unsigned long) emu->x86.R_DX, ((unsigned long) emu->x86.R_CX), 0);
|
||||||
|
|
||||||
if (dev != 0)
|
if (dev != 0)
|
||||||
{
|
{
|
||||||
dbg("%s: ... OK\r\n", __FUNCTION__);
|
dbg("dev = %d\r\n", dev);
|
||||||
X86_BH = PCI_BUS_FROM_HANDLE(dev);
|
emu->x86.R_BH = PCI_BUS_FROM_HANDLE(dev);
|
||||||
//X86_BH = (char)(dev >> 16) / PCI_MAX_FUNCTION); // dev->bus->secondary;
|
//X86_BH = (char)(dev >> 16) / PCI_MAX_FUNCTION); // dev->bus->secondary;
|
||||||
X86_BL = PCI_DEVICE_FROM_HANDLE(dev) << 3 | PCI_FUNCTION_FROM_HANDLE(dev);
|
emu->x86.R_BL = PCI_DEVICE_FROM_HANDLE(dev) << 3 | PCI_FUNCTION_FROM_HANDLE(dev);
|
||||||
//X86_BL = (char)dev; // dev->path.u.pci.devfn;
|
//X86_BL = (char)dev; // dev->path.u.pci.devfn;
|
||||||
X86_AH = SUCCESSFUL;
|
emu->x86.R_AH = SUCCESSFUL;
|
||||||
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
|
emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
} else {
|
}
|
||||||
dbg("%s: ... error\r\n", __FUNCTION__);
|
else
|
||||||
X86_AH = DEVICE_NOT_FOUND;
|
{
|
||||||
X86_EFLAGS |= FB_CF; /* set carry flag */
|
dbg("device not found\r\n");
|
||||||
|
emu->x86.R_AH = DEVICE_NOT_FOUND;
|
||||||
|
emu->x86.R_EFLG |= FB_CF; /* set carry flag */
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FIND_PCI_CLASS_CODE:
|
case FIND_PCI_CLASS_CODE:
|
||||||
/* FixME: support SI != 0 */
|
/* FixME: support SI != 0 */
|
||||||
dbg("%s: FIND_PCI_CLASS_CODE %x\r\n", __FUNCTION__, X86_ECX);
|
dbg("FIND_PCI_CLASS_CODE %x", emu->x86.R_ECX);
|
||||||
dev = pci_find_classcode(X86_ECX, 0);
|
dev = pci_find_classcode(emu->x86.R_ECX, 0);
|
||||||
if (dev != 0) {
|
if (dev != 0) {
|
||||||
dbg("%s: ... OK\r\n", __FUNCTION__);
|
dbg(" ...OK\r\n");
|
||||||
X86_BH = PCI_BUS_FROM_HANDLE(dev);
|
emu->x86.R_BH = PCI_BUS_FROM_HANDLE(dev);
|
||||||
X86_BL = PCI_DEVICE_FROM_HANDLE(dev) << 3 | PCI_FUNCTION_FROM_HANDLE(dev);
|
emu->x86.R_BL = PCI_DEVICE_FROM_HANDLE(dev) << 3 | PCI_FUNCTION_FROM_HANDLE(dev);
|
||||||
X86_AH = SUCCESSFUL;
|
emu->x86.R_AH = SUCCESSFUL;
|
||||||
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
|
emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dbg("%s: ... error\r\n", __FUNCTION__);
|
dbg(" ... error\r\n");
|
||||||
X86_AH = DEVICE_NOT_FOUND;
|
emu->x86.R_AH = DEVICE_NOT_FOUND;
|
||||||
X86_EFLAGS |= FB_CF; /* set carry flag */
|
emu->x86.R_EFLG |= FB_CF; /* set carry flag */
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case READ_CONFIG_BYTE:
|
case READ_CONFIG_BYTE:
|
||||||
// bus, devfn
|
// bus, devfn
|
||||||
dbg("%s: READ_CONFIG_BYTE bus = %x, devfn = %x, reg = %x\r\n", __FUNCTION__, X86_BH, X86_BL, X86_DI);
|
dbg("READ_CONFIG_BYTE bus = %x, devfn = %x, reg = %x\r\n", emu->x86.R_BH, emu->x86.R_BL, emu->x86.R_DI);
|
||||||
dev = PCI_HANDLE(X86_BH, X86_BL >> 3, X86_BL & 3);
|
dev = PCI_HANDLE(emu->x86.R_BH, emu->x86.R_BL >> 3, emu->x86.R_BL & 3);
|
||||||
X86_CL = pci_read_config_byte(dev, X86_DI);
|
emu->x86.R_CL = pci_read_config_byte(dev, emu->x86.R_DI);
|
||||||
dbg("%s: value = %x\r\n", __FUNCTION__, X86_CL);
|
dbg("value = %x\r\n", emu->x86.R_CL);
|
||||||
X86_AH = SUCCESSFUL;
|
emu->x86.R_AH = SUCCESSFUL;
|
||||||
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
|
emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case READ_CONFIG_WORD:
|
case READ_CONFIG_WORD:
|
||||||
// bus, devfn
|
// bus, devfn
|
||||||
dbg("%s: READ_CONFIG_WORD bus = %x, devfn = %x, reg = %x\r\n", __FUNCTION__, X86_BH, X86_BL, X86_DI);
|
dbg("READ_CONFIG_WORD bus = %x, devfn = %x, reg = %x\r\n", emu->x86.R_BH, emu->x86.R_BL, emu->x86.R_DI);
|
||||||
dev = PCI_HANDLE(X86_BH, X86_BL >> 3, X86_BL & 3);
|
dev = PCI_HANDLE(emu->x86.R_BH, emu->x86.R_BL >> 3, emu->x86.R_BL & 3);
|
||||||
if(X86_DI == PCIBAR1)
|
if (emu->x86.R_DI == PCIBAR1)
|
||||||
X86_CX = offset_port + 1;
|
emu->x86.R_CX = offset_port + 1;
|
||||||
else
|
else
|
||||||
X86_CX = pci_read_config_word(dev, X86_DI);
|
emu->x86.R_CX = pci_read_config_word(dev, emu->x86.R_DI);
|
||||||
dbg("%s: value = %x\r\n", __FUNCTION__, X86_CX);
|
dbg("value = %x\r\n", emu->x86.R_CX);
|
||||||
X86_AH = SUCCESSFUL;
|
emu->x86.R_AH = SUCCESSFUL;
|
||||||
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
|
emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case READ_CONFIG_DWORD:
|
case READ_CONFIG_DWORD:
|
||||||
// bus, devfn
|
// bus, devfn
|
||||||
dbg("%s: READ_CONFIG_DWORD bus = %x, devfn = %x, reg = %x\r\n", __FUNCTION__, X86_BH, X86_BL, X86_DI);
|
dbg("READ_CONFIG_DWORD bus = %x, devfn = %x, reg = %x\r\n", emu->x86.R_BH, emu->x86.R_BL, emu->x86.R_DI);
|
||||||
dev = PCI_HANDLE(X86_BH, X86_BL >> 3, X86_BL & 3);
|
dev = PCI_HANDLE(emu->x86.R_BH, emu->x86.R_BL >> 3, emu->x86.R_BL & 3);
|
||||||
if (X86_DI == PCIBAR1)
|
if (emu->x86.R_DI == PCIBAR1)
|
||||||
X86_CX = (unsigned long) offset_port + 1;
|
emu->x86.R_CX = (unsigned long) offset_port + 1;
|
||||||
else
|
else
|
||||||
X86_ECX = pci_read_config_longword(dev, X86_DI);
|
emu->x86.R_ECX = pci_read_config_longword(dev, emu->x86.R_DI);
|
||||||
dbg("%s: value = %x\r\n", __FUNCTION__, X86_ECX);
|
dbg("value = %x\r\n", emu->x86.R_ECX);
|
||||||
X86_AH = SUCCESSFUL;
|
emu->x86.R_AH = SUCCESSFUL;
|
||||||
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
|
emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WRITE_CONFIG_BYTE:
|
case WRITE_CONFIG_BYTE:
|
||||||
// bus, devfn
|
// bus, devfn
|
||||||
dbg("%s: READ_CONFIG_BYTE bus = %x, devfn = %x, reg = %x, value = %x\r\n", __FUNCTION__,
|
dbg("READ_CONFIG_BYTE bus = %x, devfn = %x, reg = %x, value = %x\r\n",
|
||||||
X86_BH, X86_BL, X86_DI, X86_CL);
|
emu->x86.R_BH, emu->x86.R_BL, emu->x86.R_DI, emu->x86.R_CL);
|
||||||
dev = PCI_HANDLE(X86_BH, X86_BL >> 3, X86_BL & 3);
|
dev = PCI_HANDLE(emu->x86.R_BH, emu->x86.R_BL >> 3, emu->x86.R_BL & 3);
|
||||||
pci_write_config_byte(dev, X86_DI, X86_CL);
|
pci_write_config_byte(dev, emu->x86.R_DI, emu->x86.R_CL);
|
||||||
X86_AH = SUCCESSFUL;
|
emu->x86.R_AH = SUCCESSFUL;
|
||||||
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
|
emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WRITE_CONFIG_WORD:
|
case WRITE_CONFIG_WORD:
|
||||||
// bus, devfn
|
// bus, devfn
|
||||||
dev = PCI_HANDLE(X86_BH, X86_BL >> 3, X86_BL & 3);
|
dev = PCI_HANDLE(emu->x86.R_BH, emu->x86.R_BL >> 3, emu->x86.R_BL & 3);
|
||||||
dbg("%s: WRITE_CONFIG_WORD bus = %x, devfn = %x, reg = %x, value = %x\r\n", X86_BH, X86_BL, X86_DI, X86_CX);
|
dbg("WRITE_CONFIG_WORD bus = %x, devfn = %x, reg = %x, value = %x\r\n", emu->x86.R_BH, emu->x86.R_BL, emu->x86.R_DI, emu->x86.R_CX);
|
||||||
if (X86_DI == PCIBAR1)
|
if (emu->x86.R_DI == PCIBAR1)
|
||||||
{
|
{
|
||||||
offset_port = X86_CX;
|
offset_port = emu->x86.R_CX;
|
||||||
X86_AH = SUCCESSFUL;
|
emu->x86.R_AH = SUCCESSFUL;
|
||||||
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
|
emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pci_write_config_word(dev, X86_DI, X86_CX);
|
pci_write_config_word(dev, emu->x86.R_DI, emu->x86.R_CX);
|
||||||
X86_AH = SUCCESSFUL;
|
emu->x86.R_AH = SUCCESSFUL;
|
||||||
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
|
emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WRITE_CONFIG_DWORD:
|
case WRITE_CONFIG_DWORD:
|
||||||
// bus, devfn
|
// bus, devfn
|
||||||
dev = PCI_HANDLE(X86_BH, X86_BL >> 3, X86_BL & 3);
|
dev = PCI_HANDLE(emu->x86.R_BH, emu->x86.R_BL >> 3, emu->x86.R_BL & 3);
|
||||||
dbg("%s: WRITE_CONFIG_DWORD bus = %x, devfn = %x, value = %x\r\n", __FUNCTION__,
|
dbg("WRITE_CONFIG_DWORD bus = %x, devfn = %x, value = %x\r\n",
|
||||||
X86_BH, X86_BL, X86_DI, X86_ECX);
|
emu->x86.R_BH, emu->x86.R_BL, emu->x86.R_DI, emu->x86.R_ECX);
|
||||||
if (X86_DI == PCIBAR1)
|
if (emu->x86.R_DI == PCIBAR1)
|
||||||
{
|
{
|
||||||
offset_port = (unsigned short) X86_ECX & 0xFFFC;
|
offset_port = (unsigned short) emu->x86.R_ECX & 0xFFFC;
|
||||||
X86_AH = SUCCESSFUL;
|
emu->x86.R_AH = SUCCESSFUL;
|
||||||
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
|
emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pci_write_config_longword(dev, X86_DI, X86_ECX);
|
pci_write_config_longword(dev, emu->x86.R_DI, emu->x86.R_ECX);
|
||||||
X86_AH = SUCCESSFUL;
|
emu->x86.R_AH = SUCCESSFUL;
|
||||||
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
|
emu->x86.R_EFLG &= ~FB_CF; /* clear carry flag */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dbg("%s: PCI_BIOS FUNC_NOT_SUPPORTED\r\n", __FUNCTION__);
|
dbg("PCI_BIOS FUNC_NOT_SUPPORTED\r\n");
|
||||||
X86_AH = FUNC_NOT_SUPPORTED;
|
emu->x86.R_AH = FUNC_NOT_SUPPORTED;
|
||||||
X86_EFLAGS |= FB_CF;
|
emu->x86.R_EFLG |= FB_CF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user