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

-- gerrit

commit cc3b46f9b29fe19ca563236a2cf9143c9bc0fa03
Author: Tomas Vanek <[email protected]>
Date:   Tue Oct 31 16:42:02 2017 +0100

    target: introduce target_reset_prepare_trigger
    
    Target specific reset_assert and reset_deassert used to control
    reset lines. It prevents using correct reset execution on
    system with more than one target.
    
    The change adds target_reset_prepare_trigger(),
    target_reset_clear_internal_state() and new options for
    target arp_reset: prepare, trigger, clear_internal_state
    
    reset_deassert can be used on multicore as multiple deasserting
    reset lines makes no harm. To differentiate a new from legacy call
    to 'arp_reset deassert' a new alias 'post_deassert' is asigned
    to this option.
    
    The second option of arp_reset is extended to accept reset mode
    keywords: 'run', 'halt' and 'init' which is an alias for 'halt'.
    
    Change-Id: Ic4f00856dde12395ded173d3b22b50e524cd43bf
    Signed-off-by: Tomas Vanek <[email protected]>

diff --git a/src/target/startup.tcl b/src/target/startup.tcl
index b8d46cf..9138c06 100644
--- a/src/target/startup.tcl
+++ b/src/target/startup.tcl
@@ -43,6 +43,37 @@ proc arp_examine_all {} {
        }
 }
 
