Add a new JTAG "setup" event; use for better DaVinci ICEpick support.

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
This commit is contained in:
dbrownell 2009-10-05 08:20:28 +00:00
parent 16a7ad5799
commit 7c7467b34f
7 changed files with 93 additions and 50 deletions

View File

@ -2428,12 +2428,18 @@ The TAP events currently defined are:
@itemize @bullet @itemize @bullet
@item @b{post-reset} @item @b{post-reset}
@* The TAP has just completed a JTAG reset. @* The TAP has just completed a JTAG reset.
For the first such handler called, the tap is still The tap may still be in the JTAG @sc{reset} state.
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 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} @emph{should not issue commands which scan the JTAG IR or DR registers}
of any particular target. of any particular target.
@b{NOTE:} As this is written (September 2009), nothing prevents such access. @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} @item @b{tap-disable}
@* The TAP needs to be disabled. This handler should @* The TAP needs to be disabled. This handler should
implement @command{jtag tapdisable} implement @command{jtag tapdisable}
@ -2450,7 +2456,7 @@ contents to be accurate), you might:
@example @example
jtag configure CHIP.jrc -event post-reset @{ jtag configure CHIP.jrc -event post-reset @{
echo "Reset done" echo "JTAG Reset done"
... non-scan jtag operations to be done after reset ... non-scan jtag operations to be done after reset
@} @}
@end example @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 In OpenOCD, tap enabling/disabling is invoked by the Tcl commands
shown below, and is implemented using TAP event handlers. shown below, and is implemented using TAP event handlers.
So for example, when defining a TAP for a CPU connected to 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: code that looks something like this:
@example @example
jtag configure CHIP.cpu -event tap-enable @{ jtag configure CHIP.cpu -event tap-enable @{
echo "Enabling CPU TAP"
... jtag operations using CHIP.jrc ... jtag operations using CHIP.jrc
@} @}
jtag configure CHIP.cpu -event tap-disable @{ jtag configure CHIP.cpu -event tap-disable @{
echo "Disabling CPU TAP"
... jtag operations using CHIP.jrc ... jtag operations using CHIP.jrc
@} @}
@end example @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 @deffn Command {jtag tapdisable} dotted.name
If necessary, disables the tap If necessary, disables the tap
by sending it a @option{tap-disable} event. by sending it a @option{tap-disable} event.

View File

