Bochs/bochs/iodev/iodebug.cc

355 lines
7.6 KiB
C++
Raw Normal View History

/////////////////////////////////////////////////////////////////////////
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
// $Id: iodebug.cc,v 1.11 2002-10-24 21:07:38 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
#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);
}
// Destructor
bx_iodebug_c::~bx_iodebug_c( void )
{
}
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
int bx_iodebug_c::init( void )
{
int i;
BX_IODEBUG_THIS devices->register_io_read_handler(this, read_handler, 0x8A00,"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_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;
}
return(1);
}
int 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->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->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->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->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");
}