cleaned up. X86emu does not work with debug trace on currently.

This commit is contained in:
Markus Fröschle
2014-01-03 21:03:35 +00:00
parent 087851d22f
commit 47d7e8e965
28 changed files with 1254 additions and 1227 deletions

View File

@@ -9,7 +9,7 @@
# can be either "Y" or "N" (without quotes). "Y" for using the m68k-elf-, "N" for using the m68k-atari-mint
# toolchain
COMPILE_ELF=N
COMPILE_ELF=Y
ifeq (Y,$(COMPILE_ELF))
TCPREFIX=m68k-elf-
@@ -33,6 +33,15 @@ INCLUDE=-Iinclude
CFLAGS=-mcpu=5474 \
-Wall \
-Os \
-g \
-fomit-frame-pointer \
-ffreestanding \
-fleading-underscore \
-Wa,--register-prefix-optional
CFLAGS_OPTIMIZED = -mcpu=5474 \
-Wall \
-O2 \
-g \
-fomit-frame-pointer \
-ffreestanding \
-fleading-underscore \
@@ -94,6 +103,7 @@ CSRCS= \
queue.c \
net_timer.c \
am79c874.c \
bcm5222.c \
nif.c \
fecbd.c \
fec.c \
@@ -177,6 +187,18 @@ ifeq (firebee,$(1))
else
MACHINE=MACHINE_M5484LITE
endif
# always optimize x86 emulator objects
$(1)/objs/x86decode.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86sys.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86debug.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86prim_ops.o:CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86ops.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86ops2.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86fpu.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86biosemu.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86pcibios.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/%.o:%.c
$(CC) $$(CFLAGS) -D$$(MACHINE) $(INCLUDE) -c $$< -o $$@

View File

@@ -60,6 +60,7 @@ SECTIONS
OBJDIR/fecbd.o(.text)
OBJDIR/fec.o(.text)
OBJDIR/am79c874.o(.text)
OBJDIR/bcm5222.o(.text)
OBJDIR/ip.o(.text)
OBJDIR/udp.o(text)
OBJDIR/bootp.o(text)

View File

