diff options
author | Spencer Oliver <ntfreak@users.sourceforge.net> | 2010-01-19 21:00:55 +0000 |
---|---|---|
committer | Spencer Oliver <ntfreak@users.sourceforge.net> | 2010-01-20 09:07:55 +0000 |
commit | 0c3a4b4d818554ea00dc993d31cea9f3e0d1a87d (patch) | |
tree | 5aaa6baf33bb49344f2f492a0eaf299032e08a13 /src/target/cortex_m3.c | |
parent | 20d1ef70e8417da7efc8a032992ee7672a19e296 (diff) |
ARMV7M: handle bkpt instruction on resume/step
Skip over a bkpt instruction if found on resume/step.
Only software breakpoints known to OpenOCD are currently handled.
So this handles the special case of either a user added bkpt
or library added, eg. semi-hosting support.
Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
Diffstat (limited to 'src/target/cortex_m3.c')
-rw-r--r-- | src/target/cortex_m3.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index 48f81148..762e3184 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -638,6 +638,16 @@ 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_maybe_skip_bkpt_inst(target, NULL); + } + resume_pc = buf_get_u32(r->value, 0, 32); armv7m_restore_context(target); @@ -690,6 +700,7 @@ static int cortex_m3_step(struct target *target, int current, struct swjdp_common *swjdp = &armv7m->swjdp_info; struct breakpoint *breakpoint = NULL; struct reg *pc = armv7m->core_cache->reg_list + 15; + bool bkpt_inst_found = false; if (target->state != TARGET_HALTED) { @@ -709,14 +720,23 @@ static int cortex_m3_step(struct target *target, int current, cortex_m3_unset_breakpoint(target, breakpoint); } + armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found); + target->debug_reason = DBG_REASON_SINGLESTEP; armv7m_restore_context(target); target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - /* set step and clear halt */ - cortex_m3_write_debug_halt_mask(target, C_STEP, C_HALT); + /* if no bkpt instruction is found at pc then we can perform + * a normal step, otherwise we have to manually step over the bkpt + * instruction - as such simulate a step */ + if (bkpt_inst_found == false) + { + /* set step and clear halt */ + cortex_m3_write_debug_halt_mask(target, C_STEP, C_HALT); + } + mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); /* registers are now invalid */ @@ -735,6 +755,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; } |