target/cortex_m: do not use VECTRESET on Cortex-M0, M0+ and M1

Cortex-M0, M0+ and M1 do not support VECTRESET bit in AIRCR.
Without this change the 'reset' command silently fails if VECTRESET
is requested.

Detect these cores, show warning if VECTRESET is about to use
and use SYSRESETREQ instead.

Change-Id: Ief174373e3ef0e6b287c57911c0aca4dfa8209f2
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/4794
Tested-by: jenkins
Reviewed-by: Jean-Christian de Rivaz <jcamdr70@gmail.com>
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
log_output
Tomas Vanek 2018-12-07 17:00:12 +01:00
parent 651998e337
commit cb5c6477f5
3 changed files with 28 additions and 6 deletions

View File

@ -9002,11 +9002,15 @@ otherwise fallback to @option{vectreset}.
@item @option{sysresetreq} use NVIC SYSRESETREQ to reset system. @item @option{sysresetreq} use NVIC SYSRESETREQ to reset system.
@item @option{vectreset} use NVIC VECTRESET to reset system. @item @option{vectreset} use NVIC VECTRESET to reset system.
@end itemize @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 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 are unaffected. A solution would be to use a @code{reset-init} event handler
the peripherals. to manually reset the peripherals.
@xref{targetevents,,Target Events}. @xref{targetevents,,Target Events}.
Cortex-M0, M0+ and M1 do not support @option{vectreset}, use @option{sysresetreq}
instead.
@end deffn @end deffn
@subsection ARMv8-A specific commands @subsection ARMv8-A specific commands

View File

@ -1041,10 +1041,18 @@ static int cortex_m_assert_reset(struct target *target)
retval = ERROR_OK; retval = ERROR_OK;
} else { } else {
/* Use a standard Cortex-M3 software reset mechanism. /* 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 * This has the disadvantage of not resetting the peripherals, so a
* reset-init event handler is needed to perform any peripheral resets. * 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) LOG_DEBUG("Using Cortex-M %s", (reset_config == CORTEX_M_RESET_SYSRESETREQ)
? "SYSRESETREQ" : "VECTRESET"); ? "SYSRESETREQ" : "VECTRESET");
@ -2027,6 +2035,9 @@ int cortex_m_examine(struct target *target)
} }
LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid); 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) { if (i == 4) {
target_read_u32(target, MVFR0, &mvfr0); target_read_u32(target, MVFR0, &mvfr0);
target_read_u32(target, MVFR1, &mvfr1); target_read_u32(target, MVFR1, &mvfr1);
@ -2418,8 +2429,14 @@ COMMAND_HANDLER(handle_cortex_m_reset_config_command)
if (CMD_ARGC > 0) { if (CMD_ARGC > 0) {
if (strcmp(*CMD_ARGV, "sysresetreq") == 0) if (strcmp(*CMD_ARGV, "sysresetreq") == 0)
cortex_m->soft_reset_config = CORTEX_M_RESET_SYSRESETREQ; 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) { switch (cortex_m->soft_reset_config) {

View File

@ -184,6 +184,7 @@ struct cortex_m_common {
struct reg_cache *dwt_cache; struct reg_cache *dwt_cache;
enum cortex_m_soft_reset_config soft_reset_config; enum cortex_m_soft_reset_config soft_reset_config;
bool vectreset_supported;
enum cortex_m_isrmasking_mode isrmasking_mode; enum cortex_m_isrmasking_mode isrmasking_mode;