[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