target: improve robustness of reset command
Before this change jim_target_reset() checked examined state of a target and failed without calling .assert_reset in particular target layer (and without comprehensible warning to user). Cortex-M target (which refuses access to DP under active SRST): If connection is lost then reset process fails before asserting SRST and connection with MCU is not restored. This resulted in: 1) A lot of Cortex-M MCUs required use of reset button or cycling power after firmware blocked SWD access somehow (sleep, misconfigured clock etc). If firmware blocks SWD access early during initialization, a MCU could become completely inaccessible by SWD. 2) If OpenOCD is (re)started and a MCU is in a broken state unresponsive to SWD, reset command does not work even if it could help to restore communication. Hopefully this scenario is not possible under full JTAG. jim_target_reset() in target.c now does not check examined state and delegates this task to a particular target. All targets have been checked and xx_assert_reset() (or xx_deassert_reset()) procedures were changed to check examined state if needed. Targets except arm11, cortex_a and cortex_m just fail if target is not examined although it may be possible to use at least hw reset. Left as TODO for developers familiar with these targets. cortex_m_assert_reset(): memory access errors are stored instead of immediate returning them to a higher level. Errors from less important reads/writes are ignored. Requested reset always leads to a configured action. arm11_assert_reset() just asserts hw reset in case of not examined target. cortex_a_assert_reset() works as usual in case of not examined target. Change-Id: I84fa869f4f58e2fa83b6ea75de84440d9dc3d929 Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-on: http://openocd.zylin.com/2606 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de> Reviewed-by: Paul Fertser <fercerpav@gmail.com>
This commit is contained in:
committed by
Freddie Chopin
parent
baf08b0a1a
commit
8825804273
@@ -694,21 +694,32 @@ static int arm11_assert_reset(struct target *target)
|
||||
{
|
||||
struct arm11_common *arm11 = target_to_arm11(target);
|
||||
|
||||
/* optionally catch reset vector */
|
||||
if (target->reset_halt && !(arm11->vcr & 1))
|
||||
CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr | 1));
|
||||
|
||||
/* Issue some kind of warm reset. */
|
||||
if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
|
||||
target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
|
||||
else if (jtag_get_reset_config() & RESET_HAS_SRST) {
|
||||
/* REVISIT handle "pulls" cases, if there's
|
||||
* hardware that needs them to work.
|
||||
*/
|
||||
jtag_add_reset(0, 1);
|
||||
if (!(target_was_examined(target))) {
|
||||
if (jtag_get_reset_config() & RESET_HAS_SRST)
|
||||
jtag_add_reset(0, 1);
|
||||
else {
|
||||
LOG_WARNING("Reset is not asserted because the target is not examined.");
|
||||
LOG_WARNING("Use a reset button or power cycle the target.");
|
||||
return ERROR_TARGET_NOT_EXAMINED;
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR("%s: how to reset?", target_name(target));
|
||||
return ERROR_FAIL;
|
||||
|
||||
/* optionally catch reset vector */
|
||||
if (target->reset_halt && !(arm11->vcr & 1))
|
||||
CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr | 1));
|
||||
|
||||
/* Issue some kind of warm reset. */
|
||||
if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
|
||||
target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
|
||||
else if (jtag_get_reset_config() & RESET_HAS_SRST) {
|
||||
/* REVISIT handle "pulls" cases, if there's
|
||||
* hardware that needs them to work.
|
||||
*/
|
||||
jtag_add_reset(0, 1);
|
||||
} else {
|
||||
LOG_ERROR("%s: how to reset?", target_name(target));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* registers are now invalid */
|
||||
|
||||
Reference in New Issue
Block a user