Add a new JTAG "setup" event; use for better DaVinci ICEpick support.
authordbrownell <dbrownell@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Mon, 5 Oct 2009 08:20:28 +0000 (08:20 +0000)
committerdbrownell <dbrownell@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Mon, 5 Oct 2009 08:20:28 +0000 (08:20 +0000)
The model is that this fires after scanchain verification, when it's
safe to call "jtag tapenable $TAPNAME".  So it will fire as part of
non-error paths of "init" and "reset" command processing.  However it
will *NOT* trigger during "jtag_reset" processing, which skips all
scan chain verification, or after verification errors.

ALSO:
 - switch DaVinci chips to use this new mechanism
 - log TAP activation/deactivation, since their IDCODEs aren't verified
 - unify "enum jtag_event" scripted event notifications
 - remove duplicative JTAG_TAP_EVENT_POST_RESET

git-svn-id: svn://svn.berlios.de/openocd/trunk@2800 b42882b7-edfa-0310-969c-e2dbd0fdcd60

doc/openocd.texi
src/jtag/core.c
src/jtag/jtag.h
src/jtag/tcl.c
tcl/target/ti_dm355.cfg
tcl/target/ti_dm365.cfg
tcl/target/ti_dm6446.cfg

index 32797fb397c36faa65720a2b7ed7dbc0c02c8034..8156de4d19b092da9ebe54b223e1cfeb755bb59c 100644 (file)
@@ -2428,12 +2428,18 @@ The TAP events currently defined are:
 @itemize @bullet
 @item @b{post-reset}
 @* The TAP has just completed a JTAG reset.
-For the first such handler called, the tap is still
-in the JTAG @sc{reset} state.
+The tap may still be in the JTAG @sc{reset} state.
+Handlers for these events might perform initialization sequences
+such as issuing TCK cycles, TMS sequences to ensure
+exit from the ARM SWD mode, and more.
+
 Because the scan chain has not yet been verified, handlers for these events
 @emph{should not issue commands which scan the JTAG IR or DR registers}
 of any particular target.
 @b{NOTE:} As this is written (September 2009), nothing prevents such access.
+@item @b{setup}
+@* The scan chain has been reset and verified.
+This handler may enable TAPs as needed.
 @item @b{tap-disable}
 @* The TAP needs to be disabled.  This handler should
 implement @command{jtag tapdisable}
@@ -2450,7 +2456,7 @@ contents to be accurate), you might:
 
 @example
 jtag configure CHIP.jrc -event post-reset @{
-  echo "Reset done"
+  echo "JTAG Reset done"
   ... non-scan jtag operations to be done after reset
 @}
 @end example
@@ -2493,20 +2499,30 @@ does include a kind of JTAG router functionality.
 In OpenOCD, tap enabling/disabling is invoked by the Tcl commands
 shown below, and is implemented using TAP event handlers.
 So for example, when defining a TAP for a CPU connected to
-a JTAG router, you should define TAP event handlers using
+a JTAG router, your @file{target.cfg} file
+should define TAP event handlers using
 code that looks something like this:
 
 @example
 jtag configure CHIP.cpu -event tap-enable @{
-  echo "Enabling CPU TAP"
   ... jtag operations using CHIP.jrc
 @}
 jtag configure CHIP.cpu -event tap-disable @{
-  echo "Disabling CPU TAP"
   ... jtag operations using CHIP.jrc
 @}
 @end example
 
+Then you might want that CPU's TAP enabled almost all the time:
+
+@example
+jtag configure $CHIP.jrc -event setup "jtag tapenable $CHIP.cpu"
+@end example
+
+Note how that particular setup event handler declaration
+uses quotes to evaluate @code{$CHIP} when the event is configured.
+Using brackets @{ @} would cause it to be evaluated later,
+at runtime, when it might have a different value.
+
 @deffn Command {jtag tapdisable} dotted.name
 If necessary, disables the tap
 by sending it a @option{tap-disable} event.
index 6177c1dc824513bb0a16c205420cc02aba3ad4c6..128504046cbd2672895ddb6c045a9bbb258f3cbf 100644 (file)
@@ -61,8 +61,8 @@ static int jtag_error = ERROR_OK;
 static const char *jtag_event_strings[] =
 {
        [JTAG_TRST_ASSERTED] = "TAP reset",
+       [JTAG_TAP_EVENT_SETUP] = "TAP setup",
        [JTAG_TAP_EVENT_ENABLE] = "TAP enabled",
-       [JTAG_TAP_EVENT_POST_RESET] = "TAP post reset",
        [JTAG_TAP_EVENT_DISABLE] = "TAP disabled",
 };
 
@@ -489,7 +489,7 @@ void jtag_add_tlr(void)
 
        /* NOTE: order here matches TRST path in jtag_add_reset() */
        jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
-       jtag_notify_reset();
+       jtag_notify_event(JTAG_TRST_ASSERTED);
 }
 
 void jtag_add_pathmove(int num_states, const tap_state_t *path)
