///////////////////////////////////////////////////////////////////////// // $Id: bochs.h,v 1.70 2002-07-14 13:23:10 vruppert Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002 MandrakeSoft S.A. // // MandrakeSoft S.A. // 43, rue d'Aboukir // 75002 Paris - France // http://www.linux-mandrake.com/ // http://www.mandrakesoft.com/ // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // bochs.h is the master header file for all C++ code. It includes all // the system header files needed by bochs, and also includes all the bochs // C++ header files. Because bochs.h and the files that it includes has // structure and class definitions, it cannot be called from C code. // #ifndef BX_BOCHS_H # define BX_BOCHS_H 1 #include "config.h" /* generated by configure script from config.h.in */ extern "C" { #include #include #include #include #ifndef WIN32 # include #else # include #endif #include #if BX_WITH_MACOS # include # include #elif BX_WITH_CARBON # include # include # include /* for MAXPATHLEN */ # include #else # ifndef WIN32 # include # include # endif # include # include #endif #include #include #include #ifdef macintosh # define SuperDrive "[fd:]" #endif } #include "osdep.h" /* platform dependent includes and defines */ #include "debug/debug.h" #include "bxversion.h" #include "gui/siminterface.h" // // some macros to interface the CPU and memory to external environment // so that these functions can be redirected to the debugger when // needed. // #if ((BX_DEBUGGER == 1) && (BX_NUM_SIMULATORS >= 2)) // =-=-=-=-=-=-=- Redirected to cosimulation debugger -=-=-=-=-=-=-= #define BX_VGA_MEM_READ(addr) bx_dbg_ucmem_read(addr) #define BX_VGA_MEM_WRITE(addr, val) bx_dbg_ucmem_write(addr, val) #if BX_SUPPORT_A20 # define A20ADDR(x) ( (x) & bx_pc_system.a20_mask ) #else # define A20ADDR(x) (x) #endif #define BX_INP(addr, len) bx_dbg_inp(addr, len) #define BX_OUTP(addr, val, len) bx_dbg_outp(addr, val, len) #define BX_HRQ (bx_pc_system.HRQ) #define BX_RAISE_HLDA() bx_dbg_raise_HLDA() #define BX_TICK1() #define BX_INTR bx_pc_system.INTR #define BX_SET_INTR(b) bx_dbg_set_INTR(b) #if BX_SIM_ID == 0 # define BX_CPU_C bx_cpu0_c # define BX_CPU bx_cpu0 # define BX_MEM_C bx_mem0_c # define BX_MEM bx_mem0 #else # define BX_CPU_C bx_cpu1_c # define BX_CPU bx_cpu1 # define BX_MEM_C bx_mem1_c # define BX_MEM bx_mem1 #endif #define BX_SET_ENABLE_A20(enabled) bx_dbg_async_pin_request(BX_DBG_ASYNC_PENDING_A20, \ enabled) #define BX_GET_ENABLE_A20() bx_pc_system.get_enable_a20() #error FIXME: cosim mode not fixed yet #else // =-=-=-=-=-=-=- Normal optimized use -=-=-=-=-=-=-=-=-=-=-=-=-=-= #define BX_VGA_MEM_READ(addr) (bx_devices.vga->mem_read(addr)) #define BX_VGA_MEM_WRITE(addr, val) bx_devices.vga->mem_write(addr, val) #if BX_SUPPORT_A20 # define A20ADDR(x) ( (x) & bx_pc_system.a20_mask ) #else # define A20ADDR(x) (x) #endif // // some pc_systems functions just redirect to the IO devices so optimize // by eliminating call here // // #define BX_INP(addr, len) bx_pc_system.inp(addr, len) // #define BX_OUTP(addr, val, len) bx_pc_system.outp(addr, val, len) #define BX_INP(addr, len) bx_devices.inp(addr, len) #define BX_OUTP(addr, val, len) bx_devices.outp(addr, val, len) #define BX_TICK1() bx_pc_system.tick1() #define BX_TICKN(n) bx_pc_system.tickn(n) #define BX_INTR bx_pc_system.INTR #define BX_SET_INTR(b) bx_pc_system.set_INTR(b) #define BX_CPU_C bx_cpu_c #define BX_MEM_C bx_mem_c // macros for DMA handling #define BX_REGISTER_DMA8_CHANNEL(channel, dmaRead, dmaWrite, name) \ bx_dma.registerDMA8Channel(channel, dmaRead, dmaWrite, name) #define BX_REGISTER_DMA16_CHANNEL(channel, dmaRead, dmaWrite, name) \ bx_dma.registerDMA16Channel(channel, dmaRead, dmaWrite, name) #define BX_UNREGISTER_DMA_CHANNEL(channel) \ bx_dma.unregisterDMAChannel(channel) #define BX_DMA_SET_DRQ(channel, val) bx_dma.set_DRQ(channel, val) #define BX_DMA_GET_TC() bx_dma.get_TC() #define BX_HRQ (bx_pc_system.HRQ) #define BX_RAISE_HLDA() bx_dma.raise_HLDA() #define BX_MEM_READ_PHYSICAL(phy_addr, len, ptr) \ BX_MEM(0)->read_physical(BX_CPU(0), phy_addr, len, ptr) #define BX_MEM_WRITE_PHYSICAL(addr, len, ptr) \ BX_MEM(0)->write_physical(BX_CPU(0), phy_addr, len, ptr) #if BX_SMP_PROCESSORS==1 #define BX_CPU(x) (&bx_cpu) #define BX_MEM(x) (&bx_mem) #else #define BX_CPU(x) (bx_cpu_array[x]) #define BX_MEM(x) (bx_mem_array[x]) #endif #define BX_SET_ENABLE_A20(enabled) bx_pc_system.set_enable_a20(enabled) #define BX_GET_ENABLE_A20() bx_pc_system.get_enable_a20() #endif // you can't use static member functions on the CPU, if there are going // to be 2 cpus. Check this early on. #if (BX_SMP_PROCESSORS>1) # if (BX_USE_CPU_SMF!=0) # error For SMP simulation, BX_USE_CPU_SMF must be 0. # endif #endif // #define BX_IAC() bx_pc_system.IAC() #define BX_IAC() bx_devices.pic->IAC() //#define BX_IAC() bx_dbg_IAC() // // Ways for the the external environment to report back information // to the debugger. // #if BX_DEBUGGER # define BX_DBG_ASYNC_INTR bx_guard.async.irq # define BX_DBG_ASYNC_DMA bx_guard.async.dma #if (BX_NUM_SIMULATORS > 1) // for multiple simulators, we always need this info, since we're // going to replay it. # define BX_DBG_DMA_REPORT(addr, len, what, val) \ bx_dbg_dma_report(addr, len, what, val) # define BX_DBG_IAC_REPORT(vector, irq) \ bx_dbg_iac_report(vector, irq) # define BX_DBG_A20_REPORT(val) \ bx_dbg_a20_report(val) # define BX_DBG_IO_REPORT(addr, size, op, val) \ bx_dbg_io_report(addr, size, op, val) # define BX_DBG_UCMEM_REPORT(addr, size, op, val) #else // for a single simulator debug environment, we can optimize a little // by conditionally calling, as per requested. # define BX_DBG_DMA_REPORT(addr, len, what, val) \ if (bx_guard.report.dma) bx_dbg_dma_report(addr, len, what, val) # define BX_DBG_IAC_REPORT(vector, irq) \ if (bx_guard.report.irq) bx_dbg_iac_report(vector, irq) # define BX_DBG_A20_REPORT(val) \ if (bx_guard.report.a20) bx_dbg_a20_report(val) # define BX_DBG_IO_REPORT(addr, size, op, val) \ if (bx_guard.report.io) bx_dbg_io_report(addr, size, op, val) # define BX_DBG_UCMEM_REPORT(addr, size, op, val) \ if (bx_guard.report.ucmem) bx_dbg_ucmem_report(addr, size, op, val) #endif // #if (BX_NUM_SIMULATORS > 1) #else // #if BX_DEBUGGER // debugger not compiled in, use empty stubs # define BX_DBG_ASYNC_INTR 1 # define BX_DBG_ASYNC_DMA 1 # define BX_DBG_DMA_REPORT(addr, len, what, val) # define BX_DBG_IAC_REPORT(vector, irq) # define BX_DBG_A20_REPORT(val) # define BX_DBG_IO_REPORT(addr, size, op, val) # define BX_DBG_UCMEM_REPORT(addr, size, op, val) #endif // #if BX_DEBUGGER extern Bit8u DTPageDirty[]; #if BX_DYNAMIC_TRANSLATION # define BX_DYN_DIRTY_PAGE(page) DTPageDirty[page] = 1; #else # define BX_DYN_DIRTY_PAGE(page) #endif #define MAGIC_LOGNUM 0x12345678 typedef class logfunctions { char *prefix; int type; // values of onoff: 0=ignore, 1=report, 2=ask, 3=fatal #define ACT_IGNORE 0 #define ACT_REPORT 1 #define ACT_ASK 2 #define ACT_FATAL 3 #define N_ACT 4 int onoff[N_LOGLEV]; class iofunctions *logio; public: logfunctions(void); logfunctions(class iofunctions *); ~logfunctions(void); void info(const char *fmt, ...); void error(const char *fmt, ...); void panic(const char *fmt, ...); void ldebug(const char *fmt, ...); void fatal (const char *prefix, const char *fmt, va_list ap); void ask (int level, const char *prefix, const char *fmt, va_list ap); void put(char *); void settype(int); void setio(class iofunctions *); void setonoff(int loglev, int value) { assert (loglev >= 0 && loglev < N_LOGLEV); onoff[loglev] = value; } char *getprefix () { return prefix; } int getonoff(int level) { assert (level>=0 && level=0 && i<4) return loglevel[i]; else return "?"; } char *getaction(int i) { static char *name[] = { "ignore", "report", "ask", "fatal" }; assert (i>=ACT_IGNORE && i