]> git.sur5r.net Git - openocd/commitdiff
target: groundwork for "reset-assert" event
authorDavid Brownell <dbrownell@users.sourceforge.net>
Sat, 28 Nov 2009 02:50:20 +0000 (18:50 -0800)
committerDavid Brownell <dbrownell@users.sourceforge.net>
Sat, 28 Nov 2009 02:50:20 +0000 (18:50 -0800)
This defines a "reset-assert" event and a supporting utility
routine, and documents both how targets should implement it
and how config scripts should use it.  Core-specific updates
are needed to make this work.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
doc/openocd.texi
src/target/target.c
src/target/target.h

index e94c9d02bfef6afe80f226273deb1f967bf98529..b32ed213f16aa1f6f8000451fbcb5c0fe8464ad1 100644 (file)
@@ -1411,6 +1411,20 @@ chip can be tweaked by the board.
 Some chips have specific ways the TRST and SRST signals are
 managed. In the unusual case that these are @emph{chip specific}
 and can never be changed by board wiring, they could go here.
+For example, some chips can't support JTAG debugging without
+both signals.
+
+Provide a @code{reset-assert} event handler if you can.
+Such a handler uses JTAG operations to reset the target,
+letting this target config be used in systems which don't
+provide the optional SRST signal, or on systems where you
+don't want to reset all targets at once.
+Such a handler might write to chip registers to force a reset,
+use a JRC to do that (preferable -- the target may be wedged!),
+or force a watchdog timer to trigger.
+(For Cortex-M3 targets, this is not necessary.  The target
+driver knows how to use trigger an NVIC reset when SRST is
+not available.)
 
 Some chips need special attention during reset handling if
 they're going to be used with JTAG.
@@ -1418,6 +1432,8 @@ An example might be needing to send some commands right
 after the target's TAP has been reset, providing a
 @code{reset-deassert-post} event handler that writes a chip
 register to report that JTAG debugging is being done.
+Another would be reconfiguring the watchdog so that it stops
+counting while the core is halted in the debugger.
 
 JTAG clocking constraints often change during reset, and in
 some cases target config files (rather than board config files)
@@ -2401,6 +2417,12 @@ There are also @emph{event handlers} associated with TAPs or Targets.
 Those handlers are Tcl procedures you can provide, which are invoked
 at particular points in the reset sequence.
 
+@emph{When SRST is not an option} you must set
+up a @code{reset-assert} event handler for your target.
+For example, some JTAG adapters don't include the SRST signal;
+and some boards have multiple targets, and you won't always
+want to reset everything at once.
+
 After configuring those mechanisms, you might still
 find your board doesn't start up or reset correctly.
 For example, maybe it needs a slightly different sequence
@@ -3390,9 +3412,14 @@ For example:
 @itemize @bullet
 @item What should happen when GDB connects? Should your target reset?
 @item When GDB tries to flash the target, do you need to enable the flash via a special command?
+@item Is using SRST appropriate (and possible) on your system?
+Or instead of that, do you need to issue JTAG commands to trigger reset?
+SRST usually resets everything on the scan chain, which can be inappropriate.
 @item During reset, do you need to write to certain memory locations
 to set up system clocks or
 to reconfigure the SDRAM?
+How about configuring the watchdog timer, or other peripherals,
+to stop running while you hold the core stopped for debugging?
 @end itemize
 
 All of the above items can be addressed by target event handlers.
@@ -3457,16 +3484,28 @@ The following target events are defined:
 @item @b{reset-assert-pre}
 @* Issued as part of @command{reset} processing
 after @command{reset_init} was triggered
-but before SRST alone is re-asserted on the tap.
+but before either SRST alone is re-asserted on the scan chain,
+or @code{reset-assert} is triggered.
+@item @b{reset-assert}
+@* Issued as part of @command{reset} processing
+after @command{reset-assert-pre} was triggered.
+When such a handler is present, cores which support this event will use
+it instead of asserting SRST.
+This support is essential for debugging with JTAG interfaces which
+don't include an SRST line (JTAG doesn't require SRST), and for
+selective reset on scan chains that have multiple targets.
 @item @b{reset-assert-post}
 @* Issued as part of @command{reset} processing
