diff --git a/Makefile b/Makefile index 66c4818..feb1130 100644 --- a/Makefile +++ b/Makefile @@ -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 $$@ diff --git a/bas.lk.in b/bas.lk.in index 1653d06..8b5482f 100644 --- a/bas.lk.in +++ b/bas.lk.in @@ -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) diff --git a/dma/dma.c b/dma/dma.c index 58416d1..ccfad51 100644 --- a/dma/dma.c +++ b/dma/dma.c @@ -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(); } } diff --git a/include/fec.h b/include/fec.h index ba4d2d7..9d0c4bc 100644 --- a/include/fec.h +++ b/include/fec.h @@ -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); diff --git a/include/firebee.h b/include/firebee.h index 5054766..a0c3509 100644 --- a/include/firebee.h +++ b/include/firebee.h @@ -43,7 +43,7 @@ #endif /* COMPILE_RAM */ -#define DRIVER_MEM_BUFFER_SIZE 0x80000 +#define DRIVER_MEM_BUFFER_SIZE 0x100000 #define EMUTOS_BASE_ADDRESS 0xe0600000 diff --git a/include/m5484l.h b/include/m5484l.h index 1292a5a..4876f5e 100644 --- a/include/m5484l.h +++ b/include/m5484l.h @@ -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 diff --git a/include/net.h b/include/net.h index 2631bb4..e6ce6ec 100644 --- a/include/net.h +++ b/include/net.h @@ -1,32 +1,32 @@ -/* - * File: net.h - * Purpose: Network definitions and prototypes for BaS. - * - * Notes: - */ - -#ifndef _NET_H -#define _NET_H - -/********************************************************************/ - -/* - * Include information and prototypes for all protocols - */ -#include "eth.h" -#include "nbuf.h" -#include "nif.h" -#include "ip.h" -#include "icmp.h" -#include "arp.h" -#include "udp.h" -#include "tftp.h" - -/********************************************************************/ - -extern int net_init(void); - -/********************************************************************/ - -#endif /* _NET_H */ - +/* + * File: net.h + * Purpose: Network definitions and prototypes for BaS. + * + * Notes: + */ + +#ifndef _NET_H +#define _NET_H + + +/* + * Include information and prototypes for all protocols + */ +#include "eth.h" +#include "nbuf.h" +#include "nif.h" +#include "ip.h" +#include "icmp.h" +#include "arp.h" +#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 */ + diff --git a/include/x86debug.h b/include/x86debug.h index 31d34cc..84698c3 100644 --- a/include/x86debug.h +++ b/include/x86debug.h @@ -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) diff --git a/include/x86regs.h b/include/x86regs.h index 5d4d8cc..c3507b3 100644 --- a/include/x86regs.h +++ b/include/x86regs.h @@ -39,6 +39,7 @@ #ifndef __X86EMU_REGS_H #define __X86EMU_REGS_H +#include "x86debug.h" /*---------------------- Macros and type definitions ----------------------*/ diff --git a/net/am79c874.c b/net/am79c874.c index 252b636..263a1a1 100644 --- a/net/am79c874.c +++ b/net/am79c874.c @@ -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 */ diff --git a/net/arp.c b/net/arp.c index 0b3caf0..ca0a450 100644 --- a/net/arp.c +++ b/net/arp.c @@ -6,9 +6,18 @@ */ #include "net.h" +#include "net_timer.h" +#include "bas_printf.h" #include #include +#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,13 +310,20 @@ 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; + } } } diff --git a/net/fec.c b/net/fec.c index 1c69b7e..e129baa 100644 --- a/net/fec.c +++ b/net/fec.c @@ -18,6 +18,7 @@ #include "bas_printf.h" #include "util.h" #include "am79c874.h" +#include "bcm5222.h" #include #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 */ } diff --git a/net/ip.c b/net/ip.c index 811b3e9..38f2854 100644 --- a/net/ip.c +++ b/net/ip.c @@ -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); diff --git a/net/nbuf.c b/net/nbuf.c index 4e1725c..dac1692 100644 --- a/net/nbuf.c +++ b/net/nbuf.c @@ -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 */ diff --git a/net/net_timer.c b/net/net_timer.c index 3bde409..3c40ec9 100644 --- a/net/net_timer.c +++ b/net/net_timer.c @@ -8,9 +8,18 @@ #include "net_timer.h" #include #include +#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 diff --git a/net/nif.c b/net/nif.c index 545daa7..790e16b 100644 --- a/net/nif.c +++ b/net/nif.c @@ -1,117 +1,133 @@ -/* - * File: nif.c - * Purpose: Network InterFace routines - * - * Notes: - * - * Modifications: - * - */ -#include "net.h" -#include "bas_types.h" -#include -#include - -int nif_protocol_exist(NIF *nif, uint16_t protocol) -{ - /* - * This function searches the list of supported protocols - * on the particular NIF and if a protocol handler exists, - * true is returned. This function is useful for network cards - * that needn't read in the entire frame but can discard frames - * arbitrarily. - */ - int index; - - for (index = 0; index < nif->num_protocol; ++index) - { - if (nif->protocol[index].protocol == protocol) - { - return true; - } - } - return false; -} - -void nif_protocol_handler(NIF *nif, uint16_t protocol, NBUF *pNbuf) -{ - /* - * This function searches the list of supported protocols - * on the particular NIF and if a protocol handler exists, - * the protocol handler is invoked. This routine called by - * network device driver after receiving a frame. - */ - int index; - - for (index = 0; index < nif->num_protocol; ++index) - { - if (nif->protocol[index].protocol == protocol) - nif->protocol[index].handler(nif,pNbuf); - } -} - -void *nif_get_protocol_info(NIF *nif, uint16_t protocol) -{ - /* - * This function searches the list of supported protocols - * on the particular NIF and returns a pointer to the - * config info for 'protocol', otherwise NULL is returned. - */ - int index; - - for (index = 0; index < nif->num_protocol; ++index) - { - if (nif->protocol[index].protocol == protocol) - return (void *)nif->protocol[index].info; - } - return (void *)0; -} - -int nif_bind_protocol(NIF *nif, uint16_t protocol, void (*handler)(NIF *,NBUF *), - void *info) -{ - /* - * This function registers 'protocol' as a supported - * protocol in 'nif'. - */ - if (nif->num_protocol < (MAX_SUP_PROTO - 1)) - { - nif->protocol[nif->num_protocol].protocol = protocol; - nif->protocol[nif->num_protocol].handler = (void(*)(NIF*,NBUF*))handler; - nif->protocol[nif->num_protocol].info = info; - ++nif->num_protocol; - return true; - } - return false; -} - -NIF *nif_init (NIF *nif) -{ - int i; - - for (i = 0; i < ETH_ADDR_LEN; ++i) - { - nif->hwa[i] = 0; - nif->broadcast[i] = 0xFF; - } - - for (i = 0; i < MAX_SUP_PROTO; ++i) - { - nif->protocol[i].protocol = 0; - nif->protocol[i].handler = 0; - nif->protocol[i].info = 0; - } - nif->num_protocol = 0; - - nif->mtu = 0; - nif->ch = 0; - nif->send = 0; - - nif->f_rx = 0; - nif->f_tx = 0; - nif->f_rx_err = 0; - nif->f_tx_err = 0; - nif->f_err = 0; - - return nif; -} +/* + * File: nif.c + * Purpose: Network InterFace routines + * + * Notes: + * + * Modifications: + * + */ +#include "net.h" +#include "bas_types.h" +#include "bas_printf.h" + +#include +#include + +#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) +{ + /* + * This function searches the list of supported protocols + * on the particular NIF and if a protocol handler exists, + * true is returned. This function is useful for network cards + * that needn't read in the entire frame but can discard frames + * arbitrarily. + */ + int index; + + for (index = 0; index < nif->num_protocol; ++index) + { + if (nif->protocol[index].protocol == protocol) + { + return true; + } + } + return false; +} + +void nif_protocol_handler(NIF *nif, uint16_t protocol, NBUF *pNbuf) +{ + /* + * This function searches the list of supported protocols + * on the particular NIF and if a protocol handler exists, + * the protocol handler is invoked. This routine called by + * network device driver after receiving a frame. + */ + int index; + + 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) +{ + /* + * This function searches the list of supported protocols + * on the particular NIF and returns a pointer to the + * config info for 'protocol', otherwise NULL is returned. + */ + int index; + + for (index = 0; index < nif->num_protocol; ++index) + { + if (nif->protocol[index].protocol == protocol) + return (void *)nif->protocol[index].info; + } + return (void *)0; +} + +int nif_bind_protocol(NIF *nif, uint16_t protocol, void (*handler)(NIF *,NBUF *), + void *info) +{ + /* + * This function registers 'protocol' as a supported + * protocol in 'nif'. + */ + if (nif->num_protocol < (MAX_SUP_PROTO - 1)) + { + nif->protocol[nif->num_protocol].protocol = protocol; + nif->protocol[nif->num_protocol].handler = (void(*)(NIF*,NBUF*))handler; + nif->protocol[nif->num_protocol].info = info; + ++nif->num_protocol; + + return true; + } + return false; +} + +NIF *nif_init (NIF *nif) +{ + int i; + + for (i = 0; i < ETH_ADDR_LEN; ++i) + { + nif->hwa[i] = 0; + nif->broadcast[i] = 0xFF; + } + + for (i = 0; i < MAX_SUP_PROTO; ++i) + { + nif->protocol[i].protocol = 0; + nif->protocol[i].handler = 0; + nif->protocol[i].info = 0; + } + nif->num_protocol = 0; + + nif->mtu = 0; + nif->ch = 0; + nif->send = 0; + + nif->f_rx = 0; + nif->f_tx = 0; + nif->f_rx_err = 0; + nif->f_tx_err = 0; + nif->f_err = 0; + + return nif; +} diff --git a/net/udp.c b/net/udp.c index e7c0b9b..1900ccc 100644 --- a/net/udp.c +++ b/net/udp.c @@ -8,6 +8,7 @@ * */ #include "bas_types.h" +#include "bas_printf.h" #include "net.h" #include @@ -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); } diff --git a/pci/pci.c b/pci/pci.c index 4a75b4c..fc93095 100644 --- a/pci/pci.c +++ b/pci/pci.c @@ -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) diff --git a/radeon/radeon_base.c b/radeon/radeon_base.c index 812a425..be1f6e6 100644 --- a/radeon/radeon_base.c +++ b/radeon/radeon_base.c @@ -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__); diff --git a/sys/BaS.c b/sys/BaS.c index 6a1c8a1..b8588d7 100644 --- a/sys/BaS.c +++ b/sys/BaS.c @@ -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: "); diff --git a/sys/driver_mem.c b/sys/driver_mem.c index faabc3b..a52a8af 100644 --- a/sys/driver_mem.c +++ b/sys/driver_mem.c @@ -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]; diff --git a/sys/exceptions.S b/sys/exceptions.S index 3a206d9..b962075 100644 --- a/sys/exceptions.S +++ b/sys/exceptions.S @@ -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) diff --git a/video/fbmodedb.c b/video/fbmodedb.c index 344b270..862a0a7 100644 --- a/video/fbmodedb.c +++ b/video/fbmodedb.c @@ -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 */ { diff --git a/video/video.c b/video/video.c index 91d1097..20b6ae4 100644 --- a/video/video.c +++ b/video/video.c @@ -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) diff --git a/x86emu/x86biosemu.c b/x86emu/x86biosemu.c index e35e735..19d633f 100644 --- a/x86emu/x86biosemu.c +++ b/x86emu/x86biosemu.c @@ -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; + 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 */ } diff --git a/x86emu/x86decode.c b/x86emu/x86decode.c index 34d1e3d..6dd7edb 100644 --- a/x86emu/x86decode.c +++ b/x86emu/x86decode.c @@ -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 @@ -47,26 +47,26 @@ /**************************************************************************** REMARKS: Handles any pending asychronous interrupts. -****************************************************************************/ + ****************************************************************************/ static void x86emu_intr_handle(void) { - uint8_t intno; + uint8_t intno; - if (M.x86.intr & INTR_SYNCH) { - intno = M.x86.intno; - if (_X86EMU_intrTab[intno]) { - (*_X86EMU_intrTab[intno])(intno); - } else { - push_word((uint16_t)M.x86.R_FLG); - CLEAR_FLAG(F_IF); - CLEAR_FLAG(F_TF); - push_word(M.x86.R_CS); - M.x86.R_CS = mem_access_word(intno * 4 + 2); - push_word(M.x86.R_IP); - M.x86.R_IP = mem_access_word(intno * 4); - M.x86.intr = 0; - } - } + if (M.x86.intr & INTR_SYNCH) { + intno = M.x86.intno; + if (_X86EMU_intrTab[intno]) { + (*_X86EMU_intrTab[intno])(intno); + } else { + push_word((uint16_t) M.x86.R_FLG); + CLEAR_FLAG(F_IF); + CLEAR_FLAG(F_TF); + push_word(M.x86.R_CS); + M.x86.R_CS = mem_access_word(intno * 4 + 2); + push_word(M.x86.R_IP); + M.x86.R_IP = mem_access_word(intno * 4); + M.x86.intr = 0; + } + } } /**************************************************************************** @@ -76,13 +76,13 @@ 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); - x86emu_dump_regs(); - M.x86.intno = intrnum; - M.x86.intr |= INTR_SYNCH; + dbg("%s: Rasing exception 0x%02x\r\n", __FUNCTION__, intrnum); + x86emu_dump_regs(); + M.x86.intno = intrnum; + M.x86.intr |= INTR_SYNCH; } /**************************************************************************** @@ -90,53 +90,58 @@ 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; + uint8_t op1; - M.x86.intr = 0; - DB(x86emu_end_instr();) + M.x86.intr = 0; + DB(x86emu_end_instr();) - for (;;) { -DB( 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"); - X86EMU_trace_regs(); - } - else { - if (M.x86.debug) - DPRINT("Service completed successfully\r\n"); - }) - return; - } - if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) || - !ACCESS_FLAG(F_IF)) { - x86emu_intr_handle(); - } - } - op1 = (*sys_rdb)(((uint32_t)M.x86.R_CS << 4) + (M.x86.R_IP++)); - (*x86emu_optab[op1])(op1); - //if (M.x86.debug & DEBUG_EXIT) { - // M.x86.debug &= ~DEBUG_EXIT; - // return; - //} - } + 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) + { + if (M.x86.R_SP != 0) + { + dbg("%s: halted\r\n", __FUNCTION__); + X86EMU_trace_regs(); + } + else + { + if (M.x86.debug) + dbg("%s: Service completed successfully\r\n", __FUNCTION__); + } + return; + } + if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) || + !ACCESS_FLAG(F_IF)) { + x86emu_intr_handle(); + } + } + op1 = (*sys_rdb)(((uint32_t)M.x86.R_CS << 4) + (M.x86.R_IP++)); + (*x86emu_optab[op1])(op1); + //if (M.x86.debug & DEBUG_EXIT) { + // M.x86.debug &= ~DEBUG_EXIT; + // return; + //} + } } /**************************************************************************** REMARKS: Halts the system by setting the halted system flag. -****************************************************************************/ + ****************************************************************************/ void X86EMU_halt_sys(void) { - M.x86.intr |= INTR_HALTED; + M.x86.intr |= INTR_HALTED; } /**************************************************************************** @@ -150,21 +155,21 @@ 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, - int *regl) + int *mod, + int *regh, + int *regl) { - int fetched; + int fetched; -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); - *mod = (fetched >> 6) & 0x03; - *regh = (fetched >> 3) & 0x07; - *regl = (fetched >> 0) & 0x07; + 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); + *mod = (fetched >> 6) & 0x03; + *regh = (fetched >> 3) & 0x07; + *regl = (fetched >> 0) & 0x07; } /**************************************************************************** @@ -176,16 +181,16 @@ 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; + uint8_t fetched; -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); - return fetched; + 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); + return fetched; } /**************************************************************************** @@ -197,17 +202,17 @@ 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; + uint16_t fetched; -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; - INC_DECODED_INST_LEN(2); - return fetched; + 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; + INC_DECODED_INST_LEN(2); + return fetched; } /**************************************************************************** @@ -219,17 +224,17 @@ 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; + uint32_t fetched; -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; - INC_DECODED_INST_LEN(4); - return fetched; + 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; + INC_DECODED_INST_LEN(4); + return fetched; } /**************************************************************************** @@ -247,52 +252,52 @@ 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) - switch (M.x86.mode & SYSMODE_SEGMASK) { - case 0: /* default case: use ds register */ - case SYSMODE_SEGOVR_DS: - case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS: - return M.x86.R_DS; - case SYSMODE_SEG_DS_SS: /* non-overridden, use ss register */ - return M.x86.R_SS; - case SYSMODE_SEGOVR_CS: - case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS: - return M.x86.R_CS; - case SYSMODE_SEGOVR_ES: - case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS: - return M.x86.R_ES; - case SYSMODE_SEGOVR_FS: - case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS: - return M.x86.R_FS; - case SYSMODE_SEGOVR_GS: - case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS: - return M.x86.R_GS; - case SYSMODE_SEGOVR_SS: - case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS: - return M.x86.R_SS; - default: + switch (M.x86.mode & SYSMODE_SEGMASK) { + case 0: /* default case: use ds register */ + case SYSMODE_SEGOVR_DS: + case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS: + return M.x86.R_DS; + case SYSMODE_SEG_DS_SS: /* non-overridden, use ss register */ + return M.x86.R_SS; + case SYSMODE_SEGOVR_CS: + case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS: + return M.x86.R_CS; + case SYSMODE_SEGOVR_ES: + case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS: + return M.x86.R_ES; + case SYSMODE_SEGOVR_FS: + case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS: + return M.x86.R_FS; + case SYSMODE_SEGOVR_GS: + case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS: + return M.x86.R_GS; + case SYSMODE_SEGOVR_SS: + case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS: + return M.x86.R_SS; + default: #ifdef DEBUG - DPRINT("error: should not happen: multiple overrides.\r\n"); + DPRINT("error: should not happen: multiple overrides.\r\n"); #endif - HALT_SYS(); - return 0; - } + HALT_SYS(); + return 0; + } } /**************************************************************************** @@ -303,15 +308,15 @@ 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) + unsigned int offset) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access((uint16_t)get_data_segment(), offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((uint16_t)get_data_segment(), offset); #endif - return (*sys_rdb)((get_data_segment() << 4) + offset); + return (*sys_rdb)((get_data_segment() << 4) + offset); } /**************************************************************************** @@ -322,15 +327,15 @@ 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) + unsigned int offset) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access((uint16_t)get_data_segment(), offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((uint16_t)get_data_segment(), offset); #endif - return (*sys_rdw)((get_data_segment() << 4) + offset); + return (*sys_rdw)((get_data_segment() << 4) + offset); } /**************************************************************************** @@ -341,15 +346,15 @@ 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) + unsigned int offset) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access((uint16_t)get_data_segment(), offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((uint16_t)get_data_segment(), offset); #endif - return (*sys_rdl)((get_data_segment() << 4) + offset); + return (*sys_rdl)((get_data_segment() << 4) + offset); } /**************************************************************************** @@ -361,16 +366,16 @@ 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) + unsigned int segment, + unsigned int offset) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access(segment, offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); #endif - return (*sys_rdb)(((uint32_t)segment << 4) + offset); + return (*sys_rdb)(((uint32_t)segment << 4) + offset); } /**************************************************************************** @@ -382,16 +387,16 @@ 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) + unsigned int segment, + unsigned int offset) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access(segment, offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); #endif - return (*sys_rdw)(((uint32_t)segment << 4) + offset); + return (*sys_rdw)(((uint32_t)segment << 4) + offset); } /**************************************************************************** @@ -403,16 +408,16 @@ 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) + unsigned int segment, + unsigned int offset) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access(segment, offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); #endif - return (*sys_rdl)(((uint32_t)segment << 4) + offset); + return (*sys_rdl)(((uint32_t)segment << 4) + offset); } /**************************************************************************** @@ -425,16 +430,16 @@ 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) + unsigned int offset, + uint8_t val) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access((uint16_t)get_data_segment(), offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((uint16_t)get_data_segment(), offset); #endif - (*sys_wrb)((get_data_segment() << 4) + offset, val); + (*sys_wrb)((get_data_segment() << 4) + offset, val); } /**************************************************************************** @@ -447,16 +452,16 @@ 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) + unsigned int offset, + uint16_t val) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access((uint16_t)get_data_segment(), offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((uint16_t)get_data_segment(), offset); #endif - (*sys_wrw)((get_data_segment() << 4) + offset, val); + (*sys_wrw)((get_data_segment() << 4) + offset, val); } /**************************************************************************** @@ -469,16 +474,16 @@ 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) + unsigned int offset, + uint32_t val) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access((uint16_t)get_data_segment(), offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access((uint16_t)get_data_segment(), offset); #endif - (*sys_wrl)((get_data_segment() << 4) + offset, val); + (*sys_wrl)((get_data_segment() << 4) + offset, val); } /**************************************************************************** @@ -491,17 +496,17 @@ 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, - uint8_t val) + unsigned int segment, + unsigned int offset, + uint8_t val) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access(segment, offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); #endif - (*sys_wrb)(((uint32_t)segment << 4) + offset, val); + (*sys_wrb)(((uint32_t)segment << 4) + offset, val); } /**************************************************************************** @@ -514,17 +519,17 @@ 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, - uint16_t val) + unsigned int segment, + unsigned int offset, + uint16_t val) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access(segment, offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); #endif - (*sys_wrw)(((uint32_t)segment << 4) + offset, val); + (*sys_wrw)(((uint32_t)segment << 4) + offset, val); } /**************************************************************************** @@ -537,17 +542,17 @@ 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, - uint32_t val) + unsigned int segment, + unsigned int offset, + uint32_t val) { #ifdef DEBUG - if (CHECK_DATA_ACCESS()) - x86emu_check_data_access(segment, offset); + if (CHECK_DATA_ACCESS()) + x86emu_check_data_access(segment, offset); #endif - (*sys_wrl)(((uint32_t)segment << 4) + offset, val); + (*sys_wrl)(((uint32_t)segment << 4) + offset, val); } /**************************************************************************** @@ -560,38 +565,38 @@ 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) + int reg) { - switch (reg) { - case 0: - DECODE_PRINTF("AL"); - return &M.x86.R_AL; - case 1: - DECODE_PRINTF("CL"); - return &M.x86.R_CL; - case 2: - DECODE_PRINTF("DL"); - return &M.x86.R_DL; - case 3: - DECODE_PRINTF("BL"); - return &M.x86.R_BL; - case 4: - DECODE_PRINTF("AH"); - return &M.x86.R_AH; - case 5: - DECODE_PRINTF("CH"); - return &M.x86.R_CH; - case 6: - DECODE_PRINTF("DH"); - return &M.x86.R_DH; - case 7: - DECODE_PRINTF("BH"); - return &M.x86.R_BH; - } - HALT_SYS(); - return NULL; /* NOT REACHED OR REACHED ON ERROR */ + switch (reg) { + case 0: + DECODE_PRINTF("AL"); + return &M.x86.R_AL; + case 1: + DECODE_PRINTF("CL"); + return &M.x86.R_CL; + case 2: + DECODE_PRINTF("DL"); + return &M.x86.R_DL; + case 3: + DECODE_PRINTF("BL"); + return &M.x86.R_BL; + case 4: + DECODE_PRINTF("AH"); + return &M.x86.R_AH; + case 5: + DECODE_PRINTF("CH"); + return &M.x86.R_CH; + case 6: + DECODE_PRINTF("DH"); + return &M.x86.R_DH; + case 7: + DECODE_PRINTF("BH"); + return &M.x86.R_BH; + } + HALT_SYS(); + return NULL; /* NOT REACHED OR REACHED ON ERROR */ } /**************************************************************************** @@ -604,38 +609,38 @@ 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) + int reg) { - switch (reg) { - case 0: - DECODE_PRINTF("AX"); - return &M.x86.R_AX; - case 1: - DECODE_PRINTF("CX"); - return &M.x86.R_CX; - case 2: - DECODE_PRINTF("DX"); - return &M.x86.R_DX; - case 3: - DECODE_PRINTF("BX"); - return &M.x86.R_BX; - case 4: - DECODE_PRINTF("SP"); - return &M.x86.R_SP; - case 5: - DECODE_PRINTF("BP"); - return &M.x86.R_BP; - case 6: - DECODE_PRINTF("SI"); - return &M.x86.R_SI; - case 7: - DECODE_PRINTF("DI"); - return &M.x86.R_DI; - } - HALT_SYS(); - return NULL; /* NOTREACHED OR REACHED ON ERROR */ + switch (reg) { + case 0: + DECODE_PRINTF("AX"); + return &M.x86.R_AX; + case 1: + DECODE_PRINTF("CX"); + return &M.x86.R_CX; + case 2: + DECODE_PRINTF("DX"); + return &M.x86.R_DX; + case 3: + DECODE_PRINTF("BX"); + return &M.x86.R_BX; + case 4: + DECODE_PRINTF("SP"); + return &M.x86.R_SP; + case 5: + DECODE_PRINTF("BP"); + return &M.x86.R_BP; + case 6: + DECODE_PRINTF("SI"); + return &M.x86.R_SI; + case 7: + DECODE_PRINTF("DI"); + return &M.x86.R_DI; + } + HALT_SYS(); + return NULL; /* NOTREACHED OR REACHED ON ERROR */ } /**************************************************************************** @@ -648,38 +653,38 @@ 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) + int reg) { - switch (reg) { - case 0: - DECODE_PRINTF("EAX"); - return &M.x86.R_EAX; - case 1: - DECODE_PRINTF("ECX"); - return &M.x86.R_ECX; - case 2: - DECODE_PRINTF("EDX"); - return &M.x86.R_EDX; - case 3: - DECODE_PRINTF("EBX"); - return &M.x86.R_EBX; - case 4: - DECODE_PRINTF("ESP"); - return &M.x86.R_ESP; - case 5: - DECODE_PRINTF("EBP"); - return &M.x86.R_EBP; - case 6: - DECODE_PRINTF("ESI"); - return &M.x86.R_ESI; - case 7: - DECODE_PRINTF("EDI"); - return &M.x86.R_EDI; - } - HALT_SYS(); - return NULL; /* NOTREACHED OR REACHED ON ERROR */ + switch (reg) { + case 0: + DECODE_PRINTF("EAX"); + return &M.x86.R_EAX; + case 1: + DECODE_PRINTF("ECX"); + return &M.x86.R_ECX; + case 2: + DECODE_PRINTF("EDX"); + return &M.x86.R_EDX; + case 3: + DECODE_PRINTF("EBX"); + return &M.x86.R_EBX; + case 4: + DECODE_PRINTF("ESP"); + return &M.x86.R_ESP; + case 5: + DECODE_PRINTF("EBP"); + return &M.x86.R_EBP; + case 6: + DECODE_PRINTF("ESI"); + return &M.x86.R_ESI; + case 7: + DECODE_PRINTF("EDI"); + return &M.x86.R_EDI; + } + HALT_SYS(); + return NULL; /* NOTREACHED OR REACHED ON ERROR */ } /**************************************************************************** @@ -693,36 +698,36 @@ 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) + int reg) { - switch (reg) { - case 0: - DECODE_PRINTF("ES"); - return &M.x86.R_ES; - case 1: - DECODE_PRINTF("CS"); - return &M.x86.R_CS; - case 2: - DECODE_PRINTF("SS"); - return &M.x86.R_SS; - case 3: - DECODE_PRINTF("DS"); - return &M.x86.R_DS; - case 4: - DECODE_PRINTF("FS"); - return &M.x86.R_FS; - case 5: - DECODE_PRINTF("GS"); - return &M.x86.R_GS; - case 6: - case 7: - DECODE_PRINTF("ILLEGAL SEGREG"); - break; - } - HALT_SYS(); - return NULL; /* NOT REACHED OR REACHED ON ERROR */ + switch (reg) { + case 0: + DECODE_PRINTF("ES"); + return &M.x86.R_ES; + case 1: + DECODE_PRINTF("CS"); + return &M.x86.R_CS; + case 2: + DECODE_PRINTF("SS"); + return &M.x86.R_SS; + case 3: + DECODE_PRINTF("DS"); + return &M.x86.R_DS; + case 4: + DECODE_PRINTF("FS"); + return &M.x86.R_FS; + case 5: + DECODE_PRINTF("GS"); + return &M.x86.R_GS; + case 6: + case 7: + DECODE_PRINTF("ILLEGAL SEGREG"); + break; + } + HALT_SYS(); + return NULL; /* NOT REACHED OR REACHED ON ERROR */ } /**************************************************************************** @@ -736,45 +741,45 @@ 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) + int scale, + int index) { - scale = 1 << scale; - if (scale > 1) { - DECODE_PRINTF2("[%d*", scale); - } else { - DECODE_PRINTF("["); - } - switch (index) { - case 0: - DECODE_PRINTF("EAX]"); - return M.x86.R_EAX * index; - case 1: - DECODE_PRINTF("ECX]"); - return M.x86.R_ECX * index; - case 2: - DECODE_PRINTF("EDX]"); - return M.x86.R_EDX * index; - case 3: - DECODE_PRINTF("EBX]"); - return M.x86.R_EBX * index; - case 4: - DECODE_PRINTF("0]"); - return 0; - case 5: - DECODE_PRINTF("EBP]"); - return M.x86.R_EBP * index; - case 6: - DECODE_PRINTF("ESI]"); - return M.x86.R_ESI * index; - case 7: - DECODE_PRINTF("EDI]"); - return M.x86.R_EDI * index; - } - HALT_SYS(); - return 0; /* NOT REACHED OR REACHED ON ERROR */ + scale = 1 << scale; + if (scale > 1) { + DECODE_PRINTF2("[%d*", scale); + } else { + DECODE_PRINTF("["); + } + switch (index) { + case 0: + DECODE_PRINTF("EAX]"); + return M.x86.R_EAX * index; + case 1: + DECODE_PRINTF("ECX]"); + return M.x86.R_ECX * index; + case 2: + DECODE_PRINTF("EDX]"); + return M.x86.R_EDX * index; + case 3: + DECODE_PRINTF("EBX]"); + return M.x86.R_EBX * index; + case 4: + DECODE_PRINTF("0]"); + return 0; + case 5: + DECODE_PRINTF("EBP]"); + return M.x86.R_EBP * index; + case 6: + DECODE_PRINTF("ESI]"); + return M.x86.R_ESI * index; + case 7: + DECODE_PRINTF("EDI]"); + return M.x86.R_EDI * index; + } + HALT_SYS(); + return 0; /* NOT REACHED OR REACHED ON ERROR */ } /**************************************************************************** @@ -786,74 +791,74 @@ Offset in memory for the address decoding REMARKS: Decodes SIB addressing byte and returns calculated effective address. -****************************************************************************/ + ****************************************************************************/ unsigned decode_sib_address( - int mod) + int mod) { - int sib = fetch_byte_imm(); - int ss = (sib >> 6) & 0x03; - int index = (sib >> 3) & 0x07; - int base = sib & 0x07; - int offset = 0; - int displacement; + int sib = fetch_byte_imm(); + int ss = (sib >> 6) & 0x03; + int index = (sib >> 3) & 0x07; + int base = sib & 0x07; + int offset = 0; + int displacement; - switch (base) { - case 0: - DECODE_PRINTF("[EAX]"); - offset = M.x86.R_EAX; - break; - case 1: - DECODE_PRINTF("[ECX]"); - offset = M.x86.R_ECX; - break; - case 2: - DECODE_PRINTF("[EDX]"); - offset = M.x86.R_EDX; - break; - case 3: - DECODE_PRINTF("[EBX]"); - offset = M.x86.R_EBX; - break; - case 4: - DECODE_PRINTF("[ESP]"); - offset = M.x86.R_ESP; - break; - case 5: - switch (mod) { - case 0: - displacement = (int32_t)fetch_long_imm(); - DECODE_PRINTF2("[%d]", displacement); - offset = displacement; - break; - case 1: - displacement = (int8_t)fetch_byte_imm(); - DECODE_PRINTF2("[%d][EBP]", displacement); - offset = M.x86.R_EBP + displacement; - break; - case 2: - displacement = (int32_t)fetch_long_imm(); - DECODE_PRINTF2("[%d][EBP]", displacement); - offset = M.x86.R_EBP + displacement; - break; - default: - HALT_SYS(); - } - DECODE_PRINTF("[EAX]"); - offset = M.x86.R_EAX; - break; - case 6: - DECODE_PRINTF("[ESI]"); - offset = M.x86.R_ESI; - break; - case 7: - DECODE_PRINTF("[EDI]"); - offset = M.x86.R_EDI; - break; - default: - HALT_SYS(); - } - offset += decode_sib_si(ss, index); - return offset; + switch (base) { + case 0: + DECODE_PRINTF("[EAX]"); + offset = M.x86.R_EAX; + break; + case 1: + DECODE_PRINTF("[ECX]"); + offset = M.x86.R_ECX; + break; + case 2: + DECODE_PRINTF("[EDX]"); + offset = M.x86.R_EDX; + break; + case 3: + DECODE_PRINTF("[EBX]"); + offset = M.x86.R_EBX; + break; + case 4: + DECODE_PRINTF("[ESP]"); + offset = M.x86.R_ESP; + break; + case 5: + switch (mod) { + case 0: + displacement = (int32_t)fetch_long_imm(); + DECODE_PRINTF2("[%d]", displacement); + offset = displacement; + break; + case 1: + displacement = (int8_t)fetch_byte_imm(); + DECODE_PRINTF2("[%d][EBP]", displacement); + offset = M.x86.R_EBP + displacement; + break; + case 2: + displacement = (int32_t)fetch_long_imm(); + DECODE_PRINTF2("[%d][EBP]", displacement); + offset = M.x86.R_EBP + displacement; + break; + default: + HALT_SYS(); + } + DECODE_PRINTF("[EAX]"); + offset = M.x86.R_EAX; + break; + case 6: + DECODE_PRINTF("[ESI]"); + offset = M.x86.R_ESI; + break; + case 7: + DECODE_PRINTF("[EDI]"); + offset = M.x86.R_EDI; + break; + default: + HALT_SYS(); + } + offset += decode_sib_si(ss, index); + return offset; } /**************************************************************************** @@ -868,81 +873,81 @@ 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) + int rm) { - unsigned offset; + unsigned offset; - if (M.x86.mode & SYSMODE_PREFIX_ADDR) { - /* 32-bit addressing */ - switch (rm) { - case 0: - DECODE_PRINTF("[EAX]"); - return M.x86.R_EAX; - case 1: - DECODE_PRINTF("[ECX]"); - return M.x86.R_ECX; - case 2: - DECODE_PRINTF("[EDX]"); - return M.x86.R_EDX; - case 3: - DECODE_PRINTF("[EBX]"); - return M.x86.R_EBX; - case 4: - return decode_sib_address(0); - case 5: - offset = fetch_long_imm(); - DECODE_PRINTF2("[%x]", offset); - return offset; - case 6: - DECODE_PRINTF("[ESI]"); - return M.x86.R_ESI; - case 7: - DECODE_PRINTF("[EDI]"); - return M.x86.R_EDI; - } - } else { - /* 16-bit addressing */ - switch (rm) { - case 0: - DECODE_PRINTF("[BX+SI]"); - return (M.x86.R_BX + M.x86.R_SI) & 0xffff; - case 1: - DECODE_PRINTF("[BX+DI]"); - return (M.x86.R_BX + M.x86.R_DI) & 0xffff; - case 2: - DECODE_PRINTF("[BP+SI]"); - M.x86.mode |= SYSMODE_SEG_DS_SS; - return (M.x86.R_BP + M.x86.R_SI) & 0xffff; - case 3: - DECODE_PRINTF("[BP+DI]"); - M.x86.mode |= SYSMODE_SEG_DS_SS; - return (M.x86.R_BP + M.x86.R_DI) & 0xffff; - case 4: - DECODE_PRINTF("[SI]"); - return M.x86.R_SI; - case 5: - DECODE_PRINTF("[DI]"); - return M.x86.R_DI; - case 6: - offset = fetch_word_imm(); - DECODE_PRINTF2("[%x]", offset); - return offset; - case 7: - DECODE_PRINTF("[BX]"); - return M.x86.R_BX; - } - } - HALT_SYS(); - return 0; + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + /* 32-bit addressing */ + switch (rm) { + case 0: + DECODE_PRINTF("[EAX]"); + return M.x86.R_EAX; + case 1: + DECODE_PRINTF("[ECX]"); + return M.x86.R_ECX; + case 2: + DECODE_PRINTF("[EDX]"); + return M.x86.R_EDX; + case 3: + DECODE_PRINTF("[EBX]"); + return M.x86.R_EBX; + case 4: + return decode_sib_address(0); + case 5: + offset = fetch_long_imm(); + DECODE_PRINTF2("[%x]", offset); + return offset; + case 6: + DECODE_PRINTF("[ESI]"); + return M.x86.R_ESI; + case 7: + DECODE_PRINTF("[EDI]"); + return M.x86.R_EDI; + } + } else { + /* 16-bit addressing */ + switch (rm) { + case 0: + DECODE_PRINTF("[BX+SI]"); + return (M.x86.R_BX + M.x86.R_SI) & 0xffff; + case 1: + DECODE_PRINTF("[BX+DI]"); + return (M.x86.R_BX + M.x86.R_DI) & 0xffff; + case 2: + DECODE_PRINTF("[BP+SI]"); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_SI) & 0xffff; + case 3: + DECODE_PRINTF("[BP+DI]"); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_DI) & 0xffff; + case 4: + DECODE_PRINTF("[SI]"); + return M.x86.R_SI; + case 5: + DECODE_PRINTF("[DI]"); + return M.x86.R_DI; + case 6: + offset = fetch_word_imm(); + DECODE_PRINTF2("[%x]", offset); + return offset; + case 7: + DECODE_PRINTF("[BX]"); + return M.x86.R_BX; + } + } + HALT_SYS(); + return 0; } /**************************************************************************** @@ -955,83 +960,83 @@ 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) + int rm) { - int displacement; + int displacement; - if (M.x86.mode & SYSMODE_PREFIX_ADDR) { - /* 32-bit addressing */ - if (rm != 4) - displacement = (int8_t)fetch_byte_imm(); - else - displacement = 0; + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + /* 32-bit addressing */ + if (rm != 4) + displacement = (int8_t)fetch_byte_imm(); + else + displacement = 0; - switch (rm) { - case 0: - DECODE_PRINTF2("%d[EAX]", displacement); - return M.x86.R_EAX + displacement; - case 1: - DECODE_PRINTF2("%d[ECX]", displacement); - return M.x86.R_ECX + displacement; - case 2: - DECODE_PRINTF2("%d[EDX]", displacement); - return M.x86.R_EDX + displacement; - case 3: - DECODE_PRINTF2("%d[EBX]", displacement); - return M.x86.R_EBX + displacement; - case 4: { - int offset = decode_sib_address(1); - displacement = (int8_t)fetch_byte_imm(); - DECODE_PRINTF2("[%d]", displacement); - return offset + displacement; - } - case 5: - DECODE_PRINTF2("%d[EBP]", displacement); - return M.x86.R_EBP + displacement; - case 6: - DECODE_PRINTF2("%d[ESI]", displacement); - return M.x86.R_ESI + displacement; - case 7: - DECODE_PRINTF2("%d[EDI]", displacement); - return M.x86.R_EDI + displacement; - } - } else { - /* 16-bit addressing */ - displacement = (int8_t)fetch_byte_imm(); - switch (rm) { - case 0: - DECODE_PRINTF2("%d[BX+SI]", displacement); - return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; - case 1: - DECODE_PRINTF2("%d[BX+DI]", displacement); - return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; - case 2: - DECODE_PRINTF2("%d[BP+SI]", displacement); - M.x86.mode |= SYSMODE_SEG_DS_SS; - return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; - case 3: - DECODE_PRINTF2("%d[BP+DI]", displacement); - M.x86.mode |= SYSMODE_SEG_DS_SS; - return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; - case 4: - DECODE_PRINTF2("%d[SI]", displacement); - return (M.x86.R_SI + displacement) & 0xffff; - case 5: - DECODE_PRINTF2("%d[DI]", displacement); - return (M.x86.R_DI + displacement) & 0xffff; - case 6: - DECODE_PRINTF2("%d[BP]", displacement); - M.x86.mode |= SYSMODE_SEG_DS_SS; - return (M.x86.R_BP + displacement) & 0xffff; - case 7: - DECODE_PRINTF2("%d[BX]", displacement); - return (M.x86.R_BX + displacement) & 0xffff; - } - } - HALT_SYS(); - return 0; /* SHOULD NOT HAPPEN */ + switch (rm) { + case 0: + DECODE_PRINTF2("%d[EAX]", displacement); + return M.x86.R_EAX + displacement; + case 1: + DECODE_PRINTF2("%d[ECX]", displacement); + return M.x86.R_ECX + displacement; + case 2: + DECODE_PRINTF2("%d[EDX]", displacement); + return M.x86.R_EDX + displacement; + case 3: + DECODE_PRINTF2("%d[EBX]", displacement); + return M.x86.R_EBX + displacement; + case 4: { + int offset = decode_sib_address(1); + displacement = (int8_t)fetch_byte_imm(); + DECODE_PRINTF2("[%d]", displacement); + return offset + displacement; + } + case 5: + DECODE_PRINTF2("%d[EBP]", displacement); + return M.x86.R_EBP + displacement; + case 6: + DECODE_PRINTF2("%d[ESI]", displacement); + return M.x86.R_ESI + displacement; + case 7: + DECODE_PRINTF2("%d[EDI]", displacement); + return M.x86.R_EDI + displacement; + } + } else { + /* 16-bit addressing */ + displacement = (int8_t)fetch_byte_imm(); + switch (rm) { + case 0: + DECODE_PRINTF2("%d[BX+SI]", displacement); + return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; + case 1: + DECODE_PRINTF2("%d[BX+DI]", displacement); + return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; + case 2: + DECODE_PRINTF2("%d[BP+SI]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; + case 3: + DECODE_PRINTF2("%d[BP+DI]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; + case 4: + DECODE_PRINTF2("%d[SI]", displacement); + return (M.x86.R_SI + displacement) & 0xffff; + case 5: + DECODE_PRINTF2("%d[DI]", displacement); + return (M.x86.R_DI + displacement) & 0xffff; + case 6: + DECODE_PRINTF2("%d[BP]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + displacement) & 0xffff; + case 7: + DECODE_PRINTF2("%d[BX]", displacement); + return (M.x86.R_BX + displacement) & 0xffff; + } + } + HALT_SYS(); + return 0; /* SHOULD NOT HAPPEN */ } /**************************************************************************** @@ -1044,84 +1049,84 @@ 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) + int rm) { - if (M.x86.mode & SYSMODE_PREFIX_ADDR) { - int displacement; + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + int displacement; - /* 32-bit addressing */ - if (rm != 4) - displacement = (int32_t)fetch_long_imm(); - else - displacement = 0; + /* 32-bit addressing */ + if (rm != 4) + displacement = (int32_t)fetch_long_imm(); + else + displacement = 0; - switch (rm) { - case 0: - DECODE_PRINTF2("%d[EAX]", displacement); - return M.x86.R_EAX + displacement; - case 1: - DECODE_PRINTF2("%d[ECX]", displacement); - return M.x86.R_ECX + displacement; - case 2: - DECODE_PRINTF2("%d[EDX]", displacement); - return M.x86.R_EDX + displacement; - case 3: - DECODE_PRINTF2("%d[EBX]", displacement); - return M.x86.R_EBX + displacement; - case 4: { - int offset = decode_sib_address(2); - displacement = (int32_t)fetch_long_imm(); - DECODE_PRINTF2("[%d]", displacement); - return offset + displacement; - } - case 5: - DECODE_PRINTF2("%d[EBP]", displacement); - return M.x86.R_EBP + displacement; - case 6: - DECODE_PRINTF2("%d[ESI]", displacement); - return M.x86.R_ESI + displacement; - case 7: - DECODE_PRINTF2("%d[EDI]", displacement); - return M.x86.R_EDI + displacement; - } - } else { - int displacement = (int16_t)fetch_word_imm(); + switch (rm) { + case 0: + DECODE_PRINTF2("%d[EAX]", displacement); + return M.x86.R_EAX + displacement; + case 1: + DECODE_PRINTF2("%d[ECX]", displacement); + return M.x86.R_ECX + displacement; + case 2: + DECODE_PRINTF2("%d[EDX]", displacement); + return M.x86.R_EDX + displacement; + case 3: + DECODE_PRINTF2("%d[EBX]", displacement); + return M.x86.R_EBX + displacement; + case 4: { + int offset = decode_sib_address(2); + displacement = (int32_t)fetch_long_imm(); + DECODE_PRINTF2("[%d]", displacement); + return offset + displacement; + } + case 5: + DECODE_PRINTF2("%d[EBP]", displacement); + return M.x86.R_EBP + displacement; + case 6: + DECODE_PRINTF2("%d[ESI]", displacement); + return M.x86.R_ESI + displacement; + case 7: + DECODE_PRINTF2("%d[EDI]", displacement); + return M.x86.R_EDI + displacement; + } + } else { + int displacement = (int16_t)fetch_word_imm(); - /* 16-bit addressing */ - switch (rm) { - case 0: - DECODE_PRINTF2("%d[BX+SI]", displacement); - return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; - case 1: - DECODE_PRINTF2("%d[BX+DI]", displacement); - return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; - case 2: - DECODE_PRINTF2("%d[BP+SI]", displacement); - M.x86.mode |= SYSMODE_SEG_DS_SS; - return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; - case 3: - DECODE_PRINTF2("%d[BP+DI]", displacement); - M.x86.mode |= SYSMODE_SEG_DS_SS; - return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; - case 4: - DECODE_PRINTF2("%d[SI]", displacement); - return (M.x86.R_SI + displacement) & 0xffff; - case 5: - DECODE_PRINTF2("%d[DI]", displacement); - return (M.x86.R_DI + displacement) & 0xffff; - case 6: - DECODE_PRINTF2("%d[BP]", displacement); - M.x86.mode |= SYSMODE_SEG_DS_SS; - return (M.x86.R_BP + displacement) & 0xffff; - case 7: - DECODE_PRINTF2("%d[BX]", displacement); - return (M.x86.R_BX + displacement) & 0xffff; - } - } - HALT_SYS(); - return 0; /* SHOULD NOT HAPPEN */ + /* 16-bit addressing */ + switch (rm) { + case 0: + DECODE_PRINTF2("%d[BX+SI]", displacement); + return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; + case 1: + DECODE_PRINTF2("%d[BX+DI]", displacement); + return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; + case 2: + DECODE_PRINTF2("%d[BP+SI]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; + case 3: + DECODE_PRINTF2("%d[BP+DI]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; + case 4: + DECODE_PRINTF2("%d[SI]", displacement); + return (M.x86.R_SI + displacement) & 0xffff; + case 5: + DECODE_PRINTF2("%d[DI]", displacement); + return (M.x86.R_DI + displacement) & 0xffff; + case 6: + DECODE_PRINTF2("%d[BP]", displacement); + M.x86.mode |= SYSMODE_SEG_DS_SS; + return (M.x86.R_BP + displacement) & 0xffff; + case 7: + DECODE_PRINTF2("%d[BX]", displacement); + return (M.x86.R_BX + displacement) & 0xffff; + } + } + HALT_SYS(); + return 0; /* SHOULD NOT HAPPEN */ } @@ -1136,15 +1141,15 @@ the decode_rmXX_address functions REMARKS: Return the offset given by "mod" addressing. -****************************************************************************/ + ****************************************************************************/ unsigned decode_rmXX_address(int mod, int rm) { - if(mod == 0) - return decode_rm00_address(rm); - if(mod == 1) - return decode_rm01_address(rm); - return decode_rm10_address(rm); + if(mod == 0) + return decode_rm00_address(rm); + if(mod == 1) + return decode_rm01_address(rm); + return decode_rm10_address(rm); } diff --git a/x86emu/x86ops.c b/x86emu/x86ops.c index a2d9291..f281e36 100644 --- a/x86emu/x86ops.c +++ b/x86emu/x86ops.c @@ -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 diff --git a/x86emu/x86pcibios.c b/x86emu/x86pcibios.c index 212ebd7..06b7727 100644 --- a/x86emu/x86pcibios.c +++ b/x86emu/x86pcibios.c @@ -2,6 +2,7 @@ #include "pci.h" #include "x86emu.h" #include "x86pcibios.h" +#include "x86debug.h" extern unsigned short offset_port; @@ -11,232 +12,147 @@ int x86_pcibios_emulator() unsigned long dev; switch (X86_AX) { - case PCI_BIOS_PRESENT: -#ifdef DEBUG_X86EMU_PCI - DPRINT("PCI_BIOS_PRESENT\r\n"); -#endif - X86_AH = 0x00; /* no config space/special cycle support */ - X86_AL = 0x01; /* config mechanism 1 */ - X86_EDX = 'P' | 'C' << 8 | 'I' << 16 | ' ' << 24; - X86_EBX = 0x0210; /* Version 2.10 */ - X86_ECX = 0xFF00; /* FixME: Max bus number */ - 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); + case PCI_BIOS_PRESENT: + 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; + X86_EBX = 0x0210; /* Version 2.10 */ + X86_ECX = 0xFF00; /* FixME: Max bus number */ + X86_EFLAGS &= ~FB_CF; /* clear carry flag */ + ret = 1; + break; - if (dev != 0) { -#ifdef DEBUG_X86EMU_PCI - DPRINT(" ... OK\r\n"); -#endif - 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); - //X86_BL = (char)dev; // dev->path.u.pci.devfn; - X86_AH = SUCCESSFUL; - X86_EFLAGS &= ~FB_CF; /* clear carry flag */ - ret = 1; - } else { -#ifdef DEBUG_X86EMU_PCI - DPRINT(" ... error\r\n"); -#endif - 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 - dev = pci_find_classcode(X86_ECX, 0); - if (dev != 0) { -#ifdef DEBUG_X86EMU_PCI - DPRINT(" ... OK\r\n"); -#endif - 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 - 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 - X86_CL = pci_read_config_byte(dev, X86_DI); -#ifdef DEBUG_X86EMU_PCI - DPRINTVALHEX(" value ", X86_CL); - DPRINT("\r\n"); -#endif - 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 - 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 - 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; - else - X86_ECX = pci_read_config_longword(dev, X86_DI); -#ifdef DEBUG_X86EMU_PCI - DPRINTVALHEX(" value ", X86_ECX); - DPRINT("\r\n"); -#endif - 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 - 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 + case FIND_PCI_DEVICE: + /* FixME: support SI != 0 */ + // vendor, device + 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) + { + 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); + //X86_BL = (char)dev; // dev->path.u.pci.devfn; + X86_AH = SUCCESSFUL; + X86_EFLAGS &= ~FB_CF; /* clear carry flag */ + ret = 1; + } else { + 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 */ + dbg("%s: FIND_PCI_CLASS_CODE %x\r\n", __FUNCTION__, X86_ECX); + dev = pci_find_classcode(X86_ECX, 0); + if (dev != 0) { + 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 + { + 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 + 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); + dbg("%s: value = %x\r\n", __FUNCTION__, X86_CL); 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) - { -#ifdef DEBUG_X86EMU_PCI - DPRINT(" ... OK\r\n"); -#endif - 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_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 + + case READ_CONFIG_WORD: + // bus, devfn + 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); + dbg("%s: value = %x\r\n", __FUNCTION__, X86_CX); 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 + + case READ_CONFIG_DWORD: + // bus, devfn + 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); + dbg("%s: value = %x\r\n", __FUNCTION__, 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 - X86_AH = FUNC_NOT_SUPPORTED; - X86_EFLAGS |= FB_CF; - break; + break; + + case WRITE_CONFIG_BYTE: + // bus, devfn + 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; + break; + + case WRITE_CONFIG_WORD: + // bus, devfn + 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) + { + offset_port = X86_CX; + X86_AH = SUCCESSFUL; + X86_EFLAGS &= ~FB_CF; /* clear carry flag */ + ret = 1; + 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 + 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; + } + pci_write_config_longword(dev, X86_DI, X86_ECX); + X86_AH = SUCCESSFUL; + X86_EFLAGS &= ~FB_CF; /* clear carry flag */ + ret = 1; + break; + + default: + dbg("%s: PCI_BIOS FUNC_NOT_SUPPORTED\r\n", __FUNCTION__); + X86_AH = FUNC_NOT_SUPPORTED; + X86_EFLAGS |= FB_CF; + break; } return ret;