aboutsummaryrefslogtreecommitdiffstats
path: root/tools/ioemu/iodev/iodebug.cc
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ioemu/iodev/iodebug.cc')
-rw-r--r--tools/ioemu/iodev/iodebug.cc354
1 files changed, 354 insertions, 0 deletions
diff --git a/tools/ioemu/iodev/iodebug.cc b/tools/ioemu/iodev/iodebug.cc
new file mode 100644
index 0000000000..ca2314ede6
--- /dev/null
+++ b/tools/ioemu/iodev/iodebug.cc
@@ -0,0 +1,354 @@
+/////////////////////////////////////////////////////////////////////////
+// $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 */