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

Reply via email to