diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 9497aa037..aeaeb1829 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -652,6 +652,11 @@ static int cortex_m_endreset_event(struct target *target) register_cache_invalidate(armv7m->arm.core_cache); + /* TODO: invalidate also working areas (needed in the case of detected reset). + * Doing so will require flash drivers to test if working area + * is still valid in all target algo calling loops. + */ + /* make sure we have latest dhcsr flags */ retval = cortex_m_read_dhcsr_atomic_sticky(target); if (retval != ERROR_OK) @@ -2396,6 +2401,20 @@ int cortex_m_examine(struct target *target) retval = target_read_u32(target, DCB_DHCSR, &cortex_m->dcb_dhcsr); if (retval != ERROR_OK) return retval; + + /* Don't cumulate sticky S_RESET_ST at the very first read of DHCSR + * as S_RESET_ST may indicate a reset that happened long time ago + * (most probably the power-on reset before OpenOCD was started). + * As we are just initializing the debug system we do not need + * to call cortex_m_endreset_event() in the following poll. + */ + if (!cortex_m->dcb_dhcsr_sticky_is_recent) { + cortex_m->dcb_dhcsr_sticky_is_recent = true; + if (cortex_m->dcb_dhcsr & S_RESET_ST) { + LOG_TARGET_DEBUG(target, "reset happened some time ago, ignore"); + cortex_m->dcb_dhcsr &= ~S_RESET_ST; + } + } cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr); if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) { diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 168613590..69368a919 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -206,6 +206,8 @@ struct cortex_m_common { /* Context information */ uint32_t dcb_dhcsr; uint32_t dcb_dhcsr_cumulated_sticky; + /* DCB DHCSR has been at least once read, so the sticky bits have been reset */ + bool dcb_dhcsr_sticky_is_recent; uint32_t nvic_dfsr; /* Debug Fault Status Register - shows reason for debug halt */ uint32_t nvic_icsr; /* Interrupt Control State Register - shows active and pending IRQ */