[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openocd-development
Subject:    [OpenOCD-devel] [PATCH]: 9df92da target: add configuration option -dbg_under_srst [WIP]
From:       gerrit () openocd ! org (gerrit)
Date:       2017-10-29 19:49:52
Message-ID: 20171029194952.5CEAA2522D54 () mail ! openocd ! org
[Download RAW message or body]

This is an automated email from Gerrit.

Tomas Vanek (vanekt@fbl.cz) just uploaded a new patch set to Gerrit, which you can \
find at http://openocd.zylin.com/4280

-- gerrit

commit 9df92da13658ffbd7b19c59e72a536980aa76d73
Author: Tomas Vanek <vanekt@fbl.cz>
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 <vanekt@fbl.cz>

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
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic