This is an automated email from Gerrit. Tomas Vanek ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/2606
-- gerrit commit f1f118dc0f51de50b94de2dc8a5166e6f9e78662 Author: Tomas Vanek <[email protected]> Date: Sun Mar 15 19:09:15 2015 +0100 target/target, cortex_m: improve robustness of reset command Level 1 - any device: reset is not called if target is not examined (target.c) Level 2 - a Cortex-M device or a board 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. Main change is in cortex_m_assert_reset(): memory access errors are stored instead of immediate returning them to higher level. Errors from less important reads/writes are ignored. Requested reset always leads to a configured action. If no error is returned from memory access routines the change does not have any influence on program flow. Change-Id: I84fa869f4f58e2fa83b6ea75de84440d9dc3d929 Signed-off-by: Tomas Vanek <[email protected]> diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 357d468..4b210d0 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -996,33 +996,24 @@ static int cortex_m_assert_reset(struct target *target) /* Enable debug requests */ int retval; retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m->dcb_dhcsr); - if (retval != ERROR_OK) - return retval; - if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) { + /* Store important errors instead of failing and proceed to reset assert */ + + if (retval != ERROR_OK || !(cortex_m->dcb_dhcsr & C_DEBUGEN)) retval = mem_ap_write_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN); - if (retval != ERROR_OK) - return retval; - } /* If the processor is sleeping in a WFI or WFE instruction, the * C_HALT bit must be asserted to regain control */ - if (cortex_m->dcb_dhcsr & S_SLEEP) { + if (retval == ERROR_OK && (cortex_m->dcb_dhcsr & S_SLEEP)) retval = mem_ap_write_u32(swjdp, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN); - if (retval != ERROR_OK) - return retval; - } - retval = mem_ap_write_u32(swjdp, DCB_DCRDR, 0); - if (retval != ERROR_OK) - return retval; + mem_ap_write_u32(swjdp, DCB_DCRDR, 0); + /* Ignore less important errors */ if (!target->reset_halt) { /* Set/Clear C_MASKINTS in a separate operation */ if (cortex_m->dcb_dhcsr & C_MASKINTS) { - retval = mem_ap_write_atomic_u32(swjdp, DCB_DHCSR, + mem_ap_write_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT); - if (retval != ERROR_OK) - return retval; } /* clear any debug flags before resuming */ @@ -1037,16 +1028,19 @@ static int cortex_m_assert_reset(struct target *target) * bad vector table entries. Should this include MMERR or * other flags too? */ - retval = mem_ap_write_atomic_u32(swjdp, DCB_DEMCR, + int retval2 = mem_ap_write_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET); - if (retval != ERROR_OK) - return retval; + if (retval != ERROR_OK || retval2 != ERROR_OK) + LOG_INFO("AP write error, reset will not halt"); } if (jtag_reset_config & RESET_HAS_SRST) { /* default to asserting srst */ if (!srst_asserted) adapter_assert_reset(); + + /* srst is asserted, ignore AP access errors */ + 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. @@ -1061,27 +1055,23 @@ static int cortex_m_assert_reset(struct target *target) "handler to reset any peripherals or configure hardware srst support."); } - retval = mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR, + int retval3 = mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | ((reset_config == CORTEX_M_RESET_SYSRESETREQ) ? AIRCR_SYSRESETREQ : AIRCR_VECTRESET)); - if (retval != ERROR_OK) + if (retval3 != ERROR_OK) LOG_DEBUG("Ignoring AP write error right after reset"); - retval = ahbap_debugport_init(swjdp); - if (retval != ERROR_OK) { + retval3 = ahbap_debugport_init(swjdp); + if (retval3 != ERROR_OK) LOG_ERROR("DP initialisation failed"); - return retval; - } - { + else { /* I do not know why this is necessary, but it * fixes strange effects (step/resume cause NMI * after reset) on LM3S6918 -- Michael Schwingen */ uint32_t tmp; - retval = mem_ap_read_atomic_u32(swjdp, NVIC_AIRCR, &tmp); - if (retval != ERROR_OK) - return retval; + mem_ap_read_atomic_u32(swjdp, NVIC_AIRCR, &tmp); } } @@ -1090,6 +1080,10 @@ static int cortex_m_assert_reset(struct target *target) register_cache_invalidate(cortex_m->armv7m.arm.core_cache); + /* now return stored error code if any */ + if (retval != ERROR_OK) + return retval; + if (target->reset_halt) { retval = target_halt(target); if (retval != ERROR_OK) diff --git a/src/target/target.c b/src/target/target.c index 5c88384..10887ce 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -4874,7 +4874,9 @@ static int jim_target_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (!target->tap->enabled) return jim_target_tap_disabled(interp); if (!(target_was_examined(target))) { - LOG_ERROR("Target not examined yet"); + LOG_INFO("Target not examined yet - continuing"); +/* Question: any reason to return here? Do we need to check examined state at all? */ + if (0) return ERROR_TARGET_NOT_EXAMINED; } if (!target->type->assert_reset || !target->type->deassert_reset) { -- ------------------------------------------------------------------------------ Dive into the World of Parallel Programming The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
