final revision of the memory protection material
This commit is contained in:
parent
a10f33a8c7
commit
0a762c4023
@ -1,97 +1,156 @@
|
|||||||
#include "bochs.h"
|
#include "bochs.h"
|
||||||
|
|
||||||
bx_iodebug_c bx_iodebug;
|
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
|
// Constructor
|
||||||
bx_iodebug_c::bx_iodebug_c( void )
|
bx_iodebug_c::bx_iodebug_c( void )
|
||||||
{
|
{
|
||||||
put("IODEBUG");
|
put("IODEBUG");
|
||||||
settype(IODEBUGLOG);
|
settype(IODEBUGLOG);
|
||||||
memset(&s, 0, sizeof(s));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
bx_iodebug_c::~bx_iodebug_c( void )
|
bx_iodebug_c::~bx_iodebug_c( void )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int bx_iodebug_c::init( bx_devices_c *d )
|
int bx_iodebug_c::init( bx_devices_c *d )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BX_IODEBUG_THIS devices = d;
|
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, 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, 0x8A00,"BOCHS IODEBUG");
|
||||||
BX_IODEBUG_THIS devices->register_io_write_handler(this, write_handler, 0x8A01,"BOCHS IODEBUG");
|
BX_IODEBUG_THIS devices->register_io_write_handler(this, write_handler, 0x8A01,"BOCHS IODEBUG");
|
||||||
fprintf( stderr, "IODEBUG initialized\n");
|
fprintf( stderr, "IODEBUG initialized\n");
|
||||||
|
|
||||||
BX_IODEBUG_THIS s.enabled = 0;
|
bx_iodebug_s.enabled = 0;
|
||||||
BX_IODEBUG_THIS s.register_select = 0;
|
bx_iodebug_s.register_select = 0;
|
||||||
for(i=0;i<BX_IODEBUG_MAX_AREAS;i++) {
|
for(i=0;i<BX_IODEBUG_MAX_AREAS;i++) {
|
||||||
BX_IODEBUG_THIS s.monitored_mem_areas_start[i] = 0;
|
bx_iodebug_s.monitored_mem_areas_start[i] = 0;
|
||||||
BX_IODEBUG_THIS s.monitored_mem_areas_end[i] = 0;
|
bx_iodebug_s.monitored_mem_areas_end[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Bit32u bx_iodebug_c::read_handler(void *this_ptr, Bit32u addr, unsigned io_len)
|
Bit32u bx_iodebug_c::read_handler(void *this_ptr, Bit32u addr, unsigned io_len)
|
||||||
{
|
{
|
||||||
bx_iodebug_c *class_ptr = (bx_iodebug_c *) this_ptr;
|
bx_iodebug_ptr = (bx_iodebug_c *) this_ptr;
|
||||||
return( class_ptr->read(addr, io_len) );
|
return( bx_iodebug_ptr->read(addr, io_len) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Bit32u bx_iodebug_c::read( Bit32u addr, unsigned 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);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void bx_iodebug_c::write_handler(void *this_ptr, Bit32u addr, Bit32u dvalue, unsigned io_len)
|
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;
|
bx_iodebug_c *class_ptr = (bx_iodebug_c *) this_ptr;
|
||||||
class_ptr->write( addr, dvalue, io_len );
|
class_ptr->write( addr, dvalue, io_len );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void bx_iodebug_c::write( Bit32u addr, Bit32u dvalue, unsigned int 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);
|
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 )
|
bx_iodebug_s.registers[bx_iodebug_s.register_select] =
|
||||||
fprintf( stderr, "IODEBUG device already activated\n");
|
(bx_iodebug_s.registers[bx_iodebug_s.register_select] << 16) +
|
||||||
else
|
(dvalue & 0x0000FFFF );
|
||||||
{
|
|
||||||
BX_IODEBUG_THIS s.enabled=1;
|
|
||||||
fprintf( stderr, "IODEBUG device activated\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( BX_IODEBUG_THIS s.enabled )
|
if( (addr != 0x8A00) || (io_len != 2) ) return;
|
||||||
|
|
||||||
|
if( !bx_iodebug_s.enabled )
|
||||||
{
|
{
|
||||||
|
if( dvalue == 0x8A00 )
|
||||||
// Register Select port
|
|
||||||
if( addr == 0x8A00 )
|
|
||||||
{
|
{
|
||||||
if( dvalue == 0x8AFF )
|
bx_iodebug_s.enabled = 1;
|
||||||
{
|
fprintf(stderr, "IODEBUG enabled\n");
|
||||||
BX_IODEBUG_THIS s.enabled = 0;
|
bx_iodebug_s.registers[0] = 0;
|
||||||
fprintf( stderr, "IODEBUG device deactivated\n");
|
bx_iodebug_s.registers[1] = 0;
|
||||||
}
|
|
||||||
fprintf( stderr, "IODEBUG register selected: %8x\n", dvalue);
|
|
||||||
BX_IODEBUG_THIS s.register_select = dvalue;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Data port
|
switch( dvalue )
|
||||||
else
|
{
|
||||||
{
|
case( 0x8A01 ):
|
||||||
fprintf( stderr, "IODEBUG value written to register %2x: %8x\n", BX_IODEBUG_THIS s.register_select, dvalue);
|
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)
|
void bx_iodebug_c::mem_write( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
|
||||||
{
|
{
|
||||||
Bit32u data32;
|
Bit32u data32;
|
||||||
Bit16u data16;
|
Bit16u data16;
|
||||||
Bit8u data8;
|
Bit8u data8;
|
||||||
|
|
||||||
int area;
|
unsigned int area;
|
||||||
if( !BX_IODEBUG_THIS s.enabled ) return;
|
if( !bx_iodebug_s.enabled ) return;
|
||||||
|
|
||||||
|
area = bx_iodebug_c::range_test( addr, len );
|
||||||
// Device is enabled, testing address ranges
|
// Device is enabled, testing address ranges
|
||||||
if( area = BX_IODEBUG_THIS range_test( addr, len ) )
|
if( area )
|
||||||
{
|
{
|
||||||
area--;
|
area--;
|
||||||
fprintf( stderr,
|
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,
|
area,
|
||||||
BX_IODEBUG_THIS s.monitored_mem_areas_start[area],
|
bx_cpu.eip,
|
||||||
BX_IODEBUG_THIS s.monitored_mem_areas_end[area],
|
bx_iodebug_s.monitored_mem_areas_start[area],
|
||||||
|
bx_iodebug_s.monitored_mem_areas_end[area],
|
||||||
(unsigned int)addr);
|
(unsigned int)addr);
|
||||||
data32 = * (Bit32u *)data;
|
data32 = * (Bit32u *)data;
|
||||||
data16 = (Bit16u)data32;
|
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)
|
switch(len)
|
||||||
{
|
{
|
||||||
case(1):
|
case(1):
|
||||||
fprintf(stderr,"%2x\n", (unsigned int)data8);
|
fprintf(stderr,"%02X\n", (unsigned int)data8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case(2):
|
case(2):
|
||||||
fprintf(stderr,"%4x\n", (unsigned int)data16);
|
fprintf(stderr,"%04X\n", (unsigned int)data16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case(4):
|
case(4):
|
||||||
fprintf(stderr,"%8x\n", (unsigned int)data32);
|
fprintf(stderr,"%08X\n", (unsigned int)data32);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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)
|
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
|
// 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 )
|
unsigned int bx_iodebug_c::range_test( Bit32u addr, unsigned int len )
|
||||||
{
|
{
|
||||||
int i;
|
unsigned int i;
|
||||||
|
|
||||||
for(i=0;i<BX_IODEBUG_MAX_AREAS;i++)
|
for(i=0;i<BX_IODEBUG_MAX_AREAS;i++)
|
||||||
{
|
{
|
||||||
if( BX_IODEBUG_THIS s.monitored_mem_areas_start[i] ||
|
if( (bx_iodebug_s.monitored_mem_areas_start[i]!=0) ||
|
||||||
BX_IODEBUG_THIS s.monitored_mem_areas_end[i] )
|
(bx_iodebug_s.monitored_mem_areas_end[i]!=0) )
|
||||||
{
|
{
|
||||||
if( (addr+len-1) < BX_IODEBUG_THIS s.monitored_mem_areas_start[i] )
|
if( (Bit32u)(addr+len-1) < bx_iodebug_s.monitored_mem_areas_start[i] )
|
||||||
continue;
|
continue;
|
||||||
if( addr > BX_IODEBUG_THIS s.monitored_mem_areas_end[i] )
|
if( addr < bx_iodebug_s.monitored_mem_areas_end[i] )
|
||||||
|
{
|
||||||
return(++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");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user