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
@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.

View 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;
}

View 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 */

View 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);
}

View 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

View 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

View 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.