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/4280

-- gerrit

commit 9df92da13658ffbd7b19c59e72a536980aa76d73
Author: Tomas Vanek <[email protected]>
Date:   Sun Oct 29 15:27:13 2017 +0100

    target: add configuration option -dbg_under_srst [WIP]
    
    The option srst_nogate/srst_gates_jtag is implemented as an adapter 
attribute.
    In fact this is a feature of the target.
    
    This change adds a target configuration option -dbg_under_srst.
    srst_nogate/srst_gates_jtag is retained for compatibility with numerous 
scripts.
    
    ocd_reset_inner scripts checks all targets and if one or more of them
    are not compatible with srst_nogate, reconfigures reset to srst_gates_jtag.
    The loop calling all targets arp_reset assert is split to two parts to
    differentiate targets with working dbg_under_srst (they are set under SRST)
    and others (they are set before SRST asserted).
    
    I admit the use-case with two or more devices on one JTAG chain (where one
    has dbg_under_srst working and the other not) is very rare.
    
    Change-Id: Id8f321680b29823e49512caae715779be4ed69a8
    Signed-off-by: Tomas Vanek <[email protected]>

diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 149a923..3808782 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -1066,25 +1066,34 @@ int cortex_m_prepare_reset(struct target *target, bool 
halt, bool without_srst)
 
 static int cortex_m_assert_reset(struct target *target)
 {
+       struct cortex_m_common *cortex_m = target_to_cm(target);
+
        LOG_DEBUG("target->state: %s",
                target_state_name(target));
 
        if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) {
                /* allow scripts to override the reset event */
-
                target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
 
-               struct cortex_m_common *cortex_m = target_to_cm(target);
-               register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
                target->state = TARGET_RESET;
+               register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
 
                return ERROR_OK;
        }
 
        enum reset_types jtag_reset_config = jtag_get_reset_config();
+       bool srst = jtag_reset_config & RESET_HAS_SRST;
+
+       if (srst && target->dbg_under_srst == DBG_UNDER_SRST_CLEARED) {
+               /* Preparing reset would be useless on target where
+                * debug gets cleared by SRST */
+               target->state = TARGET_RESET;
+               register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
+
+               return ERROR_OK;
+       }
 
-       return cortex_m_prepare_reset(target, target->reset_halt,
-                               (jtag_reset_config & RESET_HAS_SRST) == 0);
+       return cortex_m_prepare_reset(target, target->reset_halt, !srst);
 }
 
 static int cortex_m_deassert_reset(struct target *target)
@@ -1099,9 +1108,9 @@ static int cortex_m_deassert_reset(struct target *target)
 
        enum reset_types jtag_reset_config = jtag_get_reset_config();
 