@@ -704,7 +704,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst)
                         * sequence must match jtag_add_tlr().
                         */
                        jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
-                       jtag_notify_reset();
+                       jtag_notify_event(JTAG_TRST_ASSERTED);
                }
        }
 }
@@ -1232,6 +1232,7 @@ static int jtag_init_inner(struct command_context_s *cmd_ctx)
 {
        jtag_tap_t *tap;
        int retval;
+       bool issue_setup = true;
 
        LOG_DEBUG("Init JTAG chain");
 
@@ -1249,13 +1250,21 @@ static int jtag_init_inner(struct command_context_s *cmd_ctx)
        if (jtag_examine_chain() != ERROR_OK)
        {
                LOG_ERROR("Trying to use configured scan chain anyway...");
+               issue_setup = false;
        }
 
        if (jtag_validate_ircapture() != ERROR_OK)
        {
                LOG_WARNING("Errors during IR capture, continuing anyway...");
+               issue_setup = false;
        }
 
+       if (issue_setup)
+               jtag_notify_event(JTAG_TAP_EVENT_SETUP);
+       else
+               LOG_WARNING("Bypassing JTAG setup events due to errors");
+
+
        return ERROR_OK;
 }
 
index 938d854bccc05debb1155e421f14a9d6d5d604b8..f255a70e19fd0772131c13f129c5919eba341472 100644 (file)
@@ -192,23 +192,32 @@ extern unsigned jtag_tap_count(void);
 
 
 /*
- * There are three cases when JTAG_TRST_ASSERTED callback is invoked. The
- * event is invoked *after* TRST is asserted(or queued rather). It is illegal
- * to communicate with the JTAG interface during the callback(as there is
- * currently a queue being built).
+ * - TRST_ASSERTED triggers two sets of callbacks, after operations to
+ *   reset the scan chain -- via TMS+TCK signaling, or deasserting the
+ *   nTRST signal -- are queued:
  *
- * - TMS reset
- * - SRST pulls TRST
- * - TRST asserted
+ *    + Callbacks in C code fire first, patching internal state
+ *    + Then post-reset event scripts fire ... activating JTAG circuits
+ *      via TCK cycles, exiting SWD mode via TMS sequences, etc
  *
- * TAP activation/deactivation is currently implemented outside the core
- * using scripted code that understands the specific router type.
+ *   During those callbacks, scan chain contents have not been validated.
+ *   JTAG operations that address a specific TAP (primarily DR/IR scans)
+ *   must *not* be queued.
+ *
+ * - TAP_EVENT_SETUP is reported after TRST_ASSERTED, and after the scan
+ *   chain has been validated.  JTAG operations including scans that
+ *   target specific TAPs may be performed.
+ *
+ * - TAP_EVENT_ENABLE and TAP_EVENT_DISABLE implement TAP activation and
+ *   deactivation outside the core using scripted code that understands
+ *   the specific JTAG router type.  They might be triggered indirectly
+ *   from EVENT_SETUP operations.
  */
 enum jtag_event {
        JTAG_TRST_ASSERTED,
+       JTAG_TAP_EVENT_SETUP,
        JTAG_TAP_EVENT_ENABLE,
        JTAG_TAP_EVENT_DISABLE,
-       JTAG_TAP_EVENT_POST_RESET,
 };
 
 struct jtag_tap_event_action_s
@@ -643,8 +652,8 @@ extern void jtag_execute_queue_noclear(void);
 /// @returns the number of times the scan queue has been flushed
 int jtag_get_flush_queue_count(void);
 
-/// Notify all TAP's about a TLR reset
-void jtag_notify_reset(void);
+/// Report Tcl event to all TAPs
+void jtag_notify_event(enum jtag_event);
 
 
 /* can be implemented by hw + sw */