+proc arp_default_reset_assert_pre {} {
+       global arp_reset_mode
+       set t [target current]
+       if { (![using_jtag] || [jtag tapisenabled [$t cget -chain-position]])
+           && [reset_config_includes srst]
+           && [$t cget -dbg-under-srst] eq "gated"} {
+               $t arp_reset prepare $arp_reset_mode
+       }
+}
+
+proc arp_default_reset_assert_post {} {
+       global arp_reset_mode
+       set t [target current]
+       if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} {
+               set dbg_u_srst [$t cget -dbg-under-srst]
+               set srst [reset_config_includes srst]
+               set prep_trig [expr {$srst ? "prepare" : "trigger"}]
+               if {$dbg_u_srst eq "working" || !$srst && $dbg_u_srst eq 
"gated"} {
+                       $t arp_reset $prep_trig $arp_reset_mode
+               } elseif {$dbg_u_srst eq "cleared"} {
+                       $t arp_reset clear_internal_state 0
+               }
+       }
+}
+
+proc set_debug_under_reset { target capability } {
+       $target configure -event reset-assert-pre arp_default_reset_assert_pre
+       $target configure -event reset-assert-post arp_default_reset_assert_post
+       $target configure -dbg-under-srst $capability
+}
+
 proc ocd_process_reset_inner { MODE } {
        set targets [target names]
 
@@ -79,7 +110,8 @@ proc ocd_process_reset_inner { MODE } {
        # 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"} {
+                       set dbg_u_srst [$t cget -dbg-under-srst]
+                       if {$dbg_u_srst ne "working" && $dbg_u_srst ne 
"unknown"} {
                                reset_config srst_gates_jtag
                                echo "'srst_nogate' is not supported by at 
least one target"
                                echo "Reset config changed to 'srst_gates_jtag'"
@@ -106,25 +138,17 @@ proc ocd_process_reset_inner { MODE } {
        }
 
        # Prepare all targets with debug not working under SRST
-       # Note: Preparing a target with debug cleared by SRST has no point
-       # if SRST enabled
+       # TODO: for old targets only, remove
        foreach t $targets {
-               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
+               if {(![using_jtag] || [jtag tapisenabled [$t cget 
-chain-position]])
+                   && [$t cget -dbg-under-srst] eq "unknown"} {
+                       $t arp_reset assert $MODE
                }
        }
 
        # 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
        }
@@ -141,7 +165,7 @@ proc ocd_process_reset_inner { MODE } {
        }
        foreach t $targets {
                if {![using_jtag] || [jtag tapisenabled [$t cget 
-chain-position]]} {
-                       $t arp_reset deassert $arp_reset_halting
+                       $t arp_reset [expr {[$t cget -dbg-under-srst] eq 
"unknown"?"deassert":"post_deassert"}] $MODE
                }
        }
        foreach t $targets {
diff --git a/src/target/target.c b/src/target/target.c
index d4386e2..f385ee3 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -156,6 +156,10 @@ static const Jim_Nvp nvp_assert[] = {
        { .name = "F", NVP_DEASSERT },
        { .name = "t", NVP_ASSERT },
        { .name = "f", NVP_DEASSERT },
+       { .name = "prepare", NVP_PREPARE },
+       { .name = "trigger", NVP_TRIGGER },
+       { .name = "post_deassert", NVP_POST_DEASSERT },
+       { .name = "clear_internal_state", NVP_CLEAR_INTERNAL_STATE },
        { .name = NULL, .value = -1 }
 };
 
@@ -696,6 +700,7 @@ static int default_examine(struct target *target)
 }
 
 /* no check by default */
+/*TODO: remove and use reset_deassert_post or reset_end event */
 static int default_check_reset(struct target *target)
 {
        return ERROR_OK;
@@ -759,6 +764,31 @@ const char *target_type_name(struct target *target)
        return target->type->name;
 }
 
+int target_reset_prepare_trigger(struct target *target, bool halt, bool 
trigger)
+{
+       if (!target->type->reset_prepare_trigger) {
+               if (halt || trigger) {
+                       LOG_ERROR("Target %s does not support 
reset_prepare_trigger",
+                                       target_name(target));
+                       return ERROR_FAIL;
+               }
+               LOG_DEBUG("Target %s does not support reset_prepare",
+                               target_name(target));
+               return ERROR_OK;
+       }
+       return target->type->reset_prepare_trigger(target, halt, trigger);
+}
+
+int target_reset_clear_internal_state(struct target *target)
+{
+       if (!target->type->reset_clear_internal_state) {
+               LOG_DEBUG("Target %s does not support 
reset_clear_internal_state",
+                               target_name(target));
+               return ERROR_OK;
+       }
+       return target->type->reset_clear_internal_state(target);
+}
+
 static int target_soft_reset_halt(struct target *target)
 {
        if (!target_was_examined(target)) {
@@ -5159,7 +5189,7 @@ static int jim_target_reset(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
 
        if (goi.argc != 2) {
                Jim_WrongNumArgs(interp, 0, argv,
-                               "([tT]|[fF]|assert|deassert) BOOL");
+                               
"[prepare|trigger|post_deassert|clear_internal_state|assert|deassert] 
[run|halt|BOOL]");
                return JIM_ERR;
        }
 
@@ -5170,36 +5200,101 @@ static int jim_target_reset(Jim_Interp *interp, int 
argc, Jim_Obj *const *argv)
                return e;
        }
        /* the halt or not param */
-       jim_wide a;
-       e = Jim_GetOpt_Wide(&goi, &a);
+       Jim_Obj *o;
+       e = Jim_GetOpt_Obj(&goi, &o);
        if (e != JIM_OK)
                return e;
 
        struct target *target = Jim_CmdPrivData(goi.interp);
+       Jim_Nvp *n2;
+       e = Jim_Nvp_name2value_obj(interp, nvp_reset_modes, o, &n2);
+       if (e == JIM_OK) {
+               target->reset_halt = n2->value == RESET_HALT || n2->value == 
RESET_INIT;
+       } else {
+               jim_wide a;
+               e = Jim_GetWide(interp, o, &a);
+               if (e == JIM_OK)
+                       target->reset_halt = a != 0;
+       }
+       if (e != JIM_OK) {
+               Jim_GetOpt_NvpUnknown(&goi, nvp_reset_modes, 1);
+               return e;
+       }
+
        if (!target->tap->enabled)
                return jim_target_tap_disabled(interp);
 
-       if (!target->type->assert_reset || !target->type->deassert_reset) {
-               Jim_SetResultFormatted(interp,
-                               "No target-specific reset for %s",
-                               target_name(target));
-               return JIM_ERR;
-       }
-
        if (target->defer_examine)
                target_reset_examined(target);
 
-       /* determine if we should halt or not. */
-       target->reset_halt = !!a;
-       /* When this happens - all workareas are invalid. */
-       target_free_all_working_areas_restore(target, 0);
-
-       /* do the assert */
-       if (n->value == NVP_ASSERT)
+       e = ERROR_FAIL;
+       switch (n->value) {
+       case NVP_ASSERT:
+               if (!target->type->assert_reset) {
+                       Jim_SetResultFormatted(interp,
+                               "No target-specific reset assert for %s",
+                               target_name(target));
+                       return JIM_ERR;
+               }
                e = target->type->assert_reset(target);
-       else
+               break;
+
+       case NVP_PREPARE:
+               if (target->type->reset_prepare_trigger) {
+                       e = target->type->reset_prepare_trigger(target, 
target->reset_halt, false);
+               } else {
+                       LOG_DEBUG("No target-specific reset prepare for %s",
+                               target_name(target));
+                       e = ERROR_OK;
+               }
+               break;
+
+       case NVP_TRIGGER:
+               if (!target->type->reset_prepare_trigger) {
+                       Jim_SetResultFormatted(interp,
+                               "No target-specific reset prepare/trigger for 
%s",
+                               target_name(target));
+                       return JIM_ERR;
+               }
+               e = target->type->reset_prepare_trigger(target, 
target->reset_halt, true);
+               break;
+
+       case NVP_DEASSERT:
+               if (!target->type->deassert_reset) {
+                       Jim_SetResultFormatted(interp,
+                               "No target-specific reset deassert for %s",
+                               target_name(target));
+                       return JIM_ERR;
+               }
                e = target->type->deassert_reset(target);
-       return (e == ERROR_OK) ? JIM_OK : JIM_ERR;
+               break;
+
+       case NVP_POST_DEASSERT:
+               if (target->type->deassert_reset) {
+                       e = target->type->deassert_reset(target);
+               } else {
+                       LOG_DEBUG("No target-specific reset post_deassert for 
%s",
+                               target_name(target));
+                       e = ERROR_OK;
+               }
+               break;
+
+       case NVP_CLEAR_INTERNAL_STATE:
+               if (target->type->reset_clear_internal_state) {
+                       e = target->type->reset_clear_internal_state(target);
+               } else {
+                       LOG_DEBUG("No target-specific reset clear internal 
state for %s",
+                               target_name(target));
+                       e = ERROR_OK;
+               }
+       }
+       if (e != ERROR_OK)
+               return JIM_ERR;
+
+       /* When this happens - all workareas are invalid. */
+       /*TODO: move to reset_clear_internal_state */
+       target_free_all_working_areas_restore(target, 0);
+       return JIM_OK;
 }
 
 static int jim_target_halt(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
diff --git a/src/target/target.h b/src/target/target.h
index 60223d4..a9a6ac0 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -67,6 +67,10 @@ enum target_state {
 enum nvp_assert {
        NVP_DEASSERT,
        NVP_ASSERT,
+       NVP_PREPARE,
+       NVP_TRIGGER,
+       NVP_POST_DEASSERT,
+       NVP_CLEAR_INTERNAL_STATE,
 };
 
 enum target_dbg_under_srst {
@@ -368,6 +372,8 @@ int target_poll(struct target *target);
 int target_resume(struct target *target, int current, target_addr_t address,
                int handle_breakpoints, int debug_execution);
 int target_halt(struct target *target);
+int target_reset_prepare_trigger(struct target *target, bool halt, bool 
trigger);
+int target_reset_clear_internal_state(struct target *target);
 int target_call_event_callbacks(struct target *target, enum target_event 
event);
 int target_call_reset_callbacks(struct target *target, enum target_reset_mode 
reset_mode);
 int target_call_trace_callbacks(struct target *target, size_t len, uint8_t 
*data);
diff --git a/src/target/target_type.h b/src/target/target_type.h
index 0960e6d..281cecf 100644
--- a/src/target/target_type.h
+++ b/src/target/target_type.h
@@ -86,7 +86,23 @@ struct target_type {
         * reset run; halt
      */
        int (*deassert_reset)(struct target *target);
+       /**
+        * Substitutes assert_reset
+        * Prepares debug circuitry before or during SRST
+        * Optionally triggers reset using a debug register
+        * DOES NOT CONTROL SRST LINE!!!
+        *
+        * @param target The target to work on
+        * @param halt Prepare halt after reset
+        * @param trigger Trigger reset by setting a debug register
+        */
+       int (*reset_prepare_trigger)(struct target *target, bool halt, bool 
trigger);
        int (*soft_reset_halt)(struct target *target);
+       /**
+        * Internal target adjustment after reset
+        * Typically sets target state and clears register cache
+        */
+       int (*reset_clear_internal_state)(struct target *target);
 
        /**
         * Target register access for GDB.  Do @b not call this function

-- 

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