You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(75) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(70) |
Feb
(20) |
Mar
(52) |
Apr
(149) |
May
(387) |
Jun
(466) |
Jul
(133) |
Aug
(87) |
Sep
(122) |
Oct
(140) |
Nov
(185) |
Dec
(105) |
2010 |
Jan
(85) |
Feb
(45) |
Mar
(75) |
Apr
(17) |
May
(41) |
Jun
(52) |
Jul
(33) |
Aug
(29) |
Sep
(36) |
Oct
(15) |
Nov
(26) |
Dec
(34) |
2011 |
Jan
(26) |
Feb
(25) |
Mar
(26) |
Apr
(29) |
May
(20) |
Jun
(27) |
Jul
(15) |
Aug
(32) |
Sep
(13) |
Oct
(64) |
Nov
(60) |
Dec
(10) |
2012 |
Jan
(64) |
Feb
(63) |
Mar
(39) |
Apr
(43) |
May
(54) |
Jun
(11) |
Jul
(30) |
Aug
(45) |
Sep
(11) |
Oct
(70) |
Nov
(24) |
Dec
(23) |
2013 |
Jan
(17) |
Feb
(8) |
Mar
(35) |
Apr
(40) |
May
(20) |
Jun
(24) |
Jul
(36) |
Aug
(25) |
Sep
(42) |
Oct
(40) |
Nov
(9) |
Dec
(21) |
2014 |
Jan
(29) |
Feb
(24) |
Mar
(60) |
Apr
(22) |
May
(22) |
Jun
(46) |
Jul
(11) |
Aug
(23) |
Sep
(26) |
Oct
(10) |
Nov
(14) |
Dec
(2) |
2015 |
Jan
(28) |
Feb
(47) |
Mar
(33) |
Apr
(58) |
May
(5) |
Jun
(1) |
Jul
|
Aug
(8) |
Sep
(12) |
Oct
(25) |
Nov
(58) |
Dec
(21) |
2016 |
Jan
(12) |
Feb
(40) |
Mar
(2) |
Apr
(1) |
May
(67) |
Jun
(2) |
Jul
(5) |
Aug
(36) |
Sep
|
Oct
(24) |
Nov
(17) |
Dec
(50) |
2017 |
Jan
(14) |
Feb
(16) |
Mar
(2) |
Apr
(35) |
May
(14) |
Jun
(16) |
Jul
(3) |
Aug
(3) |
Sep
|
Oct
(19) |
Nov
|
Dec
(16) |
2018 |
Jan
(55) |
Feb
(11) |
Mar
(34) |
Apr
(14) |
May
(4) |
Jun
(20) |
Jul
(39) |
Aug
(16) |
Sep
(17) |
Oct
(16) |
Nov
(20) |
Dec
(30) |
2019 |
Jan
(29) |
Feb
(24) |
Mar
(37) |
Apr
(26) |
May
(19) |
Jun
(21) |
Jul
(2) |
Aug
(3) |
Sep
(9) |
Oct
(12) |
Nov
(12) |
Dec
(12) |
2020 |
Jan
(47) |
Feb
(36) |
Mar
(54) |
Apr
(44) |
May
(37) |
Jun
(19) |
Jul
(32) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(32) |
Dec
(11) |
2021 |
Jan
(14) |
Feb
(5) |
Mar
(40) |
Apr
(32) |
May
(42) |
Jun
(31) |
Jul
(29) |
Aug
(47) |
Sep
(38) |
Oct
(17) |
Nov
(74) |
Dec
(33) |
2022 |
Jan
(11) |
Feb
(15) |
Mar
(40) |
Apr
(21) |
May
(39) |
Jun
(44) |
Jul
(19) |
Aug
(46) |
Sep
(79) |
Oct
(35) |
Nov
(21) |
Dec
(15) |
2023 |
Jan
(56) |
Feb
(13) |
Mar
(43) |
Apr
(28) |
May
(60) |
Jun
(15) |
Jul
(29) |
Aug
(28) |
Sep
(32) |
Oct
(21) |
Nov
(42) |
Dec
(39) |
2024 |
Jan
(35) |
Feb
(17) |
Mar
(28) |
Apr
(7) |
May
(14) |
Jun
(35) |
Jul
(30) |
Aug
(35) |
Sep
(30) |
Oct
(28) |
Nov
(38) |
Dec
(18) |
2025 |
Jan
(21) |
Feb
(28) |
Mar
(36) |
Apr
(35) |
May
(34) |
Jun
(58) |
Jul
(9) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <zw...@ma...> - 2009-06-03 03:39:08
|
Author: zwelch Date: 2009-06-03 03:39:04 +0200 (Wed, 03 Jun 2009) New Revision: 2018 Modified: trunk/src/jtag/interface.h Log: Update documentationf or jtag_interface structure members. Modified: trunk/src/jtag/interface.h =================================================================== --- trunk/src/jtag/interface.h 2009-06-03 01:29:01 UTC (rev 2017) +++ trunk/src/jtag/interface.h 2009-06-03 01:39:04 UTC (rev 2018) @@ -189,49 +189,89 @@ typedef struct jtag_interface_s { + /// The name of the JTAG interface driver. char* name; - /* queued command execution + /** + * Execute queued commands. + * @returns ERROR_OK on success, or an error code on failure. */ int (*execute_queue)(void); - /* interface initalization + /** + * Set the interface speed. + * @param speed The new interface speed setting. + * @returns ERROR_OK on success, or an error code on failure. */ int (*speed)(int speed); + + /** + * The interface driver may register additional commands to expose + * additional features not covered by the standard command set. + * @param cmd_ctx The context in which commands should be registered. + * @returns ERROR_OK on success, or an error code on failure. + */ int (*register_commands)(struct command_context_s* cmd_ctx); + + /** + * Interface driver must initalize any resources and connect to a + * JTAG device. + * @returns ERROR_OK on success, or an error code on failure. + */ int (*init)(void); + + /** + * Interface driver must tear down all resources and disconnect from + * the JTAG device. + * @returns ERROR_OK on success, or an error code on failure. + */ int (*quit)(void); - /* returns JTAG maxium speed for KHz. 0=RTCK. The function returns + /** + * Returns JTAG maxium speed for KHz. 0=RTCK. The function returns * a failure if it can't support the KHz/RTCK. * * WARNING!!!! if RTCK is *slow* then think carefully about * whether you actually want to support this in the driver. * Many target scripts are written to handle the absence of RTCK * and use a fallback kHz TCK. + * @returns ERROR_OK on success, or an error code on failure. */ int (*khz)(int khz, int* jtag_speed); - /* returns the KHz for the provided JTAG speed. 0=RTCK. The function returns - * a failure if it can't support the KHz/RTCK. */ + /** + * Calculate the clock frequency (in KHz) for the given @a speed. + * @param speed The desired interface speed setting. + * @param khz On return, contains the speed in KHz (0 for RTCK). + * @returns ERROR_OK on success, or an error code if the + * interface cannot support the specified speed (KHz or RTCK). + */ int (*speed_div)(int speed, int* khz); - /* Read and clear the power dropout flag. Note that a power dropout - * can be transitionary, easily much less than a ms. + /** + * Read and clear the power dropout flag. Note that a power dropout + * can be transitionary, easily much less than a ms. * - * So to find out if the power is *currently* on, you must invoke - * this method twice. Once to clear the power dropout flag and a - * second time to read the current state. + * To find out if the power is *currently* on, one must invoke this + * method twice. Once to clear the power dropout flag and a second + * time to read the current state. The default implementation + * never reports power dropouts. * - * Currently the default implementation is never to detect power dropout. + * @returns ERROR_OK on success, or an error code on failure. */ int (*power_dropout)(int* power_dropout); - /* Read and clear the srst asserted detection flag. + /** + * Read and clear the srst asserted detection flag. * - * NB!!!! like power_dropout this does *not* read the current - * state. srst assertion is transitionary and *can* be much - * less than 1ms. + * Like power_dropout this does *not* read the current + * state. SRST assertion is transitionary and may be much + * less than 1ms, so the interface driver must watch for these + * events until this routine is called. + * + * @param srst_asserted On return, indicates whether SRST has + * been asserted. + * @returns ERROR_OK on success, or an error code on failure. */ int (*srst_asserted)(int* srst_asserted); } jtag_interface_t; |
From: <zw...@ma...> - 2009-06-03 03:29:04
|
Author: zwelch Date: 2009-06-03 03:29:01 +0200 (Wed, 03 Jun 2009) New Revision: 2017 Modified: trunk/src/jtag/jtag.h Log: Remove vestigal tap_transition type from public jtag API. Modified: trunk/src/jtag/jtag.h =================================================================== --- trunk/src/jtag/jtag.h 2009-06-03 01:26:01 UTC (rev 2016) +++ trunk/src/jtag/jtag.h 2009-06-03 01:29:01 UTC (rev 2017) @@ -102,16 +102,7 @@ */ const char* tap_state_name(tap_state_t state); -typedef struct tap_transition_s -{ - tap_state_t high; - tap_state_t low; -} tap_transition_t; -//extern tap_transition_t tap_transitions[16]; /* describe the TAP state diagram */ - - - extern tap_state_t cmd_queue_end_state; /* finish DR scans in dr_end_state */ extern tap_state_t cmd_queue_cur_state; /* current TAP state */ |
From: <zw...@ma...> - 2009-06-03 03:26:21
|
Author: zwelch Date: 2009-06-03 03:26:01 +0200 (Wed, 03 Jun 2009) New Revision: 2016 Modified: trunk/src/jtag/amt_jtagaccel.c trunk/src/jtag/arm-jtag-ew.c trunk/src/jtag/at91rm9200.c trunk/src/jtag/bitbang.c trunk/src/jtag/bitq.c trunk/src/jtag/dummy.c trunk/src/jtag/ep93xx.c trunk/src/jtag/ft2232.c trunk/src/jtag/gw16012.c trunk/src/jtag/jlink.c trunk/src/jtag/jtag.c trunk/src/jtag/jtag.h trunk/src/jtag/jtag_driver.c trunk/src/jtag/parport.c trunk/src/jtag/presto.c trunk/src/jtag/rlink/rlink.c trunk/src/jtag/usbprog.c trunk/src/jtag/vsllink.c trunk/src/jtag/zy1000.c trunk/src/xsvf/xsvf.c Log: Remove interface.h from public JTAG header, include it where required. Modified: trunk/src/jtag/amt_jtagaccel.c =================================================================== --- trunk/src/jtag/amt_jtagaccel.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/amt_jtagaccel.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -22,7 +22,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #if PARPORT_USE_PPDEV == 1 Modified: trunk/src/jtag/arm-jtag-ew.c =================================================================== --- trunk/src/jtag/arm-jtag-ew.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/arm-jtag-ew.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -25,7 +25,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include <usb.h> Modified: trunk/src/jtag/at91rm9200.c =================================================================== --- trunk/src/jtag/at91rm9200.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/at91rm9200.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -22,7 +22,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include "bitbang.h" #include <sys/mman.h> Modified: trunk/src/jtag/bitbang.c =================================================================== --- trunk/src/jtag/bitbang.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/bitbang.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -27,6 +27,7 @@ #include "bitbang.h" #define INCLUDE_JTAG_INTERFACE_H #include "jtag.h" +#include "interface.h" /** * Function bitbang_stableclocks Modified: trunk/src/jtag/bitq.c =================================================================== --- trunk/src/jtag/bitq.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/bitq.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -23,6 +23,7 @@ #define INCLUDE_JTAG_INTERFACE_H #include "bitq.h" +#include "interface.h" bitq_interface_t* bitq_interface; /* low level bit queue interface */ Modified: trunk/src/jtag/dummy.c =================================================================== --- trunk/src/jtag/dummy.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/dummy.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -22,7 +22,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include "bitbang.h" Modified: trunk/src/jtag/ep93xx.c =================================================================== --- trunk/src/jtag/ep93xx.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/ep93xx.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -22,7 +22,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include "bitbang.h" #define TDO_BIT 1 Modified: trunk/src/jtag/ft2232.c =================================================================== --- trunk/src/jtag/ft2232.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/ft2232.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -41,7 +41,7 @@ /* project specific includes */ #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include "time_support.h" #if IS_CYGWIN == 1 Modified: trunk/src/jtag/gw16012.c =================================================================== --- trunk/src/jtag/gw16012.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/gw16012.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -22,7 +22,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #if 1 Modified: trunk/src/jtag/jlink.c =================================================================== --- trunk/src/jtag/jlink.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/jlink.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -26,7 +26,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include <usb.h> Modified: trunk/src/jtag/jtag.c =================================================================== --- trunk/src/jtag/jtag.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/jtag.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -31,6 +31,7 @@ #define INCLUDE_JTAG_INTERFACE_H #include "jtag.h" #include "minidriver.h" +#include "interface.h" #ifdef HAVE_STRINGS_H #include <strings.h> Modified: trunk/src/jtag/jtag.h =================================================================== --- trunk/src/jtag/jtag.h 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/jtag.h 2009-06-03 01:26:01 UTC (rev 2016) @@ -224,8 +224,6 @@ extern void jtag_queue_command(jtag_command_t *cmd); extern void jtag_command_queue_reset(void); -#include "interface.h" - #endif // INCLUDE_JTAG_INTERFACE_H /* forward declaration */ Modified: trunk/src/jtag/jtag_driver.c =================================================================== --- trunk/src/jtag/jtag_driver.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/jtag_driver.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -32,7 +32,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include "minidriver.h" #include "command.h" Modified: trunk/src/jtag/parport.c =================================================================== --- trunk/src/jtag/parport.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/parport.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -25,7 +25,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include "bitbang.h" /* -ino: 060521-1036 */ Modified: trunk/src/jtag/presto.c =================================================================== --- trunk/src/jtag/presto.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/presto.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -26,7 +26,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include "time_support.h" #include "bitq.h" Modified: trunk/src/jtag/rlink/rlink.c =================================================================== --- trunk/src/jtag/rlink/rlink.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/rlink/rlink.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -29,7 +29,7 @@ /* project specific includes */ #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include "rlink.h" #include "st7.h" #include "ep1_cmd.h" Modified: trunk/src/jtag/usbprog.c =================================================================== --- trunk/src/jtag/usbprog.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/usbprog.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -35,7 +35,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include <usb.h> Modified: trunk/src/jtag/vsllink.c =================================================================== --- trunk/src/jtag/vsllink.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/vsllink.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -27,7 +27,7 @@ #endif #define INCLUDE_JTAG_INTERFACE_H -#include "jtag.h" +#include "interface.h" #include <usb.h> Modified: trunk/src/jtag/zy1000.c =================================================================== --- trunk/src/jtag/zy1000.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/jtag/zy1000.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -23,6 +23,7 @@ #define INCLUDE_JTAG_INTERFACE_H #include "embeddedice.h" #include "minidriver.h" +#include "interface.h" #include "bitbang.h" #include <cyg/hal/hal_io.h> // low level i/o Modified: trunk/src/xsvf/xsvf.c =================================================================== --- trunk/src/xsvf/xsvf.c 2009-06-03 01:23:48 UTC (rev 2015) +++ trunk/src/xsvf/xsvf.c 2009-06-03 01:26:01 UTC (rev 2016) @@ -41,7 +41,6 @@ #include "config.h" #endif -#define INCLUDE_JTAG_INTERFACE_H #include "xsvf.h" #include "jtag.h" |
From: <zw...@ma...> - 2009-06-03 03:23:54
|
Author: zwelch Date: 2009-06-03 03:23:48 +0200 (Wed, 03 Jun 2009) New Revision: 2015 Modified: trunk/src/jtag/interface.h trunk/src/jtag/jtag.h Log: Expose tap_state_by_name TAP helper available in public API. Modified: trunk/src/jtag/interface.h =================================================================== --- trunk/src/jtag/interface.h 2009-06-03 00:59:13 UTC (rev 2014) +++ trunk/src/jtag/interface.h 2009-06-03 01:23:48 UTC (rev 2015) @@ -160,12 +160,6 @@ */ tap_state_t tap_state_transition(tap_state_t current_state, bool tms); -/** - * Function tap_state_name - * Returns a string suitable for display representing the JTAG tap_state - */ -const char* tap_state_name(tap_state_t state); - /// Provides user-friendly name lookup of TAP states. tap_state_t tap_state_by_name(const char *name); Modified: trunk/src/jtag/jtag.h =================================================================== --- trunk/src/jtag/jtag.h 2009-06-03 00:59:13 UTC (rev 2014) +++ trunk/src/jtag/jtag.h 2009-06-03 01:23:48 UTC (rev 2015) @@ -96,6 +96,12 @@ #endif } tap_state_t; +/** + * Function tap_state_name + * Returns a string suitable for display representing the JTAG tap_state + */ +const char* tap_state_name(tap_state_t state); + typedef struct tap_transition_s { tap_state_t high; |
From: <zw...@ma...> - 2009-06-03 02:59:18
|
Author: zwelch Date: 2009-06-03 02:59:13 +0200 (Wed, 03 Jun 2009) New Revision: 2014 Modified: trunk/doc/openocd.texi Log: David Brownell <da...@pa...>: Update docs for most of the remaining commands in jtag.c: - switch to @deffn - these are just the "low level" JTAG commands - resolve much goofage! * remove docs for non-existent commands * add missing docs for some existing commands * fix incorrect docs for some commands - just index TAP states overall, not individually - current name is "RUN/IDLE" not "IDLE" Cross checked against the source. This also creates an "Interface Drivers" section, analagous to how (NOR) Flash and NAND drivers are presented; that's not yet sorted. Modified: trunk/doc/openocd.texi =================================================================== --- trunk/doc/openocd.texi 2009-06-03 00:56:50 UTC (rev 2013) +++ trunk/doc/openocd.texi 2009-06-03 00:59:13 UTC (rev 2014) @@ -1335,19 +1335,26 @@ @verbatim interface arm-jtag-ew @end verbatim -@section Interface Command +@section Interface Configuration + The interface command tells OpenOCD what type of JTAG dongle you are using. Depending on the type of dongle, you may need to have one or more additional commands. -@itemize @bullet +@deffn {Config Command} {interface} name +Use the interface driver @var{name} to connect to the +target. +@end deffn -@item @b{interface} <@var{name}> -@cindex interface -@*Use the interface driver <@var{name}> to connect to the -target. Currently supported interfaces are +@deffn Command {jtag interface} +Returns the name of the interface driver being used. +@end deffn +@section Interface Drivers + +Currently supported interface drivers are: + @itemize @minus @item @b{parport} @@ -1386,10 +1393,8 @@ @item @b{arm-jtag-ew} @* Olimex ARM-JTAG-EW USB adapter -@comment - End parameters @end itemize -@comment - End Interface -@end itemize + @subsection parport options @itemize @bullet @@ -1523,10 +1528,6 @@ The OpenOCD default value is 2 and for some systems a value of 10 has proved useful. @end itemize -@subsection ep93xx options -@cindex ep93xx options -Currently, there are no options available for the ep93xx interface. - @anchor{JTAG Speed} @section JTAG Speed JTAG clock setup is part of system setup. @@ -1646,7 +1647,7 @@ board-specific script might do things like setting up DRAM. (@xref{Reset Command}.) -@section SRST and TRST Signal Issues +@section SRST and TRST Issues Because SRST and TRST are hardware signals, they can have a variety of system-specific constraints. Some of the most @@ -1685,6 +1686,15 @@ signals to both levels (push/pull) to minimize rise times. Use the @command{reset_config} @var{trst_type} and @var{srst_type} parameters to say how to drive reset signals. + +@item @emph{Special initialization} ... Targets sometimes need +special JTAG initialization sequences to handle chip-specific +issues (not limited to errata). +For example, certain JTAG commands might need to be issued while +the system as a whole is in a reset state (SRST active) +but the JTAG scan chain is usable (TRST inactive). +(@xref{JTAG Commands}, where the @command{jtag_reset} +command is presented.) @end itemize There can also be other issues. @@ -4236,88 +4246,204 @@ @node JTAG Commands @chapter JTAG Commands @cindex JTAG Commands -Generally most people will not use the bulk of these commands. They -are mostly used by the OpenOCD developers or those who need to -directly manipulate the JTAG taps. +Most general purpose JTAG commands have been presented earlier. +(@xref{JTAG Speed}, @ref{Reset Configuration}, and @ref{TAP Creation}.) +Lower level JTAG commands, as presented here, +may be needed to work with targets which require special +attention during operations such as reset or initialization. -In general these commands control JTAG taps at a very low level. For -example if you need to control a JTAG Route Controller (i.e.: the -OMAP3530 on the Beagle Board has one) you might use these commands in -a script or an event procedure. -@section Commands -@cindex Commands +To use these commands you will need to understand some +of the basics of JTAG, including: + @itemize @bullet -@item @b{scan_chain} -@cindex scan_chain -@*Print current scan chain configuration. -@item @b{jtag_reset} <@var{trst}> <@var{srst}> -@cindex jtag_reset -@*Toggle reset lines. -@item @b{endstate} <@var{tap_state}> -@cindex endstate -@*Finish JTAG operations in <@var{tap_state}>. -@item @b{runtest} <@var{num_cycles}> -@cindex runtest -@*Move to Run-Test/Idle, and execute <@var{num_cycles}> -@item @b{statemove} [@var{tap_state}] -@cindex statemove -@*Move to current endstate or [@var{tap_state}] -@item @b{irscan} <@var{device}> <@var{instr}> [@var{dev2}] [@var{instr2}] ... -@cindex irscan -@*Execute IR scan <@var{device}> <@var{instr}> [@var{dev2}] [@var{instr2}] ... -@item @b{drscan} <@var{device}> [@var{dev2}] [@var{var2}] ... -@cindex drscan -@*Execute DR scan <@var{device}> [@var{dev2}] [@var{var2}] ... -@item @b{verify_ircapture} <@option{enable}|@option{disable}> -@cindex verify_ircapture -@*Verify value captured during Capture-IR. Default is enabled. -@item @b{var} <@var{name}> [@var{num_fields}|@var{del}] [@var{size1}] ... -@cindex var -@*Allocate, display or delete variable <@var{name}> [@var{num_fields}|@var{del}] [@var{size1}] ... -@item @b{field} <@var{var}> <@var{field}> [@var{value}|@var{flip}] -@cindex field -Display/modify variable field <@var{var}> <@var{field}> [@var{value}|@var{flip}]. +@item A JTAG scan chain consists of a sequence of individual TAP +devices such as a CPUs. +@item Control operations involve moving each TAP through the same +standard state machine (in parallel) +using their shared TMS and clock signals. +@item Data transfer involves shifting data through the chain of +instruction or data registers of each TAP, writing new register values +while the reading previous ones. +@item Data register sizes are a function of the instruction active in +a given TAP, while instruction register sizes are fixed for each TAP. +All TAPs support a BYPASS instruction with a single bit data register. +@item The way OpenOCD differentiates between TAP devices is by +shifting different instructions into (and out of) their instruction +registers. @end itemize -@section Tap states -@cindex Tap states -Available tap_states are: +@section Low Level JTAG Commands + +These commands are used by developers who need to access +JTAG instruction or data registers, possibly controlling +the order of TAP state transitions. +If you're not debugging OpenOCD internals, or bringing up a +new JTAG adapter or a new type of TAP device (like a CPU or +JTAG router), you probably won't need to use these commands. + +@deffn Command {drscan} tap [numbits value]+ [@option{-endstate} tap_state] +Loads the data register of @var{tap} with a series of bit fields +that specify the entire register. +Each field is @var{numbits} bits long with +a numeric @var{value} (hexadecimal encouraged). +The return value holds the original value of each +of those fields. + +For example, a 38 bit number might be specified as one +field of 32 bits then one of 6 bits. +@emph{For portability, never pass fields which are more +than 32 bits long. Many OpenOCD implementations do not +support 64-bit (or larger) integer values.} + +All TAPs other than @var{tap} must be in BYPASS mode. +The single bit in their data registers does not matter. + +When @var{tap_state} is specified, the JTAG state machine is left +in that state. +For example @sc{drpause} might be specified, so that more +instructions can be issued before re-entering the @sc{run/idle} state. +If the end state is not specified, the @sc{run/idle} state is entered. + +@quotation Warning +OpenOCD does not record information about data register lengths, +so @emph{it is important that you get the bit field lengths right}. +Remember that different JTAG instructions refer to different +data registers, which may have different lengths. +Moreover, those lengths may not be fixed; +the SCAN_N instruction can change the length of +the register accessed by the INTEST instruction +(by connecting a different scan chain). +@end quotation +@end deffn + +@deffn Command {flush_count} +Returns the number of times the JTAG queue has been flushed. +This may be used for performance tuning. + +For example, flushing a queue over USB involves a +minimum latency, often several milliseconds, which does +not change with the amount of data which is written. +You may be able to identify performance problems by finding +tasks which waste bandwidth by flushing small transfers too often, +instead of batching them into larger operations. +@end deffn + +@deffn Command {endstate} tap_state +Flush any pending JTAG operations, +and return with all TAPs in @var{tap_state}. +This state should be a stable state such as @sc{reset}, +@sc{run/idle}, +@sc{drpause}, or @sc{irpause}. +@end deffn + +@deffn Command {irscan} [tap instruction]+ [@option{-endstate} tap_state] +For each @var{tap} listed, loads the instruction register +with its associated numeric @var{instruction}. +(The number of bits in that instruction may be displayed +using the @command{scan_chain} command.) +For other TAPs, a BYPASS instruction is loaded. + +When @var{tap_state} is specified, the JTAG state machine is left +in that state. +For example @sc{irpause} might be specified, so the data register +can be loaded before re-entering the @sc{run/idle} state. +If the end state is not specified, the @sc{run/idle} state is entered. + +@quotation Note +OpenOCD currently supports only a single field for instruction +register values, unlike data register values. +For TAPs where the instruction register length is more than 32 bits, +portable scripts currently must issue only BYPASS instructions. +@end quotation +@end deffn + +@deffn Command {jtag_reset} trst srst +Set values of reset signals. +The @var{trst} and @var{srst} parameter values may be +@option{0}, indicating that reset is inactive (pulled or driven high), +or @option{1}, indicating it is active (pulled or driven low). +The @command{reset_config} command should already have been used +to configure how the board and JTAG adapter treat these two +signals, and to say if either signal is even present. +@xref{Reset Configuration}. +@end deffn + +@deffn Command {runtest} @var{num_cycles} +Move to the @sc{run/idle} state, and execute at least +@var{num_cycles} of the JTAG clock (TCK). +Instructions often need some time +to execute before they take effect. +@end deffn + +@deffn Command {scan_chain} +Displays the TAPs in the scan chain configuration, +and their status. +The set of TAPs listed by this command is fixed by +exiting the OpenOCD configuration stage, +but systems with a JTAG router can +enable or disable TAPs dynamically. +In addition to the enable/disable status, the contents of +each TAP's instruction register can also change. +@end deffn + +@c tms_sequence (short|long) +@c ... temporary, debug-only, probably gone before 0.2 ships + +@deffn Command {verify_ircapture} (@option{enable}|@option{disable}) +Verify values captured during @sc{ircapture} and returned +during IR scans. Default is enabled, but this can be +overridden by @command{verify_jtag}. +@end deffn + +@deffn Command {verify_jtag} (@option{enable}|@option{disable}) +Enables verification of DR and IR scans, to help detect +programming errors. For IR scans, @command{verify_ircapture} +must also be enabled. +Default is enabled. +@end deffn + +@section TAP state names +@cindex TAP state names + +The @var{tap_state} names used by OpenOCD in the @command{drscan}, +@command{endstate}, and @command{irscan} commands are: + @itemize @bullet @item @b{RESET} -@cindex RESET -@item @b{IDLE} -@cindex IDLE +@item @b{RUN/IDLE} @item @b{DRSELECT} -@cindex DRSELECT @item @b{DRCAPTURE} -@cindex DRCAPTURE @item @b{DRSHIFT} -@cindex DRSHIFT @item @b{DREXIT1} -@cindex DREXIT1 @item @b{DRPAUSE} -@cindex DRPAUSE @item @b{DREXIT2} -@cindex DREXIT2 @item @b{DRUPDATE} -@cindex DRUPDATE @item @b{IRSELECT} -@cindex IRSELECT @item @b{IRCAPTURE} -@cindex IRCAPTURE @item @b{IRSHIFT} -@cindex IRSHIFT @item @b{IREXIT1} -@cindex IREXIT1 @item @b{IRPAUSE} -@cindex IRPAUSE @item @b{IREXIT2} -@cindex IREXIT2 @item @b{IRUPDATE} -@cindex IRUPDATE @end itemize +Note that only six of those states are fully ``stable'' in the +face of TMS fixed and a free-running JTAG clock; for all the +others, the next TCK transition changes to a new state. +@itemize @bullet +@item @sc{reset} is probably most useful with @command{endstate}, +but entering it frequently has side effects. +(This is the only stable state with TMS high.) +@item From @sc{drshift} and @sc{irshift}, clock transitions will +produce side effects by changing register contents. The values +to be latched in upcoming @sc{drupdate} or @sc{irupdate} states +may not be as expected. +@item @sc{run/idle}, @sc{drpause}, and @sc{irpause} are reasonable +choices after @command{drscan} or @command{irscan} commands, +since they are free of side effects. +@end itemize + @node TFTP @chapter TFTP @cindex TFTP |
From: <zw...@ma...> - 2009-06-03 02:56:55
|
Author: zwelch Date: 2009-06-03 02:56:50 +0200 (Wed, 03 Jun 2009) New Revision: 2013 Modified: trunk/doc/openocd.texi Log: David Brownell <da...@pa...>: Rework the TAP creation documentation. - Try to use "TAP" not "tap" everywhere; it's an acronym. - Update the associated "target config files" section: * reference the "TAP Creation" chapter for details * simplify: reference interesting multi-tap config files * let's not forget CPU configuration (*before* workspace setup) * streamline it a bit * move that workspace-vs-mmu issue to a better location - Clean up TAP creation doc mess * switch to @deffn * (re)organize the remaining stuff * reference the "Config File Guidelines" chapter - Tweak the "Target Configuration" chapter * rename as "CPU configuration"; unconfuse vs. target/*.cfg * bring out that it's not just there for GDB * move TAP events to the TAP chapter, where they belong (bugfix) Modified: trunk/doc/openocd.texi =================================================================== --- trunk/doc/openocd.texi 2009-06-03 00:45:21 UTC (rev 2012) +++ trunk/doc/openocd.texi 2009-06-03 00:56:50 UTC (rev 2013) @@ -69,8 +69,8 @@ * Daemon Configuration:: Daemon Configuration * Interface - Dongle Configuration:: Interface - Dongle Configuration * Reset Configuration:: Reset Configuration -* Tap Creation:: Tap Creation -* Target Configuration:: Target Configuration +* TAP Creation:: TAP Creation +* CPU Configuration:: CPU Configuration * Flash Commands:: Flash Commands * NAND Flash Commands:: NAND Flash Commands * General Commands:: General Commands @@ -111,7 +111,10 @@ devices. @b{JTAG:} OpenOCD uses a ``hardware interface dongle'' to communicate -with the JTAG (IEEE 1149.1) compliant taps on your target board. +with the JTAG (IEEE 1149.1) compliant TAPs on your target board. +A @dfn{TAP} is a ``Test Access Port'', a module which processes +special instructions and data. TAPs are daisy-chained within and +between chips and boards. @b{Dongles:} OpenOCD currently supports many types of hardware dongles: USB based, parallel port based, and other standalone boxes that run @@ -835,9 +838,12 @@ board file. Boards may also contain multiple targets, i.e.: Two CPUs, or a CPU and an FPGA or CPLD. @item @b{target} -@* Think chip. The ``target'' directory represents a JTAG tap (or -chip) OpenOCD should control, not a board. Two common types of targets +@* Think chip. The ``target'' directory represents the JTAG TAPs +on a chip +which OpenOCD should control, not a board. Two common types of targets are ARM chips and FPGA or CPLD chips. +When a chip has multiple TAPs (maybe it has both ARM and DSP cores), +the target config file defines all of them. @end itemize @b{If needed...} The user in their ``openocd.cfg'' file or the board @@ -902,9 +908,9 @@ @enumerate @item Set defaults -@item Create taps +@item Add TAPs to the scan chain +@item Add CPU targets @item Reset configuration -@item Work areas @item CPU/Chip/CPU-Core specific features @item On-Chip flash @end enumerate @@ -1002,7 +1008,6 @@ # these names still work! network.cpu configure ... params video.cpu configure ... params - @end example @subsection Default Value Boiler Plate Code @@ -1028,90 +1033,69 @@ @} else @{ set _CPUTAPID 0x3f0f0f0f @} - @end example -@subsection Creating Taps -After the ``defaults'' are choosen [see above] the taps are created. +@subsection Adding TAPs to the Scan Chain +After the ``defaults'' are set up, +add the TAPs on each chip to the JTAG scan chain. +@xref{TAP Creation}, and the naming convention +for taps. -@b{SIMPLE example:} such as an Atmel AT91SAM7X256 +In the simplest case the chip has only one TAP, +probably for a CPU or FPGA. +The config file for the Atmel AT91SAM7X256 +looks (in part) like this: @example -# for an ARM7TDMI. -set _TARGETNAME [format "%s.cpu" $_CHIPNAME] jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \ -expected-id $_CPUTAPID @end example -@b{COMPLEX example:} +A board with two such at91sam7 chips would be able +to source such a config file twice, with different +values for @code{CHIPNAME} and @code{CPUTAPID}, so +it adds a different TAP each time. -This is an SNIP/example for an STR912 - which has 3 internal taps. Key features shown: +There are more complex examples too, with chips that have +multiple TAPs. Ones worth looking at include: -@enumerate -@item @b{Unform tap names} - See: Tap Naming Convention -@item @b{_TARGETNAME} is created at the end where used. -@end enumerate +@itemize +@item @file{target/omap3530.cfg} -- with a disabled ARM, and a JRC +(there's a DSP too, which is not listed) +@item @file{target/str912.cfg} -- with flash, CPU, and boundary scan +@item @file{target/ti_dm355.cfg} -- with ETM, ARM, and JRC (this JRC +is not currently used) +@end itemize -@example -if @{ [info exists FLASHTAPID ] @} @{ - set _FLASHTAPID $FLASHTAPID -@} else @{ - set _FLASHTAPID 0x25966041 -@} -jtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 \ - -expected-id $_FLASHTAPID +@subsection Add CPU targets -if @{ [info exists CPUTAPID ] @} @{ - set _CPUTAPID $CPUTAPID -@} else @{ - set _CPUTAPID 0x25966041 -@} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0xf -irmask 0xe \ - -expected-id $_CPUTAPID +After adding a TAP for a CPU, you should set it up so that +GDB and other commands can use it. +@xref{CPU Configuration}. +For the at91sam7 example above, the command can look like this: +@example +target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME +@end example -if @{ [info exists BSTAPID ] @} @{ - set _BSTAPID $BSTAPID -@} else @{ - set _BSTAPID 0x1457f041 -@} -jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 \ - -expected-id $_BSTAPID +Work areas are small RAM areas associated with CPU targets. +They are used by OpenOCD to speed up downloads, +and to download small snippets of code to program flash chips. +If the chip includes a form of ``on-chip-ram'' - and many do - define +a work area if you can. +Again using the at91sam7 as an example, this can look like: -set _TARGETNAME [format "%s.cpu" $_CHIPNAME] +@example +$_TARGETNAME configure -work-area-phys 0x00200000 \ + -work-area-size 0x4000 -work-area-backup 0 @end example -@b{Tap Naming Convention} - -See the command ``jtag newtap'' for detail, but in brief the names you should use are: - -@itemize @bullet -@item @b{tap} -@item @b{cpu} -@item @b{flash} -@item @b{bs} -@item @b{etb} -@item @b{jrc} -@item @b{unknownN} - it happens :-( -@end itemize - @subsection Reset Configuration Some chips have specific ways the TRST and SRST signals are managed. If these are @b{CHIP SPECIFIC} they go here, if they are @b{BOARD SPECIFIC} they go in the board file. -@subsection Work Areas - -Work areas are small RAM areas used by OpenOCD to speed up downloads, -and to download small snippets of code to program flash chips. - -If the chip includes a form of ``on-chip-ram'' - and many do - define -a reasonable work area and use the ``backup'' option. - -@b{PROBLEMS:} On more complex chips, this ``work area'' may become -inaccessible if/when the application code enables or disables the MMU. - @subsection ARM Core Specific Hacks If the chip has a DCC, enable it. If the chip is an ARM9 with some @@ -1800,209 +1784,274 @@ @end deffn -@node Tap Creation -@chapter Tap Creation -@cindex tap creation -@cindex tap configuration +@node TAP Creation +@chapter TAP Creation +@cindex TAP creation +@cindex TAP configuration -In order for OpenOCD to control a target, a JTAG tap must be -defined/created. +@emph{Test Access Ports} (TAPs) are the core of JTAG. +TAPs serve many roles, including: -Commands to create taps are normally found in a configuration file and -are not normally typed by a human. - -When a tap is created a @b{dotted.name} is created for the tap. Other -commands use that dotted.name to manipulate or refer to the tap. - -Tap Uses: @itemize @bullet -@item @b{Debug Target} A tap can be used by a GDB debug target -@item @b{Flash Programing} Some chips program the flash directly via JTAG, -instead of indirectly by making a CPU do it. -@item @b{Boundry Scan} Some chips support boundary scan. +@item @b{Debug Target} A CPU TAP can be used as a GDB debug target +@item @b{Flash Programing} Some chips program the flash directly via JTAG. +Others do it indirectly, making a CPU do it. +@item @b{Program Download} Using the same CPU support GDB uses, +you can initialize a DRAM controller, download code to DRAM, and then +start running that code. +@item @b{Boundary Scan} Most chips support boundary scan, which +helps test for board assembly problems like solder bridges +and missing connections @end itemize +OpenOCD must know about the active TAPs on your board(s). +Setting up the TAPs is the core task of your configuration files. +Once those TAPs are set up, you can pass their names to code +which sets up CPUs and exports them as GDB targets, +probes flash memory, performs low-level JTAG operations, and more. -@anchor{jtag newtap} -@section jtag newtap -@b{@t{jtag newtap CHIPNAME TAPNAME configparams ....}} -@cindex jtag newtap -@cindex tap -@cindex tap order -@cindex tap geometry +@section Scan Chains -@comment START options -@itemize @bullet -@item @b{CHIPNAME} -@* is a symbolic name of the chip. -@item @b{TAPNAME} -@* is a symbol name of a tap present on the chip. -@item @b{Required configparams} -@* Every tap has 3 required configparams, and several ``optional -parameters'', the required parameters are: -@comment START REQUIRED -@itemize @bullet -@item @b{-irlen NUMBER} - the length in bits of the instruction register, mostly 4 or 5 bits. -@item @b{-ircapture NUMBER} - the IDCODE capture command, usually 0x01. -@item @b{-irmask NUMBER} - the corresponding mask for the IR register. For -some devices, there are bits in the IR that aren't used. This lets you mask -them off when doing comparisons. In general, this should just be all ones for -the size of the IR. -@comment END REQUIRED -@end itemize -An example of a FOOBAR Tap +OpenOCD uses a JTAG adapter (interface) to talk to your board, +which has a daisy chain of TAPs. +That daisy chain is called a @dfn{scan chain}. +Simple configurations may have a single TAP in the scan chain, +perhaps for a microcontroller. +Complex configurations might have a dozen or more TAPs: +several in one chip, more in the next, and connecting +to other boards with their own chips and TAPs. + +Unfortunately those TAPs can't always be autoconfigured, +because not all devices provide good support for that. +(JTAG doesn't require supporting IDCODE instructions.) +The configuration mechanism currently supported by OpenOCD +requires explicit configuration of all TAP devices using +@command{jtag newtap} commands. +One like this would create a tap named @code{chip1.cpu}: + @example -jtag newtap foobar tap -irlen 7 -ircapture 0x42 -irmask 0x55 +jtag newtap chip1 cpu -irlen 7 -ircapture 0x01 -irmask 0x55 @end example -Creates the tap ``foobar.tap'' with the instruction register (IR) is 7 -bits long, during Capture-IR 0x42 is loaded into the IR, and bits -[6,4,2,0] are checked. -@item @b{Optional configparams} -@comment START Optional -@itemize @bullet -@item @b{-expected-id NUMBER} -@* By default it is zero. If non-zero represents the -expected tap ID used when the JTAG chain is examined. Repeat -the option as many times as required if multiple id's can be -expected. See below. -@item @b{-disable} -@item @b{-enable} -@* By default not specified the tap is enabled. Some chips have a -JTAG route controller (JRC) that is used to enable and/or disable -specific JTAG taps. You can later enable or disable any JTAG tap via -the command @b{jtag tapenable DOTTED.NAME} or @b{jtag tapdisable -DOTTED.NAME} -@comment END Optional -@end itemize +Each target configuration file lists the TAPs provided +by a given chip. +Board configuration files combine all the targets on a board, +and so forth. +Note that @emph{the order in which TAPs are created is very important.} +It must match the order in the JTAG scan chain, both inside +a single chip and between them. -@comment END OPTIONS -@end itemize -@b{Notes:} -@comment START NOTES -@itemize @bullet -@item @b{Technically} -@* newtap is a sub command of the ``jtag'' command -@item @b{Big Picture Background} -@*GDB Talks to OpenOCD using the GDB protocol via -TCP/IP. OpenOCD then uses the JTAG interface (the dongle) to -control the JTAG chain on your board. Your board has one or more chips -in a @i{daisy chain configuration}. Each chip may have one or more -JTAG taps. GDB ends up talking via OpenOCD to one of the taps. -@item @b{NAME Rules} -@*Names follow ``C'' symbol name rules (start with alpha ...) -@item @b{TAPNAME - Conventions} -@itemize @bullet -@item @b{tap} - should be used only FPGA or CPLD like devices with a single tap. -@item @b{cpu} - the main CPU of the chip, alternatively @b{foo.arm} and @b{foo.dsp} -@item @b{flash} - if the chip has a flash tap, example: str912.flash -@item @b{bs} - for boundary scan if this is a seperate tap. -@item @b{etb} - for an embedded trace buffer (example: an ARM ETB11) -@item @b{jrc} - for JTAG route controller (example: OMAP3530 found on Beagleboards) -@item @b{unknownN} - where N is a number if you have no idea what the tap is for -@item @b{Other names} - Freescale IMX31 has a SDMA (smart dma) with a JTAG tap, that tap should be called the ``sdma'' tap. -@item @b{When in doubt} - use the chip maker's name in their data sheet. -@end itemize -@item @b{DOTTED.NAME} -@* @b{CHIPNAME}.@b{TAPNAME} creates the tap name, aka: the -@b{Dotted.Name} is the @b{CHIPNAME} and @b{TAPNAME} combined with a -dot (period); for example: @b{xilinx.tap}, @b{str912.flash}, -@b{omap3530.jrc}, or @b{stm32.cpu} The @b{dotted.name} is used in -numerous other places to refer to various taps. -@item @b{ORDER} -@* The order this command appears via the config files is -important. -@item @b{Multi Tap Example} -@* This example is based on the ST Microsystems STR912. See the ST -document titled: @b{STR91xFAxxx, Section 3.15 Jtag Interface, Page: +For example, the ST Microsystems STR912 chip has +three separate TAPs@footnote{See the ST +document titled: @emph{STR91xFAxxx, Section 3.15 Jtag Interface, Page: 28/102, Figure 3: JTAG chaining inside the STR91xFA}. - @url{http://eu.st.com/stonline/products/literature/ds/13495.pdf} -@*@b{checked: 28/nov/2008} +Checked: 28-Nov-2008}. +To configure those taps, @file{target/str912.cfg} +includes commands something like this: -The diagram shows that the TDO pin connects to the flash tap, flash TDI -connects to the CPU debug tap, CPU TDI connects to the boundary scan -tap which then connects to the TDI pin. - @example - # The order is... - # create tap: 'str912.flash' - jtag newtap str912 flash ... params ... - # create tap: 'str912.cpu' - jtag newtap str912 cpu ... params ... - # create tap: 'str912.bs' - jtag newtap str912 bs ... params ... +jtag newtap str912 flash ... params ... +jtag newtap str912 cpu ... params ... +jtag newtap str912 bs ... params ... @end example -@item @b{Note: Deprecated} - Index Numbers -@* Prior to 28/nov/2008, JTAG taps where numbered from 0..N this -feature is still present, however its use is highly discouraged and -should not be counted upon. Update all of your scripts to use -TAP names rather than numbers. -@item @b{Multiple chips} -@* If your board has multiple chips, you should be -able to @b{source} two configuration files, in the proper order, and -have the taps created in the proper order. -@comment END NOTES +Actual config files use a variable instead of literals like +@option{str912}, to support more than one chip of each type. +@xref{Config File Guidelines}. + +@section TAP Names + +When a TAP objects is created with @command{jtag newtap}, +a @dfn{dotted.name} is created for the TAP, combining the +name of a module (usually a chip) and a label for the TAP. +For example: @code{xilinx.tap}, @code{str912.flash}, +@code{omap3530.jrc}, @code{dm6446.dsp}, or @code{stm32.cpu}. +Many other commands use that dotted.name to manipulate or +refer to the TAP. For example, CPU configuration uses the +name, as does declaration of NAND or NOR flash banks. + +The components of a dotted name should follow ``C'' symbol +name rules: start with an alphabetic character, then numbers +and underscores are OK; while others (including dots!) are not. + +@quotation Tip +In older code, JTAG TAPs were numbered from 0..N. +This feature is still present. +However its use is highly discouraged, and +should not be counted upon. +Update all of your scripts to use TAP names rather than numbers. +Using TAP numbers in target configuration scripts prevents +reusing on boards with multiple targets. +@end quotation + +@anchor{TAP Creation Commands} +@section TAP Creation Commands + +@c shouldn't this be(come) a {Config Command}? +@anchor{jtag newtap} +@deffn Command {jtag newtap} chipname tapname configparams... +Creates a new TAP with the dotted name @var{chipname}.@var{tapname}, +and configured according to the various @var{configparams}. + +The @var{chipname} is a symbolic name for the chip. +Conventionally target config files use @code{$_CHIPNAME}, +defaulting to the model name given by the chip vendor but +overridable. + +@cindex TAP naming convention +The @var{tapname} reflects the role of that TAP, +and should follow this convention: + +@itemize @bullet +@item @code{bs} -- For boundary scan if this is a seperate TAP; +@item @code{cpu} -- The main CPU of the chip, alternatively +@code{arm} and @code{dsp} on chips with both ARM and DSP CPUs, +@code{arm1} and @code{arm2} on chips two ARMs, and so forth; +@item @code{etb} -- For an embedded trace buffer (example: an ARM ETB11); +@item @code{flash} -- If the chip has a flash TAP, like the str912; +@item @code{jrc} -- For JTAG route controller (example: the ICEpick modules +on many Texas Instruments chips, like the OMAP3530 on Beagleboards); +@item @code{tap} -- Should be used only FPGA or CPLD like devices +with a single TAP; +@item @code{unknownN} -- If you have no idea what the TAP is for (N is a number); +@item @emph{when in doubt} -- Use the chip maker's name in their data sheet. +For example, the Freescale IMX31 has a SDMA (Smart DMA) with +a JTAG TAP; that TAP should be named @code{sdma}. @end itemize -@comment at command level -@section Enable/Disable Taps -@b{Note:} These commands are intended to be used as a machine/script -interface. Humans might find the ``scan_chain'' command more helpful -when querying the state of the JTAG taps. +Every TAP requires at least the following @var{configparams}: -@b{By default, all taps are enabled} +@itemize @bullet +@item @code{-ircapture} @var{NUMBER} +@*The IDCODE capture command, such as 0x01. +@item @code{-irlen} @var{NUMBER} +@*The length in bits of the +instruction register, such as 4 or 5 bits. +@item @code{-irmask} @var{NUMBER} +@*A mask for the IR register. +For some devices, there are bits in the IR that aren't used. +This lets OpenOCD mask them off when doing IDCODE comparisons. +In general, this should just be all ones for the size of the IR. +@end itemize +A TAP may also provide optional @var{configparams}: + @itemize @bullet -@item @b{jtag tapenable} @var{DOTTED.NAME} -@item @b{jtag tapdisable} @var{DOTTED.NAME} -@item @b{jtag tapisenabled} @var{DOTTED.NAME} +@item @code{-disable} (or @code{-enable}) +@*Use the @code{-disable} paramater to flag a TAP which is not +linked in to the scan chain when it is declared. +You may use @code{-enable} to highlight the default state +(the TAP is linked in). +@xref{Enabling and Disabling TAPs}. +@item @code{-expected-id} @var{number} +@*A non-zero value represents the expected 32-bit IDCODE +found when the JTAG chain is examined. +These codes are not required by all JTAG devices. +@emph{Repeat the option} as many times as required if more than one +ID code could appear (for example, multiple versions). @end itemize -@cindex tap enable -@cindex tap disable -@cindex JRC -@cindex route controller +@end deffn -These commands are used when your target has a JTAG route controller -that effectively adds or removes a tap from the JTAG chain in a -non-standard way. +@c @deffn Command {jtag arp_init-reset} +@c ... more or less "init" ? -The ``standard way'' to remove a tap would be to place the tap in -bypass mode. But with the advent of modern chips, this is not always a -good solution. Some taps operate slowly, others operate fast, and -there are other JTAG clock synchronisation problems one must face. To -solve that problem, the JTAG route controller was introduced. Rather -than ``bypass'' the tap, the tap is completely removed from the -circuit and skipped. +@anchor{Enabling and Disabling TAPs} +@section Enabling and Disabling TAPs +@cindex TAP events +In some systems, a @dfn{JTAG Route Controller} (JRC) +is used to enable and/or disable specific JTAG TAPs. +Many ARM based chips from Texas Instruments include +an ``ICEpick'' module, which is a JRC. +Such chips include DaVinci and OMAP3 processors. -From OpenOCD's point of view, a JTAG tap is in one of 3 states: +A given TAP may not be visible until the JRC has been +told to link it into the scan chain; and if the JRC +has been told to unlink that TAP, it will no longer +be visible. +Such routers address problems that JTAG ``bypass mode'' +ignores, such as: -@itemize @bullet -@item @b{Enabled - Not In ByPass} and has a variable bit length -@item @b{Enabled - In ByPass} and has a length of exactly 1 bit. -@item @b{Disabled} and has a length of ZERO and is removed from the circuit. +@itemize +@item The scan chain can only go as fast as its slowest TAP. +@item Having many TAPs slows instruction scans, since all +TAPs receive new instructions. +@item TAPs in the scan chain must be powered up, which wastes +power and prevents debugging some power management mechanisms. @end itemize -The IEEE JTAG definition has no concept of a ``disabled'' tap. -@b{Historical note:} this feature was added 28/nov/2008 +The IEEE 1149.1 JTAG standard has no concept of a ``disabled'' tap, +as implied by the existence of JTAG routers. +However, the upcoming IEEE 1149.7 framework (layered on top of JTAG) +does include a kind of JTAG router functionality. -@b{jtag tapisenabled DOTTED.NAME} +@c (a) currently the event handlers don't seem to be able to +@c fail in a way that could lead to no-change-of-state. +@c (b) eventually non-event configuration should be possible, +@c in which case some this documentation must move. -This command returns 1 if the named tap is currently enabled, 0 if not. -This command exists so that scripts that manipulate a JRC (like the -OMAP3530 has) can determine if OpenOCD thinks a tap is presently -enabled or disabled. +@deffn Command {jtag cget} dotted.name @option{-event} name +@deffnx Command {jtag configure} dotted.name @option{-event} name string +At this writing this mechanism is used only for event handling, +and the only two events relate to TAP enabling and disabling. -@page -@node Target Configuration -@chapter Target Configuration +The @code{configure} subcommand assigns an event handler, +a TCL string which is evaluated when the event is triggered. +The @code{cget} subcommand returns that handler. +The two possible values for an event @var{name} +are @option{tap-disable} and @option{tap-enable}. + +So for example, when defining a TAP for a CPU connected to +a JTAG router, you 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 +@end deffn + +@deffn Command {jtag tapdisable} dotted.name +@deffnx Command {jtag tapenable} dotted.name +@deffnx Command {jtag tapisenabled} dotted.name +These three commands all return the string "1" if the tap +specified by @var{dotted.name} is enabled, +and "0" if it is disbabled. +The @command{tapenable} variant first enables the tap +by sending it a @option{tap-enable} event. +The @command{tapdisable} variant first disables the tap +by sending it a @option{tap-disable} event. + +@quotation Note +Humans will find the @command{scan_chain} command more helpful +than the script-oriented @command{tapisenabled} +for querying the state of the JTAG taps. +@end quotation +@end deffn + +@node CPU Configuration +@chapter CPU Configuration @cindex GDB target -This chapter discusses how to create a GDB debug target. Before -creating a ``target'' a JTAG tap DOTTED.NAME must exist first. +This chapter discusses how to create a GDB debug target for a CPU. +You can also access these targets without GDB +(@pxref{Architecture and Core Commands}) and, where relevant, +through various kinds of NAND and NOR flash commands. +Also, if you have multiple CPUs you can have multiple such targets. +Before creating a ``target'', you must have added its TAP to the scan chain. +When you've added that TAP, you will have a @code{dotted.name} +which is used to set up the CPU support. +The chip-specific configuration file will normally configure its CPU(s) +right after it adds all of the chip's TAPs to the scan chain. + @section targets [NAME] @b{Note:} This command name is PLURAL - not singular. @@ -2067,7 +2116,7 @@ @section TARGETNAME (object) commands @b{Use:} Once a target is created, an ``object name'' that represents the target is created. By convention, the target name is identical to the -tap name. In a multiple target system, one can preceed many common +tap name. In a multiple target system, one can precede many common commands with a specific target name and effect only that target. @example str912.cpu mww 0x1234 0x42 @@ -2242,22 +2291,6 @@ @* Success @item @b{resumed} @* Target has resumed -@item @b{tap-enable} -@* Executed by @b{jtag tapenable DOTTED.NAME} command. Example: -@example -jtag configure DOTTED.NAME -event tap-enable @{ - puts "Enabling CPU" - ... -@} -@end example -@item @b{tap-disable} -@*Executed by @b{jtag tapdisable DOTTED.NAME} command. Example: -@example -jtag configure DOTTED.NAME -event tap-disable @{ - puts "Disabling CPU" - ... -@} -@end example @end itemize @anchor{Target Create} @@ -2338,6 +2371,11 @@ @} @end example +@b{PROBLEM:} On more complex chips, the work area can become +inaccessible when application code enables or disables the MMU. +For example, the MMU context used to acess the virtual address +will probably matter. + @section Target Variants @itemize @bullet @item @b{cortex_m3} |
From: <zw...@ma...> - 2009-06-03 02:45:36
|
Author: zwelch Date: 2009-06-03 02:45:21 +0200 (Wed, 03 Jun 2009) New Revision: 2012 Added: trunk/src/jtag/interface.c Modified: trunk/src/jtag/Makefile.am trunk/src/jtag/interface.h trunk/src/jtag/jtag.c Log: Move the JTAG cable interface API implementation - Cloned the src/jtag/jtag.c file to src/jtag/interface.c. - For each for of those files, deleted the contents of the other. - Add new source file to automake input. Modified: trunk/src/jtag/Makefile.am =================================================================== --- trunk/src/jtag/Makefile.am 2009-06-03 00:33:22 UTC (rev 2011) +++ trunk/src/jtag/Makefile.am 2009-06-03 00:45:21 UTC (rev 2012) @@ -117,6 +117,7 @@ libjtag_la_SOURCES = \ jtag.c \ + interface.c \ $(DRIVERFILES) \ $(BITBANGFILES) \ $(PARPORTFILES) \ Copied: trunk/src/jtag/interface.c (from rev 2011, trunk/src/jtag/jtag.c) =================================================================== --- trunk/src/jtag/jtag.c 2009-06-03 00:33:22 UTC (rev 2011) +++ trunk/src/jtag/interface.c 2009-06-03 00:45:21 UTC (rev 2012) @@ -0,0 +1,465 @@ +/*************************************************************************** + * Copyright (C) 2005 by Dominic Rath * + * Dom...@gm... * + * * + * Copyright (C) 2007,2008 vind Harboe * + * oyv...@zy... * + * * + * Copyright (C) 2009 SoftPLC Corporation * + * http://softplc.com * + * di...@so... * + * * + * Copyright (C) 2009 Zachary T Welch * + * zw...@su... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "jtag.h" +#include "interface.h" + +/** + * @see tap_set_state() and tap_get_state() accessors. + * Actual name is not important since accessors hide it. + */ +static tap_state_t state_follower = TAP_RESET; + +void tap_set_state_impl( tap_state_t new_state ) +{ + /* this is the state we think the TAPs are in now, was cur_state */ + state_follower = new_state; +} + +tap_state_t tap_get_state() +{ + return state_follower; +} + +/** + * @see tap_set_end_state() and tap_get_end_state() accessors. + * Actual name is not important because accessors hide it. + */ +static tap_state_t end_state_follower = TAP_RESET; + +void tap_set_end_state( tap_state_t new_end_state ) +{ + /* this is the state we think the TAPs will be in at completion of the + current TAP operation, was end_state + */ + end_state_follower = new_end_state; +} + +tap_state_t tap_get_end_state() +{ + return end_state_follower; +} + + +int tap_move_ndx( tap_state_t astate ) +{ + /* given a stable state, return the index into the tms_seqs[] array within tap_get_tms_path() */ + + int ndx; + + switch( astate ) + { + case TAP_RESET: ndx = 0; break; + case TAP_DRSHIFT: ndx = 2; break; + case TAP_DRPAUSE: ndx = 3; break; + case TAP_IDLE: ndx = 1; break; + case TAP_IRSHIFT: ndx = 4; break; + case TAP_IRPAUSE: ndx = 5; break; + default: + LOG_ERROR( "fatal: unstable state \"%s\" used in tap_move_ndx()", tap_state_name(astate) ); + exit(1); + } + + return ndx; +} + + +/* tap_move[i][j]: tap movement command to go from state i to state j + * 0: Test-Logic-Reset + * 1: Run-Test/Idle + * 2: Shift-DR + * 3: Pause-DR + * 4: Shift-IR + * 5: Pause-IR + * + * DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code + */ +struct tms_sequences +{ + u8 bits; + u8 bit_count; + +}; + +/* + * These macros allow us to specify TMS state transitions by bits rather than hex bytes. + * Read the bits from LSBit first to MSBit last (right-to-left). + */ +#define HEX__(n) 0x##n##LU + +#define B8__(x) \ + (((x) & 0x0000000FLU)?(1<<0):0) \ + +(((x) & 0x000000F0LU)?(1<<1):0) \ + +(((x) & 0x00000F00LU)?(1<<2):0) \ + +(((x) & 0x0000F000LU)?(1<<3):0) \ + +(((x) & 0x000F0000LU)?(1<<4):0) \ + +(((x) & 0x00F00000LU)?(1<<5):0) \ + +(((x) & 0x0F000000LU)?(1<<6):0) \ + +(((x) & 0xF0000000LU)?(1<<7):0) + +#define B8(bits,count) { ((u8)B8__(HEX__(bits))), (count) } + +static const struct tms_sequences old_tms_seqs[6][6] = /* [from_state_ndx][to_state_ndx] */ +{ + /* value clocked to TMS to move from one of six stable states to another. + * N.B. OOCD clocks TMS from LSB first, so read these right-to-left. + * N.B. These values are tightly bound to the table in tap_get_tms_path_len(). + * N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable. + * These extra ones cause no TAP state problem, because we go into reset and stay in reset. + */ + + + + /* to state: */ + /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ + { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ + { B8(1111111,7), B8(0000000,7), B8(0100101,7), B8(0000101,7), B8(0101011,7), B8(0001011,7) }, /* IDLE */ + { B8(1111111,7), B8(0110001,7), B8(0000000,7), B8(0000001,7), B8(0001111,7), B8(0101111,7) }, /* DRSHIFT */ + { B8(1111111,7), B8(0110000,7), B8(0100000,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* DRPAUSE */ + { B8(1111111,7), B8(0110001,7), B8(0000111,7), B8(0010111,7), B8(0000000,7), B8(0000001,7) }, /* IRSHIFT */ + { B8(1111111,7), B8(0110000,7), B8(0011100,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* IRPAUSE */ +}; + + + +static const struct tms_sequences short_tms_seqs[6][6] = /* [from_state_ndx][to_state_ndx] */ +{ + /* this is the table submitted by Jeff Williams on 3/30/2009 with this comment: + + OK, I added Peter's version of the state table, and it works OK for + me on MC1322x. I've recreated the jlink portion of patch with this + new state table. His changes to my state table are pretty minor in + terms of total transitions, but Peter feels that his version fixes + some long-standing problems. + Jeff + + I added the bit count into the table, reduced RESET column to 7 bits from 8. + Dick + + state specific comments: + ------------------------ + *->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to + work better on ARM9 with ft2232 driver. (Dick) + + RESET->DRSHIFT add 1 extra clock cycles in the RESET state before advancing. + needed on ARM9 with ft2232 driver. (Dick) + + RESET->IRSHIFT add 1 extra clock cycles in the RESET state before advancing. + needed on ARM9 with ft2232 driver. (Dick) + */ + + /* to state: */ + /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ + { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ + { B8(1111111,7), B8(0000000,7), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */ + { B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */ + { B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */ + { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */ + { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1) } /* IRPAUSE */ + +}; + +typedef const struct tms_sequences tms_table[6][6]; + +static tms_table *tms_seqs=&short_tms_seqs; + +int tap_get_tms_path( tap_state_t from, tap_state_t to ) +{ + return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits; +} + + +int tap_get_tms_path_len( tap_state_t from, tap_state_t to ) +{ + return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bit_count; +} + + +bool tap_is_state_stable(tap_state_t astate) +{ + bool is_stable; + + /* A switch() is used because it is symbol dependent + (not value dependent like an array), and can also check bounds. + */ + switch( astate ) + { + case TAP_RESET: + case TAP_IDLE: + case TAP_DRSHIFT: + case TAP_DRPAUSE: + case TAP_IRSHIFT: + case TAP_IRPAUSE: + is_stable = true; + break; + default: + is_stable = false; + } + + return is_stable; +} + +tap_state_t tap_state_transition(tap_state_t cur_state, bool tms) +{ + tap_state_t new_state; + + /* A switch is used because it is symbol dependent and not value dependent + like an array. Also it can check for out of range conditions. + */ + + if (tms) + { + switch (cur_state) + { + case TAP_RESET: + new_state = cur_state; + break; + case TAP_IDLE: + case TAP_DRUPDATE: + case TAP_IRUPDATE: + new_state = TAP_DRSELECT; + break; + case TAP_DRSELECT: + new_state = TAP_IRSELECT; + break; + case TAP_DRCAPTURE: + case TAP_DRSHIFT: + new_state = TAP_DREXIT1; + break; + case TAP_DREXIT1: + case TAP_DREXIT2: + new_state = TAP_DRUPDATE; + break; + case TAP_DRPAUSE: + new_state = TAP_DREXIT2; + break; + case TAP_IRSELECT: + new_state = TAP_RESET; + break; + case TAP_IRCAPTURE: + case TAP_IRSHIFT: + new_state = TAP_IREXIT1; + break; + case TAP_IREXIT1: + case TAP_IREXIT2: + new_state = TAP_IRUPDATE; + break; + case TAP_IRPAUSE: + new_state = TAP_IREXIT2; + break; + default: + LOG_ERROR( "fatal: invalid argument cur_state=%d", cur_state ); + exit(1); + break; + } + } + else + { + switch (cur_state) + { + case TAP_RESET: + case TAP_IDLE: + case TAP_DRUPDATE: + case TAP_IRUPDATE: + new_state = TAP_IDLE; + break; + case TAP_DRSELECT: + new_state = TAP_DRCAPTURE; + break; + case TAP_DRCAPTURE: + case TAP_DRSHIFT: + case TAP_DREXIT2: + new_state = TAP_DRSHIFT; + break; + case TAP_DREXIT1: + case TAP_DRPAUSE: + new_state = TAP_DRPAUSE; + break; + case TAP_IRSELECT: + new_state = TAP_IRCAPTURE; + break; + case TAP_IRCAPTURE: + case TAP_IRSHIFT: + case TAP_IREXIT2: + new_state = TAP_IRSHIFT; + break; + case TAP_IREXIT1: + case TAP_IRPAUSE: + new_state = TAP_IRPAUSE; + break; + default: + LOG_ERROR( "fatal: invalid argument cur_state=%d", cur_state ); + exit(1); + break; + } + } + + return new_state; +} + +const char* tap_state_name(tap_state_t state) +{ + const char* ret; + + switch( state ) + { + case TAP_RESET: ret = "RESET"; break; + case TAP_IDLE: ret = "RUN/IDLE"; break; + case TAP_DRSELECT: ret = "DRSELECT"; break; + case TAP_DRCAPTURE: ret = "DRCAPTURE"; break; + case TAP_DRSHIFT: ret = "DRSHIFT"; break; + case TAP_DREXIT1: ret = "DREXIT1"; break; + case TAP_DRPAUSE: ret = "DRPAUSE"; break; + case TAP_DREXIT2: ret = "DREXIT2"; break; + case TAP_DRUPDATE: ret = "DRUPDATE"; break; + case TAP_IRSELECT: ret = "IRSELECT"; break; + case TAP_IRCAPTURE: ret = "IRCAPTURE"; break; + case TAP_IRSHIFT: ret = "IRSHIFT"; break; + case TAP_IREXIT1: ret = "IREXIT1"; break; + case TAP_IRPAUSE: ret = "IRPAUSE"; break; + case TAP_IREXIT2: ret = "IREXIT2"; break; + case TAP_IRUPDATE: ret = "IRUPDATE"; break; + default: ret = "???"; + } + + return ret; +} + +tap_state_t tap_state_by_name(const char *name) +{ + tap_state_t x; + + for( x = 0 ; x < TAP_NUM_STATES ; x++ ){ + /* be nice to the human */ + if( 0 == strcasecmp( name, tap_state_name(x) ) ){ + return x; + } + } + /* not found */ + return TAP_INVALID; +} + +#ifdef _DEBUG_JTAG_IO_ + +#define JTAG_DEBUG_STATE_APPEND(buf, len, bit) \ + do { buf[len] = bit ? '1' : '0'; } while(0) +#define JTAG_DEBUG_STATE_PRINT(a, b, astr, bstr) \ + DEBUG_JTAG_IO("TAP/SM: %9s -> %5s\tTMS: %s\tTDI: %s", \ + tap_state_name(a), tap_state_name(b), astr, bstr) + +tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, + unsigned tap_bits, tap_state_t next_state) +{ + const u8 *tms_buffer; + const u8 *tdi_buffer; + unsigned tap_bytes; + unsigned cur_byte; + unsigned cur_bit; + + unsigned tap_out_bits; + char tms_str[33]; + char tdi_str[33]; + + tap_state_t last_state; + + // set startstate (and possibly last, if tap_bits == 0) + last_state = next_state; + DEBUG_JTAG_IO("TAP/SM: START state: %s", tap_state_name(next_state)); + + tms_buffer = (const u8 *)tms_buf; + tdi_buffer = (const u8 *)tdi_buf; + + tap_bytes = TAP_SCAN_BYTES(tap_bits); + DEBUG_JTAG_IO("TAP/SM: TMS bits: %u (bytes: %u)", tap_bits, tap_bytes); + + tap_out_bits = 0; + for(cur_byte = 0; cur_byte < tap_bytes; cur_byte++) + { + for(cur_bit = 0; cur_bit < 8; cur_bit++) + { + // make sure we do not run off the end of the buffers + unsigned tap_bit = cur_byte * 8 + cur_bit; + if (tap_bit == tap_bits) + break; + + // check and save TMS bit + tap_bit = !!(tms_buffer[cur_byte] & (1 << cur_bit)); + JTAG_DEBUG_STATE_APPEND(tms_str, tap_out_bits, tap_bit); + + // use TMS bit to find the next TAP state + next_state = tap_state_transition(last_state, tap_bit); + + // check and store TDI bit + tap_bit = !!(tdi_buffer[cur_byte] & (1 << cur_bit)); + JTAG_DEBUG_STATE_APPEND(tdi_str, tap_out_bits, tap_bit); + + // increment TAP bits + tap_out_bits++; + + // Only show TDO bits on state transitions, or + // after some number of bits in the same state. + if ((next_state == last_state) && (tap_out_bits < 32)) + continue; + + // terminate strings and display state transition + tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0; + JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str); + + // reset state + last_state = next_state; + tap_out_bits = 0; + } + } + + if (tap_out_bits) + { + // terminate strings and display state transition + tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0; + JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str); + } + + DEBUG_JTAG_IO("TAP/SM: FINAL state: %s", tap_state_name(next_state)); + + return next_state; +} +#endif // _DEBUG_JTAG_IO_ + +void tap_use_new_tms_table(bool use_new) +{ + tms_seqs = use_new ? &short_tms_seqs : &old_tms_seqs; +} +bool tap_uses_new_tms_table(void) +{ + return tms_seqs == &short_tms_seqs; +} + Modified: trunk/src/jtag/interface.h =================================================================== --- trunk/src/jtag/interface.h 2009-06-03 00:33:22 UTC (rev 2011) +++ trunk/src/jtag/interface.h 2009-06-03 00:45:21 UTC (rev 2012) @@ -26,6 +26,8 @@ #ifndef OPENOCD_JTAG_INTERFACE_H #define OPENOCD_JTAG_INTERFACE_H +#include "jtag.h" + /* @file * The "Cable Helper API" is what the cable drivers can use to help * implement their "Cable API". So a Cable Helper API is a set of Modified: trunk/src/jtag/jtag.c =================================================================== --- trunk/src/jtag/jtag.c 2009-06-03 00:33:22 UTC (rev 2011) +++ trunk/src/jtag/jtag.c 2009-06-03 00:45:21 UTC (rev 2012) @@ -2795,443 +2795,6 @@ } } -/*-----<Cable Helper API>---------------------------------------*/ - -/* these Cable Helper API functions are all documented in the jtag.h header file, - using a Doxygen format. And since Doxygen's configuration file "Doxyfile", - is setup to prefer its docs in the header file, no documentation is here, for - if it were, it would have to be doubly maintained. -*/ - -/** - * @see tap_set_state() and tap_get_state() accessors. - * Actual name is not important since accessors hide it. - */ -static tap_state_t state_follower = TAP_RESET; - -void tap_set_state_impl( tap_state_t new_state ) -{ - /* this is the state we think the TAPs are in now, was cur_state */ - state_follower = new_state; -} - -tap_state_t tap_get_state() -{ - return state_follower; -} - -/** - * @see tap_set_end_state() and tap_get_end_state() accessors. - * Actual name is not important because accessors hide it. - */ -static tap_state_t end_state_follower = TAP_RESET; - -void tap_set_end_state( tap_state_t new_end_state ) -{ - /* this is the state we think the TAPs will be in at completion of the - current TAP operation, was end_state - */ - end_state_follower = new_end_state; -} - -tap_state_t tap_get_end_state() -{ - return end_state_follower; -} - - -int tap_move_ndx( tap_state_t astate ) -{ - /* given a stable state, return the index into the tms_seqs[] array within tap_get_tms_path() */ - - int ndx; - - switch( astate ) - { - case TAP_RESET: ndx = 0; break; - case TAP_DRSHIFT: ndx = 2; break; - case TAP_DRPAUSE: ndx = 3; break; - case TAP_IDLE: ndx = 1; break; - case TAP_IRSHIFT: ndx = 4; break; - case TAP_IRPAUSE: ndx = 5; break; - default: - LOG_ERROR( "fatal: unstable state \"%s\" used in tap_move_ndx()", tap_state_name(astate) ); - exit(1); - } - - return ndx; -} - - -/* tap_move[i][j]: tap movement command to go from state i to state j - * 0: Test-Logic-Reset - * 1: Run-Test/Idle - * 2: Shift-DR - * 3: Pause-DR - * 4: Shift-IR - * 5: Pause-IR - * - * DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code - */ -struct tms_sequences -{ - u8 bits; - u8 bit_count; - -}; - -/* - * These macros allow us to specify TMS state transitions by bits rather than hex bytes. - * Read the bits from LSBit first to MSBit last (right-to-left). - */ -#define HEX__(n) 0x##n##LU - -#define B8__(x) \ - (((x) & 0x0000000FLU)?(1<<0):0) \ - +(((x) & 0x000000F0LU)?(1<<1):0) \ - +(((x) & 0x00000F00LU)?(1<<2):0) \ - +(((x) & 0x0000F000LU)?(1<<3):0) \ - +(((x) & 0x000F0000LU)?(1<<4):0) \ - +(((x) & 0x00F00000LU)?(1<<5):0) \ - +(((x) & 0x0F000000LU)?(1<<6):0) \ - +(((x) & 0xF0000000LU)?(1<<7):0) - -#define B8(bits,count) { ((u8)B8__(HEX__(bits))), (count) } - -static const struct tms_sequences old_tms_seqs[6][6] = /* [from_state_ndx][to_state_ndx] */ -{ - /* value clocked to TMS to move from one of six stable states to another. - * N.B. OOCD clocks TMS from LSB first, so read these right-to-left. - * N.B. These values are tightly bound to the table in tap_get_tms_path_len(). - * N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable. - * These extra ones cause no TAP state problem, because we go into reset and stay in reset. - */ - - - - /* to state: */ - /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ - { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ - { B8(1111111,7), B8(0000000,7), B8(0100101,7), B8(0000101,7), B8(0101011,7), B8(0001011,7) }, /* IDLE */ - { B8(1111111,7), B8(0110001,7), B8(0000000,7), B8(0000001,7), B8(0001111,7), B8(0101111,7) }, /* DRSHIFT */ - { B8(1111111,7), B8(0110000,7), B8(0100000,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* DRPAUSE */ - { B8(1111111,7), B8(0110001,7), B8(0000111,7), B8(0010111,7), B8(0000000,7), B8(0000001,7) }, /* IRSHIFT */ - { B8(1111111,7), B8(0110000,7), B8(0011100,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* IRPAUSE */ -}; - - - -static const struct tms_sequences short_tms_seqs[6][6] = /* [from_state_ndx][to_state_ndx] */ -{ - /* this is the table submitted by Jeff Williams on 3/30/2009 with this comment: - - OK, I added Peter's version of the state table, and it works OK for - me on MC1322x. I've recreated the jlink portion of patch with this - new state table. His changes to my state table are pretty minor in - terms of total transitions, but Peter feels that his version fixes - some long-standing problems. - Jeff - - I added the bit count into the table, reduced RESET column to 7 bits from 8. - Dick - - state specific comments: - ------------------------ - *->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to - work better on ARM9 with ft2232 driver. (Dick) - - RESET->DRSHIFT add 1 extra clock cycles in the RESET state before advancing. - needed on ARM9 with ft2232 driver. (Dick) - - RESET->IRSHIFT add 1 extra clock cycles in the RESET state before advancing. - needed on ARM9 with ft2232 driver. (Dick) - */ - - /* to state: */ - /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ - { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ - { B8(1111111,7), B8(0000000,7), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */ - { B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */ - { B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */ - { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */ - { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1) } /* IRPAUSE */ - -}; - -typedef const struct tms_sequences tms_table[6][6]; - -static tms_table *tms_seqs=&short_tms_seqs; - -int tap_get_tms_path( tap_state_t from, tap_state_t to ) -{ - return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits; -} - - -int tap_get_tms_path_len( tap_state_t from, tap_state_t to ) -{ - return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bit_count; -} - - -bool tap_is_state_stable(tap_state_t astate) -{ - bool is_stable; - - /* A switch() is used because it is symbol dependent - (not value dependent like an array), and can also check bounds. - */ - switch( astate ) - { - case TAP_RESET: - case TAP_IDLE: - case TAP_DRSHIFT: - case TAP_DRPAUSE: - case TAP_IRSHIFT: - case TAP_IRPAUSE: - is_stable = true; - break; - default: - is_stable = false; - } - - return is_stable; -} - -tap_state_t tap_state_transition(tap_state_t cur_state, bool tms) -{ - tap_state_t new_state; - - /* A switch is used because it is symbol dependent and not value dependent - like an array. Also it can check for out of range conditions. - */ - - if (tms) - { - switch (cur_state) - { - case TAP_RESET: - new_state = cur_state; - break; - case TAP_IDLE: - case TAP_DRUPDATE: - case TAP_IRUPDATE: - new_state = TAP_DRSELECT; - break; - case TAP_DRSELECT: - new_state = TAP_IRSELECT; - break; - case TAP_DRCAPTURE: - case TAP_DRSHIFT: - new_state = TAP_DREXIT1; - break; - case TAP_DREXIT1: - case TAP_DREXIT2: - new_state = TAP_DRUPDATE; - break; - case TAP_DRPAUSE: - new_state = TAP_DREXIT2; - break; - case TAP_IRSELECT: - new_state = TAP_RESET; - break; - case TAP_IRCAPTURE: - case TAP_IRSHIFT: - new_state = TAP_IREXIT1; - break; - case TAP_IREXIT1: - case TAP_IREXIT2: - new_state = TAP_IRUPDATE; - break; - case TAP_IRPAUSE: - new_state = TAP_IREXIT2; - break; - default: - LOG_ERROR( "fatal: invalid argument cur_state=%d", cur_state ); - exit(1); - break; - } - } - else - { - switch (cur_state) - { - case TAP_RESET: - case TAP_IDLE: - case TAP_DRUPDATE: - case TAP_IRUPDATE: - new_state = TAP_IDLE; - break; - case TAP_DRSELECT: - new_state = TAP_DRCAPTURE; - break; - case TAP_DRCAPTURE: - case TAP_DRSHIFT: - case TAP_DREXIT2: - new_state = TAP_DRSHIFT; - break; - case TAP_DREXIT1: - case TAP_DRPAUSE: - new_state = TAP_DRPAUSE; - break; - case TAP_IRSELECT: - new_state = TAP_IRCAPTURE; - break; - case TAP_IRCAPTURE: - case TAP_IRSHIFT: - case TAP_IREXIT2: - new_state = TAP_IRSHIFT; - break; - case TAP_IREXIT1: - case TAP_IRPAUSE: - new_state = TAP_IRPAUSE; - break; - default: - LOG_ERROR( "fatal: invalid argument cur_state=%d", cur_state ); - exit(1); - break; - } - } - - return new_state; -} - -const char* tap_state_name(tap_state_t state) -{ - const char* ret; - - switch( state ) - { - case TAP_RESET: ret = "RESET"; break; - case TAP_IDLE: ret = "RUN/IDLE"; break; - case TAP_DRSELECT: ret = "DRSELECT"; break; - case TAP_DRCAPTURE: ret = "DRCAPTURE"; break; - case TAP_DRSHIFT: ret = "DRSHIFT"; break; - case TAP_DREXIT1: ret = "DREXIT1"; break; - case TAP_DRPAUSE: ret = "DRPAUSE"; break; - case TAP_DREXIT2: ret = "DREXIT2"; break; - case TAP_DRUPDATE: ret = "DRUPDATE"; break; - case TAP_IRSELECT: ret = "IRSELECT"; break; - case TAP_IRCAPTURE: ret = "IRCAPTURE"; break; - case TAP_IRSHIFT: ret = "IRSHIFT"; break; - case TAP_IREXIT1: ret = "IREXIT1"; break; - case TAP_IRPAUSE: ret = "IRPAUSE"; break; - case TAP_IREXIT2: ret = "IREXIT2"; break; - case TAP_IRUPDATE: ret = "IRUPDATE"; break; - default: ret = "???"; - } - - return ret; -} - -tap_state_t tap_state_by_name(const char *name) -{ - tap_state_t x; - - for( x = 0 ; x < TAP_NUM_STATES ; x++ ){ - /* be nice to the human */ - if( 0 == strcasecmp( name, tap_state_name(x) ) ){ - return x; - } - } - /* not found */ - return TAP_INVALID; -} - -#ifdef _DEBUG_JTAG_IO_ - -#define JTAG_DEBUG_STATE_APPEND(buf, len, bit) \ - do { buf[len] = bit ? '1' : '0'; } while(0) -#define JTAG_DEBUG_STATE_PRINT(a, b, astr, bstr) \ - DEBUG_JTAG_IO("TAP/SM: %9s -> %5s\tTMS: %s\tTDI: %s", \ - tap_state_name(a), tap_state_name(b), astr, bstr) - -tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, - unsigned tap_bits, tap_state_t next_state) -{ - const u8 *tms_buffer; - const u8 *tdi_buffer; - unsigned tap_bytes; - unsigned cur_byte; - unsigned cur_bit; - - unsigned tap_out_bits; - char tms_str[33]; - char tdi_str[33]; - - tap_state_t last_state; - - // set startstate (and possibly last, if tap_bits == 0) - last_state = next_state; - DEBUG_JTAG_IO("TAP/SM: START state: %s", tap_state_name(next_state)); - - tms_buffer = (const u8 *)tms_buf; - tdi_buffer = (const u8 *)tdi_buf; - - tap_bytes = TAP_SCAN_BYTES(tap_bits); - DEBUG_JTAG_IO("TAP/SM: TMS bits: %u (bytes: %u)", tap_bits, tap_bytes); - - tap_out_bits = 0; - for(cur_byte = 0; cur_byte < tap_bytes; cur_byte++) - { - for(cur_bit = 0; cur_bit < 8; cur_bit++) - { - // make sure we do not run off the end of the buffers - unsigned tap_bit = cur_byte * 8 + cur_bit; - if (tap_bit == tap_bits) - break; - - // check and save TMS bit - tap_bit = !!(tms_buffer[cur_byte] & (1 << cur_bit)); - JTAG_DEBUG_STATE_APPEND(tms_str, tap_out_bits, tap_bit); - - // use TMS bit to find the next TAP state - next_state = tap_state_transition(last_state, tap_bit); - - // check and store TDI bit - tap_bit = !!(tdi_buffer[cur_byte] & (1 << cur_bit)); - JTAG_DEBUG_STATE_APPEND(tdi_str, tap_out_bits, tap_bit); - - // increment TAP bits - tap_out_bits++; - - // Only show TDO bits on state transitions, or - // after some number of bits in the same state. - if ((next_state == last_state) && (tap_out_bits < 32)) - continue; - - // terminate strings and display state transition - tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0; - JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str); - - // reset state - last_state = next_state; - tap_out_bits = 0; - } - } - - if (tap_out_bits) - { - // terminate strings and display state transition - tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0; - JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str); - } - - DEBUG_JTAG_IO("TAP/SM: FINAL state: %s", tap_state_name(next_state)); - - return next_state; -} -#endif // _DEBUG_JTAG_IO_ - -void tap_use_new_tms_table(bool use_new) -{ - tms_seqs = use_new ? &short_tms_seqs : &old_tms_seqs; -} -bool tap_uses_new_tms_table(void) -{ - return tms_seqs == &short_tms_seqs; -} - static int handle_tms_sequence_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { if (argc > 1) @@ -3256,9 +2819,6 @@ return ERROR_OK; } -/*-----</Cable Helper API>--------------------------------------*/ - - /** * Function jtag_add_statemove * moves from the current state to the goal \a state. This needs |
From: <zw...@ma...> - 2009-06-03 02:34:46
|
Author: zwelch Date: 2009-06-03 02:33:22 +0200 (Wed, 03 Jun 2009) New Revision: 2011 Modified: trunk/src/jtag/interface.h trunk/src/jtag/jtag.c Log: Add missed accessor for checking the current TMS table. Modified: trunk/src/jtag/interface.h =================================================================== --- trunk/src/jtag/interface.h 2009-06-03 00:24:21 UTC (rev 2010) +++ trunk/src/jtag/interface.h 2009-06-03 00:33:22 UTC (rev 2011) @@ -169,6 +169,8 @@ /// Allow switching between old and new TMS tables. @see tap_get_tms_path void tap_use_new_tms_table(bool use_new); +/// @returns True if new TMS table is active; false otherwise. +bool tap_uses_new_tms_table(void); #ifdef _DEBUG_JTAG_IO_ /** Modified: trunk/src/jtag/jtag.c =================================================================== --- trunk/src/jtag/jtag.c 2009-06-03 00:24:21 UTC (rev 2010) +++ trunk/src/jtag/jtag.c 2009-06-03 00:33:22 UTC (rev 2011) @@ -3227,6 +3227,10 @@ { tms_seqs = use_new ? &short_tms_seqs : &old_tms_seqs; } +bool tap_uses_new_tms_table(void) +{ + return tms_seqs == &short_tms_seqs; +} static int handle_tms_sequence_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { @@ -3246,7 +3250,8 @@ tap_use_new_tms_table(use_new_table); } - command_print(cmd_ctx, "tms sequence is %s", (tms_seqs==&short_tms_seqs) ? "short": "long"); + command_print(cmd_ctx, "tms sequence is %s", + tap_uses_new_tms_table() ? "short": "long"); return ERROR_OK; } |
From: <zw...@ma...> - 2009-06-03 02:24:27
|
Author: zwelch Date: 2009-06-03 02:24:21 +0200 (Wed, 03 Jun 2009) New Revision: 2010 Modified: trunk/src/jtag/interface.h trunk/src/jtag/jtag.c Log: Split and simplify handle_tms_sequence_command for further factoring. Modified: trunk/src/jtag/interface.h =================================================================== --- trunk/src/jtag/interface.h 2009-06-03 00:17:42 UTC (rev 2009) +++ trunk/src/jtag/interface.h 2009-06-03 00:24:21 UTC (rev 2010) @@ -167,6 +167,9 @@ /// Provides user-friendly name lookup of TAP states. tap_state_t tap_state_by_name(const char *name); +/// Allow switching between old and new TMS tables. @see tap_get_tms_path +void tap_use_new_tms_table(bool use_new); + #ifdef _DEBUG_JTAG_IO_ /** * @brief Prints verbose TAP state transitions for the given TMS/TDI buffers. Modified: trunk/src/jtag/jtag.c =================================================================== --- trunk/src/jtag/jtag.c 2009-06-03 00:17:42 UTC (rev 2009) +++ trunk/src/jtag/jtag.c 2009-06-03 00:24:21 UTC (rev 2010) @@ -3223,24 +3223,27 @@ } #endif // _DEBUG_JTAG_IO_ +void tap_use_new_tms_table(bool use_new) +{ + tms_seqs = use_new ? &short_tms_seqs : &old_tms_seqs; +} + static int handle_tms_sequence_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { + if (argc > 1) + return ERROR_COMMAND_SYNTAX_ERROR; + if (argc == 1) { + bool use_new_table; if (strcmp(args[0], "short") == 0) - { - tms_seqs=&short_tms_seqs; - } + use_new_table = true; else if (strcmp(args[0], "long") == 0) - { - tms_seqs=&old_tms_seqs; - } else - { + use_new_table = false; + else return ERROR_COMMAND_SYNTAX_ERROR; - } - } else if (argc != 0) - { - return ERROR_COMMAND_SYNTAX_ERROR; + + tap_use_new_tms_table(use_new_table); } command_print(cmd_ctx, "tms sequence is %s", (tms_seqs==&short_tms_seqs) ? "short": "long"); |
From: <zw...@ma...> - 2009-06-03 02:17:47
|
Author: zwelch Date: 2009-06-03 02:17:42 +0200 (Wed, 03 Jun 2009) New Revision: 2009 Modified: trunk/src/jtag/interface.h trunk/src/jtag/jtag.c Log: Make tap_state_by_name available in new JTAG interface API header. Modified: trunk/src/jtag/interface.h =================================================================== --- trunk/src/jtag/interface.h 2009-06-02 23:59:13 UTC (rev 2008) +++ trunk/src/jtag/interface.h 2009-06-03 00:17:42 UTC (rev 2009) @@ -164,6 +164,9 @@ */ const char* tap_state_name(tap_state_t state); +/// Provides user-friendly name lookup of TAP states. +tap_state_t tap_state_by_name(const char *name); + #ifdef _DEBUG_JTAG_IO_ /** * @brief Prints verbose TAP state transitions for the given TMS/TDI buffers. Modified: trunk/src/jtag/jtag.c =================================================================== --- trunk/src/jtag/jtag.c 2009-06-02 23:59:13 UTC (rev 2008) +++ trunk/src/jtag/jtag.c 2009-06-03 00:17:42 UTC (rev 2009) @@ -217,14 +217,6 @@ static jtag_interface_t *jtag_interface = NULL; int jtag_speed = 0; -/* forward declarations */ -//void jtag_add_pathmove(int num_states, tap_state_t *path); -//void jtag_add_runtest(int num_cycles, tap_state_t endstate); -//void jtag_add_end_state(tap_state_t endstate); -//void jtag_add_sleep(u32 us); -//int jtag_execute_queue(void); -static tap_state_t tap_state_by_name(const char *name); - /* jtag commands */ static int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); static int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -3132,7 +3124,7 @@ return ret; } -static tap_state_t tap_state_by_name( const char *name ) +tap_state_t tap_state_by_name(const char *name) { tap_state_t x; |
From: <zw...@ma...> - 2009-06-03 01:59:20
|
Author: zwelch Date: 2009-06-03 01:59:13 +0200 (Wed, 03 Jun 2009) New Revision: 2008 Added: trunk/src/jtag/interface.h Modified: trunk/src/jtag/Makefile.am trunk/src/jtag/jtag.h Log: Add private src/jtag/interface.h for use by JTAG interface drivers: - Move the jtag_interface structure definition. - Move the Cable API declarations. - Add new header file to automake input. The next patch will move the implementation to interface.c. Modified: trunk/src/jtag/Makefile.am =================================================================== --- trunk/src/jtag/Makefile.am 2009-06-02 23:21:18 UTC (rev 2007) +++ trunk/src/jtag/Makefile.am 2009-06-02 23:59:13 UTC (rev 2008) @@ -136,6 +136,7 @@ $(ARMJTAGEWFILES) noinst_HEADERS = \ + interface.h \ minidriver.h \ bitbang.h \ jtag.h \ Added: trunk/src/jtag/interface.h =================================================================== --- trunk/src/jtag/interface.h 2009-06-02 23:21:18 UTC (rev 2007) +++ trunk/src/jtag/interface.h 2009-06-02 23:59:13 UTC (rev 2008) @@ -0,0 +1,236 @@ +/*************************************************************************** + * Copyright (C) 2005 by Dominic Rath * + * Dom...@gm... * + * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyv...@zy... * + * * + * Copyright (C) 2009 Zachary T Welch * + * zw...@su... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef OPENOCD_JTAG_INTERFACE_H +#define OPENOCD_JTAG_INTERFACE_H + +/* @file + * The "Cable Helper API" is what the cable drivers can use to help + * implement their "Cable API". So a Cable Helper API is a set of + * helper functions used by cable drivers, and this is different from a + * Cable API. A "Cable API" is what higher level code used to talk to a + * cable. + */ + + +/** implementation of wrapper function tap_set_state() */ +void tap_set_state_impl(tap_state_t new_state); + +/** + * This function sets the state of a "state follower" which tracks the + * state of the TAPs connected to the cable. The state follower is + * hopefully always in the same state as the actual TAPs in the jtag + * chain, and will be so if there are no bugs in the tracking logic + * within that cable driver. + * + * All the cable drivers call this function to indicate the state they + * think the TAPs attached to their cables are in. Because this + * function can also log transitions, it will be helpful to call this + * function with every transition that the TAPs being manipulated are + * expected to traverse, not just end points of a multi-step state path. + * + * @param new_state The state we think the TAPs are currently in (or + * are about to enter). + */ +#if defined(_DEBUG_JTAG_IO_) +#define tap_set_state(new_state) \ + do { \ + LOG_DEBUG( "tap_set_state(%s)", tap_state_name(new_state) ); \ + tap_set_state_impl(new_state); \ + } while (0) +#else +static inline void tap_set_state(tap_state_t new_state) +{ + tap_set_state_impl(new_state); +} +#endif + +/** + * This function gets the state of the "state follower" which tracks the + * state of the TAPs connected to the cable. @see tap_set_state @return + * tap_state_t The state the TAPs are in now. + */ +tap_state_t tap_get_state(void); + +/** + * This function sets the state of an "end state follower" which tracks + * the state that any cable driver thinks will be the end (resultant) + * state of the current TAP SIR or SDR operation. + * + * At completion of that TAP operation this value is copied into the + * state follower via tap_set_state(). + * + * @param new_end_state The state the TAPs should enter at completion of + * a pending TAP operation. + */ +void tap_set_end_state(tap_state_t new_end_state); + +/** + * For more information, @see tap_set_end_state + * @return tap_state_t - The state the TAPs should be in at completion of the current TAP operation. + */ +tap_state_t tap_get_end_state(void); + +/** + * This function provides a "bit sequence" indicating what has to be + * done with TMS during a sequence of seven TAP clock cycles in order to + * get from state \a "from" to state \a "to". + * + * The length of the sequence must be determined with a parallel call to + * tap_get_tms_path_len(). + * + * @param from The starting state. + * @param to The desired final state. + * @return int The required TMS bit sequence, with the first bit in the + * sequence at bit 0. + */ +int tap_get_tms_path(tap_state_t from, tap_state_t to); + + +/** + * Function int tap_get_tms_path_len + * returns the total number of bits that represents a TMS path + * transition as given by the function tap_get_tms_path(). + * + * For at least one interface (JLink) it's not OK to simply "pad" TMS + * sequences to fit a whole byte. (I suspect this is a general TAP + * problem within OOCD.) Padding TMS causes all manner of instability + * that's not easily discovered. Using this routine we can apply + * EXACTLY the state transitions required to make something work - no + * more - no less. + * + * @param from is the starting state + * @param to is the resultant or final state + * @return int - the total number of bits in a transition. + */ +int tap_get_tms_path_len(tap_state_t from, tap_state_t to); + + +/** + * Function tap_move_ndx + * when given a stable state, returns an index from 0-5. The index corresponds to a + * sequence of stable states which are given in this order: <p> + * { TAP_RESET, TAP_IDLE, TAP_DRSHIFT, TAP_DRPAUSE, TAP_IRSHIFT, TAP_IRPAUSE } + * <p> + * This sequence corresponds to look up tables which are used in some of the + * cable drivers. + * @param astate is the stable state to find in the sequence. If a non stable + * state is passed, this may cause the program to output an error message + * and terminate. + * @return int - the array (or sequence) index as described above + */ +int tap_move_ndx(tap_state_t astate); + +/** + * Function tap_is_state_stable + * returns true if the \a astate is stable. + */ +bool tap_is_state_stable(tap_state_t astate); + +/** + * Function tap_state_transition + * takes a current TAP state and returns the next state according to the tms value. + * @param current_state is the state of a TAP currently. + * @param tms is either zero or non-zero, just like a real TMS line in a jtag interface. + * @return tap_state_t - the next state a TAP would enter. + */ +tap_state_t tap_state_transition(tap_state_t current_state, bool tms); + +/** + * Function tap_state_name + * Returns a string suitable for display representing the JTAG tap_state + */ +const char* tap_state_name(tap_state_t state); + +#ifdef _DEBUG_JTAG_IO_ +/** + * @brief Prints verbose TAP state transitions for the given TMS/TDI buffers. + * @param tms_buf must points to a buffer containing the TMS bitstream. + * @param tdi_buf must points to a buffer containing the TDI bitstream. + * @param tap_len must specify the length of the TMS/TDI bitstreams. + * @param start_tap_state must specify the current TAP state. + * @returns the final TAP state; pass as @a start_tap_state in following call. + */ +tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, + unsigned tap_len, tap_state_t start_tap_state); +#else +static inline tap_state_t jtag_debug_state_machine(const void *tms_buf, + const void *tdi_buf, unsigned tap_len, tap_state_t start_tap_state) +{ + return start_tap_state; +} +#endif // _DEBUG_JTAG_IO_ + +typedef struct jtag_interface_s +{ + char* name; + + /* queued command execution + */ + int (*execute_queue)(void); + + /* interface initalization + */ + int (*speed)(int speed); + int (*register_commands)(struct command_context_s* cmd_ctx); + int (*init)(void); + int (*quit)(void); + + /* returns JTAG maxium speed for KHz. 0=RTCK. The function returns + * a failure if it can't support the KHz/RTCK. + * + * WARNING!!!! if RTCK is *slow* then think carefully about + * whether you actually want to support this in the driver. + * Many target scripts are written to handle the absence of RTCK + * and use a fallback kHz TCK. + */ + int (*khz)(int khz, int* jtag_speed); + + /* returns the KHz for the provided JTAG speed. 0=RTCK. The function returns + * a failure if it can't support the KHz/RTCK. */ + int (*speed_div)(int speed, int* khz); + + /* Read and clear the power dropout flag. Note that a power dropout + * can be transitionary, easily much less than a ms. + * + * So to find out if the power is *currently* on, you must invoke + * this method twice. Once to clear the power dropout flag and a + * second time to read the current state. + * + * Currently the default implementation is never to detect power dropout. + */ + int (*power_dropout)(int* power_dropout); + + /* Read and clear the srst asserted detection flag. + * + * NB!!!! like power_dropout this does *not* read the current + * state. srst assertion is transitionary and *can* be much + * less than 1ms. + */ + int (*srst_asserted)(int* srst_asserted); +} jtag_interface_t; + + +#endif // OPENOCD_JTAG_INTERFACE_H Property changes on: trunk/src/jtag/interface.h ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/src/jtag/jtag.h =================================================================== --- trunk/src/jtag/jtag.h 2009-06-02 23:21:18 UTC (rev 2007) +++ trunk/src/jtag/jtag.h 2009-06-02 23:59:13 UTC (rev 2008) @@ -105,160 +105,7 @@ //extern tap_transition_t tap_transitions[16]; /* describe the TAP state diagram */ -#ifdef INCLUDE_JTAG_INTERFACE_H -/*-----<Cable Helper API>-------------------------------------------*/ - -/* The "Cable Helper API" is what the cable drivers can use to help implement - * their "Cable API". So a Cable Helper API is a set of helper functions used by - * cable drivers, and this is different from a Cable API. A "Cable API" is what - * higher level code used to talk to a cable. - */ - - -/** implementation of wrapper function tap_set_state() */ -void tap_set_state_impl(tap_state_t new_state); - -/** - * Function tap_set_state - * sets the state of a "state follower" which tracks the state of the TAPs connected to the - * cable. The state follower is hopefully always in the same state as the actual - * TAPs in the jtag chain, and will be so if there are no bugs in the tracking logic within that - * cable driver. All the cable drivers call this function to indicate the state they think - * the TAPs attached to their cables are in. Because this function can also log transitions, - * it will be helpful to call this function with every transition that the TAPs being manipulated - * are expected to traverse, not just end points of a multi-step state path. - * @param new_state is the state we think the TAPs are currently in or are about to enter. - */ -#if defined(_DEBUG_JTAG_IO_) -#define tap_set_state(new_state) \ - do { \ - LOG_DEBUG( "tap_set_state(%s)", tap_state_name(new_state) ); \ - tap_set_state_impl(new_state); \ - } while (0) -#else -static inline void tap_set_state(tap_state_t new_state) -{ - tap_set_state_impl(new_state); -} - -#endif - -/** - * Function tap_get_state - * gets the state of the "state follower" which tracks the state of the TAPs connected to - * the cable. - * @see tap_set_state - * @return tap_state_t - The state the TAPs are in now. - */ -tap_state_t tap_get_state(void); - -/** - * Function tap_set_end_state - * sets the state of an "end state follower" which tracks the state that any cable driver - * thinks will be the end (resultant) state of the current TAP SIR or SDR operation. At completion - * of that TAP operation this value is copied into the state follower via tap_set_state(). - * @param new_end_state is that state the TAPs should enter at completion of a pending TAP operation. - */ -void tap_set_end_state(tap_state_t new_end_state); - -/** - * Function tap_get_end_state - * @see tap_set_end_state - * @return tap_state_t - The state the TAPs should be in at completion of the current TAP operation. - */ -tap_state_t tap_get_end_state(void); - -/** - * Function tap_get_tms_path - * returns a 7 bit long "bit sequence" indicating what has to be done with TMS - * during a sequence of seven TAP clock cycles in order to get from - * state \a "from" to state \a "to". - * @param from is the starting state - * @param to is the resultant or final state - * @return int - a 7 bit sequence, with the first bit in the sequence at bit 0. - */ -int tap_get_tms_path(tap_state_t from, tap_state_t to); - - -/** - * Function int tap_get_tms_path_len - * returns the total number of bits that represents a TMS path - * transition as given by the function tap_get_tms_path(). - * - * For at least one interface (JLink) it's not OK to simply "pad" TMS sequences - * to fit a whole byte. (I suspect this is a general TAP problem within OOCD.) - * Padding TMS causes all manner of instability that's not easily - * discovered. Using this routine we can apply EXACTLY the state transitions - * required to make something work - no more - no less. - * - * @param from is the starting state - * @param to is the resultant or final state - * @return int - the total number of bits in a transition. - */ -int tap_get_tms_path_len(tap_state_t from, tap_state_t to); - - -/** - * Function tap_move_ndx - * when given a stable state, returns an index from 0-5. The index corresponds to a - * sequence of stable states which are given in this order: <p> - * { TAP_RESET, TAP_IDLE, TAP_DRSHIFT, TAP_DRPAUSE, TAP_IRSHIFT, TAP_IRPAUSE } - * <p> - * This sequence corresponds to look up tables which are used in some of the - * cable drivers. - * @param astate is the stable state to find in the sequence. If a non stable - * state is passed, this may cause the program to output an error message - * and terminate. - * @return int - the array (or sequence) index as described above - */ -int tap_move_ndx(tap_state_t astate); - -/** - * Function tap_is_state_stable - * returns true if the \a astate is stable. - */ -bool tap_is_state_stable(tap_state_t astate); - -/** - * Function tap_state_transition - * takes a current TAP state and returns the next state according to the tms value. - * @param current_state is the state of a TAP currently. - * @param tms is either zero or non-zero, just like a real TMS line in a jtag interface. - * @return tap_state_t - the next state a TAP would enter. - */ -tap_state_t tap_state_transition(tap_state_t current_state, bool tms); - -/** - * Function tap_state_name - * Returns a string suitable for display representing the JTAG tap_state - */ -const char* tap_state_name(tap_state_t state); - -#ifdef _DEBUG_JTAG_IO_ -/** - * @brief Prints verbose TAP state transitions for the given TMS/TDI buffers. - * @param tms_buf must points to a buffer containing the TMS bitstream. - * @param tdi_buf must points to a buffer containing the TDI bitstream. - * @param tap_len must specify the length of the TMS/TDI bitstreams. - * @param start_tap_state must specify the current TAP state. - * @returns the final TAP state; pass as @a start_tap_state in following call. - */ -tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, - unsigned tap_len, tap_state_t start_tap_state); -#else -static inline tap_state_t jtag_debug_state_machine(const void *tms_buf, - const void *tdi_buf, unsigned tap_len, tap_state_t start_tap_state) -{ - return start_tap_state; -} -#endif // _DEBUG_JTAG_IO_ - -/*-----</Cable Helper API>------------------------------------------*/ - -#endif // INCLUDE_JTAG_INTERFACE_H - - extern tap_state_t cmd_queue_end_state; /* finish DR scans in dr_end_state */ extern tap_state_t cmd_queue_cur_state; /* current TAP state */ @@ -371,6 +218,8 @@ extern void jtag_queue_command(jtag_command_t *cmd); extern void jtag_command_queue_reset(void); +#include "interface.h" + #endif // INCLUDE_JTAG_INTERFACE_H /* forward declaration */ @@ -442,59 +291,6 @@ LINE_PUSH_PULL = 0x1, }; -#ifdef INCLUDE_JTAG_INTERFACE_H - -typedef struct jtag_interface_s -{ - char* name; - - /* queued command execution - */ - int (*execute_queue)(void); - - /* interface initalization - */ - int (*speed)(int speed); - int (*register_commands)(struct command_context_s* cmd_ctx); - int (*init)(void); - int (*quit)(void); - - /* returns JTAG maxium speed for KHz. 0=RTCK. The function returns - * a failure if it can't support the KHz/RTCK. - * - * WARNING!!!! if RTCK is *slow* then think carefully about - * whether you actually want to support this in the driver. - * Many target scripts are written to handle the absence of RTCK - * and use a fallback kHz TCK. - */ - int (*khz)(int khz, int* jtag_speed); - - /* returns the KHz for the provided JTAG speed. 0=RTCK. The function returns - * a failure if it can't support the KHz/RTCK. */ - int (*speed_div)(int speed, int* khz); - - /* Read and clear the power dropout flag. Note that a power dropout - * can be transitionary, easily much less than a ms. - * - * So to find out if the power is *currently* on, you must invoke - * this method twice. Once to clear the power dropout flag and a - * second time to read the current state. - * - * Currently the default implementation is never to detect power dropout. - */ - int (*power_dropout)(int* power_dropout); - - /* Read and clear the srst asserted detection flag. - * - * NB!!!! like power_dropout this does *not* read the current - * state. srst assertion is transitionary and *can* be much - * less than 1ms. - */ - int (*srst_asserted)(int* srst_asserted); -} jtag_interface_t; - -#endif // INCLUDE_JTAG_INTERFACE_H - enum jtag_event { JTAG_TRST_ASSERTED }; @@ -804,7 +600,7 @@ extern int jtag_scan_size(const scan_command_t* cmd); extern int jtag_read_buffer(u8* buffer, const scan_command_t* cmd); extern int jtag_build_buffer(const scan_command_t* cmd, u8** buffer); -#endif // INCLUDE_JTAG_INTERFACE_H +#endif // INCLUDE_JTAG_INTERFACE_H extern void jtag_sleep(u32 us); extern int jtag_call_event_callbacks(enum jtag_event event); |
From: <zw...@ma...> - 2009-06-03 01:21:26
|
Author: zwelch Date: 2009-06-03 01:21:18 +0200 (Wed, 03 Jun 2009) New Revision: 2007 Modified: trunk/src/jtag/jtag.c trunk/src/jtag/jtag.h trunk/src/jtag/jtag_driver.c trunk/src/jtag/minidriver.h Log: Finish removing '#ifdef HAVE_JTAG_MINIDRIVER_H' from jtag.h: - Wraps JTAG callback API functions: - Outlines jtag_add_callback() and jtag_add_callback4(). - Adds interface_ prefix to existing in-tree driver implementation. - Declare the driver interfaces routines in miniheader.h file. This patch requires renaming the equivalent macros in out-of-tree jtag_minidriver.h implementations. Modified: trunk/src/jtag/jtag.c =================================================================== --- trunk/src/jtag/jtag.c 2009-06-02 23:15:12 UTC (rev 2006) +++ trunk/src/jtag/jtag.c 2009-06-02 23:21:18 UTC (rev 2007) @@ -590,7 +590,17 @@ jtag_error=retval; } +void jtag_add_callback(jtag_callback1_t f, u8 *in) +{ + interface_jtag_add_callback(f, in); +} +void jtag_add_callback4(jtag_callback_t f, u8 *in, + jtag_callback_data_t data1, jtag_callback_data_t data2, + jtag_callback_data_t data3) +{ + interface_jtag_add_callback4(f, in, data1, data2, data3); +} int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, int num_bits); Modified: trunk/src/jtag/jtag.h =================================================================== --- trunk/src/jtag/jtag.h 2009-06-02 23:15:12 UTC (rev 2006) +++ trunk/src/jtag/jtag.h 2009-06-02 23:21:18 UTC (rev 2007) @@ -599,12 +599,8 @@ * fail, use the jtag_callback_t variant */ typedef void (*jtag_callback1_t)(u8 *in); -#ifndef HAVE_JTAG_MINIDRIVER_H /* A simpler version of jtag_add_callback4 */ extern void jtag_add_callback(jtag_callback1_t, u8 *in); -#else -/* implemented by minidriver */ -#endif /* This type can store an integer safely by a normal cast on 64 and @@ -650,11 +646,9 @@ * If the execution of the queue fails before the callbacks, then the * callbacks may or may not be invoked depending on driver implementation. */ -#ifndef HAVE_JTAG_MINIDRIVER_H -extern void jtag_add_callback4(jtag_callback_t, u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3); -#else -/* implemented by minidriver */ -#endif +extern void jtag_add_callback4(jtag_callback_t, u8 *in, + jtag_callback_data_t data1, jtag_callback_data_t data2, + jtag_callback_data_t data3); /* run a TAP_RESET reset. End state is TAP_RESET, regardless Modified: trunk/src/jtag/jtag_driver.c =================================================================== --- trunk/src/jtag/jtag_driver.c 2009-06-02 23:15:12 UTC (rev 2006) +++ trunk/src/jtag/jtag_driver.c 2009-06-02 23:21:18 UTC (rev 2007) @@ -466,7 +466,7 @@ } /* add callback to end of queue */ -void jtag_add_callback4(jtag_callback_t callback, u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) +void interface_jtag_add_callback4(jtag_callback_t callback, u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) { struct jtag_callback_entry *entry=cmd_queue_alloc(sizeof(struct jtag_callback_entry)); @@ -514,7 +514,7 @@ return ERROR_OK; } -void jtag_add_callback(jtag_callback1_t callback, u8 *in) +void interface_jtag_add_callback(jtag_callback1_t callback, u8 *in) { jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0); } Modified: trunk/src/jtag/minidriver.h =================================================================== --- trunk/src/jtag/minidriver.h 2009-06-02 23:15:12 UTC (rev 2006) +++ trunk/src/jtag/minidriver.h 2009-06-02 23:21:18 UTC (rev 2007) @@ -83,6 +83,12 @@ int num_fields, const int* num_bits, const u32* value, tap_state_t end_state); +extern void interface_jtag_add_callback(jtag_callback1_t f, u8 *in); + +extern void interface_jtag_add_callback4(jtag_callback_t f, u8 *in, + jtag_callback_data_t data1, jtag_callback_data_t data2, + jtag_callback_data_t data3); + #endif extern int interface_jtag_add_ir_scan( |
From: <zw...@ma...> - 2009-06-03 01:15:23
|
Author: zwelch Date: 2009-06-03 01:15:12 +0200 (Wed, 03 Jun 2009) New Revision: 2006 Added: trunk/src/jtag/minidriver.h Modified: trunk/src/jtag/Makefile.am trunk/src/jtag/jtag.c trunk/src/jtag/jtag.h trunk/src/jtag/jtag_driver.c trunk/src/jtag/zy1000.c Log: Add header file for JTAG minidriver: - Wraps all minidriver API functions using API front-ends: - Outlines jtag_add_dr_out() and jtag_alloc_in_value32(). - Adds interface_ prefix to existing jtag_alloc_invalue_32 routines. - Re-inline these interface definitions in new header file. - Re-inline parts of the (mini)driver implementations in minidriver.h. - Replace INCLUDE_JTAG_MINIDRIVER_H with #include directives. The next patch will finish removing '#ifdef HAVE_JTAG_MINIDRIVER_H' from jtag.h. Modified: trunk/src/jtag/Makefile.am =================================================================== --- trunk/src/jtag/Makefile.am 2009-06-02 21:06:12 UTC (rev 2005) +++ trunk/src/jtag/Makefile.am 2009-06-02 23:15:12 UTC (rev 2006) @@ -136,6 +136,7 @@ $(ARMJTAGEWFILES) noinst_HEADERS = \ + minidriver.h \ bitbang.h \ jtag.h \ bitq.h \ Modified: trunk/src/jtag/jtag.c =================================================================== --- trunk/src/jtag/jtag.c 2009-06-02 21:06:12 UTC (rev 2005) +++ trunk/src/jtag/jtag.c 2009-06-02 23:15:12 UTC (rev 2006) @@ -28,9 +28,9 @@ #include "config.h" #endif -#define INCLUDE_JTAG_MINIDRIVER_H #define INCLUDE_JTAG_INTERFACE_H #include "jtag.h" +#include "minidriver.h" #ifdef HAVE_STRINGS_H #include <strings.h> @@ -526,6 +526,11 @@ cmd_queue_cur_state = cmd_queue_end_state; } +void jtag_alloc_in_value32(scan_field_t *field) +{ + interface_jtag_alloc_in_value32(field); +} + void jtag_add_ir_scan_noverify(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) { int retval; @@ -682,8 +687,20 @@ jtag_error=retval; } +void jtag_add_dr_out(jtag_tap_t* tap, + int num_fields, const int* num_bits, const u32* value, + tap_state_t end_state) +{ + if (end_state != TAP_INVALID) + cmd_queue_end_state = end_state; + cmd_queue_cur_state = cmd_queue_end_state; + interface_jtag_add_dr_out(tap, + num_fields, num_bits, value, + cmd_queue_end_state); +} + void jtag_add_tlr(void) { jtag_prelude(TAP_RESET); Modified: trunk/src/jtag/jtag.h =================================================================== --- trunk/src/jtag/jtag.h 2009-06-02 21:06:12 UTC (rev 2005) +++ trunk/src/jtag/jtag.h 2009-06-02 23:15:12 UTC (rev 2006) @@ -585,18 +585,8 @@ * allocation method is used, for the synchronous case the temporary 32 bits come * from the input field itself. */ - -#ifndef HAVE_JTAG_MINIDRIVER_H extern void jtag_alloc_in_value32(scan_field_t *field); -#else -static __inline__ void jtag_alloc_in_value32(scan_field_t *field) -{ - field->in_value=field->intmp; -} -#endif - - /* This version of jtag_add_dr_scan() uses the check_value/mask fields */ extern void jtag_add_dr_scan_check(int num_fields, scan_field_t* fields, tap_state_t endstate); extern void jtag_add_plain_ir_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate); @@ -841,61 +831,6 @@ #define ERROR_JTAG_NOT_STABLE_STATE (-105) #define ERROR_JTAG_DEVICE_ERROR (-107) -#ifdef INCLUDE_JTAG_MINIDRIVER_H - -extern void interface_jtag_add_scan_check_alloc(scan_field_t *field); - -extern int interface_jtag_add_ir_scan( - int num_fields, const scan_field_t* fields, - tap_state_t endstate); -extern int interface_jtag_add_plain_ir_scan( - int num_fields, const scan_field_t* fields, - tap_state_t endstate); - -extern int interface_jtag_add_dr_scan( - int num_fields, const scan_field_t* fields, - tap_state_t endstate); -extern int interface_jtag_add_plain_dr_scan( - int num_fields, const scan_field_t* fields, - tap_state_t endstate); - -extern int interface_jtag_add_tlr(void); -extern int interface_jtag_add_pathmove(int num_states, const tap_state_t* path); -extern int interface_jtag_add_runtest(int num_cycles, tap_state_t endstate); - -/** - * This drives the actual srst and trst pins. srst will always be 0 - * if jtag_reset_config & RESET_SRST_PULLS_TRST != 0 and ditto for - * trst. - * - * the higher level jtag_add_reset will invoke jtag_add_tlr() if - * approperiate - */ -extern int interface_jtag_add_reset(int trst, int srst); -extern int interface_jtag_add_end_state(tap_state_t endstate); -extern int interface_jtag_add_sleep(u32 us); -extern int interface_jtag_add_clocks(int num_cycles); -extern int interface_jtag_execute_queue(void); - -/** - * Calls the interface callback to execute the queue. This routine - * is used by the JTAG driver layer and should not be called directly. - */ -extern int default_interface_jtag_execute_queue(void); - - -#endif // INCLUDE_JTAG_MINIDRIVER_H - -/* this allows JTAG devices to implement the entire jtag_xxx() layer in hw/sw */ -#ifdef HAVE_JTAG_MINIDRIVER_H -/* Here a #define MINIDRIVER() and an inline version of hw fifo interface_jtag_add_dr_out can be defined */ -#include "jtag_minidriver.h" -#else -extern void interface_jtag_add_dr_out(jtag_tap_t* tap, int num_fields, const int* num_bits, const u32* value, - tap_state_t end_state); - -#endif - /* jtag_add_dr_out() is a version of jtag_add_dr_scan() which * only scans data out. It operates on 32 bit integers instead * of 8 bit, which makes it a better impedance match with @@ -921,18 +856,11 @@ * There is no jtag_add_dr_outin() version of this fn that also allows * clocking data back in. Patches gladly accepted! */ -static __inline__ void jtag_add_dr_out(jtag_tap_t* tap, int num_fields, const int* num_bits, const u32* value, - tap_state_t end_state) -{ - if (end_state != TAP_INVALID) - cmd_queue_end_state = end_state; - cmd_queue_cur_state = cmd_queue_end_state; - interface_jtag_add_dr_out(tap, num_fields, num_bits, value, cmd_queue_end_state); -} +extern void jtag_add_dr_out(jtag_tap_t* tap, + int num_fields, const int* num_bits, const u32* value, + tap_state_t end_state); - - /** * Function jtag_add_statemove * moves from the current state to the goal \a state. This needs Modified: trunk/src/jtag/jtag_driver.c =================================================================== --- trunk/src/jtag/jtag_driver.c 2009-06-02 21:06:12 UTC (rev 2005) +++ trunk/src/jtag/jtag_driver.c 2009-06-02 23:15:12 UTC (rev 2006) @@ -31,9 +31,9 @@ #include "config.h" #endif -#define INCLUDE_JTAG_MINIDRIVER_H #define INCLUDE_JTAG_INTERFACE_H #include "jtag.h" +#include "minidriver.h" #include "command.h" struct jtag_callback_entry @@ -488,12 +488,6 @@ } } -void interface_jtag_add_scan_check_alloc(scan_field_t *field) -{ - unsigned num_bytes = TAP_SCAN_BYTES(field->num_bits); - field->in_value = (u8 *)cmd_queue_alloc(num_bytes); -} - int interface_jtag_execute_queue(void) { int retval = default_interface_jtag_execute_queue(); @@ -514,11 +508,6 @@ return retval; } -void jtag_alloc_in_value32(scan_field_t *field) -{ - field->in_value=(u8 *)cmd_queue_alloc(4); -} - static int jtag_convert_to_callback4(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) { ((jtag_callback1_t)data1)(in); Added: trunk/src/jtag/minidriver.h =================================================================== --- trunk/src/jtag/minidriver.h 2009-06-02 21:06:12 UTC (rev 2005) +++ trunk/src/jtag/minidriver.h 2009-06-02 23:15:12 UTC (rev 2006) @@ -0,0 +1,127 @@ +/*************************************************************************** + * Copyright (C) 2005 by Dominic Rath * + * Dom...@gm... * + * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyv...@zy... * + * * + * Copyright (C) 2009 Zachary T Welch * + * zw...@su... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef MINIDRIVER_H +#define MINIDRIVER_H + +/* @page jtagminidriver JTAG Mini-Driver + * + * The JTAG minidriver interface allows the definition of alternate + * interface functions, instead of the built-in asynchronous driver + * module that is used by the standard JTAG interface drivers. + * + * In addtion to the functions defined in the c minidriver.h file, the + * @c jtag_minidriver.h file must declare the following functions (or + * define static inline versions of them): + * - jtag_add_callback + * - jtag_add_callback4 + * - interface_jtag_add_dr_out + * + * The following core functions are declared in this file for use by + * the minidriver and do @b not need to be defined by an implementation: + * - default_interface_jtag_execute_queue() + */ + +#ifdef HAVE_JTAG_MINIDRIVER_H + +#include "jtag_minidriver.h" + +static inline void interface_jtag_alloc_in_value32(scan_field_t *field) +{ + field->in_value = field->intmp; +} + +static inline void interface_jtag_add_scan_check_alloc(scan_field_t *field) +{ + /* We're executing this synchronously, so try to use local storage. */ + if (field->num_bits > 32) + { + unsigned num_bytes = TAP_SCAN_BYTES(field->num_bits); + field->in_value = (u8 *)malloc(num_bytes); + field->allocated = 1; + } + else + field->in_value = field->intmp; +} + +#else + +static inline void interface_jtag_alloc_in_value32(scan_field_t *field) +{ + field->in_value = (u8 *)cmd_queue_alloc(4); +} + +static inline void interface_jtag_add_scan_check_alloc(scan_field_t *field) +{ + unsigned num_bytes = TAP_SCAN_BYTES(field->num_bits); + field->in_value = (u8 *)cmd_queue_alloc(num_bytes); +} + +extern void interface_jtag_add_dr_out(jtag_tap_t* tap, + int num_fields, const int* num_bits, const u32* value, + tap_state_t end_state); + +#endif + +extern int interface_jtag_add_ir_scan( + int num_fields, const scan_field_t* fields, + tap_state_t endstate); +extern int interface_jtag_add_plain_ir_scan( + int num_fields, const scan_field_t* fields, + tap_state_t endstate); + +extern int interface_jtag_add_dr_scan( + int num_fields, const scan_field_t* fields, + tap_state_t endstate); +extern int interface_jtag_add_plain_dr_scan( + int num_fields, const scan_field_t* fields, + tap_state_t endstate); + +extern int interface_jtag_add_tlr(void); +extern int interface_jtag_add_pathmove(int num_states, const tap_state_t* path); +extern int interface_jtag_add_runtest(int num_cycles, tap_state_t endstate); + +/** + * This drives the actual srst and trst pins. srst will always be 0 + * if jtag_reset_config & RESET_SRST_PULLS_TRST != 0 and ditto for + * trst. + * + * the higher level jtag_add_reset will invoke jtag_add_tlr() if + * approperiate + */ +extern int interface_jtag_add_reset(int trst, int srst); +extern int interface_jtag_add_end_state(tap_state_t endstate); +extern int interface_jtag_add_sleep(u32 us); +extern int interface_jtag_add_clocks(int num_cycles); +extern int interface_jtag_execute_queue(void); + +/** + * Calls the interface callback to execute the queue. This routine + * is used by the JTAG driver layer and should not be called directly. + */ +extern int default_interface_jtag_execute_queue(void); + + +#endif // MINIDRIVER_H Property changes on: trunk/src/jtag/minidriver.h ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/src/jtag/zy1000.c =================================================================== --- trunk/src/jtag/zy1000.c 2009-06-02 21:06:12 UTC (rev 2005) +++ trunk/src/jtag/zy1000.c 2009-06-02 23:15:12 UTC (rev 2006) @@ -20,9 +20,9 @@ #include "config.h" #endif -#define INCLUDE_JTAG_MINIDRIVER_H #define INCLUDE_JTAG_INTERFACE_H #include "embeddedice.h" +#include "minidriver.h" #include "bitbang.h" #include <cyg/hal/hal_io.h> // low level i/o @@ -380,20 +380,7 @@ } -void interface_jtag_add_scan_check_alloc(scan_field_t *field) -{ - /* We're executing this synchronously, so try to use local storage. */ - if (field->num_bits > 32) - { - unsigned num_bytes = TAP_SCAN_BYTES(field->num_bits); - field->in_value = (u8 *)malloc(num_bytes); - field->allocated = 1; - } - else - field->in_value = field->intmp; -} - int interface_jtag_execute_queue(void) { cyg_uint32 empty; |
From: ntfreak at B. <nt...@ma...> - 2009-06-02 23:06:13
|
Author: ntfreak Date: 2009-06-02 23:06:12 +0200 (Tue, 02 Jun 2009) New Revision: 2005 Modified: trunk/doc/openocd.texi trunk/src/target/arm_adi_v5.c trunk/src/target/arm_adi_v5.h trunk/src/target/armv7m.c trunk/src/target/cortex_m3.c Log: - change signature for adi_jtag_dp_scan and adi_jtag_dp_scan_u32 to use swjdp_common_t *swjdp instead of arm_jtag_t *jtag_info - change SWJDP_IR/DR_APACC to DAP_IR/DR_APACC to conform with ARM_ADI docs. - add swjdp->memaccess_tck field and code for extra tck clocks before accessing memory bus - Set default memaccess value to 8 for Cortex-M3. - Add dap memaccess command. - document all armv7 dap cmds. - Original patch submitted by Magnus Lundin [lu...@ml...]. Modified: trunk/doc/openocd.texi =================================================================== --- trunk/doc/openocd.texi 2009-06-02 16:07:31 UTC (rev 2004) +++ trunk/doc/openocd.texi 2009-06-02 21:06:12 UTC (rev 2005) @@ -4137,6 +4137,33 @@ @section ARMv7 Architecture +@subsection ARMv7 Debug Access Port (DAP) specific commands +@cindex ARMv7 Debug Access Port (DAP) specific commands +These commands are specific to ARM architecture v7 Debug Access Port (DAP), +included on cortex-m3 and cortex-a8 systems. +They are available in addition to other core-specific commands that may be available. + +@deffn Command {dap info} [num] +Displays dap info for ap [num], default currently selected AP. +@end deffn + +@deffn Command {dap apsel} [num] +Select a different AP [num] (default 0). +@end deffn + +@deffn Command {dap apid} [num] +Displays id reg from AP [num], default currently selected AP. +@end deffn + +@deffn Command {dap baseaddr} [num] +Displays debug base address from AP [num], default currently selected AP. +@end deffn + +@deffn Command {dap memaccess} [value] +Displays the number of extra tck for mem-ap memory bus access [0-255]. +If value is defined, first assigns that. +@end deffn + @subsection Cortex-M3 specific commands @cindex Cortex-M3 specific commands Modified: trunk/src/target/arm_adi_v5.c =================================================================== --- trunk/src/target/arm_adi_v5.c 2009-06-02 16:07:31 UTC (rev 2004) +++ trunk/src/target/arm_adi_v5.c 2009-06-02 21:06:12 UTC (rev 2005) @@ -59,43 +59,39 @@ ***************************************************************************/ /* Scan out and in from target ordered u8 buffers */ -int adi_jtag_dp_scan(arm_jtag_t *jtag_info, u8 instr, u8 reg_addr, u8 RnW, u8 *outvalue, u8 *invalue, u8 *ack) +int adi_jtag_dp_scan(swjdp_common_t *swjdp, u8 instr, u8 reg_addr, u8 RnW, u8 *outvalue, u8 *invalue, u8 *ack) { + arm_jtag_t *jtag_info = swjdp->jtag_info; scan_field_t fields[2]; u8 out_addr_buf; jtag_add_end_state(TAP_IDLE); arm_jtag_set_instr(jtag_info, instr, NULL); + /* Add specified number of tck clocks before accessing memory bus */ + if ((instr == DAP_IR_APACC) && ((reg_addr == AP_REG_DRW)||((reg_addr&0xF0) == AP_REG_BD0) )&& (swjdp->memaccess_tck != 0)) + jtag_add_runtest(swjdp->memaccess_tck, TAP_IDLE); + fields[0].tap = jtag_info->tap; fields[0].num_bits = 3; buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr >> 1) & 0x6) | (RnW & 0x1)); fields[0].out_value = &out_addr_buf; - fields[0].in_value = ack; - - - - fields[1].tap = jtag_info->tap; fields[1].num_bits = 32; fields[1].out_value = outvalue; - fields[1].in_value = invalue; - - - - jtag_add_dr_scan(2, fields, TAP_INVALID); return ERROR_OK; } /* Scan out and in from host ordered u32 variables */ -int adi_jtag_dp_scan_u32(arm_jtag_t *jtag_info, u8 instr, u8 reg_addr, u8 RnW, u32 outvalue, u32 *invalue, u8 *ack) +int adi_jtag_dp_scan_u32(swjdp_common_t *swjdp, u8 instr, u8 reg_addr, u8 RnW, u32 outvalue, u32 *invalue, u8 *ack) { + arm_jtag_t *jtag_info = swjdp->jtag_info; scan_field_t fields[2]; u8 out_value_buf[4]; u8 out_addr_buf; @@ -103,20 +99,21 @@ jtag_add_end_state(TAP_IDLE); arm_jtag_set_instr(jtag_info, instr, NULL); + /* Add specified number of tck clocks before accessing memory bus */ + if ((instr == DAP_IR_APACC) && ((reg_addr == AP_REG_DRW)||((reg_addr&0xF0) == AP_REG_BD0) )&& (swjdp->memaccess_tck != 0)) + jtag_add_runtest(swjdp->memaccess_tck, TAP_IDLE); + fields[0].tap = jtag_info->tap; fields[0].num_bits = 3; buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr >> 1) & 0x6) | (RnW & 0x1)); fields[0].out_value = &out_addr_buf; fields[0].in_value = ack; - - fields[1].tap = jtag_info->tap; fields[1].num_bits = 32; buf_set_u32(out_value_buf, 0, 32, outvalue); fields[1].out_value = out_value_buf; fields[1].in_value = NULL; - if (invalue) { @@ -136,14 +133,15 @@ /* scan_inout_check adds one extra inscan for DPAP_READ commands to read variables */ int scan_inout_check(swjdp_common_t *swjdp, u8 instr, u8 reg_addr, u8 RnW, u8 *outvalue, u8 *invalue) { - adi_jtag_dp_scan(swjdp->jtag_info, instr, reg_addr, RnW, outvalue, NULL, NULL); + adi_jtag_dp_scan(swjdp, instr, reg_addr, RnW, outvalue, NULL, NULL); + if ((RnW == DPAP_READ) && (invalue != NULL)) { - adi_jtag_dp_scan(swjdp->jtag_info, SWJDP_IR_DPACC, DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack); + adi_jtag_dp_scan(swjdp, DAP_IR_DPACC, DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack); } - /* In TRANS_MODE_ATOMIC all SWJDP_IR_APACC transactions wait for ack=OK/FAULT and the check CTRL_STAT */ - if ((instr == SWJDP_IR_APACC) && (swjdp->trans_mode == TRANS_MODE_ATOMIC)) + /* In TRANS_MODE_ATOMIC all DAP_IR_APACC transactions wait for ack=OK/FAULT and the check CTRL_STAT */ + if ((instr == DAP_IR_APACC) && (swjdp->trans_mode == TRANS_MODE_ATOMIC)) { return swjdp_transaction_endcheck(swjdp); } @@ -153,14 +151,15 @@ int scan_inout_check_u32(swjdp_common_t *swjdp, u8 instr, u8 reg_addr, u8 RnW, u32 outvalue, u32 *invalue) { - adi_jtag_dp_scan_u32(swjdp->jtag_info, instr, reg_addr, RnW, outvalue, NULL, NULL); + adi_jtag_dp_scan_u32(swjdp, instr, reg_addr, RnW, outvalue, NULL, NULL); + if ((RnW==DPAP_READ) && (invalue != NULL)) { - adi_jtag_dp_scan_u32(swjdp->jtag_info, SWJDP_IR_DPACC, DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack); + adi_jtag_dp_scan_u32(swjdp, DAP_IR_DPACC, DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack); } - /* In TRANS_MODE_ATOMIC all SWJDP_IR_APACC transactions wait for ack=OK/FAULT and then check CTRL_STAT */ - if ((instr == SWJDP_IR_APACC) && (swjdp->trans_mode == TRANS_MODE_ATOMIC)) + /* In TRANS_MODE_ATOMIC all DAP_IR_APACC transactions wait for ack=OK/FAULT and then check CTRL_STAT */ + if ((instr == DAP_IR_APACC) && (swjdp->trans_mode == TRANS_MODE_ATOMIC)) { return swjdp_transaction_endcheck(swjdp); } @@ -177,7 +176,7 @@ #if 0 /* Danger!!!! BROKEN!!!! */ - scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); + scan_inout_check_u32(swjdp, DAP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); /* Danger!!!! BROKEN!!!! Why will jtag_execute_queue() fail here???? R956 introduced the check on return value here and now Michael Schwingen reports that this code no longer works.... @@ -191,7 +190,7 @@ /* Why??? second time it works??? */ #endif - scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); + scan_inout_check_u32(swjdp, DAP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); if ((retval=jtag_execute_queue())!=ERROR_OK) return retval; @@ -216,7 +215,7 @@ return ERROR_JTAG_DEVICE_ERROR; } - scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); + scan_inout_check_u32(swjdp, DAP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); if ((retval=jtag_execute_queue())!=ERROR_OK) return retval; swjdp->ack = swjdp->ack & 0x7; @@ -248,8 +247,8 @@ LOG_ERROR("SWJ-DP STICKY ERROR"); /* Clear Sticky Error Bits */ - scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_WRITE, swjdp->dp_ctrl_stat | SSTICKYORUN | SSTICKYERR, NULL); - scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); + scan_inout_check_u32(swjdp, DAP_IR_DPACC, DP_CTRL_STAT, DPAP_WRITE, swjdp->dp_ctrl_stat | SSTICKYORUN | SSTICKYERR, NULL); + scan_inout_check_u32(swjdp, DAP_IR_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); if ((retval=jtag_execute_queue())!=ERROR_OK) return retval; @@ -278,12 +277,12 @@ int dap_dp_write_reg(swjdp_common_t *swjdp, u32 value, u8 reg_addr) { - return scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, reg_addr, DPAP_WRITE, value, NULL); + return scan_inout_check_u32(swjdp, DAP_IR_DPACC, reg_addr, DPAP_WRITE, value, NULL); } int dap_dp_read_reg(swjdp_common_t *swjdp, u32 *value, u8 reg_addr) { - return scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, reg_addr, DPAP_READ, 0, value); + return scan_inout_check_u32(swjdp, DAP_IR_DPACC, reg_addr, DPAP_READ, 0, value); } int dap_ap_select(swjdp_common_t *swjdp,u8 apsel) @@ -294,7 +293,7 @@ if (select != swjdp->apsel) { swjdp->apsel = select; - /* Switchin AP invalidates cached values */ + /* Switching AP invalidates cached values */ swjdp->dp_select_value = -1; swjdp->ap_csw_value = -1; swjdp->ap_tar_value = -1; @@ -320,7 +319,7 @@ int dap_ap_write_reg(swjdp_common_t *swjdp, u32 reg_addr, u8* out_value_buf) { dap_dp_bankselect(swjdp, reg_addr); - scan_inout_check(swjdp, SWJDP_IR_APACC, reg_addr, DPAP_WRITE, out_value_buf, NULL); + scan_inout_check(swjdp, DAP_IR_APACC, reg_addr, DPAP_WRITE, out_value_buf, NULL); return ERROR_OK; } @@ -328,7 +327,7 @@ int dap_ap_read_reg(swjdp_common_t *swjdp, u32 reg_addr, u8 *in_value_buf) { dap_dp_bankselect(swjdp, reg_addr); - scan_inout_check(swjdp, SWJDP_IR_APACC, reg_addr, DPAP_READ, 0, in_value_buf); + scan_inout_check(swjdp, DAP_IR_APACC, reg_addr, DPAP_READ, 0, in_value_buf); return ERROR_OK; } @@ -338,7 +337,7 @@ buf_set_u32(out_value_buf, 0, 32, value); dap_dp_bankselect(swjdp, reg_addr); - scan_inout_check(swjdp, SWJDP_IR_APACC, reg_addr, DPAP_WRITE, out_value_buf, NULL); + scan_inout_check(swjdp, DAP_IR_APACC, reg_addr, DPAP_WRITE, out_value_buf, NULL); return ERROR_OK; } @@ -346,7 +345,7 @@ int dap_ap_read_reg_u32(swjdp_common_t *swjdp, u32 reg_addr, u32 *value) { dap_dp_bankselect(swjdp, reg_addr); - scan_inout_check_u32(swjdp, SWJDP_IR_APACC, reg_addr, DPAP_READ, 0, value); + scan_inout_check_u32(swjdp, DAP_IR_APACC, reg_addr, DPAP_READ, 0, value); return ERROR_OK; } @@ -723,15 +722,15 @@ dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE, address); /* Scan out first read */ - adi_jtag_dp_scan(swjdp->jtag_info, SWJDP_IR_APACC, AP_REG_DRW, DPAP_READ, 0, NULL, NULL); + adi_jtag_dp_scan(swjdp, DAP_IR_APACC, AP_REG_DRW, DPAP_READ, 0, NULL, NULL); for (readcount = 0; readcount < blocksize - 1; readcount++) { /* Scan out read instruction and scan in previous value */ - adi_jtag_dp_scan(swjdp->jtag_info, SWJDP_IR_APACC, AP_REG_DRW, DPAP_READ, 0, buffer + 4 * readcount, &swjdp->ack); + adi_jtag_dp_scan(swjdp, DAP_IR_APACC, AP_REG_DRW, DPAP_READ, 0, buffer + 4 * readcount, &swjdp->ack); } /* Scan in last value */ - adi_jtag_dp_scan(swjdp->jtag_info, SWJDP_IR_DPACC, DP_RDBUFF, DPAP_READ, 0, buffer + 4 * readcount, &swjdp->ack); + adi_jtag_dp_scan(swjdp, DAP_IR_DPACC, DP_RDBUFF, DPAP_READ, 0, buffer + 4 * readcount, &swjdp->ack); if (swjdp_transaction_endcheck(swjdp) == ERROR_OK) { wcount = wcount - blocksize; Modified: trunk/src/target/arm_adi_v5.h =================================================================== --- trunk/src/target/arm_adi_v5.h 2009-06-02 16:07:31 UTC (rev 2004) +++ trunk/src/target/arm_adi_v5.h 2009-06-02 21:06:12 UTC (rev 2005) @@ -27,8 +27,8 @@ #include "register.h" #include "arm_jtag.h" -#define SWJDP_IR_DPACC 0xA -#define SWJDP_IR_APACC 0xB +#define DAP_IR_DPACC 0xA +#define DAP_IR_APACC 0xB #define DPAP_WRITE 0 #define DPAP_READ 1 @@ -97,6 +97,8 @@ u8 trans_mode; u8 trans_rw; u8 ack; + /* extra tck clocks for memory bus access */ + u32 memaccess_tck; } swjdp_common_t; /* Internal functions used in the module, partial transactions, use with caution */ @@ -141,4 +143,6 @@ extern int handle_dap_apsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); extern int handle_dap_apid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); extern int handle_dap_baseaddr_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +extern int handle_dap_memaccess_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); + #endif Modified: trunk/src/target/armv7m.c =================================================================== --- trunk/src/target/armv7m.c 2009-06-02 16:07:31 UTC (rev 2004) +++ trunk/src/target/armv7m.c 2009-06-02 21:06:12 UTC (rev 2005) @@ -544,10 +544,11 @@ command_t *arm_adi_v5_dap_cmd; arm_adi_v5_dap_cmd = register_command(cmd_ctx, NULL, "dap", NULL, COMMAND_ANY, "cortex dap specific commands"); - register_command(cmd_ctx, arm_adi_v5_dap_cmd, "info", handle_dap_info_command, COMMAND_EXEC, "dap info for ap [num], default currently selected AP"); - register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apsel", handle_dap_apsel_command, COMMAND_EXEC, "select a different AP [num] (default 0)"); - register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apid", handle_dap_apid_command, COMMAND_EXEC, "return id reg from AP [num], default currently selected AP"); - register_command(cmd_ctx, arm_adi_v5_dap_cmd, "baseaddr", handle_dap_baseaddr_command, COMMAND_EXEC, "return debug base address from AP [num], default currently selected AP"); + register_command(cmd_ctx, arm_adi_v5_dap_cmd, "info", handle_dap_info_command, COMMAND_EXEC, "Displays dap info for ap [num], default currently selected AP"); + register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apsel", handle_dap_apsel_command, COMMAND_EXEC, "Select a different AP [num] (default 0)"); + register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apid", handle_dap_apid_command, COMMAND_EXEC, "Displays id reg from AP [num], default currently selected AP"); + register_command(cmd_ctx, arm_adi_v5_dap_cmd, "baseaddr", handle_dap_baseaddr_command, COMMAND_EXEC, "Displays debug base address from AP [num], default currently selected AP"); + register_command(cmd_ctx, arm_adi_v5_dap_cmd, "memaccess", handle_dap_memaccess_command, COMMAND_EXEC, "set/get number of extra tck for mem-ap memory bus access [0-255]"); return ERROR_OK; } @@ -786,6 +787,25 @@ return retval; } +int handle_dap_memaccess_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + target_t *target = get_current_target(cmd_ctx); + armv7m_common_t *armv7m = target->arch_info; + swjdp_common_t *swjdp = &armv7m->swjdp_info; + u32 memaccess_tck; + + memaccess_tck = swjdp->memaccess_tck; + if (argc > 0) + { + memaccess_tck = strtoul(args[0], NULL, 0); + } + + swjdp->memaccess_tck = memaccess_tck; + command_print(cmd_ctx, "memory bus access delay set to %i tck", swjdp->memaccess_tck); + + return ERROR_OK; +} + int handle_dap_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { target_t *target = get_current_target(cmd_ctx); Modified: trunk/src/target/cortex_m3.c =================================================================== --- trunk/src/target/cortex_m3.c 2009-06-02 16:07:31 UTC (rev 2004) +++ trunk/src/target/cortex_m3.c 2009-06-02 21:06:12 UTC (rev 2005) @@ -1564,9 +1564,12 @@ int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, jtag_tap_t *tap) { + int retval; armv7m_common_t *armv7m; armv7m = &cortex_m3->armv7m; + armv7m_init_arch_info(target, armv7m); + /* prepare JTAG information for the new target */ cortex_m3->jtag_info.tap = tap; cortex_m3->jtag_info.scann_size = 4; @@ -1575,6 +1578,7 @@ armv7m->swjdp_info.ap_csw_value = -1; armv7m->swjdp_info.ap_tar_value = -1; armv7m->swjdp_info.jtag_info = &cortex_m3->jtag_info; + armv7m->swjdp_info.memaccess_tck = 8; /* initialize arch-specific breakpoint handling */ @@ -1590,13 +1594,17 @@ armv7m->pre_restore_context = NULL; armv7m->post_restore_context = NULL; - armv7m_init_arch_info(target, armv7m); armv7m->arch_info = cortex_m3; armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32; armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32; target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target); + if ((retval = arm_jtag_setup_connection(&cortex_m3->jtag_info)) != ERROR_OK) + { + return retval; + } + return ERROR_OK; } |
From: ntfreak at B. <nt...@ma...> - 2009-06-02 18:07:31
|
Author: ntfreak Date: 2009-06-02 18:07:31 +0200 (Tue, 02 Jun 2009) New Revision: 2004 Modified: trunk/src/jtag/jlink.c Log: - hack added to fix a issue with v5/6 jlink v5/6 jlink seems to have an issue if the first tap move is not divisible by 8, so we send a TLR on first power up Modified: trunk/src/jtag/jlink.c =================================================================== --- trunk/src/jtag/jlink.c 2009-06-02 13:37:06 UTC (rev 2003) +++ trunk/src/jtag/jlink.c 2009-06-02 16:07:31 UTC (rev 2004) @@ -306,7 +306,8 @@ static int jlink_init(void) { int check_cnt; - + int i; + jlink_jtag_handle = jlink_usb_open(); if (jlink_jtag_handle == 0) @@ -341,6 +342,13 @@ jlink_tap_init(); jlink_speed(jtag_speed); + /* v5/6 jlink seems to have an issue if the first tap move + * is not divisible by 8, so we send a TLR on first power up */ + for (i = 0; i < 8; i++) { + jlink_tap_append_step(1, 0); + } + jlink_tap_execute(); + return ERROR_OK; } |
From: oharboe at B. <oh...@ma...> - 2009-06-02 15:37:17
|
Author: oharboe Date: 2009-06-02 15:37:06 +0200 (Tue, 02 Jun 2009) New Revision: 2003 Modified: trunk/src/jtag/jtag_driver.c Log: remove unecessary #ifdef as file is only built when minidriver is enabled. Modified: trunk/src/jtag/jtag_driver.c =================================================================== --- trunk/src/jtag/jtag_driver.c 2009-06-02 10:09:53 UTC (rev 2002) +++ trunk/src/jtag/jtag_driver.c 2009-06-02 13:37:06 UTC (rev 2003) @@ -36,7 +36,6 @@ #include "jtag.h" #include "command.h" -#ifndef HAVE_JTAG_MINIDRIVER_H struct jtag_callback_entry { struct jtag_callback_entry *next; @@ -531,5 +530,3 @@ jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0); } -#endif - |
From: oharboe at B. <oh...@ma...> - 2009-06-02 12:09:54
|
Author: oharboe Date: 2009-06-02 12:09:53 +0200 (Tue, 02 Jun 2009) New Revision: 2002 Modified: trunk/src/jtag/jtag.h trunk/src/jtag/jtag_driver.c trunk/src/jtag/zy1000.c trunk/src/target/embeddedice.c Log: some trivial minidriver fixes Modified: trunk/src/jtag/jtag.h =================================================================== --- trunk/src/jtag/jtag.h 2009-06-02 10:07:47 UTC (rev 2001) +++ trunk/src/jtag/jtag.h 2009-06-02 10:09:53 UTC (rev 2002) @@ -890,9 +890,7 @@ #ifdef HAVE_JTAG_MINIDRIVER_H /* Here a #define MINIDRIVER() and an inline version of hw fifo interface_jtag_add_dr_out can be defined */ #include "jtag_minidriver.h" -#define MINIDRIVER(a) notused ## a #else -#define MINIDRIVER(a) a extern void interface_jtag_add_dr_out(jtag_tap_t* tap, int num_fields, const int* num_bits, const u32* value, tap_state_t end_state); Modified: trunk/src/jtag/jtag_driver.c =================================================================== --- trunk/src/jtag/jtag_driver.c 2009-06-02 10:07:47 UTC (rev 2001) +++ trunk/src/jtag/jtag_driver.c 2009-06-02 10:09:53 UTC (rev 2002) @@ -36,6 +36,7 @@ #include "jtag.h" #include "command.h" +#ifndef HAVE_JTAG_MINIDRIVER_H struct jtag_callback_entry { struct jtag_callback_entry *next; @@ -69,11 +70,12 @@ dst->in_value = src->in_value; } + /** * see jtag_add_ir_scan() * */ -int MINIDRIVER(interface_jtag_add_ir_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) +int interface_jtag_add_ir_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) { size_t num_taps = jtag_NumEnabledTaps(); @@ -147,7 +149,7 @@ * see jtag_add_plain_ir_scan() * */ -int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) +int interface_jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) { jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); @@ -176,7 +178,7 @@ * see jtag_add_dr_scan() * */ -int MINIDRIVER(interface_jtag_add_dr_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) +int interface_jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) { /* count devices in bypass */ @@ -261,7 +263,7 @@ * The bypass status of TAPs is set by jtag_add_ir_scan(). * */ -void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap, +void interface_jtag_add_dr_out(jtag_tap_t *target_tap, int in_num_fields, const int *num_bits, const u32 *value, @@ -344,7 +346,7 @@ * see jtag_add_plain_dr_scan() * */ -int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) +int interface_jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) { jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); @@ -366,7 +368,7 @@ return ERROR_OK; } -int MINIDRIVER(interface_jtag_add_tlr)(void) +int interface_jtag_add_tlr(void) { tap_state_t state = TAP_RESET; @@ -383,7 +385,7 @@ return ERROR_OK; } -int MINIDRIVER(interface_jtag_add_pathmove)(int num_states, const tap_state_t *path) +int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) { /* allocate memory for a new list member */ jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); @@ -402,7 +404,7 @@ return ERROR_OK; } -int MINIDRIVER(interface_jtag_add_runtest)(int num_cycles, tap_state_t state) +int interface_jtag_add_runtest(int num_cycles, tap_state_t state) { /* allocate memory for a new list member */ jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); @@ -418,7 +420,7 @@ return ERROR_OK; } -int MINIDRIVER(interface_jtag_add_clocks)( int num_cycles ) +int interface_jtag_add_clocks( int num_cycles ) { /* allocate memory for a new list member */ jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); @@ -433,7 +435,7 @@ return ERROR_OK; } -int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst) +int interface_jtag_add_reset(int req_trst, int req_srst) { /* allocate memory for a new list member */ jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); @@ -449,7 +451,7 @@ return ERROR_OK; } -int MINIDRIVER(interface_jtag_add_sleep)(u32 us) +int interface_jtag_add_sleep(u32 us) { /* allocate memory for a new list member */ jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); @@ -487,18 +489,6 @@ } } - -static int jtag_convert_to_callback4(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) -{ - ((jtag_callback1_t)data1)(in); - return ERROR_OK; -} - -void jtag_add_callback(jtag_callback1_t callback, u8 *in) -{ - jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0); -} - void interface_jtag_add_scan_check_alloc(scan_field_t *field) { unsigned num_bytes = TAP_SCAN_BYTES(field->num_bits); @@ -529,3 +519,17 @@ { field->in_value=(u8 *)cmd_queue_alloc(4); } + +static int jtag_convert_to_callback4(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) +{ + ((jtag_callback1_t)data1)(in); + return ERROR_OK; +} + +void jtag_add_callback(jtag_callback1_t callback, u8 *in) +{ + jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0); +} + +#endif + Modified: trunk/src/jtag/zy1000.c =================================================================== --- trunk/src/jtag/zy1000.c 2009-06-02 10:07:47 UTC (rev 2001) +++ trunk/src/jtag/zy1000.c 2009-06-02 10:09:53 UTC (rev 2002) @@ -535,7 +535,7 @@ } -int interface_jtag_add_ir_scan(int num_fields, scan_field_t *fields, tap_state_t state) +int interface_jtag_add_ir_scan(int num_fields, const scan_field_t *fields, tap_state_t state) { int j; @@ -596,7 +596,7 @@ -int interface_jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, tap_state_t state) +int interface_jtag_add_plain_ir_scan(int num_fields, const scan_field_t *fields, tap_state_t state) { scanFields(num_fields, fields, TAP_IRSHIFT, cmd_queue_end_state); @@ -605,7 +605,7 @@ /*extern jtag_command_t **jtag_get_last_command_p(void);*/ -int interface_jtag_add_dr_scan(int num_fields, scan_field_t *fields, tap_state_t state) +int interface_jtag_add_dr_scan(int num_fields, const scan_field_t *fields, tap_state_t state) { int j; @@ -649,7 +649,7 @@ return ERROR_OK; } -int interface_jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, tap_state_t state) +int interface_jtag_add_plain_dr_scan(int num_fields, const scan_field_t *fields, tap_state_t state) { scanFields(num_fields, fields, TAP_DRSHIFT, cmd_queue_end_state); return ERROR_OK; @@ -732,7 +732,7 @@ return ERROR_OK; } -int interface_jtag_add_pathmove(int num_states, tap_state_t *path) +int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) { int state_count; int tms = 0; Modified: trunk/src/target/embeddedice.c =================================================================== --- trunk/src/target/embeddedice.c 2009-06-02 10:07:47 UTC (rev 2001) +++ trunk/src/target/embeddedice.c 2009-06-02 10:09:53 UTC (rev 2002) @@ -489,8 +489,9 @@ return ERROR_TARGET_TIMEOUT; } +#ifndef HAVE_JTAG_MINIDRIVER_H /* this is the inner loop of the open loop DCC write of data to target */ -void MINIDRIVER(embeddedice_write_dcc)(jtag_tap_t *tap, int reg_addr, u8 *buffer, int little, int count) +void embeddedice_write_dcc(jtag_tap_t *tap, int reg_addr, u8 *buffer, int little, int count) { int i; for (i = 0; i < count; i++) @@ -499,3 +500,6 @@ buffer += 4; } } +#else +/* provided by minidriver */ +#endif |
From: oharboe at B. <oh...@ma...> - 2009-06-02 12:07:48
|
Author: oharboe Date: 2009-06-02 12:07:47 +0200 (Tue, 02 Jun 2009) New Revision: 2001 Modified: trunk/src/helper/types.h Log: more missing eCos types Modified: trunk/src/helper/types.h =================================================================== --- trunk/src/helper/types.h 2009-06-02 08:29:03 UTC (rev 2000) +++ trunk/src/helper/types.h 2009-06-02 10:07:47 UTC (rev 2001) @@ -139,6 +139,20 @@ #ifdef __ECOS /* eCos plain lacks this definition... */ typedef CYG_ADDRWORD intptr_t; +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; +#define INT8_MAX 0x7f +#define INT8_MIN (-INT8_MAX - 1) +#define UINT8_MAX (__CONCAT(INT8_MAX, U) * 2U + 1U) +#define INT16_MAX 0x7fff +#define INT16_MIN (-INT16_MAX - 1) +#define UINT16_MAX (__CONCAT(INT16_MAX, U) * 2U + 1U) +#define INT32_MAX 0x7fffffffL +#define INT32_MIN (-INT32_MAX - 1L) +#define UINT32_MAX (__CONCAT(INT32_MAX, U) * 2UL + 1UL) +#define INT64_MAX 0x7fffffffffffffffLL +#define INT64_MIN (-INT64_MAX - 1LL) +#define UINT64_MAX (__CONCAT(INT64_MAX, U) * 2ULL + 1ULL) #endif #endif /* TYPES_H */ |
From: <zw...@ma...> - 2009-06-02 10:29:07
|
Author: zwelch Date: 2009-06-02 10:29:03 +0200 (Tue, 02 Jun 2009) New Revision: 2000 Modified: trunk/configure.in trunk/src/jtag/Makefile.am Log: Only include jtag_driver.c in the build when minidriver is not in use. Modified: trunk/configure.in =================================================================== --- trunk/configure.in 2009-06-02 08:04:21 UTC (rev 1999) +++ trunk/configure.in 2009-06-02 08:29:03 UTC (rev 2000) @@ -13,7 +13,7 @@ AC_CHECK_HEADERS(dirent.h) AC_CHECK_HEADERS(fcntl.h) AC_CHECK_HEADERS(ifaddrs.h) -AC_CHECK_HEADERS(jtag_minidriver.h) +AC_CHECK_HEADERS(jtag_minidriver.h,[build_minidriver=yes],[build_minidriver=no]) AC_CHECK_HEADERS(malloc.h) AC_CHECK_HEADERS(netdb.h) AC_CHECK_HEADERS(netinet/in.h) @@ -857,6 +857,7 @@ AM_CONDITIONAL(IS_WIN32, test $is_win32 = yes) AM_CONDITIONAL(IS_DARWIN, test $is_darwin = yes) AM_CONDITIONAL(BITQ, test $build_bitq = yes) +AM_CONDITIONAL(MINIDRIVER, test $build_minidriver = yes) AC_LANG_C AC_PROG_CC Modified: trunk/src/jtag/Makefile.am =================================================================== --- trunk/src/jtag/Makefile.am 2009-06-02 08:04:21 UTC (rev 1999) +++ trunk/src/jtag/Makefile.am 2009-06-02 08:29:03 UTC (rev 2000) @@ -51,6 +51,12 @@ ECOSBOARDFILES = endif +if MINIDRIVER +DRIVERFILES = +else +DRIVERFILES = jtag_driver.c +endif + if AT91RM9200 AT91RM9200FILES = at91rm9200.c else @@ -111,7 +117,7 @@ libjtag_la_SOURCES = \ jtag.c \ - jtag_driver.c \ + $(DRIVERFILES) \ $(BITBANGFILES) \ $(PARPORTFILES) \ $(DUMMYFILES) \ |
From: <zw...@ma...> - 2009-06-02 10:04:29
|
Author: zwelch Date: 2009-06-02 10:04:21 +0200 (Tue, 02 Jun 2009) New Revision: 1999 Modified: trunk/src/jtag/jtag.c trunk/src/jtag/jtag.h trunk/src/jtag/jtag_driver.c trunk/src/jtag/zy1000.c Log: Move interface_jtag_add_scan_check_alloc implementations to their respective implementation files. Modified: trunk/src/jtag/jtag.c =================================================================== --- trunk/src/jtag/jtag.c 2009-06-02 07:51:16 UTC (rev 1998) +++ trunk/src/jtag/jtag.c 2009-06-02 08:04:21 UTC (rev 1999) @@ -594,27 +594,6 @@ return jtag_check_value_inner(in, (u8 *)data1, (u8 *)data2, (int)data3); } -#ifdef HAVE_JTAG_MINIDRIVER_H -void interface_jtag_add_scan_check_alloc(scan_field_t *field) -{ - /* We're executing this synchronously, so try to use local storage. */ - if (field->num_bits > 32) - { - unsigned num_bytes = TAP_SCAN_BYTES(field->num_bits); - field->in_value = (u8 *)malloc(num_bytes); - field->allocated = 1; - } - else - field->in_value = field->intmp; -} -#else -void interface_jtag_add_scan_check_alloc(scan_field_t *field) -{ - unsigned num_bytes = TAP_SCAN_BYTES(field->num_bits); - field->in_value = (u8 *)cmd_queue_alloc(num_bytes); -} -#endif - static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state), int in_num_fields, scan_field_t *in_fields, tap_state_t state) { Modified: trunk/src/jtag/jtag.h =================================================================== --- trunk/src/jtag/jtag.h 2009-06-02 07:51:16 UTC (rev 1998) +++ trunk/src/jtag/jtag.h 2009-06-02 08:04:21 UTC (rev 1999) @@ -843,6 +843,8 @@ #ifdef INCLUDE_JTAG_MINIDRIVER_H +extern void interface_jtag_add_scan_check_alloc(scan_field_t *field); + extern int interface_jtag_add_ir_scan( int num_fields, const scan_field_t* fields, tap_state_t endstate); Modified: trunk/src/jtag/jtag_driver.c =================================================================== --- trunk/src/jtag/jtag_driver.c 2009-06-02 07:51:16 UTC (rev 1998) +++ trunk/src/jtag/jtag_driver.c 2009-06-02 08:04:21 UTC (rev 1999) @@ -499,6 +499,12 @@ jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0); } +void interface_jtag_add_scan_check_alloc(scan_field_t *field) +{ + unsigned num_bytes = TAP_SCAN_BYTES(field->num_bits); + field->in_value = (u8 *)cmd_queue_alloc(num_bytes); +} + int interface_jtag_execute_queue(void) { int retval = default_interface_jtag_execute_queue(); Modified: trunk/src/jtag/zy1000.c =================================================================== --- trunk/src/jtag/zy1000.c 2009-06-02 07:51:16 UTC (rev 1998) +++ trunk/src/jtag/zy1000.c 2009-06-02 08:04:21 UTC (rev 1999) @@ -380,6 +380,18 @@ } +void interface_jtag_add_scan_check_alloc(scan_field_t *field) +{ + /* We're executing this synchronously, so try to use local storage. */ + if (field->num_bits > 32) + { + unsigned num_bytes = TAP_SCAN_BYTES(field->num_bits); + field->in_value = (u8 *)malloc(num_bytes); + field->allocated = 1; + } + else + field->in_value = field->intmp; +} int interface_jtag_execute_queue(void) |
From: <zw...@ma...> - 2009-06-02 09:51:22
|
Author: zwelch Date: 2009-06-02 09:51:16 +0200 (Tue, 02 Jun 2009) New Revision: 1998 Modified: trunk/configure.in trunk/src/jtag/ft2232.c Log: Add high-speed device support in FT2232 driver: - Initial support for FT2232H/FT4232H devices from FTDI. - Add --enable-ftd2xx-highspeed option to configure script. - Original patch submitted by Joern Kaipf <li...@jo...>. Modified: trunk/configure.in =================================================================== --- trunk/configure.in 2009-06-02 07:21:44 UTC (rev 1997) +++ trunk/configure.in 2009-06-02 07:51:16 UTC (rev 1998) @@ -310,6 +310,10 @@ AC_ARG_ENABLE(ft2232_ftd2xx, AS_HELP_STRING([--enable-ft2232_ftd2xx], [Enable building support for FT2232 based devices using the FTD2XX driver from ftdichip.com]), [build_ft2232_ftd2xx=$enableval], [build_ft2232_ftd2xx=no]) + +AC_ARG_ENABLE(ftd2xx_highspeed, + AS_HELP_STRING([--enable-ftd2xx-highspeed], [Enable building support for FT2232H and FT4232H-based devices (requires >=libftd2xx-0.4.16)]), + [want_ftd2xx_highspeed=$enableval], [want_ftd2xx_highspeed=maybe]) AC_ARG_ENABLE(amtjtagaccel, AS_HELP_STRING([--enable-amtjtagaccel], [Enable building the Amontec JTAG-Accelerator driver]), @@ -737,6 +741,32 @@ return 0; } ], [ AC_MSG_RESULT([Success!])] , [ AC_MSG_ERROR([Cannot build & run test program using ftd2xx.lib]) ] ) + +AC_MSG_CHECKING([whether to build ftd2xx device support]) +AC_MSG_RESULT([$want_ftd2xx_highspeed]) +if test $want_ftd2xx_highspeed != no; then +AC_MSG_CHECKING([for ftd2xx highspeed device support]) +AC_COMPILE_IFELSE([ +#include "confdefs.h" +#if IS_WIN32 +#include "windows.h" +#endif +#include <stdio.h> +#include <ftd2xx.h> +DWORD x = FT_DEVICE_4232H; +], [ + AC_DEFINE(BUILD_FTD2XX_HIGHSPEED, [1], [Support FT2232H/FT4232HS with FTD2XX.]) + build_ftd2xx_highspeed=yes +], [ + build_ftd2xx_highspeed=no +] ) +AC_MSG_RESULT([$build_ftd2xx_highspeed]) + +if test $want_ftd2xx_highspeed = yes -a $build_ftd2xx_highspeed = no; then + AC_MSG_ERROR([You need a newer FTD2XX driver (version 0.4.16 or later).]) + fi +fi + LDFLAGS=$LDFLAGS_SAVE CFLAGS=$CFLAGS_SAVE fi Modified: trunk/src/jtag/ft2232.c =================================================================== --- trunk/src/jtag/ft2232.c 2009-06-02 07:21:44 UTC (rev 1997) +++ trunk/src/jtag/ft2232.c 2009-06-02 07:51:16 UTC (rev 1998) @@ -92,6 +92,8 @@ */ static int ft2232_stableclocks(int num_cycles, jtag_command_t* cmd); +/* max TCK for the high speed devices 30000 kHz */ +#define FTDI_2232H_4232H_MAX_TCK 30000 static char * ft2232_device_desc_A = NULL; static char* ft2232_device_desc = NULL; @@ -174,6 +176,7 @@ #if BUILD_FT2232_FTD2XX == 1 static FT_HANDLE ftdih = NULL; +static FT_DEVICE ftdi_device = 0; #elif BUILD_FT2232_LIBFTDI == 1 static struct ftdi_context ftdic; #endif @@ -411,13 +414,55 @@ return ERROR_OK; } +#ifdef BUILD_FTD2XX_HIGHSPEED +static bool ft2232_device_is_highspeed(void) +{ + return (ftdi_device == FT_DEVICE_2232H) || (ftdi_device == FT_DEVICE_4232H); +} +static int ft2232_adaptive_clocking(int speed) +{ + bool use_adaptive_clocking = FALSE; + if (0 == speed) + { + if (ft2232_device_is_highspeed()) + use_adaptive_clocking = TRUE; + else + { + LOG_ERROR("ft2232 device %lu does not support RTCK", ftdi_device); + return ERROR_OK; + } + } + + u8 buf = use_adaptive_clocking ? 0x96 : 0x97; + LOG_DEBUG("%2.2x", buf); + + u32 bytes_written; + int retval = ft2232_write(&buf, 1, &bytes_written); + if (ERROR_OK != retval || bytes_written != 1) + { + LOG_ERROR("unable to set adative clocking: %d", retval); + return retval; + } + + return ERROR_OK; +} +#else +static int ft2232_adaptive_clocking(int speed) +{ + // not implemented on low-speed devices + return speed ? ERROR_OK : -1234; +} +#endif + static int ft2232_speed(int speed) { u8 buf[3]; int retval; u32 bytes_written; + ft2232_adaptive_clocking(speed); + buf[0] = 0x86; /* command "set divisor" */ buf[1] = speed & 0xff; /* valueL (0=6MHz, 1=3MHz, 2=2.0MHz, ...*/ buf[2] = (speed >> 8) & 0xff; /* valueH */ @@ -449,8 +494,15 @@ { if (khz==0) { - LOG_DEBUG("RTCK not supported"); +#ifdef BUILD_FTD2XX_HIGHSPEED + *jtag_speed = 0; + return ERROR_OK; +#else + LOG_DEBUG("RCLK not supported"); + LOG_DEBUG("If you have a high-speed FTDI device, then " + "OpenOCD may be built with --enable-ftd2xx-highspeed."); return ERROR_FAIL; +#endif } /* Take a look in the FT2232 manual, @@ -1724,6 +1776,9 @@ static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int* try_more) { FT_STATUS status; + DWORD deviceID; + char SerialNumber[16]; + char Description[64]; DWORD openex_flags = 0; char* openex_string = NULL; u8 latency_timer; @@ -1854,6 +1909,27 @@ return ERROR_JTAG_INIT_FAILED; } + if ( ( status = FT_GetDeviceInfo(ftdih, &ftdi_device, &deviceID, SerialNumber, Description, NULL) ) != FT_OK ) + { + LOG_ERROR("unable to get FT_GetDeviceInfo: %lu", status); + return ERROR_JTAG_INIT_FAILED; + } + else + { + LOG_INFO("device: %lu", ftdi_device); + LOG_INFO("deviceID: %lu", deviceID); + LOG_INFO("SerialNumber: %s", SerialNumber); + LOG_INFO("Description: %s", Description); + +#ifdef BUILD_FTD2XX_HIGHSPEED + if (ft2232_device_is_highspeed()) + { + ft2232_max_tck = FTDI_2232H_4232H_MAX_TCK; + LOG_INFO("max TCK change to: %u kHz", ft2232_max_tck); + } +#endif + } + return ERROR_OK; } |
From: oharboe at B. <oh...@ma...> - 2009-06-02 09:21:45
|
Author: oharboe Date: 2009-06-02 09:21:44 +0200 (Tue, 02 Jun 2009) New Revision: 1997 Modified: trunk/src/jtag/amt_jtagaccel.c trunk/src/jtag/arm-jtag-ew.c trunk/src/jtag/bitbang.c trunk/src/jtag/ft2232.c trunk/src/jtag/gw16012.c trunk/src/jtag/jlink.c trunk/src/jtag/usbprog.c trunk/src/jtag/vsllink.c Log: Remove unused code, TAP_INVALID is never passed to drivers. Modified: trunk/src/jtag/amt_jtagaccel.c =================================================================== --- trunk/src/jtag/amt_jtagaccel.c 2009-06-02 07:05:54 UTC (rev 1996) +++ trunk/src/jtag/amt_jtagaccel.c 2009-06-02 07:21:44 UTC (rev 1997) @@ -347,24 +347,21 @@ #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); #endif - if (cmd->cmd.runtest->end_state != TAP_INVALID) - amt_jtagaccel_end_state(cmd->cmd.runtest->end_state); + amt_jtagaccel_end_state(cmd->cmd.runtest->end_state); amt_jtagaccel_runtest(cmd->cmd.runtest->num_cycles); break; case JTAG_STATEMOVE: #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); #endif - if (cmd->cmd.statemove->end_state != TAP_INVALID) - amt_jtagaccel_end_state(cmd->cmd.statemove->end_state); + amt_jtagaccel_end_state(cmd->cmd.statemove->end_state); amt_jtagaccel_state_move(); break; case JTAG_SCAN: #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state); #endif - if (cmd->cmd.scan->end_state != TAP_INVALID) - amt_jtagaccel_end_state(cmd->cmd.scan->end_state); + amt_jtagaccel_end_state(cmd->cmd.scan->end_state); scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); type = jtag_scan_type(cmd->cmd.scan); amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); Modified: trunk/src/jtag/arm-jtag-ew.c =================================================================== --- trunk/src/jtag/arm-jtag-ew.c 2009-06-02 07:05:54 UTC (rev 1996) +++ trunk/src/jtag/arm-jtag-ew.c 2009-06-02 07:21:44 UTC (rev 1997) @@ -138,20 +138,14 @@ DEBUG_JTAG_IO( "runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, \ cmd->cmd.runtest->end_state); - if (cmd->cmd.runtest->end_state != TAP_INVALID) - { - armjtagew_end_state(cmd->cmd.runtest->end_state); - } + armjtagew_end_state(cmd->cmd.runtest->end_state); armjtagew_runtest(cmd->cmd.runtest->num_cycles); break; case JTAG_STATEMOVE: DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state); - if (cmd->cmd.statemove->end_state != TAP_INVALID) - { - armjtagew_end_state(cmd->cmd.statemove->end_state); - } + armjtagew_end_state(cmd->cmd.statemove->end_state); armjtagew_state_move(); break; @@ -166,10 +160,7 @@ case JTAG_SCAN: DEBUG_JTAG_IO("scan end in %i", cmd->cmd.scan->end_state); - if (cmd->cmd.scan->end_state != TAP_INVALID) - { - armjtagew_end_state(cmd->cmd.scan->end_state); - } + armjtagew_end_state(cmd->cmd.scan->end_state); scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); DEBUG_JTAG_IO("scan input, length = %d", scan_size); Modified: trunk/src/jtag/bitbang.c =================================================================== --- trunk/src/jtag/bitbang.c 2009-06-02 07:05:54 UTC (rev 1996) +++ trunk/src/jtag/bitbang.c 2009-06-02 07:21:44 UTC (rev 1997) @@ -268,8 +268,7 @@ #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("runtest %i cycles, end in %s", cmd->cmd.runtest->num_cycles, tap_state_name(cmd->cmd.runtest->end_state) ); #endif - if (cmd->cmd.runtest->end_state != TAP_INVALID) - bitbang_end_state(cmd->cmd.runtest->end_state); + bitbang_end_state(cmd->cmd.runtest->end_state); bitbang_runtest(cmd->cmd.runtest->num_cycles); break; @@ -284,8 +283,7 @@ #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("statemove end in %s", tap_state_name(cmd->cmd.statemove->end_state)); #endif - if (cmd->cmd.statemove->end_state != TAP_INVALID) - bitbang_end_state(cmd->cmd.statemove->end_state); + bitbang_end_state(cmd->cmd.statemove->end_state); bitbang_state_move(0); break; case JTAG_PATHMOVE: @@ -299,8 +297,7 @@ #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("%s scan end in %s", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", tap_state_name(cmd->cmd.scan->end_state) ); #endif - if (cmd->cmd.scan->end_state != TAP_INVALID) - bitbang_end_state(cmd->cmd.scan->end_state); + bitbang_end_state(cmd->cmd.scan->end_state); scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); type = jtag_scan_type(cmd->cmd.scan); bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); Modified: trunk/src/jtag/ft2232.c =================================================================== --- trunk/src/jtag/ft2232.c 2009-06-02 07:05:54 UTC (rev 1996) +++ trunk/src/jtag/ft2232.c 2009-06-02 07:21:44 UTC (rev 1997) @@ -1428,9 +1428,9 @@ if (tap_get_state() != TAP_IDLE) predicted_size += 3; predicted_size += 3 * CEIL(cmd->cmd.runtest->num_cycles, 7); - if ( (cmd->cmd.runtest->end_state != TAP_INVALID) && (cmd->cmd.runtest->end_state != TAP_IDLE) ) + if ( cmd->cmd.runtest->end_state != TAP_IDLE) predicted_size += 3; - if ( (cmd->cmd.runtest->end_state == TAP_INVALID) && (tap_get_end_state() != TAP_IDLE) ) + if ( tap_get_end_state() != TAP_IDLE) predicted_size += 3; if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) { @@ -1463,8 +1463,7 @@ /* LOG_DEBUG("added TMS scan (no read)"); */ } - if (cmd->cmd.runtest->end_state != TAP_INVALID) - ft2232_end_state(cmd->cmd.runtest->end_state); + ft2232_end_state(cmd->cmd.runtest->end_state); if ( tap_get_state() != tap_get_end_state() ) { @@ -1496,8 +1495,7 @@ require_send = 0; first_unsent = cmd; } - if (cmd->cmd.statemove->end_state != TAP_INVALID) - ft2232_end_state(cmd->cmd.statemove->end_state); + ft2232_end_state(cmd->cmd.statemove->end_state); /* move to end state */ if ( tap_get_state() != tap_get_end_state() ) @@ -1563,8 +1561,7 @@ retval = ERROR_JTAG_QUEUE_FAILED; /* current command */ - if (cmd->cmd.scan->end_state != TAP_INVALID) - ft2232_end_state(cmd->cmd.scan->end_state); + ft2232_end_state(cmd->cmd.scan->end_state); ft2232_large_scan(cmd->cmd.scan, type, buffer, scan_size); require_send = 0; first_unsent = cmd->next; @@ -1584,8 +1581,7 @@ } ft2232_expect_read += ft2232_predict_scan_in(scan_size, type); /* LOG_DEBUG("new read size: %i", ft2232_expect_read); */ - if (cmd->cmd.scan->end_state != TAP_INVALID) - ft2232_end_state(cmd->cmd.scan->end_state); + ft2232_end_state(cmd->cmd.scan->end_state); ft2232_add_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); require_send = 1; if (buffer) Modified: trunk/src/jtag/gw16012.c =================================================================== --- trunk/src/jtag/gw16012.c 2009-06-02 07:05:54 UTC (rev 1996) +++ trunk/src/jtag/gw16012.c 2009-06-02 07:21:44 UTC (rev 1997) @@ -369,16 +369,14 @@ #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); #endif - if (cmd->cmd.runtest->end_state != TAP_INVALID) - gw16012_end_state(cmd->cmd.runtest->end_state); + gw16012_end_state(cmd->cmd.runtest->end_state); gw16012_runtest(cmd->cmd.runtest->num_cycles); break; case JTAG_STATEMOVE: #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); #endif - if (cmd->cmd.statemove->end_state != TAP_INVALID) - gw16012_end_state(cmd->cmd.statemove->end_state); + gw16012_end_state(cmd->cmd.statemove->end_state); gw16012_state_move(); break; case JTAG_PATHMOVE: @@ -388,8 +386,7 @@ gw16012_path_move(cmd->cmd.pathmove); break; case JTAG_SCAN: - if (cmd->cmd.scan->end_state != TAP_INVALID) - gw16012_end_state(cmd->cmd.scan->end_state); + gw16012_end_state(cmd->cmd.scan->end_state); scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); type = jtag_scan_type(cmd->cmd.scan); #ifdef _DEBUG_JTAG_IO_ Modified: trunk/src/jtag/jlink.c =================================================================== --- trunk/src/jtag/jlink.c 2009-06-02 07:05:54 UTC (rev 1996) +++ trunk/src/jtag/jlink.c 2009-06-02 07:21:44 UTC (rev 1997) @@ -157,8 +157,7 @@ cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); - if (cmd->cmd.runtest->end_state != TAP_INVALID) - jlink_end_state(cmd->cmd.runtest->end_state); + jlink_end_state(cmd->cmd.runtest->end_state); jlink_runtest(cmd->cmd.runtest->num_cycles); } @@ -167,10 +166,7 @@ { DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state); - if (cmd->cmd.statemove->end_state != TAP_INVALID) - { - jlink_end_state(cmd->cmd.statemove->end_state); - } + jlink_end_state(cmd->cmd.statemove->end_state); jlink_state_move(); } @@ -192,8 +188,7 @@ DEBUG_JTAG_IO("scan end in %s", tap_state_name(cmd->cmd.scan->end_state)); - if (cmd->cmd.scan->end_state != TAP_INVALID) - jlink_end_state(cmd->cmd.scan->end_state); + jlink_end_state(cmd->cmd.scan->end_state); scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); DEBUG_JTAG_IO("scan input, length = %d", scan_size); Modified: trunk/src/jtag/usbprog.c =================================================================== --- trunk/src/jtag/usbprog.c 2009-06-02 07:05:54 UTC (rev 1996) +++ trunk/src/jtag/usbprog.c 2009-06-02 07:21:44 UTC (rev 1997) @@ -150,16 +150,14 @@ #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); #endif - if (cmd->cmd.runtest->end_state != TAP_INVALID) - usbprog_end_state(cmd->cmd.runtest->end_state); + usbprog_end_state(cmd->cmd.runtest->end_state); usbprog_runtest(cmd->cmd.runtest->num_cycles); break; case JTAG_STATEMOVE: #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); #endif - if (cmd->cmd.statemove->end_state != TAP_INVALID) - usbprog_end_state(cmd->cmd.statemove->end_state); + usbprog_end_state(cmd->cmd.statemove->end_state); usbprog_state_move(); break; case JTAG_PATHMOVE: @@ -173,8 +171,7 @@ #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state); #endif - if (cmd->cmd.scan->end_state != TAP_INVALID) - usbprog_end_state(cmd->cmd.scan->end_state); + usbprog_end_state(cmd->cmd.scan->end_state); scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); type = jtag_scan_type(cmd->cmd.scan); usbprog_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); Modified: trunk/src/jtag/vsllink.c =================================================================== --- trunk/src/jtag/vsllink.c 2009-06-02 07:05:54 UTC (rev 1996) +++ trunk/src/jtag/vsllink.c 2009-06-02 07:21:44 UTC (rev 1997) @@ -301,20 +301,14 @@ DEBUG_JTAG_IO( "runtest %i cycles, end in %s", cmd->cmd.runtest->num_cycles, \ tap_state_name(cmd->cmd.runtest->end_state)); - if (cmd->cmd.runtest->end_state != TAP_INVALID) - { - vsllink_end_state(cmd->cmd.runtest->end_state); - } + vsllink_end_state(cmd->cmd.runtest->end_state); vsllink_runtest(cmd->cmd.runtest->num_cycles); break; case JTAG_STATEMOVE: DEBUG_JTAG_IO("statemove end in %s", tap_state_name(cmd->cmd.statemove->end_state)); - if (cmd->cmd.statemove->end_state != TAP_INVALID) - { - vsllink_end_state(cmd->cmd.statemove->end_state); - } + vsllink_end_state(cmd->cmd.statemove->end_state); vsllink_state_move(); break; @@ -327,10 +321,7 @@ break; case JTAG_SCAN: - if (cmd->cmd.scan->end_state != TAP_INVALID) - { - vsllink_end_state(cmd->cmd.scan->end_state); - } + vsllink_end_state(cmd->cmd.scan->end_state); scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); if (cmd->cmd.scan->ir_scan) |
From: <zw...@ma...> - 2009-06-02 09:06:06
|
Author: zwelch Date: 2009-06-02 09:05:54 +0200 (Tue, 02 Jun 2009) New Revision: 1996 Added: trunk/src/jtag/jtag_driver.c Modified: trunk/src/jtag/Makefile.am trunk/src/jtag/jtag.c trunk/src/jtag/jtag.h Log: Continue clean-up of JTAG driver interface: - Move all interface_jtag_* functions to jtag_driver.c. - Extern command queue routines in jtag.h (with INCLUDE_JTAG_INTERFACE_H). - Add new source file to automake inputs. Modified: trunk/src/jtag/Makefile.am =================================================================== --- trunk/src/jtag/Makefile.am 2009-06-02 06:49:53 UTC (rev 1995) +++ trunk/src/jtag/Makefile.am 2009-06-02 07:05:54 UTC (rev 1996) @@ -109,7 +109,9 @@ ARMJTAGEWFILES = endif -libjtag_la_SOURCES = jtag.c \ +libjtag_la_SOURCES = \ + jtag.c \ + jtag_driver.c \ $(BITBANGFILES) \ $(PARPORTFILES) \ $(DUMMYFILES) \ Modified: trunk/src/jtag/jtag.c =================================================================== --- trunk/src/jtag/jtag.c 2009-06-02 06:49:53 UTC (rev 1995) +++ trunk/src/jtag/jtag.c 2009-06-02 07:05:54 UTC (rev 1996) @@ -72,30 +72,6 @@ int jtag_trst = 0; int jtag_srst = 0; -#ifndef HAVE_JTAG_MINIDRIVER_H -struct jtag_callback_entry -{ - struct jtag_callback_entry *next; - - jtag_callback_t callback; - u8 *in; - jtag_callback_data_t data1; - jtag_callback_data_t data2; - jtag_callback_data_t data3; -}; - - -static struct jtag_callback_entry *jtag_callback_queue_head = NULL; -static struct jtag_callback_entry *jtag_callback_queue_tail = NULL; - -static void jtag_callback_queue_reset(void) -{ - jtag_callback_queue_head = NULL; - jtag_callback_queue_tail = NULL; -} -#endif - - jtag_command_t *jtag_command_queue = NULL; static jtag_command_t **next_command_pointer = &jtag_command_queue; static jtag_tap_t *jtag_all_taps = NULL; @@ -235,7 +211,7 @@ NULL, }; -static jtag_interface_t *jtag = NULL; +struct jtag_interface_s *jtag = NULL; /* configuration */ static jtag_interface_t *jtag_interface = NULL; @@ -527,20 +503,6 @@ next_command_pointer = &jtag_command_queue; } -/** - * Copy a scan_field_t for insertion into the queue. - * - * This allocates a new copy of out_value using cmd_queue_alloc. - */ -static void cmd_queue_scan_field_clone(scan_field_t * dst, const scan_field_t * src) -{ - dst->tap = src->tap; - dst->num_bits = src->num_bits; - dst->out_value = buf_cpy(src->out_value, cmd_queue_alloc(CEIL(src->num_bits, 8)), src->num_bits); - dst->in_value = src->in_value; -} - - static void jtag_prelude1(void) { if (jtag_trst == 1) @@ -607,80 +569,6 @@ } /** - * see jtag_add_ir_scan() - * - */ -int MINIDRIVER(interface_jtag_add_ir_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) -{ - size_t num_taps = jtag_NumEnabledTaps(); - - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); - scan_field_t * out_fields = cmd_queue_alloc(num_taps * sizeof(scan_field_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_SCAN; - cmd->cmd.scan = scan; - - scan->ir_scan = true; - scan->num_fields = num_taps; /* one field per device */ - scan->fields = out_fields; - scan->end_state = state; - - - scan_field_t * field = out_fields; /* keep track where we insert data */ - - /* loop over all enabled TAPs */ - - for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap)) - { - /* search the input field list for fields for the current TAP */ - - bool found = false; - - for (int j = 0; j < in_num_fields; j++) - { - if (tap != in_fields[j].tap) - continue; - - /* if TAP is listed in input fields, copy the value */ - - found = true; - - tap->bypass = 0; - - assert(in_fields[j].num_bits == tap->ir_length); /* input fields must have the same length as the TAP's IR */ - - cmd_queue_scan_field_clone(field, in_fields + j); - - break; - } - - if (!found) - { - /* if a TAP isn't listed in input fields, set it to BYPASS */ - - tap->bypass = 1; - - field->tap = tap; - field->num_bits = tap->ir_length; - field->out_value = buf_set_ones(cmd_queue_alloc(CEIL(tap->ir_length, 8)), tap->ir_length); - field->in_value = NULL; /* do not collect input for tap's in bypass */ - } - - /* update device information */ - buf_cpy(field->out_value, tap->cur_instr, tap->ir_length); - - field++; - } - - assert(field == out_fields + num_taps); /* paranoia: jtag_NumEnabledTaps() and jtag_NextEnabledTap() not in sync */ - - return ERROR_OK; -} - -/** * Duplicate the scan fields passed into the function into an IR SCAN command * * This function assumes that the caller handles extra fields for bypassed TAPs @@ -698,35 +586,7 @@ } -/** - * see jtag_add_plain_ir_scan() - * - */ -int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) -{ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); - scan_field_t * out_fields = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_SCAN; - cmd->cmd.scan = scan; - - scan->ir_scan = true; - scan->num_fields = in_num_fields; - scan->fields = out_fields; - scan->end_state = state; - - for (int i = 0; i < in_num_fields; i++) - cmd_queue_scan_field_clone(out_fields + i, in_fields + i); - - return ERROR_OK; -} - - - int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, int num_bits); static int jtag_check_value_mask_callback(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) @@ -825,176 +685,8 @@ } -/** - * see jtag_add_dr_scan() - * - */ -int MINIDRIVER(interface_jtag_add_dr_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) -{ - /* count devices in bypass */ - size_t bypass_devices = 0; - - for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap)) - { - if (tap->bypass) - bypass_devices++; - } - - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); - scan_field_t * out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_SCAN; - cmd->cmd.scan = scan; - - scan->ir_scan = false; - scan->num_fields = in_num_fields + bypass_devices; - scan->fields = out_fields; - scan->end_state = state; - - - scan_field_t * field = out_fields; /* keep track where we insert data */ - - /* loop over all enabled TAPs */ - - for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap)) - { - /* if TAP is not bypassed insert matching input fields */ - - if (!tap->bypass) - { - scan_field_t * start_field = field; /* keep initial position for assert() */ - - for (int j = 0; j < in_num_fields; j++) - { - if (tap != in_fields[j].tap) - continue; - - cmd_queue_scan_field_clone(field, in_fields + j); - - field++; - } - - assert(field > start_field); /* must have at least one input field per not bypassed TAP */ - } - - /* if a TAP is bypassed, generated a dummy bit*/ - else - { - field->tap = tap; - field->num_bits = 1; - field->out_value = NULL; - field->in_value = NULL; - - field++; - } - } - - assert(field == out_fields + scan->num_fields); /* no superfluous input fields permitted */ - - return ERROR_OK; -} - - - /** - * Generate a DR SCAN using the array of output values passed to the function - * - * This function assumes that the parameter target_tap specifies the one TAP - * that is not bypassed. All other TAPs must be bypassed and the function will - * generate a dummy 1bit field for them. - * - * For the target_tap a sequence of output-only fields will be generated where - * each field has the size num_bits and the field's values are taken from - * the array value. - * - * The bypass status of TAPs is set by jtag_add_ir_scan(). - * - */ -void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap, - int in_num_fields, - const int *num_bits, - const u32 *value, - tap_state_t end_state) -{ - /* count devices in bypass */ - - size_t bypass_devices = 0; - - for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap)) - { - if (tap->bypass) - bypass_devices++; - } - - - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); - scan_field_t * out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_SCAN; - cmd->cmd.scan = scan; - - scan->ir_scan = false; - scan->num_fields = in_num_fields + bypass_devices; - scan->fields = out_fields; - scan->end_state = end_state; - - - bool target_tap_match = false; - - scan_field_t * field = out_fields; /* keep track where we insert data */ - - /* loop over all enabled TAPs */ - - for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap)) - { - /* if TAP is not bypassed insert matching input fields */ - - if (!tap->bypass) - { - assert(tap == target_tap); /* target_tap must match the one not bypassed TAP */ - - target_tap_match = true; - - for (int j = 0; j < in_num_fields; j++) - { - u8 out_value[4]; - size_t scan_size = num_bits[j]; - buf_set_u32(out_value, 0, scan_size, value[j]); - - field->tap = tap; - field->num_bits = scan_size; - field->out_value = buf_cpy(out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); - field->in_value = NULL; - - field++; - } - } - - /* if a TAP is bypassed, generated a dummy bit*/ - else - { - - field->tap = tap; - field->num_bits = 1; - field->out_value = NULL; - field->in_value = NULL; - - field++; - } - } - - assert(target_tap_match); /* target_tap should be enabled and not bypassed */ -} - - -/** * Duplicate the scan fields passed into the function into a DR SCAN command * * This function assumes that the caller handles extra fields for bypassed TAPs @@ -1012,33 +704,7 @@ } -/** - * see jtag_add_plain_dr_scan() - * - */ -int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) -{ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); - scan_field_t * out_fields = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t)); - jtag_queue_command(cmd); - - cmd->type = JTAG_SCAN; - cmd->cmd.scan = scan; - - scan->ir_scan = false; - scan->num_fields = in_num_fields; - scan->fields = out_fields; - scan->end_state = state; - - for (int i = 0; i < in_num_fields; i++) - cmd_queue_scan_field_clone(out_fields + i, in_fields + i); - - return ERROR_OK; -} - - void jtag_add_tlr(void) { jtag_prelude(TAP_RESET); @@ -1049,23 +715,6 @@ jtag_error=retval; } -int MINIDRIVER(interface_jtag_add_tlr)(void) -{ - tap_state_t state = TAP_RESET; - - /* allocate memory for a new list member */ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_STATEMOVE; - - cmd->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t)); - cmd->cmd.statemove->end_state = state; - - return ERROR_OK; -} - void jtag_add_pathmove(int num_states, const tap_state_t *path) { tap_state_t cur_state = cmd_queue_cur_state; @@ -1104,41 +753,6 @@ jtag_error=retval; } -int MINIDRIVER(interface_jtag_add_pathmove)(int num_states, const tap_state_t *path) -{ - /* allocate memory for a new list member */ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_PATHMOVE; - - cmd->cmd.pathmove = cmd_queue_alloc(sizeof(pathmove_command_t)); - cmd->cmd.pathmove->num_states = num_states; - cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states); - - for (int i = 0; i < num_states; i++) - cmd->cmd.pathmove->path[i] = path[i]; - - return ERROR_OK; -} - -int MINIDRIVER(interface_jtag_add_runtest)(int num_cycles, tap_state_t state) -{ - /* allocate memory for a new list member */ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_RUNTEST; - - cmd->cmd.runtest = cmd_queue_alloc(sizeof(runtest_command_t)); - cmd->cmd.runtest->num_cycles = num_cycles; - cmd->cmd.runtest->end_state = state; - - return ERROR_OK; -} - void jtag_add_runtest(int num_cycles, tap_state_t state) { int retval; @@ -1152,21 +766,6 @@ } -int MINIDRIVER(interface_jtag_add_clocks)( int num_cycles ) -{ - /* allocate memory for a new list member */ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_STABLECLOCKS; - - cmd->cmd.stableclocks = cmd_queue_alloc(sizeof(stableclocks_command_t)); - cmd->cmd.stableclocks->num_cycles = num_cycles; - - return ERROR_OK; -} - void jtag_add_clocks( int num_cycles ) { int retval; @@ -1293,22 +892,6 @@ } } -int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst) -{ - /* allocate memory for a new list member */ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_RESET; - - cmd->cmd.reset = cmd_queue_alloc(sizeof(reset_command_t)); - cmd->cmd.reset->trst = req_trst; - cmd->cmd.reset->srst = req_srst; - - return ERROR_OK; -} - void jtag_add_end_state(tap_state_t state) { cmd_queue_end_state = state; @@ -1318,21 +901,6 @@ } } -int MINIDRIVER(interface_jtag_add_sleep)(u32 us) -{ - /* allocate memory for a new list member */ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_SLEEP; - - cmd->cmd.sleep = cmd_queue_alloc(sizeof(sleep_command_t)); - cmd->cmd.sleep->us = us; - - return ERROR_OK; -} - void jtag_add_sleep(u32 us) { keep_alive(); /* we might be running on a very slow JTAG clk */ @@ -1526,67 +1094,6 @@ return type; } - -#ifndef HAVE_JTAG_MINIDRIVER_H -/* add callback to end of queue */ -void jtag_add_callback4(jtag_callback_t callback, u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) -{ - struct jtag_callback_entry *entry=cmd_queue_alloc(sizeof(struct jtag_callback_entry)); - - entry->next=NULL; - entry->callback=callback; - entry->in=in; - entry->data1=data1; - entry->data2=data2; - entry->data3=data3; - - if (jtag_callback_queue_head==NULL) - { - jtag_callback_queue_head=entry; - jtag_callback_queue_tail=entry; - } else - { - jtag_callback_queue_tail->next=entry; - jtag_callback_queue_tail=entry; - } -} - - -static int jtag_convert_to_callback4(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) -{ - ((jtag_callback1_t)data1)(in); - return ERROR_OK; -} - -void jtag_add_callback(jtag_callback1_t callback, u8 *in) -{ - jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0); -} -#endif - -#ifndef HAVE_JTAG_MINIDRIVER_H - -int interface_jtag_execute_queue(void) -{ - int retval = default_interface_jtag_execute_queue(); - if (retval == ERROR_OK) - { - struct jtag_callback_entry *entry; - for (entry=jtag_callback_queue_head; entry!=NULL; entry=entry->next) - { - retval=entry->callback(entry->in, entry->data1, entry->data2, entry->data3); - if (retval!=ERROR_OK) - break; - } - } - - jtag_command_queue_reset(); - jtag_callback_queue_reset(); - - return retval; -} -#endif - int default_interface_jtag_execute_queue(void) { if (NULL == jtag) @@ -3718,13 +3225,6 @@ } #endif // _DEBUG_JTAG_IO_ -#ifndef HAVE_JTAG_MINIDRIVER_H -void jtag_alloc_in_value32(scan_field_t *field) -{ - field->in_value=(u8 *)cmd_queue_alloc(4); -} -#endif - static int handle_tms_sequence_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { if (argc == 1) Modified: trunk/src/jtag/jtag.h =================================================================== --- trunk/src/jtag/jtag.h 2009-06-02 06:49:53 UTC (rev 1995) +++ trunk/src/jtag/jtag.h 2009-06-02 07:05:54 UTC (rev 1996) @@ -365,6 +365,12 @@ extern jtag_command_t* jtag_command_queue; +extern void* cmd_queue_alloc(size_t size); +extern void cmd_queue_free(void); + +extern void jtag_queue_command(jtag_command_t *cmd); +extern void jtag_command_queue_reset(void); + #endif // INCLUDE_JTAG_INTERFACE_H /* forward declaration */ Copied: trunk/src/jtag/jtag_driver.c (from rev 1995, trunk/src/jtag/jtag.c) =================================================================== --- trunk/src/jtag/jtag.c 2009-06-02 06:49:53 UTC (rev 1995) +++ trunk/src/jtag/jtag_driver.c 2009-06-02 07:05:54 UTC (rev 1996) @@ -0,0 +1,525 @@ +/*************************************************************************** + * Copyright (C) 2005 by Dominic Rath * + * Dom...@gm... * + * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyv...@zy... * + * * + * Copyright (C) 2009 SoftPLC Corporation * + * http://softplc.com * + * di...@so... * + * * + * Copyright (C) 2009 Zachary T Welch * + * zw...@su... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define INCLUDE_JTAG_MINIDRIVER_H +#define INCLUDE_JTAG_INTERFACE_H +#include "jtag.h" +#include "command.h" + +struct jtag_callback_entry +{ + struct jtag_callback_entry *next; + + jtag_callback_t callback; + u8 *in; + jtag_callback_data_t data1; + jtag_callback_data_t data2; + jtag_callback_data_t data3; +}; + +static struct jtag_callback_entry *jtag_callback_queue_head = NULL; +static struct jtag_callback_entry *jtag_callback_queue_tail = NULL; + +static void jtag_callback_queue_reset(void) +{ + jtag_callback_queue_head = NULL; + jtag_callback_queue_tail = NULL; +} + +/** + * Copy a scan_field_t for insertion into the queue. + * + * This allocates a new copy of out_value using cmd_queue_alloc. + */ +static void cmd_queue_scan_field_clone(scan_field_t * dst, const scan_field_t * src) +{ + dst->tap = src->tap; + dst->num_bits = src->num_bits; + dst->out_value = buf_cpy(src->out_value, cmd_queue_alloc(CEIL(src->num_bits, 8)), src->num_bits); + dst->in_value = src->in_value; +} + +/** + * see jtag_add_ir_scan() + * + */ +int MINIDRIVER(interface_jtag_add_ir_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) +{ + size_t num_taps = jtag_NumEnabledTaps(); + + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); + scan_field_t * out_fields = cmd_queue_alloc(num_taps * sizeof(scan_field_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_SCAN; + cmd->cmd.scan = scan; + + scan->ir_scan = true; + scan->num_fields = num_taps; /* one field per device */ + scan->fields = out_fields; + scan->end_state = state; + + + scan_field_t * field = out_fields; /* keep track where we insert data */ + + /* loop over all enabled TAPs */ + + for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap)) + { + /* search the input field list for fields for the current TAP */ + + bool found = false; + + for (int j = 0; j < in_num_fields; j++) + { + if (tap != in_fields[j].tap) + continue; + + /* if TAP is listed in input fields, copy the value */ + + found = true; + + tap->bypass = 0; + + assert(in_fields[j].num_bits == tap->ir_length); /* input fields must have the same length as the TAP's IR */ + + cmd_queue_scan_field_clone(field, in_fields + j); + + break; + } + + if (!found) + { + /* if a TAP isn't listed in input fields, set it to BYPASS */ + + tap->bypass = 1; + + field->tap = tap; + field->num_bits = tap->ir_length; + field->out_value = buf_set_ones(cmd_queue_alloc(CEIL(tap->ir_length, 8)), tap->ir_length); + field->in_value = NULL; /* do not collect input for tap's in bypass */ + } + + /* update device information */ + buf_cpy(field->out_value, tap->cur_instr, tap->ir_length); + + field++; + } + + assert(field == out_fields + num_taps); /* paranoia: jtag_NumEnabledTaps() and jtag_NextEnabledTap() not in sync */ + + return ERROR_OK; +} + +/** + * see jtag_add_plain_ir_scan() + * + */ +int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) +{ + + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); + scan_field_t * out_fields = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_SCAN; + cmd->cmd.scan = scan; + + scan->ir_scan = true; + scan->num_fields = in_num_fields; + scan->fields = out_fields; + scan->end_state = state; + + for (int i = 0; i < in_num_fields; i++) + cmd_queue_scan_field_clone(out_fields + i, in_fields + i); + + return ERROR_OK; +} + + + +/** + * see jtag_add_dr_scan() + * + */ +int MINIDRIVER(interface_jtag_add_dr_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) +{ + /* count devices in bypass */ + + size_t bypass_devices = 0; + + for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap)) + { + if (tap->bypass) + bypass_devices++; + } + + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); + scan_field_t * out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_SCAN; + cmd->cmd.scan = scan; + + scan->ir_scan = false; + scan->num_fields = in_num_fields + bypass_devices; + scan->fields = out_fields; + scan->end_state = state; + + + scan_field_t * field = out_fields; /* keep track where we insert data */ + + /* loop over all enabled TAPs */ + + for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap)) + { + /* if TAP is not bypassed insert matching input fields */ + + if (!tap->bypass) + { + scan_field_t * start_field = field; /* keep initial position for assert() */ + + for (int j = 0; j < in_num_fields; j++) + { + if (tap != in_fields[j].tap) + continue; + + cmd_queue_scan_field_clone(field, in_fields + j); + + field++; + } + + assert(field > start_field); /* must have at least one input field per not bypassed TAP */ + } + + /* if a TAP is bypassed, generated a dummy bit*/ + else + { + field->tap = tap; + field->num_bits = 1; + field->out_value = NULL; + field->in_value = NULL; + + field++; + } + } + + assert(field == out_fields + scan->num_fields); /* no superfluous input fields permitted */ + + return ERROR_OK; +} + + + +/** + * Generate a DR SCAN using the array of output values passed to the function + * + * This function assumes that the parameter target_tap specifies the one TAP + * that is not bypassed. All other TAPs must be bypassed and the function will + * generate a dummy 1bit field for them. + * + * For the target_tap a sequence of output-only fields will be generated where + * each field has the size num_bits and the field's values are taken from + * the array value. + * + * The bypass status of TAPs is set by jtag_add_ir_scan(). + * + */ +void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap, + int in_num_fields, + const int *num_bits, + const u32 *value, + tap_state_t end_state) +{ + /* count devices in bypass */ + + size_t bypass_devices = 0; + + for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap)) + { + if (tap->bypass) + bypass_devices++; + } + + + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); + scan_field_t * out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_SCAN; + cmd->cmd.scan = scan; + + scan->ir_scan = false; + scan->num_fields = in_num_fields + bypass_devices; + scan->fields = out_fields; + scan->end_state = end_state; + + + bool target_tap_match = false; + + scan_field_t * field = out_fields; /* keep track where we insert data */ + + /* loop over all enabled TAPs */ + + for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap)) + { + /* if TAP is not bypassed insert matching input fields */ + + if (!tap->bypass) + { + assert(tap == target_tap); /* target_tap must match the one not bypassed TAP */ + + target_tap_match = true; + + for (int j = 0; j < in_num_fields; j++) + { + u8 out_value[4]; + size_t scan_size = num_bits[j]; + buf_set_u32(out_value, 0, scan_size, value[j]); + + field->tap = tap; + field->num_bits = scan_size; + field->out_value = buf_cpy(out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); + field->in_value = NULL; + + field++; + } + } + + /* if a TAP is bypassed, generated a dummy bit*/ + else + { + + field->tap = tap; + field->num_bits = 1; + field->out_value = NULL; + field->in_value = NULL; + + field++; + } + } + + assert(target_tap_match); /* target_tap should be enabled and not bypassed */ +} + +/** + * see jtag_add_plain_dr_scan() + * + */ +int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state) +{ + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); + scan_field_t * out_fields = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_SCAN; + cmd->cmd.scan = scan; + + scan->ir_scan = false; + scan->num_fields = in_num_fields; + scan->fields = out_fields; + scan->end_state = state; + + for (int i = 0; i < in_num_fields; i++) + cmd_queue_scan_field_clone(out_fields + i, in_fields + i); + + return ERROR_OK; +} + +int MINIDRIVER(interface_jtag_add_tlr)(void) +{ + tap_state_t state = TAP_RESET; + + /* allocate memory for a new list member */ + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_STATEMOVE; + + cmd->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t)); + cmd->cmd.statemove->end_state = state; + + return ERROR_OK; +} + +int MINIDRIVER(interface_jtag_add_pathmove)(int num_states, const tap_state_t *path) +{ + /* allocate memory for a new list member */ + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_PATHMOVE; + + cmd->cmd.pathmove = cmd_queue_alloc(sizeof(pathmove_command_t)); + cmd->cmd.pathmove->num_states = num_states; + cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states); + + for (int i = 0; i < num_states; i++) + cmd->cmd.pathmove->path[i] = path[i]; + + return ERROR_OK; +} + +int MINIDRIVER(interface_jtag_add_runtest)(int num_cycles, tap_state_t state) +{ + /* allocate memory for a new list member */ + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_RUNTEST; + + cmd->cmd.runtest = cmd_queue_alloc(sizeof(runtest_command_t)); + cmd->cmd.runtest->num_cycles = num_cycles; + cmd->cmd.runtest->end_state = state; + + return ERROR_OK; +} + +int MINIDRIVER(interface_jtag_add_clocks)( int num_cycles ) +{ + /* allocate memory for a new list member */ + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_STABLECLOCKS; + + cmd->cmd.stableclocks = cmd_queue_alloc(sizeof(stableclocks_command_t)); + cmd->cmd.stableclocks->num_cycles = num_cycles; + + return ERROR_OK; +} + +int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst) +{ + /* allocate memory for a new list member */ + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_RESET; + + cmd->cmd.reset = cmd_queue_alloc(sizeof(reset_command_t)); + cmd->cmd.reset->trst = req_trst; + cmd->cmd.reset->srst = req_srst; + + return ERROR_OK; +} + +int MINIDRIVER(interface_jtag_add_sleep)(u32 us) +{ + /* allocate memory for a new list member */ + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_SLEEP; + + cmd->cmd.sleep = cmd_queue_alloc(sizeof(sleep_command_t)); + cmd->cmd.sleep->us = us; + + return ERROR_OK; +} + +/* add callback to end of queue */ +void jtag_add_callback4(jtag_callback_t callback, u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) +{ + struct jtag_callback_entry *entry=cmd_queue_alloc(sizeof(struct jtag_callback_entry)); + + entry->next=NULL; + entry->callback=callback; + entry->in=in; + entry->data1=data1; + entry->data2=data2; + entry->data3=data3; + + if (jtag_callback_queue_head==NULL) + { + jtag_callback_queue_head=entry; + jtag_callback_queue_tail=entry; + } else + { + jtag_callback_queue_tail->next=entry; + jtag_callback_queue_tail=entry; + } +} + + +static int jtag_convert_to_callback4(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) +{ + ((jtag_callback1_t)data1)(in); + return ERROR_OK; +} + +void jtag_add_callback(jtag_callback1_t callback, u8 *in) +{ + jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0); +} + +int interface_jtag_execute_queue(void) +{ + int retval = default_interface_jtag_execute_queue(); + if (retval == ERROR_OK) + { + struct jtag_callback_entry *entry; + for (entry=jtag_callback_queue_head; entry!=NULL; entry=entry->next) + { + retval=entry->callback(entry->in, entry->data1, entry->data2, entry->data3); + if (retval!=ERROR_OK) + break; + } + } + + jtag_command_queue_reset(); + jtag_callback_queue_reset(); + + return retval; +} + +void jtag_alloc_in_value32(scan_field_t *field) +{ + field->in_value=(u8 *)cmd_queue_alloc(4); +} |
From: <zw...@ma...> - 2009-06-02 08:49:58
|
Author: zwelch Date: 2009-06-02 08:49:53 +0200 (Tue, 02 Jun 2009) New Revision: 1995 Modified: trunk/src/jtag/jtag.c Log: More JTAG interface driver cleanup: - Moves references to global jtag interface to default core implementation. - Missed this reference in the earlier "pointless" patch. Mea culpa. Important: this has a side-effect. Previously, the error return inside the interface routine short-circuited the remainder of that function when 'init' has not been called. With this patch, the command queue will be cleared in the case that 'init' has been called. Since that case indicates a buggy script, this does not seem to be a problem. Modified: trunk/src/jtag/jtag.c =================================================================== --- trunk/src/jtag/jtag.c 2009-06-02 06:33:19 UTC (rev 1994) +++ trunk/src/jtag/jtag.c 2009-06-02 06:49:53 UTC (rev 1995) @@ -1568,16 +1568,7 @@ int interface_jtag_execute_queue(void) { - int retval; - - if (jtag==NULL) - { - LOG_ERROR("No JTAG interface configured yet. Issue 'init' command in startup scripts before communicating with targets."); - return ERROR_FAIL; - } - - retval = default_interface_jtag_execute_queue(); - + int retval = default_interface_jtag_execute_queue(); if (retval == ERROR_OK) { struct jtag_callback_entry *entry; @@ -1598,6 +1589,14 @@ int default_interface_jtag_execute_queue(void) { + if (NULL == jtag) + { + LOG_ERROR("No JTAG interface configured yet. " + "Issue 'init' command in startup scripts " + "before communicating with targets."); + return ERROR_FAIL; + } + return jtag->execute_queue(); } |
From: <zw...@ma...> - 2009-06-02 08:33:23
|
Author: zwelch Date: 2009-06-02 08:33:19 +0200 (Tue, 02 Jun 2009) New Revision: 1994 Modified: trunk/src/jtag/jtag.c Log: More JTAG interface driver cleanup: - Add jtag_callback_queue_reset() to reset the callback queue. - Make interface_jtag_execute_queue() use new helper function. Modified: trunk/src/jtag/jtag.c =================================================================== --- trunk/src/jtag/jtag.c 2009-06-02 06:21:49 UTC (rev 1993) +++ trunk/src/jtag/jtag.c 2009-06-02 06:33:19 UTC (rev 1994) @@ -87,6 +87,12 @@ static struct jtag_callback_entry *jtag_callback_queue_head = NULL; static struct jtag_callback_entry *jtag_callback_queue_tail = NULL; + +static void jtag_callback_queue_reset(void) +{ + jtag_callback_queue_head = NULL; + jtag_callback_queue_tail = NULL; +} #endif @@ -1583,10 +1589,8 @@ } } - jtag_callback_queue_head = NULL; - jtag_callback_queue_tail = NULL; - jtag_command_queue_reset(); + jtag_callback_queue_reset(); return retval; } |