Fixed watchpoints handling

This commit is contained in:
Stanislav Shwartsman 2008-05-31 20:59:38 +00:00
parent 764756d74a
commit 8d17e7b539
3 changed files with 54 additions and 52 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: dbg_main.cc,v 1.146 2008-05-23 17:49:44 sshwarts Exp $
// $Id: dbg_main.cc,v 1.147 2008-05-31 20:59:38 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -114,6 +114,13 @@ static disassembler bx_disassemble;
static Bit8u bx_disasm_ibuf[32];
static char bx_disasm_tbuf[512];
// watchpoints
static unsigned num_write_watchpoints = 0;
static unsigned num_read_watchpoints = 0;
static bx_phy_address write_watchpoint[MAX_WRITE_WATCHPOINTS];
static bx_phy_address read_watchpoint[MAX_READ_WATCHPOINTS];
static bx_bool watchpoint_continue = 0;
#define DBG_PRINTF_BUFFER_LEN 1024
void dbg_printf(const char *fmt, ...)
@ -514,9 +521,37 @@ void bx_dbg_halt(unsigned cpu)
dbg_printf("CPU %d: HALTED\n", cpu);
}
void bx_dbg_check_memory_access_watchpoints(unsigned cpu, bx_phy_address phy, unsigned len, unsigned rw)
{
if (rw == BX_WRITE) {
// Check for physical write watch points
// TODO: Each breakpoint should have an associated CPU#
for (unsigned i = 0; i < num_write_watchpoints; i++) {
if (write_watchpoint[i] <= phy && write_watchpoint[i] + len > phy) {
BX_CPU(cpu)->watchpoint = phy;
BX_CPU(cpu)->break_point = BREAK_POINT_WRITE;
break;
}
}
}
else {
// Check for physical read watch points
// TODO: Each breakpoint should have an associated CPU#
for (unsigned i = 0; i < num_read_watchpoints; i++) {
if (read_watchpoint[i] <= phy && read_watchpoint[i] + len > phy) {
BX_CPU(cpu)->watchpoint = phy;
BX_CPU(cpu)->break_point = BREAK_POINT_READ;
break;
}
}
}
}
void bx_dbg_lin_memory_access(unsigned cpu, bx_address lin, bx_phy_address phy, unsigned len, unsigned pl, unsigned rw, Bit8u *data)
{
if (! BX_CPU(dbg_cpu)->trace_mem)
bx_dbg_check_memory_access_watchpoints(cpu, phy. len, rw);
if (! BX_CPU(cpu)->trace_mem)
return;
dbg_printf("[CPU%d %s]: LIN 0x" FMT_ADDRX " PHY 0x" FMT_PHY_ADDRX " (len=%d, pl=%d)",
@ -547,7 +582,9 @@ void bx_dbg_lin_memory_access(unsigned cpu, bx_address lin, bx_phy_address phy,
void bx_dbg_phy_memory_access(unsigned cpu, bx_phy_address phy, unsigned len, unsigned rw, Bit8u *data)
{
if (! BX_CPU(dbg_cpu)->trace_mem)
bx_dbg_check_memory_access_watchpoints(cpu, phy. len, rw);
if (! BX_CPU(cpu)->trace_mem)
return;
dbg_printf("[CPU%d %s]: PHY 0x" FMT_PHY_ADDRX " (len=%d)",
@ -1459,12 +1496,6 @@ void bx_dbg_print_stack_command(unsigned nwords)
}
}
unsigned num_write_watchpoints = 0;
unsigned num_read_watchpoints = 0;
bx_phy_address write_watchpoint[MAX_WRITE_WATCHPOINTS];
bx_phy_address read_watchpoint[MAX_READ_WATCHPOINTS];
bx_bool watchpoint_continue = 0;
void bx_dbg_watch(int read, bx_phy_address address)
{
if (read == -1) {

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: debug.h,v 1.42 2008-04-19 20:11:30 sshwarts Exp $
// $Id: debug.h,v 1.43 2008-05-31 20:59:38 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -302,6 +302,9 @@ void bx_dbg_halt(unsigned cpu);
void bx_dbg_lin_memory_access(unsigned cpu, bx_address lin, bx_phy_address phy, unsigned len, unsigned pl, unsigned rw, Bit8u *data);
void bx_dbg_phy_memory_access(unsigned cpu, bx_phy_address phy, unsigned len, unsigned rw, Bit8u *data);
// check memory access for watchpoints
void bx_dbg_check_memory_access_watchpoints(unsigned cpu, bx_phy_address phy, unsigned len, unsigned rw)
// commands that work with Bochs param tree
void bx_dbg_restore_command(const char *param_name, const char *path);
void bx_dbg_show_param_command(char *param);
@ -323,26 +326,18 @@ char* bx_dbg_disasm_symbolic_address(Bit32u eip, Bit32u base);
// the rest for C++
#ifdef __cplusplus
// Read/write watchpoint hack
#define MAX_WRITE_WATCHPOINTS 16
#define MAX_READ_WATCHPOINTS 16
extern unsigned num_write_watchpoints;
extern bx_phy_address write_watchpoint[MAX_WRITE_WATCHPOINTS];
extern unsigned num_read_watchpoints;
extern bx_phy_address read_watchpoint[MAX_READ_WATCHPOINTS];
typedef enum {
STOP_NO_REASON = 0,
STOP_TIME_BREAK_POINT,
STOP_READ_WATCH_POINT,
STOP_WRITE_WATCH_POINT,
STOP_MAGIC_BREAK_POINT,
STOP_MODE_BREAK_POINT,
STOP_CPU_HALTED
STOP_NO_REASON = 0,
STOP_TIME_BREAK_POINT,
STOP_READ_WATCH_POINT,
STOP_WRITE_WATCH_POINT,
STOP_MAGIC_BREAK_POINT,
STOP_MODE_BREAK_POINT,
STOP_CPU_HALTED
} stop_reason_t;
typedef enum {
BREAK_POINT_MAGIC, BREAK_POINT_READ, BREAK_POINT_WRITE, BREAK_POINT_TIME
BREAK_POINT_MAGIC, BREAK_POINT_READ, BREAK_POINT_WRITE, BREAK_POINT_TIME
} break_point_t;
#define BX_DBG_REG_EIP 10
@ -365,7 +360,7 @@ void bx_debug_break(void);
void bx_dbg_exit(int code);
#if BX_DBG_EXTENSIONS
int bx_dbg_extensions(char *command);
int bx_dbg_extensions(char *command);
#else
#define bx_dbg_extensions(command) 0
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: memory.cc,v 1.68 2008-05-09 22:33:37 sshwarts Exp $
// $Id: memory.cc,v 1.69 2008-05-31 20:59:38 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -66,18 +66,6 @@ void BX_MEM_C::writePhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned le
BX_INSTR_PHY_WRITE(cpu->which_cpu(), a20addr, len);
#if BX_DEBUGGER
// (mch) Check for physical write break points, TODO
// (bbd) Each breakpoint should have an associated CPU#, TODO
for (unsigned i = 0; i < num_write_watchpoints; i++) {
if (write_watchpoint[i] == a20addr) {
cpu->watchpoint = a20addr;
cpu->break_point = BREAK_POINT_WRITE;
break;
}
}
#endif
#if BX_SUPPORT_APIC
bx_generic_apic_c *local_apic = &cpu->local_apic;
if (local_apic->is_selected(a20addr, len)) {
@ -234,18 +222,6 @@ void BX_MEM_C::readPhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned len
BX_INSTR_PHY_READ(cpu->which_cpu(), a20addr, len);
#if BX_DEBUGGER
// (mch) Check for physical read break points, TODO
// (bbd) Each breakpoint should have an associated CPU#, TODO
for (unsigned i = 0; i < num_read_watchpoints; i++) {
if (read_watchpoint[i] == a20addr) {
cpu->watchpoint = a20addr;
cpu->break_point = BREAK_POINT_READ;
break;
}
}
#endif
#if BX_SUPPORT_APIC
bx_generic_apic_c *local_apic = &cpu->local_apic;
if (local_apic->is_selected (a20addr, len)) {