sim: implement watchpoint support.

This commit is contained in:
Daniel Beer 2012-04-25 13:31:00 +12:00
parent a354116441
commit f1e99c38d3
1 changed files with 35 additions and 3 deletions

View File

@ -38,6 +38,8 @@ struct sim_device {
int running;
uint16_t current_insn;
int watchpoint_hit;
};
#define MEM_GETB(dev, offset) ((dev)->memory[offset])
@ -51,6 +53,23 @@ struct sim_device {
(dev)->memory[offset | 1] = (value) >> 8; \
} while (0);
static void watchpoint_check(struct sim_device *dev, uint16_t addr)
{
int i;
for (i = 0; i < DEVICE_MAX_BREAKPOINTS; i++) {
const struct device_breakpoint *bp =
&dev->base.breakpoints[i];
if ((bp->flags & DEVICE_BP_ENABLED) &&
bp->type == DEVICE_BPTYPE_WATCH &&
bp->addr == addr) {
dev->watchpoint_hit = 1;
return;
}
}
}
static int fetch_operand(struct sim_device *dev,
int amode, int reg, int is_byte,
uint16_t *addr_ret, uint32_t *data_ret)
@ -114,6 +133,8 @@ static int fetch_operand(struct sim_device *dev,
break;
}
watchpoint_check(dev, addr);
if (addr_ret)
*addr_ret = addr;
@ -146,14 +167,19 @@ static int store_operand(struct sim_device *dev,
int amode, int reg, int is_byte,
uint16_t addr, uint16_t data)
{
if (amode == MSP430_AMODE_REGISTER) {
dev->regs[reg] = data;
return 0;
}
watchpoint_check(dev, addr);
if (is_byte)
MEM_SETB(dev, addr, data);
else
MEM_SETW(dev, addr, data);
if (amode == MSP430_AMODE_REGISTER)
dev->regs[reg] = data;
else if (addr < MEM_IO_END) {
if (addr < MEM_IO_END) {
if (is_byte)
return simio_write_b(addr, data);
@ -694,6 +720,7 @@ static device_status_t sim_poll(device_t dev_base)
return DEVICE_STATUS_HALTED;
ctrlc_reset();
dev->watchpoint_hit = 0;
while (count > 0) {
int i;
@ -714,6 +741,11 @@ static device_status_t sim_poll(device_t dev_base)
return DEVICE_STATUS_ERROR;
}
if (dev->watchpoint_hit) {
dev->running = 0;
return DEVICE_STATUS_HALTED;
}
if (ctrlc_check())
return DEVICE_STATUS_INTR;