Bochs/bochs/iodev/iodebug.cc
Stanislav Shwartsman 5873b26a82 Speed up compilation process.
bochs.h already not include iodev.h which reduces compilation dependences for almost all cpu and fpu files, now cpu files will not be recompiled if iodev includes was changed
2004-06-19 15:20:15 +00:00

303 lines
7.6 KiB
C++

/////////////////////////////////////////////////////////////////////////
// $Id: iodebug.cc,v 1.16 2004-06-19 15:20:12 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
#include "iodev.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 */