Skip over a bkpt instruction if found on resume/step. Only software breakpoints known to openod are handled. So this handles the special case of a user added bkpt, eg. semi-hosting.
Signed-off-by: Spencer Oliver <ntfr...@users.sourceforge.net> --- src/target/armv7m.c | 31 +++++++++++++++++++++++++++++++ src/target/armv7m.h | 2 ++ src/target/cortex_m3.c | 12 ++++++++++++ 3 files changed, 45 insertions(+), 0 deletions(-) diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 233fb95..2e21e10 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -694,6 +694,37 @@ int armv7m_blank_check_memory(struct target *target, return ERROR_OK; } +int armv7m_check_bkpt_inst(struct target *target) +{ + struct armv7m_common *armv7m = target_to_armv7m(target); + struct reg *r = armv7m->core_cache->reg_list + 15; + + /* if we halted last time due to a bkpt instruction + * then we have to manually step over it, otherwise + * the core will break again */ + + if (target->debug_reason == DBG_REASON_BREAKPOINT) + { + uint16_t op; + uint32_t pc = buf_get_u32(r->value, 0, 32); + + pc &= ~1; + if (target_read_u16(target, pc, &op) == ERROR_OK) + { + if ((op & 0xFF00) == 0xBE00) + { + pc = buf_get_u32(r->value, 0, 32) + 2; + buf_set_u32(r->value, 0, 32, pc); + r->dirty = true; + r->valid = true; + LOG_DEBUG("Skipping over BKPT instruction"); + } + } + } + + return ERROR_OK; +} + /*--------------------------------------------------------------------------*/ /* diff --git a/src/target/armv7m.h b/src/target/armv7m.h index 86caae2..27a6577 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -171,6 +171,8 @@ int armv7m_checksum_memory(struct target *target, int armv7m_blank_check_memory(struct target *target, uint32_t address, uint32_t count, uint32_t* blank); +int armv7m_check_bkpt_inst(struct target *target); + extern const struct command_registration armv7m_command_handlers[]; #endif /* ARMV7M_H */ diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index 48f8114..f2726c3 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -638,6 +638,15 @@ static int cortex_m3_resume(struct target *target, int current, r->valid = true; } + /* if we halted last time due to a bkpt instruction + * then we have to manually step over it, otherwise + * the core will break again */ + + if (!breakpoint_find(target, buf_get_u32(r->value, 0, 32)) && !debug_execution) + { + armv7m_check_bkpt_inst(target); + } + resume_pc = buf_get_u32(r->value, 0, 32); armv7m_restore_context(target); @@ -709,6 +718,8 @@ static int cortex_m3_step(struct target *target, int current, cortex_m3_unset_breakpoint(target, breakpoint); } + armv7m_check_bkpt_inst(target); + target->debug_reason = DBG_REASON_SINGLESTEP; armv7m_restore_context(target); @@ -735,6 +746,7 @@ static int cortex_m3_step(struct target *target, int current, LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32 " nvic_icsr = 0x%" PRIx32, cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr); + return ERROR_OK; } -- 1.6.5.1.1367.gcd48 _______________________________________________ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development