index 53c19e1a1b1feb6e324a3ae2a9d7961618443722..212be35577bc6a8383c3c3a98fe89f3d2fa6cd75 100644 (file)
@@ -41,7 +41,8 @@
 #endif
 
 static const Jim_Nvp nvp_jtag_tap_event[] = {
-       { .value = JTAG_TAP_EVENT_POST_RESET,   .name = "post-reset" },
+       { .value = JTAG_TRST_ASSERTED,          .name = "post-reset" },
+       { .value = JTAG_TAP_EVENT_SETUP,        .name = "setup" },
        { .value = JTAG_TAP_EVENT_ENABLE,       .name = "tap-enable" },
        { .value = JTAG_TAP_EVENT_DISABLE,      .name = "tap-disable" },
 
@@ -373,7 +374,7 @@ static void jtag_tap_handle_event(jtag_tap_t *tap, enum jtag_event e)
 
        for (jteap = tap->event_action; jteap != NULL; jteap = jteap->next) {
                if (jteap->event == e) {
-                       LOG_DEBUG("JTAG tap: %s event: %d (%s) action: %s\n",
+                       LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
                                        tap->dotted_name,
                                        e,
                                        Jim_Nvp_value2name_simple(nvp_jtag_tap_event, e)->name,
@@ -384,10 +385,12 @@ static void jtag_tap_handle_event(jtag_tap_t *tap, enum jtag_event e)
                        case JTAG_TAP_EVENT_ENABLE:
                        case JTAG_TAP_EVENT_DISABLE:
                                /* NOTE:  we currently assume the handlers
-                                * can't fail.  That presumes later code
-                                * will be verifying the scan chains ...
+                                * can't fail.  Right here is where we should
+                                * really be verifying the scan chains ...
                                 */
                                tap->enabled = (e == JTAG_TAP_EVENT_ENABLE);
+                               LOG_INFO("JTAG tap: %s %s", tap->dotted_name,
+                                       tap->enabled ? "enabled" : "disabled");
                                break;
                        default:
                                break;
@@ -586,13 +589,12 @@ static int jim_jtag_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 }
 
 
-void jtag_notify_reset(void)
+void jtag_notify_event(enum jtag_event event)
 {
        jtag_tap_t *tap;
+
        for (tap = jtag_all_taps(); tap; tap = tap->next_tap)
-       {
-               jtag_tap_handle_event(tap, JTAG_TAP_EVENT_POST_RESET);
-       }
+               jtag_tap_handle_event(tap, event);
 }
 
 
index b1e19e99d4f03b64a33c75270ba0bc6620d019f8..2551c3ed4c361d815fcd7a2b478f7da2fa935ae2 100644 (file)
@@ -9,11 +9,11 @@ if { [info exists CHIPNAME] } {
 
 # TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*
 # after JTAG reset until ICEpick is used to route them in.
-#set EMU01 "-disable"
+set EMU01 "-disable"
 
 # With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without
 # needing any ICEpick interaction.
-set EMU01 "-enable"
+#set EMU01 "-enable"
 
 source [find target/icepick.cfg]
 
@@ -50,6 +50,9 @@ if { [info exists JRC_TAPID ] } {
 }
 jtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID
 
+jtag configure $_CHIPNAME.jrc -event setup \
+       "jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm"
+
 ################
 
 # various symbol definitions, to avoid hard-wiring addresses
index 3a17d1a8be77d9f2b4372268ea21fc087448e747..e2d29bd5aa463977a7516da4c2b0bc4bb3b934a8 100644 (file)
@@ -7,16 +7,15 @@ if { [info exists CHIPNAME] } {
    set  _CHIPNAME dm365
 }
 
-#
-# For now, expect EMU0/EMU1 jumpered LOW (not TI's default) so ARM and ETB
-# are enabled without making ICEpick route ARM and ETB into the JTAG chain.
-#
-# Also note:  when running without RTCK before the PLLs are set up, you
-# may need to slow the JTAG clock down quite a lot (under 2 MHz).
-#
+# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*
+# after JTAG reset until ICEpick is used to route them in.
+set EMU01 "-disable"
+
+# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without
+# needing any ICEpick interaction.
+#set EMU01 "-enable"
+
 source [find target/icepick.cfg]
-set EMU01 "-enable"
-#set EMU01 "-disable"
 
 # Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer
 if { [info exists ETB_TAPID ] } {
@@ -46,6 +45,9 @@ if { [info exists JRC_TAPID ] } {
 }
 jtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID
 
+jtag configure $_CHIPNAME.jrc -event setup \
+       "jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm"
+
 ################
 
 # various symbol definitions, to avoid hard-wiring addresses
index e96c3e15f3910c0392bbb85bf0585d04f16163ee..4dac3d5fafa43de34e35d6b51e2e3b48d0be70f7 100644 (file)
@@ -7,17 +7,15 @@ if { [info exists CHIPNAME] } {
    set  _CHIPNAME dm6446
 }
 
-#
-# For now, expect EMU0/EMU1 jumpered LOW (not TI's default) so ARM and ETB
-# are enabled without making ICEpick route ARM and ETB into the JTAG chain.
-# Override by setting EMU01 to "-disable".
-#
-# Also note:  when running without RTCK before the PLLs are set up, you
-# may need to slow the JTAG clock down quite a lot (under 2 MHz).
-#
+# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*
+# after JTAG reset until ICEpick is used to route them in.
+set EMU01 "-disable"
+
+# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without
+# needing any ICEpick interaction.
+#set EMU01 "-enable"
+
 source [find target/icepick.cfg]
-set EMU01 "-enable"
-#set EMU01 "-disable"
 
 # Subsidiary TAP: unknown ... must enable via ICEpick
 jtag newtap $_CHIPNAME unknown -irlen 8 -disable
@@ -57,6 +55,10 @@ if { [info exists JRC_TAPID ] } {
 }
 jtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID
 
+jtag configure $_CHIPNAME.jrc -event setup \
+       "jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm"
+
+################
 # GDB target:  the ARM, using SRAM1 for scratch.  SRAM0 (also 8K)
 # and the ETB memory (4K) are other options, while trace is unused.
 # Little-endian; use the OpenOCD default.