0a7cb3a43c
For a whole lot of configure options, I put #if...#endif around code that is specific to the option, even in files which are normally only compiled when the option is on. This allows me to create a MS Visual C++ 6.0 workspace that supports many of these options. The workspace will basically compile every file all the time, but the code for disabled options will be commented out by the #if...#endif. This may one day lead to simplification of the Makefiles and configure scripts, but for the moment I'm leaving Makefiles and configure scripts alone. Affected options: BX_SUPPORT_APIC (cpu/apic.cc) BX_SUPPORT_X86_64 (cpu/*64.cc) BX_DEBUGGER (debug/*) BX_DISASM (disasm/*) BX_WITH_nameofgui (gui/*) BX_SUPPORT_CDROM (iodev/cdrom.cc) BX_NE2K_SUPPORT (iodev/eth*.cc, iodev/ne2k.cc) BX_SUPPORT_APIC (iodev/ioapic.cc) BX_IODEBUG_SUPPORT (iodev/iodebug.cc) BX_PCI_SUPPORT (iodev/pci*.cc) BX_SUPPORT_SB16 (iodev/sb*.cc) Modified Files: cpu/apic.cc cpu/arith64.cc cpu/ctrl_xfer64.cc cpu/data_xfer64.cc cpu/fetchdecode64.cc cpu/logical64.cc cpu/mult64.cc cpu/resolve64.cc cpu/shift64.cc cpu/stack64.cc debug/Makefile.in debug/crc.cc debug/dbg_main.cc debug/lexer.l debug/linux.cc debug/parser.c debug/parser.y disasm/dis_decode.cc disasm/dis_groups.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/macintosh.cc gui/rfb.cc gui/sdl.cc gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxmain.cc gui/x.cc iodev/cdrom.cc iodev/eth.cc iodev/eth_arpback.cc iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_packetmaker.cc iodev/eth_tap.cc iodev/eth_tuntap.cc iodev/eth_win32.cc iodev/ioapic.cc iodev/iodebug.cc iodev/ne2k.cc iodev/pci.cc iodev/pci2isa.cc iodev/sb16.cc iodev/soundlnx.cc iodev/soundwin.cc
355 lines
7.6 KiB
C++
355 lines
7.6 KiB
C++
/////////////////////////////////////////////////////////////////////////
|
|
// $Id: iodebug.cc,v 1.15 2002-11-19 05:47:45 bdenney Exp $
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
#include "bochs.h"
|
|
#if BX_IODEBUG_SUPPORT
|
|
|
|
|
|
|
|
bx_iodebug_c bx_iodebug;
|
|
bx_iodebug_c *bx_iodebug_ptr;
|
|
|
|
struct bx_iodebug_s_type {
|
|
bx_bool enabled;
|
|
unsigned int register_select;
|
|
Bit32u registers[2];
|
|
Bit32u monitored_mem_areas_start[BX_IODEBUG_MAX_AREAS];
|
|
Bit32u monitored_mem_areas_end[BX_IODEBUG_MAX_AREAS];
|
|
} bx_iodebug_s;
|
|
|
|
|
|
|
|
|
|
// Constructor
|
|
bx_iodebug_c::bx_iodebug_c( void )
|
|
{
|
|
put("IODEBUG");
|
|
settype(IODEBUGLOG);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Destructor
|
|
bx_iodebug_c::~bx_iodebug_c( void )
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void bx_iodebug_c::init(void)
|
|
{
|
|
int i;
|
|
|
|
DEV_register_ioread_handler(this, read_handler, 0x8A00,"BOCHS IODEBUG", 7);
|
|
DEV_register_iowrite_handler(this, write_handler, 0x8A00,"BOCHS IODEBUG", 7);
|
|
DEV_register_iowrite_handler(this, write_handler, 0x8A01,"BOCHS IODEBUG", 7);
|
|
// fprintf( stderr, "IODEBUG initialized\n");
|
|
|
|
bx_iodebug_s.enabled = 0;
|
|
bx_iodebug_s.register_select = 0;
|
|
for(i=0;i<BX_IODEBUG_MAX_AREAS;i++) {
|
|
bx_iodebug_s.monitored_mem_areas_start[i] = 0;
|
|
bx_iodebug_s.monitored_mem_areas_end[i] = 0;
|
|
}
|
|
}
|
|
|
|
void bx_iodebug_c::reset(unsigned type)
|
|
{
|
|
}
|
|
|
|
|
|
Bit32u bx_iodebug_c::read_handler(void *this_ptr, Bit32u addr, unsigned io_len)
|
|
{
|
|
bx_iodebug_ptr = (bx_iodebug_c *) this_ptr;
|
|
return( bx_iodebug_ptr->read(addr, io_len) );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bit32u bx_iodebug_c::read( Bit32u addr, unsigned io_len )
|
|
{
|
|
|
|
if(bx_iodebug_s.enabled) return(0x8A00);
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void bx_iodebug_c::write_handler(void *this_ptr, Bit32u addr, Bit32u dvalue, unsigned io_len)
|
|
{
|
|
bx_iodebug_c *class_ptr = (bx_iodebug_c *) this_ptr;
|
|
class_ptr->write( addr, dvalue, io_len );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void bx_iodebug_c::write( Bit32u addr, Bit32u dvalue, unsigned int io_len )
|
|
{
|
|
|
|
|
|
// fprintf(stderr, "IODEBUG addr: %4x\tdvalue: %8x\tio_len: %8x\n", (unsigned int)addr, (unsigned int)dvalue, io_len);
|
|
|
|
if( addr == 0x8A01 && io_len == 2 )
|
|
{
|
|
bx_iodebug_s.registers[bx_iodebug_s.register_select] =
|
|
(bx_iodebug_s.registers[bx_iodebug_s.register_select] << 16) +
|
|
(dvalue & 0x0000FFFF );
|
|
}
|
|
|
|
if( (addr != 0x8A00) || (io_len != 2) ) return;
|
|
|
|
if( !bx_iodebug_s.enabled )
|
|
{
|
|
if( dvalue == 0x8A00 )
|
|
{
|
|
bx_iodebug_s.enabled = 1;
|
|
// fprintf(stderr, "IODEBUG enabled\n");
|
|
bx_iodebug_s.registers[0] = 0;
|
|
bx_iodebug_s.registers[1] = 0;
|
|
}
|
|
return;
|
|
}
|
|
|
|
switch( dvalue )
|
|
{
|
|
case( 0x8A01 ):
|
|
bx_iodebug_s.register_select = 0;
|
|
// fprintf( stderr, "IODEBUG register 0 selected\n");
|
|
break;
|
|
|
|
case( 0x8A02 ):
|
|
bx_iodebug_s.register_select = 1;
|
|
// fprintf( stderr, "IODEBUG register 1 selected\n");
|
|
break;
|
|
|
|
case( 0x8A80 ):
|
|
bx_iodebug_s.register_select = 0;
|
|
bx_iodebug_c::add_range(
|
|
bx_iodebug_s.registers[0],
|
|
bx_iodebug_s.registers[1]);
|
|
bx_iodebug_s.registers[0] = 0;
|
|
bx_iodebug_s.registers[1] = 0;
|
|
break;
|
|
|
|
#if BX_DEBUGGER
|
|
case( 0x8AE0 ):
|
|
fprintf( stderr, "request return to dbg prompt received, 0x8AE0 command (iodebug)\n");
|
|
bx_guard.interrupt_requested=1;
|
|
break;
|
|
|
|
case( 0x8AE2):
|
|
fprintf( stderr, "request made by the guest os to disable tracing, iodebug port 0x8A00->0x8AE2\n");
|
|
BX_CPU(dbg_cpu)->trace = 0;
|
|
break;
|
|
|
|
case( 0x8AE3 ):
|
|
fprintf( stderr, "request made by the guest os to enable tracing, iodebug port 0x8A00->0x8AE3\n");
|
|
BX_CPU(dbg_cpu)->trace = 1;
|
|
break;
|
|
|
|
case( 0x8AE4 ):
|
|
fprintf( stderr, "request made by the guest os to disable register tracing, iodebug port 0x8A00->0x8AE4\n");
|
|
BX_CPU(dbg_cpu)->trace_reg = 0;
|
|
break;
|
|
|
|
case( 0x8AE5 ):
|
|
fprintf( stderr, "request made by the guest os to enable register tracing, iodebug port 0x8A00->0x8AE5\n");
|
|
BX_CPU(dbg_cpu)->trace_reg = 1;
|
|
break;
|
|
|
|
#endif
|
|
|
|
case( 0x8AFF ):
|
|
bx_iodebug_s.enabled = 0;
|
|
// fprintf( stderr, "IODEBUG device deactivated\n");
|
|
// break;
|
|
|
|
// default:
|
|
// fprintf(stderr,"IODEBUG unsupported register code\n");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Static function
|
|
void bx_iodebug_c::mem_write( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
|
|
{
|
|
Bit32u data32;
|
|
Bit16u data16;
|
|
Bit8u data8;
|
|
|
|
unsigned int area;
|
|
if( !bx_iodebug_s.enabled ) return;
|
|
|
|
area = bx_iodebug_c::range_test( addr, len );
|
|
// Device is enabled, testing address ranges
|
|
if( area )
|
|
{
|
|
area--;
|
|
#if BX_DEBUGGER
|
|
fprintf( stdout, "%s @ eip: %08X wrote at monitored memory location %8X\n", cpu->name, cpu->get_EIP(), addr);
|
|
bx_guard.interrupt_requested=1;
|
|
#else
|
|
fprintf( stderr,
|
|
"IODEBUG write to monitored memory area: %2i\tby EIP:\t\t%08X\n\trange start: \t\t%08X\trange end:\t%08X\n\taddress accessed:\t%08X\tdata written:\t",
|
|
area,
|
|
cpu->get_EIP(),
|
|
bx_iodebug_s.monitored_mem_areas_start[area],
|
|
bx_iodebug_s.monitored_mem_areas_end[area],
|
|
(unsigned int)addr);
|
|
|
|
data32 = * (Bit32u *)data;
|
|
data16 = (Bit16u)data32;
|
|
data8 = (Bit8u)data32;
|
|
|
|
switch(len)
|
|
{
|
|
case(1):
|
|
fprintf(stderr,"%02X\n", (unsigned int)data8);
|
|
break;
|
|
|
|
case(2):
|
|
fprintf(stderr,"%04X\n", (unsigned int)data16);
|
|
break;
|
|
|
|
case(4):
|
|
fprintf(stderr,"%08X\n", (unsigned int)data32);
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr, "unsupported write size\n");
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void bx_iodebug_c::mem_read( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
|
|
{
|
|
Bit32u data32;
|
|
Bit16u data16;
|
|
Bit8u data8;
|
|
|
|
unsigned int area;
|
|
if( !bx_iodebug_s.enabled ) return;
|
|
|
|
area = bx_iodebug_c::range_test( addr, len );
|
|
// Device is enabled, testing address ranges
|
|
if( area )
|
|
{
|
|
area--;
|
|
#if BX_DEBUGGER
|
|
fprintf( stdout, "%s @ eip: %8X wrote at monitored memory location %8X\n", cpu->name, cpu->get_EIP(), addr);
|
|
bx_guard.interrupt_requested=1;
|
|
#else
|
|
fprintf( stderr,
|
|
"IODEBUG read to monitored memory area: %2i\tby EIP:\t\t%08X\n\trange start: \t\t%08X\trange end:\t%08X\n\taddress accessed:\t%08X\tdata written:\t",
|
|
area,
|
|
cpu->get_EIP(),
|
|
bx_iodebug_s.monitored_mem_areas_start[area],
|
|
bx_iodebug_s.monitored_mem_areas_end[area],
|
|
(unsigned int)addr);
|
|
data32 = * (Bit32u *)data;
|
|
data16 = (Bit16u)data32;
|
|
data8 = (Bit8u)data32;
|
|
|
|
switch(len)
|
|
{
|
|
case(1):
|
|
fprintf(stderr,"%02X\n", (unsigned int)data8);
|
|
break;
|
|
|
|
case(2):
|
|
fprintf(stderr,"%04X\n", (unsigned int)data16);
|
|
break;
|
|
|
|
case(4):
|
|
fprintf(stderr,"%08X\n", (unsigned int)data32);
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr, "unsupported write size\n");
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int bx_iodebug_c::range_test( Bit32u addr, unsigned int len )
|
|
{
|
|
unsigned int i;
|
|
|
|
for(i=0;i<BX_IODEBUG_MAX_AREAS;i++)
|
|
{
|
|
if( (bx_iodebug_s.monitored_mem_areas_start[i]!=0) ||
|
|
(bx_iodebug_s.monitored_mem_areas_end[i]!=0) )
|
|
{
|
|
if( (Bit32u)(addr+len-1) < bx_iodebug_s.monitored_mem_areas_start[i] )
|
|
continue;
|
|
if( addr < bx_iodebug_s.monitored_mem_areas_end[i] )
|
|
{
|
|
return(++i);
|
|
}
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void bx_iodebug_c::add_range( Bit32u addr_start, Bit32u addr_end )
|
|
{
|
|
unsigned int i;
|
|
for(i=0;i<BX_IODEBUG_MAX_AREAS;i++)
|
|
{
|
|
if( !bx_iodebug_s.monitored_mem_areas_start[i] &&
|
|
!bx_iodebug_s.monitored_mem_areas_end[i] )
|
|
{
|
|
bx_iodebug_s.monitored_mem_areas_start[i] = addr_start;
|
|
bx_iodebug_s.monitored_mem_areas_end[i] = addr_end;
|
|
// fprintf(stderr, "IODEBUG added range successfully in slot: %i\n",i);
|
|
return;
|
|
}
|
|
}
|
|
// fprintf(stderr, "IODEBUG unable to register memory range, all slots taken\n");
|
|
}
|
|
#endif /* if BX_IODEBUG_SUPPORT */
|