-       if ((jtag_reset_config & RESET_HAS_SRST) &&
-           !(jtag_reset_config & RESET_SRST_NO_GATING) &&
-               target_was_examined(target)) {
+       if ((jtag_reset_config & RESET_HAS_SRST)
+                       && target->dbg_under_srst != DBG_UNDER_SRST_WORKING
+                       && target_was_examined(target)) {
                int retval = dap_dp_init(armv7m->debug_ap->dap);
                if (retval != ERROR_OK) {
                        LOG_ERROR("DP initialisation failed");
diff --git a/src/target/startup.tcl b/src/target/startup.tcl
index feac984..b8d46cf 100644
--- a/src/target/startup.tcl
+++ b/src/target/startup.tcl
@@ -10,12 +10,14 @@ set in_process_reset 0
 # Catch reset recursion
 proc ocd_process_reset { MODE } {
        global in_process_reset
+       global arp_reset_mode
        if {$in_process_reset} {
                set in_process_reset 0
                return -code error "'reset' can not be invoked recursively"
        }
 
        set in_process_reset 1
+       set arp_reset_mode $MODE
        set success [expr [catch {ocd_process_reset_inner $MODE} result]==0]
        set in_process_reset 0
 
@@ -59,7 +61,8 @@ proc ocd_process_reset_inner { MODE } {
                return -code error "Invalid mode: $MODE, must be one of: halt, 
init, or run";
        }
 
-        set early_reset_init [expr [reset_config_includes independent_trst] || 
[reset_config_includes srst srst_nogate]]
+       global arp_reset_halting
+       set arp_reset_halting $halt
 
        # Target event handlers *might* change which TAPs are enabled
        # or disabled, so we fire all of them.  But don't issue any
@@ -70,10 +73,23 @@ proc ocd_process_reset_inner { MODE } {
        # relative to a previous restrictive scheme
 
        foreach t $targets {
-               # New event script.
                $t invoke-event reset-start
        }
 
+       # If srst_nogate is set, check all targets whether they support it
+       if {[reset_config_includes srst srst_nogate]} {
+               foreach t $targets {
+                       if {[$t cget -dbg-under-srst] ne "working"} {
+                               reset_config srst_gates_jtag
+                               echo "'srst_nogate' is not supported by at 
least one target"
+                               echo "Reset config changed to 'srst_gates_jtag'"
+                               break;
+                       }
+               }
+       }
+        set early_reset_init [expr {[reset_config_includes independent_trst]
+                                   || [reset_config_includes srst 
srst_nogate]}]
+
        if $early_reset_init {
                # We have an independent trst or no-gating srst
 
@@ -85,36 +101,47 @@ proc ocd_process_reset_inner { MODE } {
                arp_examine_all
        }
 
-       # Assert SRST, and report the pre/post events.
-       # Note:  no target sees SRST before "pre" or after "post".
        foreach t $targets {
                $t invoke-event reset-assert-pre
        }
+
+       # Prepare all targets with debug not working under SRST
+       # Note: Preparing a target with debug cleared by SRST has no point
+       # if SRST enabled
        foreach t $targets {
-               # C code needs to know if we expect to 'halt'
-               if {![using_jtag] || [jtag tapisenabled [$t cget 
-chain-position]]} {
-                       $t arp_reset assert $halt
+               set tapenabled [expr {![using_jtag] || [jtag tapisenabled [$t 
cget -chain-position]]}]
+               if {$tapenabled && [$t cget -dbg-under-srst] ne "working"} {
+                       $t arp_reset assert $arp_reset_halting
                }
        }
+
+       # Assert SRST
        reset_assert_final $MODE
+
+       # Prepare other targets under SRST
+       foreach t $targets {
+               set tapenabled [expr {![using_jtag] || [jtag tapisenabled [$t 
cget -chain-position]]}]
+               if {$tapenabled && [$t cget -dbg-under-srst] eq "working"} {
+                       $t arp_reset assert $arp_reset_halting
+               }
+       }
        foreach t $targets {
                $t invoke-event reset-assert-post
        }
 
-       # Now de-assert SRST, and report the pre/post events.
-       # Note:  no target sees !SRST before "pre" or after "post".
        foreach t $targets {
                $t invoke-event reset-deassert-pre
        }
+
+       # Deassert SRST
        reset_deassert_initial $MODE
        if { !$early_reset_init } {
                if [using_jtag] { jtag arp_init }
                arp_examine_all
        }
        foreach t $targets {
-               # Again, de-assert code needs to know if we 'halt'
                if {![using_jtag] || [jtag tapisenabled [$t cget 
-chain-position]]} {
-                       $t arp_reset deassert $halt
+                       $t arp_reset deassert $arp_reset_halting
                }
        }
        foreach t $targets {
@@ -124,7 +151,7 @@ proc ocd_process_reset_inner { MODE } {
        # Pass 1 - Now wait for any halt (requested as part of reset
        # assert/deassert) to happen.  Ideally it takes effect without
        # first executing any instructions.
-       if { $halt } {
+       if { $arp_reset_halting } {
                foreach t $targets {
                        if {[using_jtag] && ![jtag tapisenabled [$t cget 
-chain-position]]} {
                                continue
diff --git a/src/target/target.c b/src/target/target.c
index 36318d8..51e1f60 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -266,6 +266,12 @@ static const Jim_Nvp nvp_reset_modes[] = {
        { .name = NULL     , .value = -1 },
 };
 
+static const Jim_Nvp nvp_dbg_under_srst[] = {
+       { .name = "working", .value = DBG_UNDER_SRST_WORKING },
+       { .name = "gated", .value = DBG_UNDER_SRST_GATED },
+       { .name = "cleared", .value = DBG_UNDER_SRST_CLEARED },
+};
+
 const char *debug_reason_name(struct target *t)
 {
        const char *cp;
@@ -4463,6 +4469,7 @@ enum target_cfg_param {
        TCFG_CTIBASE,
        TCFG_RTOS,
        TCFG_DEFER_EXAMINE,
+       TCFG_DBG_UNDER_SRST,
 };
 
 static Jim_Nvp nvp_config_opts[] = {
@@ -4479,6 +4486,7 @@ static Jim_Nvp nvp_config_opts[] = {
        { .name = "-ctibase",          .value = TCFG_CTIBASE },
        { .name = "-rtos",             .value = TCFG_RTOS },
        { .name = "-defer-examine",    .value = TCFG_DEFER_EXAMINE },
+       { .name = "-dbg-under-srst",   .value = TCFG_DBG_UNDER_SRST },
        { .name = NULL, .value = -1 }
 };
 
@@ -4773,6 +4781,26 @@ no_params:
                        /* loop for more */
                        break;
 
+               case TCFG_DBG_UNDER_SRST:
+                       if (goi->isconfigure) {
+                               e = Jim_GetOpt_Nvp(goi, nvp_dbg_under_srst, &n);
+                               if (e != JIM_OK) {
+                                       Jim_GetOpt_NvpUnknown(goi, 
nvp_dbg_under_srst, 1);
+                                       return e;
+                               }
+                               target->dbg_under_srst = n->value;
+                       } else {
+                               if (goi->argc != 0)
+                                       goto no_params;
+                       }
+                       n = Jim_Nvp_value2name_simple(nvp_dbg_under_srst, 
target->dbg_under_srst);
+                       if (n->name == NULL) {
+                               target->dbg_under_srst = DBG_UNDER_SRST_WORKING;
+                               n = 
Jim_Nvp_value2name_simple(nvp_dbg_under_srst, target->dbg_under_srst);
+                       }
+                       Jim_SetResultString(goi->interp, n->name, -1);
+                       /* loop for more */
+                       break;
                }
        } /* while (goi->argc) */
 
diff --git a/src/target/target.h b/src/target/target.h
index 53f9e26..df445ab 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -69,6 +69,12 @@ enum nvp_assert {
        NVP_ASSERT,
 };
 
+enum target_dbg_under_srst {
+       DBG_UNDER_SRST_WORKING = 0,
+       DBG_UNDER_SRST_GATED = 1,
+       DBG_UNDER_SRST_CLEARED = 2,
+};
+
 enum target_reset_mode {
        RESET_UNKNOWN = 0,
        RESET_RUN = 1,          /* reset and let target run */
@@ -152,7 +158,8 @@ struct target {
 
        struct target_event_action *event_action;
 
-       int reset_halt;                                         /* attempt 
resetting the CPU into the halted mode? */
+       enum target_dbg_under_srst dbg_under_srst;      /* how SRST signal 
influences the debug circuitry */
+       int reset_halt;                                         /* attempt 
resetting the CPU into the halted mode */
        uint32_t working_area;                          /* working area 
(initialised RAM). Evaluated
                                                                                
 * upon first allocation from virtual/physical address. */
        bool working_area_virt_spec;            /* virtual address specified? */

-- 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to