diff --git a/doc/openocd.texi b/doc/openocd.texi index 11ee93e2b..bc24aedb6 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -9002,11 +9002,15 @@ otherwise fallback to @option{vectreset}. @item @option{sysresetreq} use NVIC SYSRESETREQ to reset system. @item @option{vectreset} use NVIC VECTRESET to reset system. @end itemize -Using @option{vectreset} is a safe option for all current Cortex-M cores. + +Using @option{vectreset} is a safe option for Cortex-M3, M4 and M7 cores. This however has the disadvantage of only resetting the core, all peripherals -are unaffected. A solution would be to use a @code{reset-init} event handler to manually reset -the peripherals. +are unaffected. A solution would be to use a @code{reset-init} event handler +to manually reset the peripherals. @xref{targetevents,,Target Events}. + +Cortex-M0, M0+ and M1 do not support @option{vectreset}, use @option{sysresetreq} +instead. @end deffn @subsection ARMv8-A specific commands diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 07fea5137..bb8c06d0f 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -1041,10 +1041,18 @@ static int cortex_m_assert_reset(struct target *target) retval = ERROR_OK; } else { /* Use a standard Cortex-M3 software reset mechanism. - * We default to using VECRESET as it is supported on all current cores. + * We default to using VECRESET as it is supported on all current cores + * (except Cortex-M0, M0+ and M1 which support SYSRESETREQ only!) * This has the disadvantage of not resetting the peripherals, so a * reset-init event handler is needed to perform any peripheral resets. */ + if (!cortex_m->vectreset_supported + && reset_config == CORTEX_M_RESET_VECTRESET) { + reset_config = CORTEX_M_RESET_SYSRESETREQ; + LOG_WARNING("VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead."); + LOG_WARNING("Set 'cortex_m reset_config sysresetreq'."); + } + LOG_DEBUG("Using Cortex-M %s", (reset_config == CORTEX_M_RESET_SYSRESETREQ) ? "SYSRESETREQ" : "VECTRESET"); @@ -2027,6 +2035,9 @@ int cortex_m_examine(struct target *target) } LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid); + /* VECTRESET is not supported on Cortex-M0, M0+ and M1 */ + cortex_m->vectreset_supported = i > 1; + if (i == 4) { target_read_u32(target, MVFR0, &mvfr0); target_read_u32(target, MVFR1, &mvfr1); @@ -2418,8 +2429,14 @@ COMMAND_HANDLER(handle_cortex_m_reset_config_command) if (CMD_ARGC > 0) { if (strcmp(*CMD_ARGV, "sysresetreq") == 0) cortex_m->soft_reset_config = CORTEX_M_RESET_SYSRESETREQ; - else if (strcmp(*CMD_ARGV, "vectreset") == 0) - cortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET; + + else if (strcmp(*CMD_ARGV, "vectreset") == 0) { + if (target_was_examined(target) + && !cortex_m->vectreset_supported) + LOG_WARNING("VECTRESET is not supported on your Cortex-M core!"); + else + cortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET; + } } switch (cortex_m->soft_reset_config) { diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 2daf4cb24..22d9735e5 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -184,6 +184,7 @@ struct cortex_m_common { struct reg_cache *dwt_cache; enum cortex_m_soft_reset_config soft_reset_config; + bool vectreset_supported; enum cortex_m_isrmasking_mode isrmasking_mode;