-when SRST is asserted on the tap.
+after @code{reset-assert} has been triggered.
+or the target asserted SRST on the entire scan chain.
 @item @b{reset-deassert-pre}
 @* Issued as part of @command{reset} processing
-when SRST is about to be released on the tap.
+after @code{reset-assert-post} has been triggered.
 @item @b{reset-deassert-post}
 @* Issued as part of @command{reset} processing
-when SRST has been released on the tap.
+after @code{reset-deassert-pre} has been triggered
+and (if the target is using it) after SRST has been
+released on the scan chain.
 @item @b{reset-end}
 @* Issued as the final step in @command{reset} processing.
 @ignore
index 3de9f2c6a3adbea8492b6d837eb62a3b9661490f..a2bd88689cd3b2d71ad38531f7f615b9b2f076a1 100644 (file)
@@ -147,6 +147,7 @@ static const Jim_Nvp nvp_target_event[] = {
        { .value = TARGET_EVENT_RESET_START, .name = "reset-start" },
 
        { .value = TARGET_EVENT_RESET_ASSERT_PRE,    .name = "reset-assert-pre" },
+       { .value = TARGET_EVENT_RESET_ASSERT,        .name = "reset-assert" },
        { .value = TARGET_EVENT_RESET_ASSERT_POST,   .name = "reset-assert-post" },
        { .value = TARGET_EVENT_RESET_DEASSERT_PRE,  .name = "reset-deassert-pre" },
        { .value = TARGET_EVENT_RESET_DEASSERT_POST, .name = "reset-deassert-post" },
@@ -154,8 +155,8 @@ static const Jim_Nvp nvp_target_event[] = {
        { .value = TARGET_EVENT_RESET_HALT_POST,     .name = "reset-halt-post" },
        { .value = TARGET_EVENT_RESET_WAIT_PRE,      .name = "reset-wait-pre" },
        { .value = TARGET_EVENT_RESET_WAIT_POST,     .name = "reset-wait-post" },
-       { .value = TARGET_EVENT_RESET_INIT , .name = "reset-init" },
-       { .value = TARGET_EVENT_RESET_END, .name = "reset-end" },
+       { .value = TARGET_EVENT_RESET_INIT,          .name = "reset-init" },
+       { .value = TARGET_EVENT_RESET_END,           .name = "reset-end" },
 
        { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-start" },
        { .value = TARGET_EVENT_EXAMINE_END, .name = "examine-end" },
@@ -3523,6 +3524,20 @@ void target_handle_event(struct target *target, enum target_event e)
        }
 }
 
+/**
+ * Returns true only if the target has a handler for the specified event.
+ */
+bool target_has_event_action(struct target *target, enum target_event event)
+{
+       struct target_event_action *teap;
+
+       for (teap = target->event_action; teap != NULL; teap = teap->next) {
+               if (teap->event == event)
+                       return true;
+       }
+       return false;
+}
+
 enum target_cfg_param {
        TCFG_TYPE,
        TCFG_EVENT,
index 15003c654288737d884c275a44be385b136369fa..55e9088ac638b116c56d00b59a29e64b39d535b4 100644 (file)
@@ -196,6 +196,7 @@ enum target_event
 
        TARGET_EVENT_RESET_START,
        TARGET_EVENT_RESET_ASSERT_PRE,
+       TARGET_EVENT_RESET_ASSERT,      /* C code uses this instead of SRST */
        TARGET_EVENT_RESET_ASSERT_POST,
        TARGET_EVENT_RESET_DEASSERT_PRE,
        TARGET_EVENT_RESET_DEASSERT_POST,
@@ -226,7 +227,9 @@ struct target_event_action {
        struct Jim_Obj *body;
        int has_percent;
        struct target_event_action *next;
- };
+};
+
+bool target_has_event_action(struct target *target, enum target_event event);
 
 struct target_event_callback
 {