diff --git a/bochs/iodev/iodebug.cc b/bochs/iodev/iodebug.cc index 756e0911f..12c655ae4 100644 --- a/bochs/iodev/iodebug.cc +++ b/bochs/iodev/iodebug.cc @@ -1,97 +1,156 @@ #include "bochs.h" bx_iodebug_c bx_iodebug; +bx_iodebug_c *bx_iodebug_ptr; + + struct bx_iodebug_s_type { + Boolean 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); - memset(&s, 0, sizeof(s)); + } + + + + // Destructor bx_iodebug_c::~bx_iodebug_c( void ) { } + + + + int bx_iodebug_c::init( bx_devices_c *d ) { int i; BX_IODEBUG_THIS devices = d; BX_IODEBUG_THIS devices->register_io_read_handler(this, read_handler, 0x8A00,"BOCHS IODEBUG"); - BX_IODEBUG_THIS devices->register_io_read_handler(this, read_handler, 0x8A01,"BOCHS IODEBUG"); - BX_IODEBUG_THIS devices->register_io_write_handler(this, write_handler, 0x8A00,"BOCHS IODEBUG"); BX_IODEBUG_THIS devices->register_io_write_handler(this, write_handler, 0x8A01,"BOCHS IODEBUG"); fprintf( stderr, "IODEBUG initialized\n"); - BX_IODEBUG_THIS s.enabled = 0; - BX_IODEBUG_THIS s.register_select = 0; + bx_iodebug_s.enabled = 0; + bx_iodebug_s.register_select = 0; for(i=0;iread(addr, 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_THIS s.enabled) return(0x8A00); + 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 == 0x8A00 && dvalue == 0x8A00 ) + if( addr == 0x8A01 && io_len == 2 ) { - if( BX_IODEBUG_THIS s.enabled ) - fprintf( stderr, "IODEBUG device already activated\n"); - else - { - BX_IODEBUG_THIS s.enabled=1; - fprintf( stderr, "IODEBUG device activated\n"); - } + bx_iodebug_s.registers[bx_iodebug_s.register_select] = + (bx_iodebug_s.registers[bx_iodebug_s.register_select] << 16) + + (dvalue & 0x0000FFFF ); } - else if ( BX_IODEBUG_THIS s.enabled ) + if( (addr != 0x8A00) || (io_len != 2) ) return; + + if( !bx_iodebug_s.enabled ) { - - // Register Select port - if( addr == 0x8A00 ) + if( dvalue == 0x8A00 ) { - if( dvalue == 0x8AFF ) - { - BX_IODEBUG_THIS s.enabled = 0; - fprintf( stderr, "IODEBUG device deactivated\n"); - } - fprintf( stderr, "IODEBUG register selected: %8x\n", dvalue); - BX_IODEBUG_THIS s.register_select = dvalue; + bx_iodebug_s.enabled = 1; + fprintf(stderr, "IODEBUG enabled\n"); + bx_iodebug_s.registers[0] = 0; + bx_iodebug_s.registers[1] = 0; } + return; + } - // Data port - else - { - fprintf( stderr, "IODEBUG value written to register %2x: %8x\n", BX_IODEBUG_THIS s.register_select, dvalue); - } + 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; + + case( 0x8AFF ): + bx_iodebug_s.enabled = 0; + fprintf( stderr, "IODEBUG device deactivated\n"); + break; + + default: + fprintf(stderr,"IODEBUG unsupported register code\n"); } } @@ -99,24 +158,30 @@ void bx_iodebug_c::write( Bit32u addr, Bit32u dvalue, unsigned int io_len ) + + + +// Static function void bx_iodebug_c::mem_write( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data) { Bit32u data32; Bit16u data16; Bit8u data8; - int area; - if( !BX_IODEBUG_THIS s.enabled ) return; + 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 = BX_IODEBUG_THIS range_test( addr, len ) ) + if( area ) { area--; fprintf( stderr, - "IODEBUG write to monitored memory area %i\n\trange start: %8x\trange end: %8x\n\taddress accessed: %8x\tdata written: ", + "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, - BX_IODEBUG_THIS s.monitored_mem_areas_start[area], - BX_IODEBUG_THIS s.monitored_mem_areas_end[area], + bx_cpu.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; @@ -125,15 +190,15 @@ void bx_iodebug_c::mem_write( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *da switch(len) { case(1): - fprintf(stderr,"%2x\n", (unsigned int)data8); + fprintf(stderr,"%02X\n", (unsigned int)data8); break; case(2): - fprintf(stderr,"%4x\n", (unsigned int)data16); + fprintf(stderr,"%04X\n", (unsigned int)data16); break; case(4): - fprintf(stderr,"%8x\n", (unsigned int)data32); + fprintf(stderr,"%08X\n", (unsigned int)data32); break; default: @@ -146,9 +211,12 @@ void bx_iodebug_c::mem_write( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *da + + + void bx_iodebug_c::mem_read( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data) { - if( !BX_IODEBUG_THIS s.enabled ) return; + if( !bx_iodebug_s.enabled ) return; // Device is enabled, testing address range } @@ -156,18 +224,47 @@ void bx_iodebug_c::mem_read( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *dat + + + unsigned int bx_iodebug_c::range_test( Bit32u addr, unsigned int len ) { - int i; + unsigned int i; + for(i=0;i BX_IODEBUG_THIS s.monitored_mem_areas_end[i] ) + 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