@@ -51,7 +51,17 @@ struct dma_channel
void (*handler)(void);
};
static char used_reqs[32];
static char used_reqs[32] =
{
DMA_ALWAYS, DMA_DSPI_RXFIFO, DMA_DSPI_TXFIFO, DMA_DREQ0,
DMA_PSC0_RX, DMA_PSC0_TX, DMA_USB_EP0, DMA_USB_EP1,
DMA_USB_EP2, DMA_USB_EP3, DMA_PCI_TX, DMA_PCI_RX,
DMA_PSC1_RX, DMA_PSC1_TX, DMA_I2C_RX, DMA_I2C_TX,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
static struct dma_channel dma_channel[NCHANNELS] =
{
@@ -337,6 +347,7 @@ int dma_set_initiator(int initiator)
else /* No empty slots */
return 1;
break;
case DMA_PSC2_RX:
if (used_reqs[28] == 0)
{
@@ -543,8 +554,6 @@ int dma_interrupt_handler(void *arg1, void *arg2)
{
uint32_t i, interrupts;
dbg("%s: arg1 = %p, arg2 = %p\r\n", __FUNCTION__, arg1, arg2);
(void) set_ipl(7);
/*
@@ -555,7 +564,10 @@ int dma_interrupt_handler(void *arg1, void *arg2)
/* Make sure we are here for a reason */
if (interrupts == 0)
{
dbg("%s: not DMA interrupt! Spurious?\r\n", __FUNCTION__);
return 0;
}
/* Clear the interrupt in the pending register */
MCF_DMA_DIPR = interrupts;
@@ -567,7 +579,7 @@ int dma_interrupt_handler(void *arg1, void *arg2)
/* If there is a handler, call it */
if (dma_channel[i].handler != NULL)
{
dbg("%s: call handler for interrupt %d (%p)\r\n", __FUNCTION__, i, dma_channel[i].handler);
dbg("%s: call handler for DMA channel %d (%p)\r\n", __FUNCTION__, i, dma_channel[i].handler);
dma_channel[i].handler();
}
}

View File

@@ -69,7 +69,7 @@ extern void fec_duplex (uint8_t, uint8_t);
extern uint8_t fec_hash_address(const uint8_t *);
extern void fec_set_address (uint8_t ch, const uint8_t *);
extern void fec_reset (uint8_t);
extern void fec_init (uint8_t, uint8_t, const uint8_t *);
extern void fec_init(uint8_t ch, uint8_t mode, const uint8_t *pa);
extern void fec_rx_start(uint8_t, int8_t *);
extern void fec_rx_restart(uint8_t);
extern void fec_rx_stop (uint8_t);

View File

@@ -43,7 +43,7 @@
#endif /* COMPILE_RAM */
#define DRIVER_MEM_BUFFER_SIZE 0x80000
#define DRIVER_MEM_BUFFER_SIZE 0x100000
#define EMUTOS_BASE_ADDRESS 0xe0600000

View File

@@ -42,7 +42,7 @@
#define TARGET_ADDRESS BOOTFLASH_BASE_ADDRESS
#endif /* COMPILE_RAM */
#define DRIVER_MEM_BUFFER_SIZE 0x80000
#define DRIVER_MEM_BUFFER_SIZE 0x100000
#define EMUTOS_BASE_ADDRESS 0xe0100000

View File

@@ -8,7 +8,6 @@
#ifndef _NET_H
#define _NET_H
/********************************************************************/
/*
* Include information and prototypes for all protocols
@@ -22,11 +21,12 @@
#include "udp.h"
#include "tftp.h"
/********************************************************************/
#define TIMER_NETWORK 3 /* use GPT3 for network timers */
#define TMR_INTC_LVL 3 /* interrupt level for network timer */
#define TMR_INTC_PRI 0 /* interrupt priority for network timer */
extern int net_init(void);
/********************************************************************/
#endif /* _NET_H */

View File

@@ -65,7 +65,7 @@
#define CHECK_MEM_ACCESS_F 0x4 /*using regular linear pointer */
#define CHECK_DATA_ACCESS_F 0x8 /*using segment:offset*/
#ifdef DEBUG
#ifdef DBG_X86EMU
# define CHECK_IP_FETCH() (M.x86.check & CHECK_IP_FETCH_F)
# define CHECK_SP_ACCESS() (M.x86.check & CHECK_SP_ACCESS_F)
# define CHECK_MEM_ACCESS() (M.x86.check & CHECK_MEM_ACCESS_F)
@@ -77,7 +77,7 @@
# define CHECK_DATA_ACCESS()
#endif
#ifdef DEBUG
#ifdef DBG_X86EMU
# define DEBUG_INSTRUMENT() (M.x86.debug & DEBUG_INSTRUMENT_F)
# define DEBUG_DECODE() (M.x86.debug & DEBUG_DECODE_F)
# define DEBUG_TRACE() (M.x86.debug & DEBUG_TRACE_F)
@@ -116,7 +116,7 @@
# define DEBUG_DECODE_NOPRINT() 0
#endif
#ifdef DEBUG
#ifdef DBG_X86EMU
# define DECODE_PRINTF(x) if (DEBUG_DECODE()) \
x86emu_decode_printf(x)
@@ -146,7 +146,7 @@
# define SAVE_IP_CS(x,y)
#endif
#ifdef DEBUG
#ifdef DBG_X86EMU
#define TRACE_REGS() \
if (DEBUG_DISASSEMBLE()) { \
x86emu_just_disassemble(); \
@@ -157,7 +157,7 @@
# define TRACE_REGS()
#endif
#ifdef DEBUG
#ifdef DBG_X86EMU
# define SINGLE_STEP() if (DEBUG_STEP()) x86emu_single_step()
#else
# define SINGLE_STEP()
@@ -167,7 +167,7 @@
TRACE_REGS(); \
SINGLE_STEP()
#ifdef DEBUG
#ifdef DBG_X86EMU
# define START_OF_INSTR()
# define END_OF_INSTR() EndOfTheInstructionProcedure: x86emu_end_instr();
# define END_OF_INSTR_NO_TRACE() x86emu_end_instr();
@@ -177,7 +177,7 @@
# define END_OF_INSTR_NO_TRACE()
#endif
#ifdef DEBUG
#ifdef DBG_X86EMU
# define CALL_TRACE(u,v,w,x,s) \
if (DEBUG_TRACECALLREGS()) \
x86emu_dump_regs(); \
@@ -203,7 +203,7 @@
# define RETURN_TRACE(n,u,v)
#endif
#ifdef DEBUG
#ifdef DBG_X86EMU
#define DB(x) x
#else
#define DB(x)

View File

@@ -39,6 +39,7 @@
#ifndef __X86EMU_REGS_H
#define __X86EMU_REGS_H
#include "x86debug.h"
/*---------------------- Macros and type definitions ----------------------*/

View File

@@ -49,7 +49,7 @@ int am79c874_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duple
if (duplex); /* to do */
/* Initialize the MII interface */
fec_mii_init(fec_ch, SYSCLK);
fec_mii_init(fec_ch, SYSCLK / 1000);
dbg("%s: PHY reset\r\n", __FUNCTION__);
/* Reset the PHY */

View File

@@ -6,9 +6,18 @@
*/
#include "net.h"
#include "net_timer.h"
#include "bas_printf.h"
#include <stdbool.h>
#include <stddef.h>
#define DBG_ARP
#ifdef DBG_ARP
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else
#define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_ARP */
#define TIMER_NETWORK 3
static uint8_t *arp_find_pair(ARP_INFO *arptab, uint16_t protocol, uint8_t *hwa, uint8_t *pa)
@@ -219,12 +228,12 @@ void arp_request(NIF *nif, uint8_t *pa)
int i, result;
xprintf("%s\r\n", __FUNCTION__);
dbg("%s\r\n", __FUNCTION__);
pNbuf = nbuf_alloc();
if (pNbuf == NULL)
{
xprintf("ARP: arp_request couldn't allocate Tx buffer\n");
dbg("%s: arp_request couldn't allocate Tx buffer\n", __FUNCTION__);
return;
}
@@ -254,6 +263,7 @@ void arp_request(NIF *nif, uint8_t *pa)
pNbuf->length = ARP_HDR_LEN;
/* Send the ARP request */
dbg("%s: sending ARP request\r\n", __FUNCTION__);
result = nif->send(nif, nif->broadcast, nif->hwa, ETH_FRM_ARP, pNbuf);
if (result == 0)
@@ -290,7 +300,7 @@ uint8_t *arp_resolve(NIF *nif, uint16_t protocol, uint8_t *pa)
* Check to see if the necessary MAC-to-IP translation information
* is in table already
*/
if (arp_resolve_pa (nif, protocol, pa, &hwa))
if (arp_resolve_pa(nif, protocol, pa, &hwa))
return hwa;
/*
@@ -300,15 +310,22 @@ uint8_t *arp_resolve(NIF *nif, uint16_t protocol, uint8_t *pa)
*/
for (i = 0; i < 3; i++)
{
arp_request (nif, pa);
arp_request(nif, pa);
timer_set_secs(TIMER_NETWORK, ARP_TIMEOUT);
while (timer_get_reference(TIMER_NETWORK))
{
if (arp_resolve_pa (nif, protocol, pa, &hwa))
dbg("%s: try to resolve %d.%d.%d.%d\r\n", __FUNCTION__,
pa[0], pa[1], pa[2], pa[3], pa[4]);
if (arp_resolve_pa(nif, protocol, pa, &hwa))
{
dbg("%s: resolved to %02x:%02x:%02x:%02x:%02x:%02x.\r\n", __FUNCTION__,
hwa[0], hwa[1], hwa[2], hwa[3], hwa[4], hwa[5], hwa[6]);
return hwa;
}
}
}
return NULL;
}

View File

@@ -18,6 +18,7 @@
#include "bas_printf.h"
#include "util.h"
#include "am79c874.h"
#include "bcm5222.h"
#include <stdbool.h>
#if defined(MACHINE_FIREBEE)
@@ -268,30 +269,30 @@ void fec_log_dump(uint8_t ch)
*/
void fec_debug_dump(uint8_t ch)
{
dbg("\n------------- FEC%d -------------\n",ch);
dbg("EIR %08x \n", MCF_FEC_EIR(ch));
dbg("EIMR %08x \n", MCF_FEC_EIMR(ch));
dbg("ECR %08x \n", MCF_FEC_ECR(ch));
dbg("RCR %08x \n", MCF_FEC_RCR(ch));
dbg("R_HASH %08x \n", MCF_FEC_RHR_HASH(ch));
dbg("TCR %08x \n", MCF_FEC_TCR(ch));
dbg("FECTFWR %08x \n", MCF_FEC_FECTFWR(ch));
dbg("FECRFSR %08x \n", MCF_FEC_FECRFSR(ch));
dbg("FECRFCR %08x \n", MCF_FEC_FECRFCR(ch));
dbg("FECRLRFP %08x \n", MCF_FEC_FECRLRFP(ch));
dbg("FECRLWFP %08x \n", MCF_FEC_FECRLWFP(ch));
dbg("FECRFAR %08x \n", MCF_FEC_FECRFAR(ch));
dbg("FECRFRP %08x \n", MCF_FEC_FECRFRP(ch));
dbg("FECRFWP %08x \n", MCF_FEC_FECRFWP(ch));
dbg("FECTFSR %08x \n", MCF_FEC_FECTFSR(ch));
dbg("FECTFCR %08x \n", MCF_FEC_FECTFCR(ch));
dbg("FECTLRFP %08x \n", MCF_FEC_FECTLRFP(ch));
dbg("FECTLWFP %08x \n", MCF_FEC_FECTLWFP(ch));
dbg("FECTFAR %08x \n", MCF_FEC_FECTFAR(ch));
dbg("FECTFRP %08x \n", MCF_FEC_FECTFRP(ch));
dbg("FECTFWP %08x \n", MCF_FEC_FECTFWP(ch));
dbg("FRST %08x \n", MCF_FEC_FECFRST(ch));
dbg("--------------------------------\n\n");
dbg("\r\n------------- FEC%d -------------\r\n",ch);
dbg("EIR %08x \r\n", MCF_FEC_EIR(ch));
dbg("EIMR %08x \r\n", MCF_FEC_EIMR(ch));
dbg("ECR %08x \r\n", MCF_FEC_ECR(ch));
dbg("RCR %08x \r\n", MCF_FEC_RCR(ch));
dbg("R_HASH %08x \r\n", MCF_FEC_RHR_HASH(ch));
dbg("TCR %08x \r\n", MCF_FEC_TCR(ch));
dbg("FECTFWR %08x \r\n", MCF_FEC_FECTFWR(ch));
dbg("FECRFSR %08x \r\n", MCF_FEC_FECRFSR(ch));
dbg("FECRFCR %08x \r\n", MCF_FEC_FECRFCR(ch));
dbg("FECRLRFP %08x \r\n", MCF_FEC_FECRLRFP(ch));
dbg("FECRLWFP %08x \r\n", MCF_FEC_FECRLWFP(ch));
dbg("FECRFAR %08x \r\n", MCF_FEC_FECRFAR(ch));
dbg("FECRFRP %08x \r\n", MCF_FEC_FECRFRP(ch));
dbg("FECRFWP %08x \r\n", MCF_FEC_FECRFWP(ch));
dbg("FECTFSR %08x \r\n", MCF_FEC_FECTFSR(ch));
dbg("FECTFCR %08x \r\n", MCF_FEC_FECTFCR(ch));
dbg("FECTLRFP %08x \r\n", MCF_FEC_FECTLRFP(ch));
dbg("FECTLWFP %08x \r\n", MCF_FEC_FECTLWFP(ch));
dbg("FECTFAR %08x \r\n", MCF_FEC_FECTFAR(ch));
dbg("FECTFRP %08x \r\n", MCF_FEC_FECTFRP(ch));
dbg("FECTFWP %08x \r\n", MCF_FEC_FECTFWP(ch));
dbg("FRST %08x \r\n", MCF_FEC_FECFRST(ch));
dbg("--------------------------------\r\n\r\n");
}
/*
@@ -398,11 +399,11 @@ void fec_reset(uint8_t ch)
| MCF_FEC_FECRFSR_FAE
| MCF_FEC_FECRFSR_IP);
MCF_FEC_FECTFSR(ch) = (0
| MCF_FEC_FECRFSR_OF
| MCF_FEC_FECRFSR_UF
| MCF_FEC_FECRFSR_RXW
| MCF_FEC_FECRFSR_FAE
| MCF_FEC_FECRFSR_IP);
| MCF_FEC_FECTFSR_OF
| MCF_FEC_FECTFSR_UF
| MCF_FEC_FECTFSR_TXW
| MCF_FEC_FECTFSR_FAE
| MCF_FEC_FECTFSR_IP);
/* Reset the FIFOs */
MCF_FEC_FECFRST(ch) |= MCF_FEC_FECFRST_SW_RST;
@@ -1003,13 +1004,17 @@ void fec_tx_frame(uint8_t ch)
* Free up the network buffer that was just transmitted
*/
nbuf_free(pNbuf);
dbg("%s: free buffer %p from TX ring\r\n", __FUNCTION__, pNbuf);
/*
* Re-initialize the Tx BD
*/
pTxBD->data = NULL;
pTxBD->length = 0;
return;
}
dbg("%s: BD ring is empty\r\n", __FUNCTION__);
}
void fec0_tx_frame(void)
@@ -1228,16 +1233,20 @@ static void fec_irq_handler(uint8_t ch)
if (event & MCF_FEC_EIR_MII)
{
fec_log[ch].mii++;
dbg("%s: MII\r\n", __FUNCTION__);
}
if (event & MCF_FEC_EIR_TXF)
{
fec_log[ch].txf++;
dbg("%s: TXF\r\n", __FUNCTION__);
fec_log_dump(0);
}
if (event & MCF_FEC_EIR_GRA)
{
fec_log[ch].gra++;
dbg("%s: GRA\r\n", __FUNCTION__);
}
if (event & MCF_FEC_EIR_BABT)
@@ -1315,7 +1324,7 @@ void fec_eth_setup(uint8_t ch, uint8_t trcvr, uint8_t speed, uint8_t duplex, con
* Initialize the FEC
*/
fec_reset(ch);
fec_init(ch,trcvr,mac);
fec_init(ch, trcvr, mac);
if (trcvr == FEC_MODE_MII)
{
@@ -1324,8 +1333,10 @@ void fec_eth_setup(uint8_t ch, uint8_t trcvr, uint8_t speed, uint8_t duplex, con
*/
#if defined(MACHINE_FIREBEE)
am79c874_init(0, 0, speed, duplex);
#elif defined(MACHINE_M548X)
bcm_5222_init(0, 0, speed, duplex);
#else
fec_mii_init(ch, SYSCLK);
fec_mii_init(ch, SYSCLK / 1000);
#endif /* MACHINE_FIREBEE */
}

View File

@@ -280,6 +280,8 @@ void ip_handler(NIF *nif, NBUF *pNbuf)
*/
ip_frame_hdr *ipframe;
dbg("%s: packet received\r\n", __FUNCTION__);
ipframe = (ip_frame_hdr *) &pNbuf->data[pNbuf->offset];
/*
@@ -300,7 +302,7 @@ void ip_handler(NIF *nif, NBUF *pNbuf)
switch (IP_PROTOCOL(ipframe))
{
case IP_PROTO_ICMP:
// FIXME: icmp_handler(nif,pNbuf);
// FIXME: icmp_handler(nif, pNbuf);
break;
case IP_PROTO_UDP:
udp_handler(nif,pNbuf);

View File

@@ -165,6 +165,7 @@ NBUF *nbuf_remove(int q)
void nbuf_add(int q, NBUF *nbuf)
{
int level = set_ipl(7);
queue_add(&nbuf_queue[q], (QNODE *) nbuf);
set_ipl(level);
}
@@ -198,19 +199,20 @@ void nbuf_debug_dump(void)
for (i = 0; i < NBUF_MAXQ; ++i)
{
dbg("\n\nQueue #%d\n\n", i);
dbg("\tBuffer Location\tOffset\tLength\n");
dbg("--------------------------------------\n");
dbg("\r\n\r\nQueue #%d\r\n\r\n", i);
dbg("\tBuffer Location\tOffset\tLength\r\n");
dbg("--------------------------------------\r\n");
j = 0;
nbuf = (NBUF *) queue_peek(&nbuf_queue[i]);
while (nbuf != NULL)
{
dbg("%d\t 0x%08x\t0x%04x\t0x%04x\n",j++,nbuf->data,
dbg("%d\t0x%08x\t0x%04x\t0x%04x\r\n", j++, nbuf->data,
nbuf->offset,
nbuf->length);
nbuf = (NBUF *) nbuf->node.next;
}
}
dbg("\r\n");
set_ipl(level);
#endif /* DBG_NBUF */

View File

@@ -8,9 +8,18 @@
#include "net_timer.h"
#include <stdint.h>
#include <stdbool.h>
#include "bas_printf.h"
#include "MCF5475.h"
#include "interrupts.h"
#define DBG_TMR
#ifdef DBG_TMR
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else
#define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_TMR */
#if defined(MACHINE_FIREBEE)
#include "firebee.h"
#elif defined(MACHINE_M5484LITE)
@@ -37,6 +46,8 @@ int timer_default_isr(void *not_used, NET_TIMER *t)
*/
MCF_GPT_GMS(t->ch) = 0;
dbg("%s: timer isr called for timer channel %d\r\n", __FUNCTION__);
/*
* Clear the reference - the desired seconds have expired
*/
@@ -119,7 +130,12 @@ bool timer_init(uint8_t ch, uint8_t lvl, uint8_t pri)
* initialization code.
*/
if (!((ch <= 3) && (lvl <= 7) && (lvl >= 1) && (pri <= 7)))
{
dbg("%s: illegal parameters (ch=%d, lvl=%d, pri=%d)\r\n", __FUNCTION__,
ch, lvl, pri);
return false;
}
/*
* Reset the timer
@@ -143,8 +159,10 @@ bool timer_init(uint8_t ch, uint8_t lvl, uint8_t pri)
(void *) &net_timer[ch])
)
{
dbg("%s: could not register timer interrupt handler\r\n", __FUNCTION__);
return false;
}
dbg("%s: timer handler registered\r\n", __FUNCTION__);
/*
* Calculate the require CNT value to get a 1 second timeout
@@ -162,7 +180,7 @@ bool timer_init(uint8_t ch, uint8_t lvl, uint8_t pri)
* CNT = SYSTEM_CLOCK * (1000000/0xFFFF)
*/
net_timer[ch].pre = 0xFFFF;
net_timer[ch].cnt = (uint16_t) (SYSCLK * (1000000 / 0xFFFF));
net_timer[ch].cnt = (uint16_t) ((SYSCLK / 1000) * (1000000 / 0xFFFF));
/*
* Save off the appropriate mode select register value

View File

@@ -9,9 +9,18 @@
*/
#include "net.h"
#include "bas_types.h"
#include "bas_printf.h"
#include <stdint.h>
#include <stdbool.h>
#define DBG_NIF
#ifdef DBG_NIF
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else
#define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_NIF */
int nif_protocol_exist(NIF *nif, uint16_t protocol)
{
/*
@@ -46,8 +55,14 @@ void nif_protocol_handler(NIF *nif, uint16_t protocol, NBUF *pNbuf)
for (index = 0; index < nif->num_protocol; ++index)
{
if (nif->protocol[index].protocol == protocol)
{
dbg("%s: call protocol handler for protocol %d at %p\r\n", __FUNCTION__, protocol,
nif->protocol[index].handler);
nif->protocol[index].handler(nif,pNbuf);
return;
}
}
dbg("%s: no protocol handler found for protocol %d\r\n", __FUNCTION__, protocol);
}
void *nif_get_protocol_info(NIF *nif, uint16_t protocol)
@@ -80,6 +95,7 @@ int nif_bind_protocol(NIF *nif, uint16_t protocol, void (*handler)(NIF *,NBUF *)
nif->protocol[nif->num_protocol].handler = (void(*)(NIF*,NBUF*))handler;
nif->protocol[nif->num_protocol].info = info;
++nif->num_protocol;
return true;
}
return false;

View File

@@ -8,6 +8,7 @@
*
*/
#include "bas_types.h"
#include "bas_printf.h"
#include "net.h"
#include <stddef.h>
@@ -106,6 +107,8 @@ uint16_t udp_obtain_free_port(void)
int udp_send(NIF *nif, uint8_t *dest, int sport, int dport, NBUF *pNbuf)
{
uint8_t *myip;
if (nif == NULL)
{
dbg("%s: nif is NULL\r\n", __FUNCTION__);
@@ -135,8 +138,14 @@ int udp_send(NIF *nif, uint8_t *dest, int sport, int dport, NBUF *pNbuf)
/* Add the length of the UDP packet to the total length of the packet */
pNbuf->length += 8;
return (ip_send(nif, dest, ip_get_myip(nif_get_protocol_info(nif, ETH_FRM_IP)),
IP_PROTO_UDP, pNbuf));
myip = ip_get_myip(nif_get_protocol_info(nif, ETH_FRM_IP));
dbg("%s: sent UDP request to %d.%d.%d.%d from %d.%d.%d.%d\r\n", __FUNCTION__,
dest[0], dest[1], dest[2], dest[3],
myip[0], myip[1], myip[2], myip[3]);
return (ip_send(nif, dest, myip, IP_PROTO_UDP, pNbuf));
}
void udp_handler(NIF *nif, NBUF *pNbuf)
@@ -149,6 +158,8 @@ void udp_handler(NIF *nif, NBUF *pNbuf)
udpframe = (udp_frame_hdr *) &pNbuf->data[pNbuf->offset];
dbg("%s: packet received\r\n", __FUNCTION__);
/*
* Adjust the length and valid data offset of the packet we are
* passing on
@@ -164,7 +175,7 @@ void udp_handler(NIF *nif, NBUF *pNbuf)
handler(nif, pNbuf);
else
{
xprintf("Received UDP packet for non-supported port\n");
dbg("%s: received UDP packet for non-supported port\n", __FUNCTION__);
nbuf_free(pNbuf);
}

View File

@@ -892,9 +892,9 @@ void init_xlbus_arbiter(void)
MCF_XLB_XARB_PRIEN = MCF_XLB_XARB_PRIEN_M0 | /* activate programmed priority for Coldfire core */
MCF_XLB_XARB_PRIEN_M2 | /* activate programmed priority for Multichannel DMA */
MCF_XLB_XARB_PRIEN_M3; /* activate programmed priority for PCI target interface */
MCF_XLB_XARB_PRI = MCF_XLB_XARB_PRI_M0P(3) | /* Coldfire core gets lowest */
MCF_XLB_XARB_PRI = MCF_XLB_XARB_PRI_M0P(7) | /* Coldfire core gets lowest */
MCF_XLB_XARB_PRI_M2P(5) | /* Multichannel DMA mid priority */
MCF_XLB_XARB_PRI_M3P(7); /* PCI target interface is highest priority */
MCF_XLB_XARB_PRI_M3P(3); /* PCI target interface is highest priority */
}
void init_pci(void)

View File

@@ -61,7 +61,7 @@
#include "bas_printf.h"
#include "exceptions.h" /* for set_ipl() */
//#define DBG_RADEON
#define DBG_RADEON
#ifdef DBG_RADEON
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else
@@ -670,23 +670,14 @@ static void radeon_get_pllinfo(struct radeonfb_info *rinfo)
*/
if (!force_measure_pll && (rinfo->bios_seg != NULL))
{
#ifdef DRIVER_IN_ROM // problem if BIOS ROM is invalid after run_bios()
rinfo->pll.sclk = rinfo->bios_pll.sclk;
rinfo->pll.mclk = rinfo->bios_pll.mclk;
rinfo->pll.ref_clk = rinfo->bios_pll.ref_clk;
rinfo->pll.ref_div = rinfo->bios_pll.ref_div;
rinfo->pll.ppll_min = rinfo->bios_pll.ppll_min;
rinfo->pll.ppll_max = rinfo->bios_pll.ppll_max;
#else
uint16_t pll_info_block = BIOS_IN16(rinfo->fp_bios_start + 0x30);
rinfo->pll.sclk = BIOS_IN16(pll_info_block + 0x08);
rinfo->pll.mclk = BIOS_IN16(pll_info_block + 0x0a);
rinfo->pll.ref_clk = BIOS_IN16(pll_info_block + 0x0e);
rinfo->pll.ref_div = BIOS_IN16(pll_info_block + 0x10);
rinfo->pll.ppll_min = BIOS_IN32(pll_info_block + 0x12);
rinfo->pll.ppll_max = BIOS_IN32(pll_info_block + 0x16);
#endif
dbg("%s: Retreived PLL infos from BIOS\r\n", __FUNCTION__);
goto found;
}
@@ -831,20 +822,31 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
v.xres_virtual = (pitch << 6) / ((v.bits_per_pixel + 1) / 8);
if (((v.xres_virtual * v.yres_virtual * nom) / den) > info->screen_size)
{
dbg("%s: mode %d x %d rejected (screen size too small)\r\n", __FUNCTION__, v.xres_virtual, v.yres_virtual);
return -1; //-EINVAL;
}
if (v.xres_virtual < v.xres)
v.xres = v.xres_virtual;
if (v.xoffset < 0)
v.xoffset = 0;
if (v.yoffset < 0)
v.yoffset = 0;
if (v.xoffset > v.xres_virtual - v.xres)
v.xoffset = v.xres_virtual - v.xres - 1;
if (v.yoffset > v.yres_virtual - v.yres)
v.yoffset = v.yres_virtual - v.yres - 1;
v.red.msb_right = v.green.msb_right = v.blue.msb_right = 0;
v.transp.offset = v.transp.length = v.transp.msb_right = 0;
dbg("%s: using mode %d x %d \r\n", __FUNCTION__, v.xres, v.yres);
memcpy(var, &v, sizeof(v));
return 0;
}
@@ -1786,6 +1788,7 @@ int radeonfb_set_par(struct fb_info *info)
static void radeonfb_check_modes(struct fb_info *info, struct mode_option *resolution)
{
struct radeonfb_info *rinfo = info->par;
radeon_check_modes(rinfo, resolution);
}
@@ -1839,6 +1842,7 @@ static struct fb_ops radeonfb_ops =
static int radeon_set_fbinfo(struct radeonfb_info *rinfo)
{
struct fb_info *info = rinfo->info;
info->par = rinfo;
info->fbops = &radeonfb_ops;
info->ram_base = info->screen_base = rinfo->fb_base;
@@ -1848,7 +1852,10 @@ static int radeon_set_fbinfo(struct radeonfb_info *rinfo)
info->screen_size = MAX_MAPPED_VRAM;
else if (info->screen_size > MIN_MAPPED_VRAM)
info->screen_size = MIN_MAPPED_VRAM;
dbg("radeonfb: radeon_set_fbinfo: screen_size %lx\r\n", info->screen_size);
dbg("%s: ram_base %p\r\n", __FUNCTION__, info->screen_base);
dbg("%s: ram_size %p\r\n", __FUNCTION__, info->ram_size);
/* Fill fix common fields */
memcpy(info->fix.id, rinfo->name, sizeof(info->fix.id));
info->fix.smem_start = rinfo->fb_base_phys;
@@ -2117,7 +2124,7 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
if ((rinfo->bios_seg != NULL))
{
dbg("%s: run VGA BIOS\r\n", __FUNCTION__);
//run_bios(rinfo);
run_bios(rinfo);
}
else
{
@@ -2180,7 +2187,8 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent)
dbg("%s: build mode list\r\n", __FUNCTION__);
radeon_check_modes(rinfo, &resolution);
/* save current mode regs before we switch into the new one
/*
* save current mode regs before we switch into the new one
* so we can restore this upon exit
*/
dbg("%s: save current mode\r\n", __FUNCTION__);

View File

@@ -290,15 +290,27 @@ void network_init(void)
memcpy(nif1.hwa, mac, 6);
memcpy(nif1.broadcast, bc, 6);
dbg("%s: ethernet address is %02X:%02X:%02X:%02X:%02X:%02X\r\n", __FUNCTION__,
nif1.hwa[0], nif1.hwa[1], nif1.hwa[2],
nif1.hwa[3], nif1.hwa[4], nif1.hwa[5]);
timer_init(TIMER_NETWORK, TMR_INTC_LVL, TMR_INTC_PRI);
arp_init(&arp_info);
nif_bind_protocol(&nif1, ETH_FRM_ARP, arp_handler, (void *) &arp_info);
ip_init(&ip_info, myip, gateway, netmask);
nif_bind_protocol(&nif1, ETH_FRM_IP, ip_handler, (void *) &ip_info);
dma_irq_enable(6, 6);
//set_ipl(0);
// bootp_request(&nif1, 0);
udp_init();
dma_irq_enable(6, 6);
set_ipl(0);
bootp_request(&nif1, 0);
fec_eth_stop(0);
}
void BaS(void)
@@ -315,7 +327,7 @@ void BaS(void)
/* copy EMUTOS */
src = (uint8_t *) EMUTOS;
memcpy(dst, src, EMUTOS_SIZE);
dma_memcpy(dst, src, EMUTOS_SIZE);
xprintf("finished\r\n");
xprintf("initialize MMU: ");

View File

@@ -301,7 +301,7 @@ int driver_mem_init(void)
{
if (use_count == 0)
{
dbg("%s: initialise driver_mem_buffer[] at %p, size %x\r\n", __FUNCTION__, driver_mem_buffer, DRIVER_MEM_BUFFER_SIZE);
dbg("%s: initialise driver_mem_buffer[] at %p, size 0x%x\r\n", __FUNCTION__, driver_mem_buffer, DRIVER_MEM_BUFFER_SIZE);
memset(driver_mem_buffer, 0, DRIVER_MEM_BUFFER_SIZE);
pmd.mp_mfl = pmd.mp_rover = &tab_md[0];

View File

@@ -310,6 +310,7 @@ init_vec_loop:
// install lowlevel_isr_handler for the FEC0 interrupt
move.l a1,(INT_SOURCE_FEC0 + 64) * 4(a0)
#ifndef MACHINE_FIREBEE
// FEC1 not wired on the FireBee
move.l a1,(INT_SOURCE_FEC1 + 64) * 4(a0)

View File

@@ -507,6 +507,7 @@ int fb_find_mode(struct fb_var_screeninfo *var,
default_mode = &modedb[DEFAULT_MODEDB_INDEX];
if (!default_bpp)
default_bpp = 8;
/* Did the user specify a video mode? */
if (resolution->used) /* fVDI mode */
{

View File

@@ -277,9 +277,18 @@ void videl_screen_init(void)
static struct fb_info fb;
struct fb_info *info_fb = &fb;
const char monitor_layout[1024];
const char monitor_layout[1024] = "CRT,CRT";
int16_t ignore_edid;
struct mode_option resolution;
struct mode_option resolution =
{
.used = 0,
.width = 640,
.height = 480,
.bpp = 8,
.freq = 60,
.flags = 0
};
int16_t force_measure_pll;
void install_vbl_timer(void *func, int remove)

View File

@@ -62,7 +62,7 @@ struct pci_data
uint16_t reserved_2;
};
struct radeonfb_info *rinfo_biosemu;
static struct radeonfb_info *rinfo_biosemu;
uint16_t offset_port;
uint32_t offset_mem;
static uint32_t offset_io;
@@ -105,9 +105,7 @@ uint8_t inb(uint16_t port)
if ((port >= offset_port) && (port <= offset_port + 0xFF))
{
//dbg("%s:\r\n", __FUNCTION__);
val = *(uint8_t *)(offset_io+(uint32_t)port);
val = * (uint8_t *) (offset_io + (uint32_t) port);
//dbg("%s: inb(0x%x) = 0x%x\r\n", __FUNCTION__, port, val);
}
return val;
@@ -117,11 +115,10 @@ uint16_t inw(uint16_t port)
{
uint16_t val = 0;
if ((port >= offset_port) && (port <= offset_port+0xFF))
if ((port >= offset_port) && (port <= offset_port + 0xFF))
{
//dbg("inw(");
val = swpw(*(uint16_t *)(offset_io+(uint32_t)port));
//dbg("0x%x) = 0x%x\r\n", port, val);
val = swpw(*(uint16_t *)(offset_io + (uint32_t) port));
//dbg("inw(0x%x) = 0x%x\r\n", port, val);
}
return val;
}
@@ -129,42 +126,38 @@ uint16_t inw(uint16_t port)
uint32_t inl(uint16_t port)
{
uint32_t val = 0;
if ((port >= offset_port) && (port <= offset_port+0xFF))
if ((port >= offset_port) && (port <= offset_port + 0xFF))
{
//dbg("inl(");
val = swpl(*(uint32_t *)(offset_io+(uint32_t)port));
val = swpl(*(uint32_t *)(offset_io + (uint32_t) port));
//dbg("0x%x) = 0x%x\r\n", port, val);
}
else if (port == 0xCF8)
{
//dbg("inl(");
val = config_address_reg;
//dbg("0x%x) = 0x%x\r\n", port, val);
dbg("inl(0x%x) = 0x%x\r\n", port, val);
}
else if ((port == 0xCFC) && ((config_address_reg & 0x80000000) != 0))
{
dbg("%s: PCI BIOS access to register %x\r\n", __FUNCTION__, config_address_reg);
switch (config_address_reg & 0xFC)
{
case PCIIDR:
val = ((uint32_t) rinfo_biosemu->chipset << 16) + PCI_VENDOR_ID_ATI;
break;
case PCIBAR1:
val = (uint32_t) offset_port + 1;
break;
default:
val = pci_read_config_longword(rinfo_biosemu->handle, config_address_reg & 0xFC);
break;
}
//dbg("inl(0x%x) = 0x%x\r\n", port, val);
dbg("inl(0x%x) = 0x%x\r\n", port, val);
}
return val;
}
#ifdef DBG_X86EMU
#undef DBG_X86EMU
#define DBG_
#endif
void outb(uint8_t val, uint16_t port)
{
if ((port >= offset_port) && (port <= offset_port + 0xFF))
@@ -192,7 +185,7 @@ void outl(uint32_t val, uint16_t port)
}
else if (port == 0xCF8)
{
//dbg("outl(0x%x, 0x%x)\r\n", port, val);
dbg("outl(0x%x, 0x%x)\r\n", port, val);
config_address_reg = val;
}
else if ((port == 0xCFC) && ((config_address_reg & 0x80000000) !=0))
@@ -201,16 +194,12 @@ void outl(uint32_t val, uint16_t port)
offset_port = (uint16_t)val & 0xFFFC;
else
{
//dbg("outl(0x%x, 0x%x)\r\n", port, val);
dbg("outl(0x%x, 0x%x) to PCI config space\r\n", port, val);
pci_write_config_longword(rinfo_biosemu->handle, config_address_reg & 0xFC, val);
}
}
}
#ifdef DBG_
#define DBG_X86EMU
#endif
/* Interrupt multiplexer */
void do_int(int num)
@@ -364,14 +353,8 @@ static int setup_system_bios(void *base_addr)
* and all other locations by filling them with "hlt"
* TODO: implement hlt-handler for these
*/
// for(i=0; i<0x10000; base[i++]=0xF4);
for(i = 0; i < SIZE_EMU; base[i++] = 0xF4);
/* set bios date */
//strcpy(base + 0x0FFF5, "06/11/99");
/* set up eisa ident string */
//strcpy(base + 0x0FFD9, "PCI_ISA");
/* write system model id for IBM-AT */
//*((unsigned char *) (base + 0x0FFFE)) = 0xfc;
for(i = 0; i < SIZE_EMU + 4; base[i++] = 0xF4);
return(1);
}
@@ -536,7 +519,7 @@ void run_bios(struct radeonfb_info *rinfo)
struct pci_data *rom_data;
unsigned long rom_size=0;
unsigned long image_size=0;
void *biosmem = (void *) 0x01000000; /* when run_bios() is called, SDRAM is valid but not added to the system */
void *biosmem = (void *) 0x0100000; /* when run_bios() is called, SDRAM is valid but not added to the system */
unsigned long addr;
unsigned short initialcs;
unsigned short initialip;
@@ -551,38 +534,31 @@ void run_bios(struct radeonfb_info *rinfo)
rinfo_biosemu = rinfo;
config_address_reg = 0;
offset_port = 0x300;
#ifdef DIRECT_ACCESS
offset_io = (uint32_t) rinfo->io_base - (uint32_t) offset_port;
offset_mem = (uint32_t) rinfo->fb_base - 0xA0000;
#else
offset_io = rinfo->io_base_phys -(uint32_t) offset_port;
offset_mem = rinfo->fb_base_phys - 0xA0000;
#endif
rom_header = (struct rom_header *) 0;
do
{
rom_header = (struct rom_header *)((unsigned long)rom_header + image_size); // get next image
rom_data = (struct pci_data *)((unsigned long)rom_header + (unsigned long)BIOS_IN16((long)&rom_header->data));
image_size = (unsigned long)BIOS_IN16((long)&rom_data->ilen) * 512;
rom_header = (struct rom_header *) ((unsigned long) rom_header + image_size); // get next image
rom_data = (struct pci_data *) ((unsigned long)rom_header + (unsigned long) BIOS_IN16((long) &rom_header->data));
image_size = (unsigned long) BIOS_IN16((long) &rom_data->ilen) * 512;
} while ((BIOS_IN8((long) &rom_data->type) != 0) && (BIOS_IN8((long) &rom_data->indicator) != 0)); // make sure we got x86 version
if (BIOS_IN8((long) &rom_data->type) != 0)
{
dbg("%s: ROM data type = 0x%x\r\n", __FUNCTION__, BIOS_IN8((long) &rom_data->type));
return;
}
rom_size = (unsigned long) BIOS_IN8((long) &rom_header->size) * 512;
if (PCI_CLASS_DISPLAY_VGA == BIOS_IN16((long) &rom_data->class_hi))
{
//biosmem = driver_mem_alloc(SIZE_EMU);
biosmem = (char *) 0x100000;
if (biosmem == 0)
{
dbg("%s: could not allocate X86 BIOS memory\r\n", __FUNCTION__);
return;
}
memset((char *) biosmem, 0, SIZE_EMU);
setup_system_bios((char *) biosmem);
dbg("%s: Copying VGA ROM Image from %p to %p (0x%lx bytes)\r\n", __FUNCTION__, (long) rinfo->bios_seg + (long) rom_header,
dbg("%s: Copying VGA ROM Image from %p to %p (0x%lx bytes)\r\n",
__FUNCTION__, (long) rinfo->bios_seg + (long) rom_header,
biosmem + PCI_VGA_RAM_IMAGE_START, rom_size);
{
long bytes_align = (long) rom_header & 3;
@@ -590,30 +566,21 @@ void run_bios(struct radeonfb_info *rinfo)
ptr = (unsigned char *) biosmem;
i = (long) rom_header;
j = PCI_VGA_RAM_IMAGE_START;
if (bytes_align)
for(; i < 4 - bytes_align; ptr[j++] = BIOS_IN8(i++));
for(; i < (long) rom_header + rom_size; *((unsigned long *)&ptr[j]) = swpl(BIOS_IN32(i)), i += 4, j += 4);
for(; i < (long) rom_header + rom_size; i += 4, j += 4)
*((unsigned long *) &ptr[j]) = swpl(BIOS_IN32(i));
}
addr = PCI_VGA_RAM_IMAGE_START;
}
else
{
#ifdef USE_SDRAM
#if 0
if (os_magic)
{
biosmem = Mxalloc(SIZE_EMU, 3);
if (biosmem == 0)
return;
}
#endif
#else
biosmem = Mxalloc(SIZE_EMU, 0);
if (biosmem == 0)
return;
#endif /* USE_SDRAM */
setup_system_bios((char *)biosmem);
memset((char *)biosmem, 0, SIZE_EMU);
setup_system_bios((char *) biosmem);
memset((char *) biosmem, 0, SIZE_EMU);
dbg("%s: Copying non-VGA ROM Image from %p to %p (0x%lx bytes)\r\n", __FUNCTION__,
(long) rinfo->bios_seg + (long) rom_header,
biosmem + PCI_RAM_IMAGE_START,
@@ -622,11 +589,14 @@ void run_bios(struct radeonfb_info *rinfo)
for (i = (long) rom_header, j = PCI_RAM_IMAGE_START; i < (long) rom_header+rom_size; ptr[j++] = BIOS_IN8(i++));
addr = PCI_RAM_IMAGE_START;
}
initialcs = (addr & 0xF0000) >> 4;
initialip = (addr + 3) & 0xFFFF;
X86EMU_setMemBase((void *) biosmem, SIZE_EMU);
for (i = 0; i < 256; i++)
intFuncs[i] = do_int;
X86EMU_setupIntrFuncs(intFuncs);
{
char *date = "01/01/99";
@@ -648,13 +618,15 @@ void run_bios(struct radeonfb_info *rinfo)
X86_DX = 0x80;
X86_EIP = initialip;
X86_CS = initialcs;
/* Initialize stack and data segment */
X86_SS = initialcs;
X86_SP = 0xfffe;
X86_DS = 0x0040;
X86_ES = 0x0000;
/* We need a sane way to return from bios
/*
* 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.
*/
@@ -665,26 +637,16 @@ void run_bios(struct radeonfb_info *rinfo)
// pushw(0xb890); /* nop, mov ax,#0x13 */
pushw(X86_SS);
pushw(X86_SP + 2);
#ifdef DEBUG_X86EMU
#ifdef DBG_X86EMU
X86EMU_trace_on();
X86EMU_set_debug(DEBUG_DECODE_F | DEBUG_TRACE_F);
#endif
dbg("%s: X86EMU entering emulator\r\n", __FUNCTION__);
//*vblsem = 0;
X86EMU_exec();
//*vblsem = 1;
dbg("%s: X86EMU halted\r\n", __FUNCTION__);
// biosfn_set_video_mode(0x13); /* 320 x 200 x 256 colors */
#ifdef USE_SDRAM
#if 0
if (os_magic)
{
memset((char *)biosmem, 0, SIZE_EMU);
Mfree(biosmem);
}
#endif
#else
memset((char *) biosmem, 0, SIZE_EMU);
driver_mem_free(biosmem);
#endif /* USE_SDRAM */
}

View File

@@ -1,41 +1,41 @@
/****************************************************************************
*
* Realmode X86 Emulator Library
*
* Copyright (C) 1991-2004 SciTech Software, Inc.
* Copyright (C) David Mosberger-Tang
* Copyright (C) 1999 Egbert Eich
*
* ========================================================================
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of the authors not be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. The authors makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* ========================================================================
*
* Language: ANSI C
* Environment: Any
* Developer: Kendall Bennett
*
* Description: This file includes subroutines which are related to
* instruction decoding and accessess of immediate data via IP. etc.
*
****************************************************************************/
*
* Realmode X86 Emulator Library
*
* Copyright (C) 1991-2004 SciTech Software, Inc.
* Copyright (C) David Mosberger-Tang
* Copyright (C) 1999 Egbert Eich
*
* ========================================================================
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of the authors not be used
* in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. The authors makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* ========================================================================
*
* Language: ANSI C
* Environment: Any
* Developer: Kendall Bennett
*
* Description: This file includes subroutines which are related to
* instruction decoding and accessess of immediate data via IP. etc.
*
****************************************************************************/
#include "x86emui.h"
#include <stddef.h>
@@ -47,7 +47,7 @@
/****************************************************************************
REMARKS:
Handles any pending asychronous interrupts.
****************************************************************************/
****************************************************************************/
static void x86emu_intr_handle(void)
{
uint8_t intno;
@@ -57,7 +57,7 @@ static void x86emu_intr_handle(void)
if (_X86EMU_intrTab[intno]) {
(*_X86EMU_intrTab[intno])(intno);
} else {
push_word((uint16_t)M.x86.R_FLG);
push_word((uint16_t) M.x86.R_FLG);
CLEAR_FLAG(F_IF);
CLEAR_FLAG(F_TF);
push_word(M.x86.R_CS);
@@ -76,10 +76,10 @@ intrnum - Interrupt number to raise
REMARKS:
Raise the specified interrupt to be handled before the execution of the
next instruction.
****************************************************************************/
****************************************************************************/
void x86emu_intr_raise(uint8_t intrnum)
{
dbg("Rasing exception 0x%02x\r\n", intrnum);
dbg("%s: Rasing exception 0x%02x\r\n", __FUNCTION__, intrnum);
x86emu_dump_regs();
M.x86.intno = intrnum;
M.x86.intr |= INTR_SYNCH;
@@ -90,7 +90,7 @@ REMARKS:
Main execution loop for the emulator. We return from here when the system
halts, which is normally caused by a stack fault when we return from the
original real mode call.
****************************************************************************/
****************************************************************************/
void X86EMU_exec(void)
{
uint8_t op1;
@@ -98,22 +98,27 @@ void X86EMU_exec(void)
M.x86.intr = 0;
DB(x86emu_end_instr();)
for (;;) {
DB( if (CHECK_IP_FETCH())
x86emu_check_ip_access();)
for (;;)
{
if (CHECK_IP_FETCH())
x86emu_check_ip_access();
/* If debugging, save the IP and CS values. */
SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP);
INC_DECODED_INST_LEN(1);
if (M.x86.intr) {
if (M.x86.intr & INTR_HALTED) {
DB( if (M.x86.R_SP != 0) {
DPRINT("halted\r\n");
if (M.x86.intr)
{
if (M.x86.intr & INTR_HALTED)
{
if (M.x86.R_SP != 0)
{
dbg("%s: halted\r\n", __FUNCTION__);
X86EMU_trace_regs();
}
else {
else
{
if (M.x86.debug)
DPRINT("Service completed successfully\r\n");
})
dbg("%s: Service completed successfully\r\n", __FUNCTION__);
}
return;
}
if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) ||
@@ -133,7 +138,7 @@ DB( if (M.x86.R_SP != 0) {
/****************************************************************************
REMARKS:
Halts the system by setting the halted system flag.
****************************************************************************/
****************************************************************************/
void X86EMU_halt_sys(void)
{
M.x86.intr |= INTR_HALTED;
@@ -150,7 +155,7 @@ Raise the specified interrupt to be handled before the execution of the
next instruction.
NOTE: Do not inline this function, as (*sys_rdb) is already inline!
****************************************************************************/
****************************************************************************/
void fetch_decode_modrm(
int *mod,
int *regh,
@@ -158,7 +163,7 @@ void fetch_decode_modrm(
{
int fetched;
DB( if (CHECK_IP_FETCH())
DB( if (CHECK_IP_FETCH())
x86emu_check_ip_access();)
fetched = (*sys_rdb)(((uint32_t)M.x86.R_CS << 4) + (M.x86.R_IP++));
INC_DECODED_INST_LEN(1);
@@ -176,12 +181,12 @@ This function returns the immediate byte from the instruction queue, and
moves the instruction pointer to the next value.
NOTE: Do not inline this function, as (*sys_rdb) is already inline!
****************************************************************************/
****************************************************************************/
uint8_t fetch_byte_imm(void)
{
uint8_t fetched;
DB( if (CHECK_IP_FETCH())
DB( if (CHECK_IP_FETCH())
x86emu_check_ip_access();)
fetched = (*sys_rdb)(((uint32_t)M.x86.R_CS << 4) + (M.x86.R_IP++));
INC_DECODED_INST_LEN(1);
@@ -197,12 +202,12 @@ This function returns the immediate byte from the instruction queue, and
moves the instruction pointer to the next value.
NOTE: Do not inline this function, as (*sys_rdw) is already inline!
****************************************************************************/
****************************************************************************/
uint16_t fetch_word_imm(void)
{
uint16_t fetched;
DB( if (CHECK_IP_FETCH())
DB( if (CHECK_IP_FETCH())
x86emu_check_ip_access();)
fetched = (*sys_rdw)(((uint32_t)M.x86.R_CS << 4) + (M.x86.R_IP));
M.x86.R_IP += 2;
@@ -219,12 +224,12 @@ This function returns the immediate byte from the instruction queue, and
moves the instruction pointer to the next value.
NOTE: Do not inline this function, as (*sys_rdw) is already inline!
****************************************************************************/
****************************************************************************/
uint32_t fetch_long_imm(void)
{
uint32_t fetched;
DB( if (CHECK_IP_FETCH())
DB( if (CHECK_IP_FETCH())
x86emu_check_ip_access();)
fetched = (*sys_rdl)(((uint32_t)M.x86.R_CS << 4) + (M.x86.R_IP));
M.x86.R_IP += 4;
@@ -247,20 +252,20 @@ decodings of addressing modes would have to set/clear a bit describing
whether the access is relative to DS or SS. That is the function of the
cpu-state-varible M.x86.mode. There are several potential states:
repe prefix seen (handled elsewhere)
repne prefix seen (ditto)
repe prefix seen (handled elsewhere)
repne prefix seen (ditto)
cs segment override
ds segment override
es segment override
fs segment override
gs segment override
ss segment override
cs segment override
ds segment override
es segment override
fs segment override
gs segment override
ss segment override
ds/ss select (in absense of override)
ds/ss select (in absense of override)
Each of the above 7 items are handled with a bit in the mode field.
****************************************************************************/
****************************************************************************/
_INLINE uint32_t get_data_segment(void)
{
#define GET_SEGMENT(segment)
@@ -303,7 +308,7 @@ RETURNS:
Byte value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
****************************************************************************/
uint8_t fetch_data_byte(
unsigned int offset)
{
@@ -322,7 +327,7 @@ RETURNS:
Word value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
****************************************************************************/
uint16_t fetch_data_word(
unsigned int offset)
{
@@ -341,7 +346,7 @@ RETURNS:
Long value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
****************************************************************************/
uint32_t fetch_data_long(
unsigned int offset)
{
@@ -361,7 +366,7 @@ RETURNS:
Byte value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
****************************************************************************/
uint8_t fetch_data_byte_abs(
unsigned int segment,
unsigned int offset)
@@ -382,7 +387,7 @@ RETURNS:
Word value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
****************************************************************************/
uint16_t fetch_data_word_abs(
unsigned int segment,
unsigned int offset)
@@ -403,7 +408,7 @@ RETURNS:
Long value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
****************************************************************************/
uint32_t fetch_data_long_abs(
unsigned int segment,
unsigned int offset)
@@ -425,7 +430,7 @@ Writes a word value to an segmented memory location. The segment used is
the current 'default' segment, which may have been overridden.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
****************************************************************************/
void store_data_byte(
unsigned int offset,
uint8_t val)
@@ -447,7 +452,7 @@ Writes a word value to an segmented memory location. The segment used is
the current 'default' segment, which may have been overridden.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
****************************************************************************/
void store_data_word(
unsigned int offset,
uint16_t val)
@@ -469,7 +474,7 @@ Writes a long value to an segmented memory location. The segment used is
the current 'default' segment, which may have been overridden.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
****************************************************************************/
void store_data_long(
unsigned int offset,
uint32_t val)
@@ -491,7 +496,7 @@ REMARKS:
Writes a byte value to an absolute memory location.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
****************************************************************************/
void store_data_byte_abs(
unsigned int segment,
unsigned int offset,
@@ -514,7 +519,7 @@ REMARKS:
Writes a word value to an absolute memory location.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
****************************************************************************/
void store_data_word_abs(
unsigned int segment,
unsigned int offset,
@@ -537,7 +542,7 @@ REMARKS:
Writes a long value to an absolute memory location.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
****************************************************************************/
void store_data_long_abs(
unsigned int segment,
unsigned int offset,
@@ -560,7 +565,7 @@ Pointer to the appropriate register
REMARKS:
Return a pointer to the register given by the R/RM field of the
modrm byte, for byte operands. Also enables the decoding of instructions.
****************************************************************************/
****************************************************************************/
uint8_t* decode_rm_byte_register(
int reg)
{
@@ -604,7 +609,7 @@ Pointer to the appropriate register
REMARKS:
Return a pointer to the register given by the R/RM field of the
modrm byte, for word operands. Also enables the decoding of instructions.
****************************************************************************/
****************************************************************************/
uint16_t* decode_rm_word_register(
int reg)
{
@@ -648,7 +653,7 @@ Pointer to the appropriate register
REMARKS:
Return a pointer to the register given by the R/RM field of the
modrm byte, for dword operands. Also enables the decoding of instructions.
****************************************************************************/
****************************************************************************/
uint32_t* decode_rm_long_register(
int reg)
{
@@ -693,7 +698,7 @@ REMARKS:
Return a pointer to the register given by the R/RM field of the
modrm byte, for word operands, modified from above for the weirdo
special case of segreg operands. Also enables the decoding of instructions.
****************************************************************************/
****************************************************************************/
uint16_t* decode_rm_seg_register(
int reg)
{
@@ -736,7 +741,7 @@ Value of scale * index
REMARKS:
Decodes scale/index of SIB byte and returns relevant offset part of
effective address.
****************************************************************************/
****************************************************************************/
unsigned decode_sib_si(
int scale,
int index)
@@ -786,7 +791,7 @@ Offset in memory for the address decoding
REMARKS:
Decodes SIB addressing byte and returns calculated effective address.
****************************************************************************/
****************************************************************************/
unsigned decode_sib_address(
int mod)
{
@@ -868,14 +873,14 @@ Return the offset given by mod=00 addressing. Also enables the
decoding of instructions.
NOTE: The code which specifies the corresponding segment (ds vs ss)
below in the case of [BP+..]. The assumption here is that at the
point that this subroutine is called, the bit corresponding to
SYSMODE_SEG_DS_SS will be zero. After every instruction
except the segment override instructions, this bit (as well
as any bits indicating segment overrides) will be clear. So
if a SS access is needed, set this bit. Otherwise, DS access
occurs (unless any of the segment override bits are set).
****************************************************************************/
below in the case of [BP+..]. The assumption here is that at the
point that this subroutine is called, the bit corresponding to
SYSMODE_SEG_DS_SS will be zero. After every instruction
except the segment override instructions, this bit (as well
as any bits indicating segment overrides) will be clear. So
if a SS access is needed, set this bit. Otherwise, DS access
occurs (unless any of the segment override bits are set).
****************************************************************************/
unsigned decode_rm00_address(
int rm)
{
@@ -955,7 +960,7 @@ Offset in memory for the address decoding
REMARKS:
Return the offset given by mod=01 addressing. Also enables the
decoding of instructions.
****************************************************************************/
****************************************************************************/
unsigned decode_rm01_address(
int rm)
{
@@ -1044,7 +1049,7 @@ Offset in memory for the address decoding
REMARKS:
Return the offset given by mod=10 addressing. Also enables the
decoding of instructions.
****************************************************************************/
****************************************************************************/
unsigned decode_rm10_address(
int rm)
{
@@ -1136,7 +1141,7 @@ the decode_rmXX_address functions
REMARKS:
Return the offset given by "mod" addressing.
****************************************************************************/
****************************************************************************/
unsigned decode_rmXX_address(int mod, int rm)
{

View File

@@ -79,7 +79,7 @@ extern unsigned decode_rmXX_address(int mod, int rm);
/* constant arrays to do several instructions in just one function */
#ifdef DEBUG
#ifdef DBG_X86EMU
static char *x86emu_GenOpName[8] = {
"ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"};
#endif
@@ -160,7 +160,7 @@ static uint32_t (*opcD1_long_operation[])(uint32_t s, uint8_t d) =
sar_long,
};
#ifdef DEBUG
#ifdef DBG_X86EMU
static char *opF6_names[8] =
{ "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" };
@@ -1284,7 +1284,7 @@ void x86emuOp_opc80_byte_RM_IMM(uint8_t X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@@ -1360,7 +1360,7 @@ void x86emuOp_opc81_word_RM_IMM(uint8_t X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@@ -1470,7 +1470,7 @@ void x86emuOp_opc82_byte_RM_IMM(uint8_t X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@@ -1544,7 +1544,7 @@ void x86emuOp_opc83_word_RM_IMM(uint8_t X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@@ -3070,7 +3070,7 @@ void x86emuOp_opcC0_byte_RM_MEM(uint8_t X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@@ -3145,7 +3145,7 @@ void x86emuOp_opcC1_word_RM_MEM(uint8_t X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@@ -3622,7 +3622,7 @@ void x86emuOp_opcD0_byte_RM_1(uint8_t X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@@ -3693,7 +3693,7 @@ void x86emuOp_opcD1_word_RM_1(uint8_t X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@@ -3795,7 +3795,7 @@ void x86emuOp_opcD2_byte_RM_CL(uint8_t X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@@ -3868,7 +3868,7 @@ void x86emuOp_opcD3_word_RM_CL(uint8_t X86EMU_UNUSED(op1))
*/
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@@ -4852,7 +4852,7 @@ void x86emuOp_opcFE_byte_RM(uint8_t X86EMU_UNUSED(op1))
/* Yet another special case instruction. */
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings
@@ -4916,7 +4916,7 @@ void x86emuOp_opcFF_word_RM(uint8_t X86EMU_UNUSED(op1))
/* Yet another special case instruction. */
START_OF_INSTR();
FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
#ifdef DBG_X86EMU
if (DEBUG_DECODE()) {
/* XXX DECODE_PRINTF may be changed to something more
general, so that it is important to leave the strings

View File

@@ -2,6 +2,7 @@
#include "pci.h"
#include "x86emu.h"
#include "x86pcibios.h"
#include "x86debug.h"
extern unsigned short offset_port;
@@ -12,9 +13,7 @@ int x86_pcibios_emulator()
switch (X86_AX) {
case PCI_BIOS_PRESENT:
#ifdef DEBUG_X86EMU_PCI
DPRINT("PCI_BIOS_PRESENT\r\n");
#endif
dbg("%s: PCI_BIOS_PRESENT\r\n", __FUNCTION__);
X86_AH = 0x00; /* no config space/special cycle support */
X86_AL = 0x01; /* config mechanism 1 */
X86_EDX = 'P' | 'C' << 8 | 'I' << 16 | ' ' << 24;
@@ -23,19 +22,16 @@ int x86_pcibios_emulator()
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
break;
case FIND_PCI_DEVICE:
/* FixME: support SI != 0 */
// vendor, device
#ifdef DEBUG_X86EMU_PCI
DPRINTVALHEX("FIND_PCI_DEVICE vendor ", X86_DX);
DPRINTVALHEX(" device ", X86_CX);
#endif
dev = pci_find_device((unsigned long) X86_DX, ((unsigned long)X86_CX), 0);
dbg("%s: FIND_PCI_DEVICE vendor = %04x, device = %04x\r\n", __FUNCTION__, X86_DX, X86_CX);
dev = pci_find_device((unsigned long) X86_DX, ((unsigned long) X86_CX), 0);
if (dev != 0) {
#ifdef DEBUG_X86EMU_PCI
DPRINT(" ... OK\r\n");
#endif
if (dev != 0)
{
dbg("%s: ... OK\r\n", __FUNCTION__);
X86_BH = PCI_BUS_FROM_HANDLE(dev);
//X86_BH = (char)(dev >> 16) / PCI_MAX_FUNCTION); // dev->bus->secondary;
X86_BL = PCI_DEVICE_FROM_HANDLE(dev) << 3 | PCI_FUNCTION_FROM_HANDLE(dev);
@@ -44,196 +40,116 @@ int x86_pcibios_emulator()
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
} else {
#ifdef DEBUG_X86EMU_PCI
DPRINT(" ... error\r\n");
#endif
dbg("%s: ... error\r\n", __FUNCTION__);
X86_AH = DEVICE_NOT_FOUND;
X86_EFLAGS |= FB_CF; /* set carry flag */
ret = 0;
}
break;
case FIND_PCI_CLASS_CODE:
/* FixME: support SI != 0 */
#ifdef DEBUG_X86EMU_PCI
DPRINTVALHEX("FIND_PCI_CLASS_CODE ", X86_ECX);
#endif
dbg("%s: FIND_PCI_CLASS_CODE %x\r\n", __FUNCTION__, X86_ECX);
dev = pci_find_classcode(X86_ECX, 0);
if (dev != 0) {
#ifdef DEBUG_X86EMU_PCI
DPRINT(" ... OK\r\n");
#endif
dbg("%s: ... OK\r\n", __FUNCTION__);
X86_BH = PCI_BUS_FROM_HANDLE(dev);
X86_BL = PCI_DEVICE_FROM_HANDLE(dev) << 3 | PCI_FUNCTION_FROM_HANDLE(dev);
X86_AH = SUCCESSFUL;
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
} else {
#ifdef DEBUG_X86EMU_PCI
DPRINT(" ... error\r\n");
#endif
}
else
{
dbg("%s: ... error\r\n", __FUNCTION__);
X86_AH = DEVICE_NOT_FOUND;
X86_EFLAGS |= FB_CF; /* set carry flag */
ret = 0;
}
break;
case READ_CONFIG_BYTE:
// bus, devfn
#ifdef DEBUG_X86EMU_PCI
DPRINTVAL("READ_CONFIG_BYTE bus ", X86_BH);
DPRINTVAL(" devfn ", X86_BL);
DPRINTVALHEX(" reg ", X86_DI);
#endif
dbg("%s: READ_CONFIG_BYTE bus = %x, devfn = %x, reg = %x\r\n", __FUNCTION__, X86_BH, X86_BL, X86_DI);
X86_CL = pci_read_config_byte(dev, X86_DI);
#ifdef DEBUG_X86EMU_PCI
DPRINTVALHEX(" value ", X86_CL);
DPRINT("\r\n");
#endif
dbg("%s: value = %x\r\n", __FUNCTION__, X86_CL);
X86_AH = SUCCESSFUL;
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
break;
case READ_CONFIG_WORD:
// bus, devfn
#ifdef DEBUG_X86EMU_PCI
DPRINTVAL("READ_CONFIG_WORD bus ", X86_BH);
DPRINTVAL(" devfn ", X86_BL);
DPRINTVALHEX(" reg ", X86_DI);
#endif
dbg("%s: READ_CONFIG_WORD bus = %x, devfn = %x, reg = %x\r\n", __FUNCTION__, X86_BH, X86_BL, X86_DI);
if(X86_DI == PCIBAR1)
X86_CX = offset_port + 1;
else
X86_CX = pci_read_config_word(dev, X86_DI);
#ifdef DEBUG_X86EMU_PCI
DPRINTVALHEX(" value ", X86_CX);
DPRINT("\r\n");
#endif
dbg("%s: value = %x\r\n", __FUNCTION__, X86_CX);
X86_AH = SUCCESSFUL;
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
break;
case READ_CONFIG_DWORD:
// bus, devfn
#ifdef DEBUG_X86EMU_PCI
DPRINTVAL("READ_CONFIG_DWORD bus ", X86_BH);
DPRINTVAL(" devfn ", X86_BL);
DPRINTVALHEX(" reg ", X86_DI);
#endif
if(X86_DI == PCIBAR1)
X86_CX = (unsigned long)offset_port+1;
dbg("%s: READ_CONFIG_DWORD bus = %x, devfn = %x, reg = %x\r\n", __FUNCTION__, X86_BH, X86_BL, X86_DI);
if (X86_DI == PCIBAR1)
X86_CX = (unsigned long) offset_port + 1;
else
X86_ECX = pci_read_config_longword(dev, X86_DI);
#ifdef DEBUG_X86EMU_PCI
DPRINTVALHEX(" value ", X86_ECX);
DPRINT("\r\n");
#endif
dbg("%s: value = %x\r\n", __FUNCTION__, X86_ECX);
X86_AH = SUCCESSFUL;
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
break;
case WRITE_CONFIG_BYTE:
// bus, devfn
#ifdef DEBUG_X86EMU_PCI
DPRINTVAL("READ_CONFIG_BYTE bus ", X86_BH);
DPRINTVAL(" devfn ", X86_BL);
DPRINTVALHEX(" reg ", X86_DI);
DPRINTVALHEX(" value ", X86_CL);
#endif
if ((ret = pci_write_config_byte(dev, X86_DI, X86_CL)) == 0)
{
#ifdef DEBUG_X86EMU_PCI
DPRINT(" ... OK\r\n");
#endif
dbg("%s: READ_CONFIG_BYTE bus = %x, devfn = %x, reg = %x\r\n", __FUNCTION__, X86_BH, X86_BL, X86_CL);
pci_write_config_byte(dev, X86_DI, X86_CL);
X86_AH = SUCCESSFUL;
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
} else {
#ifdef DEBUG_X86EMU_PCI
DPRINTVAL(" ... error ", ret);
DPRINT("\r\n");
#endif
X86_AH = DEVICE_NOT_FOUND;
X86_EFLAGS |= FB_CF; /* set carry flag */
ret = 0;
}
break;
case WRITE_CONFIG_WORD:
// bus, devfn
#ifdef DEBUG_X86EMU_PCI
DPRINTVAL("WRITE_CONFIG_WORD bus ", X86_BH);
DPRINTVAL(" devfn ", X86_BL);
DPRINTVALHEX(" reg ", X86_DI);
DPRINTVALHEX(" value ", X86_CX);
#endif
if(X86_DI == PCIBAR1) {
offset_port = X86_CX;
#ifdef DEBUG_X86EMU_PCI
DPRINT(" ... OK\r\n");
#endif
X86_AH = SUCCESSFUL;
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
break;
}
if ((ret = pci_write_config_word(dev, X86_DI, X86_CX)) == 0)
dbg("%s: WRITE_CONFIG_WORD bus = %x, devfn = %x, reg = %x, value = %x\r\n", X86_BH, X86_BL, X86_DI, X86_CX);
if (X86_DI == PCIBAR1)
{
#ifdef DEBUG_X86EMU_PCI
DPRINT(" ... OK\r\n");
#endif
offset_port = X86_CX;
X86_AH = SUCCESSFUL;
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
} else {
#ifdef DEBUG_X86EMU_PCI
DPRINTVAL(" ... error ", ret);
DPRINT("\r\n");
#endif
X86_AH = DEVICE_NOT_FOUND;
X86_EFLAGS |= FB_CF; /* set carry flag */
ret = 0;
}
break;
}
pci_write_config_word(dev, X86_DI, X86_CX);
X86_AH = SUCCESSFUL;
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
break;
case WRITE_CONFIG_DWORD:
// bus, devfn
#ifdef DEBUG_X86EMU_PCI
DPRINTVAL("WRITE_CONFIG_DWORD bus ", X86_BH);
DPRINTVAL(" devfn ", X86_BL);
DPRINTVALHEX(" reg ", X86_DI);
DPRINTVALHEX(" value ", X86_ECX);
#endif
if(X86_DI == PCIBAR1) {
offset_port = (unsigned short)X86_ECX & 0xFFFC;
#ifdef DEBUG_X86EMU_PCI
DPRINT(" ... OK\r\n");
#endif
dbg("%s: WRITE_CONFIG_DWORD bus = %x, devfn = %x, value = %x\r\n", __FUNCTION__,
X86_BH, X86_BL, X86_DI, X86_ECX);
if (X86_DI == PCIBAR1)
{
offset_port = (unsigned short) X86_ECX & 0xFFFC;
X86_AH = SUCCESSFUL;
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
break;
}
if ((ret = pci_write_config_longword(dev, X86_DI, X86_ECX)) == 0)
{
#ifdef DEBUG_X86EMU_PCI
DPRINT(" ... OK\r\n");
#endif
pci_write_config_longword(dev, X86_DI, X86_ECX);
X86_AH = SUCCESSFUL;
X86_EFLAGS &= ~FB_CF; /* clear carry flag */
ret = 1;
}
else
{
#ifdef DEBUG_X86EMU_PCI
DPRINTVAL(" ... error ", ret);
DPRINT("\r\n");
#endif
X86_AH = DEVICE_NOT_FOUND;
X86_EFLAGS |= FB_CF; /* set carry flag */
ret = 0;
}
break;
default:
#ifdef DEBUG_X86EMU_PCI
DPRINT("PCI_BIOS FUNC_NOT_SUPPORTED\r\n");
#endif
dbg("%s: PCI_BIOS FUNC_NOT_SUPPORTED\r\n", __FUNCTION__);
X86_AH = FUNC_NOT_SUPPORTED;
X86_EFLAGS |= FB_CF;
break;