@ -61,8 +61,8 @@ static int jtag_error = ERROR_OK;
static const char *jtag_event_strings[] = static const char *jtag_event_strings[] =
{ {
[JTAG_TRST_ASSERTED] = "TAP reset", [JTAG_TRST_ASSERTED] = "TAP reset",
[JTAG_TAP_EVENT_SETUP] = "TAP setup",
[JTAG_TAP_EVENT_ENABLE] = "TAP enabled", [JTAG_TAP_EVENT_ENABLE] = "TAP enabled",
[JTAG_TAP_EVENT_POST_RESET] = "TAP post reset",
[JTAG_TAP_EVENT_DISABLE] = "TAP disabled", [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() */ /* NOTE: order here matches TRST path in jtag_add_reset() */
jtag_call_event_callbacks(JTAG_TRST_ASSERTED); 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) 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(). * sequence must match jtag_add_tlr().
*/ */
jtag_call_event_callbacks(JTAG_TRST_ASSERTED); 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; jtag_tap_t *tap;
int retval; int retval;
bool issue_setup = true;
LOG_DEBUG("Init JTAG chain"); 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) if (jtag_examine_chain() != ERROR_OK)
{ {
LOG_ERROR("Trying to use configured scan chain anyway..."); LOG_ERROR("Trying to use configured scan chain anyway...");
issue_setup = false;
} }
if (jtag_validate_ircapture() != ERROR_OK) if (jtag_validate_ircapture() != ERROR_OK)
{ {
LOG_WARNING("Errors during IR capture, continuing anyway..."); 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; return ERROR_OK;
} }

View File

@ -192,23 +192,32 @@ extern unsigned jtag_tap_count(void);
/* /*
* There are three cases when JTAG_TRST_ASSERTED callback is invoked. The * - TRST_ASSERTED triggers two sets of callbacks, after operations to
* event is invoked *after* TRST is asserted(or queued rather). It is illegal * reset the scan chain -- via TMS+TCK signaling, or deasserting the
* to communicate with the JTAG interface during the callback(as there is * nTRST signal -- are queued:
* currently a queue being built).
* *
* - TMS reset * + Callbacks in C code fire first, patching internal state
* - SRST pulls TRST * + Then post-reset event scripts fire ... activating JTAG circuits
* - TRST asserted * via TCK cycles, exiting SWD mode via TMS sequences, etc
* *
* TAP activation/deactivation is currently implemented outside the core * During those callbacks, scan chain contents have not been validated.
* using scripted code that understands the specific router type. * 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 { enum jtag_event {
JTAG_TRST_ASSERTED, JTAG_TRST_ASSERTED,
JTAG_TAP_EVENT_SETUP,
JTAG_TAP_EVENT_ENABLE, JTAG_TAP_EVENT_ENABLE,
JTAG_TAP_EVENT_DISABLE, JTAG_TAP_EVENT_DISABLE,
JTAG_TAP_EVENT_POST_RESET,
}; };
struct jtag_tap_event_action_s 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 /// @returns the number of times the scan queue has been flushed
int jtag_get_flush_queue_count(void); int jtag_get_flush_queue_count(void);
/// Notify all TAP's about a TLR reset /// Report Tcl event to all TAPs
void jtag_notify_reset(void); void jtag_notify_event(enum jtag_event);
/* can be implemented by hw + sw */ /* can be implemented by hw + sw */

View File

@ -41,7 +41,8 @@
#endif #endif
static const Jim_Nvp nvp_jtag_tap_event[] = { 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_ENABLE, .name = "tap-enable" },
{ .value = JTAG_TAP_EVENT_DISABLE, .name = "tap-disable" }, { .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) { for (jteap = tap->event_action; jteap != NULL; jteap = jteap->next) {
if (jteap->event == e) { 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, tap->dotted_name,
e, e,
Jim_Nvp_value2name_simple(nvp_jtag_tap_event, e)->name, 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_ENABLE:
case JTAG_TAP_EVENT_DISABLE: case JTAG_TAP_EVENT_DISABLE:
/* NOTE: we currently assume the handlers /* NOTE: we currently assume the handlers
* can't fail. That presumes later code * can't fail. Right here is where we should
* will be verifying the scan chains ... * really be verifying the scan chains ...
*/ */
tap->enabled = (e == JTAG_TAP_EVENT_ENABLE); tap->enabled = (e == JTAG_TAP_EVENT_ENABLE);
LOG_INFO("JTAG tap: %s %s", tap->dotted_name,
tap->enabled ? "enabled" : "disabled");
break; break;
default: default:
break; 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; jtag_tap_t *tap;
for (tap = jtag_all_taps(); tap; tap = tap->next_tap) for (tap = jtag_all_taps(); tap; tap = tap->next_tap)
{ jtag_tap_handle_event(tap, event);
jtag_tap_handle_event(tap, JTAG_TAP_EVENT_POST_RESET);
}
} }

View File

@ -9,11 +9,11 @@ if { [info exists CHIPNAME] } {
# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled* # TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*
# after JTAG reset until ICEpick is used to route them in. # 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 # With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without
# needing any ICEpick interaction. # needing any ICEpick interaction.
set EMU01 "-enable" #set EMU01 "-enable"
source [find target/icepick.cfg] 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 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 # various symbol definitions, to avoid hard-wiring addresses

View File

@ -7,16 +7,15 @@ if { [info exists CHIPNAME] } {
set _CHIPNAME dm365 set _CHIPNAME dm365
} }
# # TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*
# For now, expect EMU0/EMU1 jumpered LOW (not TI's default) so ARM and ETB # after JTAG reset until ICEpick is used to route them in.
# are enabled without making ICEpick route ARM and ETB into the JTAG chain. set EMU01 "-disable"
#
# Also note: when running without RTCK before the PLLs are set up, you # With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without
# may need to slow the JTAG clock down quite a lot (under 2 MHz). # needing any ICEpick interaction.
# #set EMU01 "-enable"
source [find target/icepick.cfg] source [find target/icepick.cfg]
set EMU01 "-enable"
#set EMU01 "-disable"
# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer # Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer
if { [info exists ETB_TAPID ] } { 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 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 # various symbol definitions, to avoid hard-wiring addresses

View File

@ -7,17 +7,15 @@ if { [info exists CHIPNAME] } {
set _CHIPNAME dm6446 set _CHIPNAME dm6446
} }
# # TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*
# For now, expect EMU0/EMU1 jumpered LOW (not TI's default) so ARM and ETB # after JTAG reset until ICEpick is used to route them in.
# are enabled without making ICEpick route ARM and ETB into the JTAG chain. set EMU01 "-disable"
# Override by setting EMU01 to "-disable".
# # With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without
# Also note: when running without RTCK before the PLLs are set up, you # needing any ICEpick interaction.
# may need to slow the JTAG clock down quite a lot (under 2 MHz). #set EMU01 "-enable"
#
source [find target/icepick.cfg] source [find target/icepick.cfg]
set EMU01 "-enable"
#set EMU01 "-disable"
# Subsidiary TAP: unknown ... must enable via ICEpick # Subsidiary TAP: unknown ... must enable via ICEpick
jtag newtap $_CHIPNAME unknown -irlen 8 -disable 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 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) # GDB target: the ARM, using SRAM1 for scratch. SRAM0 (also 8K)
# and the ETB memory (4K) are other options, while trace is unused. # and the ETB memory (4K) are other options, while trace is unused.
# Little-endian; use the OpenOCD default. # Little-endian; use the OpenOCD default.