Hello Rick,

Great job.

One comment concerning your note :

+Note that the logic of this procedure will only work if the chip that is being 
boarded is
+at rest.  The PCB probably provides ways of doing that, not in the last place 
by holding
+the system reset signal active by pressing a reset button.  Where supported, 
the JTAG
+cable or the boundary scan logiccould be used to achieve a halted system.

This is true for some specific processors. But wrong for CPLD , FPGA, ...., and some ARM having methods to select Boundary Scan or internal Debug via external pin setup ...

If you want to indirect Flash a memory over JTAG Boundary Scan from a FPGA, you only need TCK TMS TDI TDO JTAG Signals:-) !

Please remove this comment, or replace "chip" by "some processors"

Regards,
Laurent
http://www.amontec.com

Amontec JTAGkey-2 : USB JTAG Debugger with up to 30Mhz JTAG frequency over High-Speed USB 2.0


Hello Oyvind,

>/ OpenOCD 0.4.0 is getting a bit long in the tooth for getting help on this
/>/ list. You'll want to move to the master branch.
/
OK, I'll setup git.  I wanted to get started on stable code, but if things
I'm running into were already resolved in git that's not worth it.

>/ Also, it could help if you posted a patch of the code you're trying to
/>/ implement.
/
The patch is attached.  Thanks for anything you can teach me.  The big
problem appears to be lack of documentation, not bugs, which is why
I wrote to this list.  The patch is incomplete but it has a docfile.

Thanks,
 -Rick
-------------- next part --------------
diff -Nur openocd-0.4.0-orig/doc/bsdl.txt openocd-0.4.0-plus_bsdl/doc/bsdl.txt
--- openocd-0.4.0-orig/doc/bsdl.txt     1970-01-01 00:00:00.000000000 +0000
+++ openocd-0.4.0-plus_bsdl/doc/bsdl.txt        2010-09-27 21:50:29.000000000 
+0000
@@ -0,0 +1,134 @@
+Generic support for Boundary Scan Definitions
+=============================================
+
+This style of bus access can often be used to control a PCB without knowing
+very much about the main chips on it.  Using the general technique of
+boundary scans, the pins on the device can be controlled from software, thus
+enabling access to most of the logic components on the PCB.
+
+
+Working principle
+-----------------
+
+OpenOCD supports generic access to the boundary scan facilities that are 
defined and
+published for many chips.  Even if the detailed test/debug specifications are 
hidden,
+there usually is a boundary scan definition to aid in PCB debugging.  This is 
why it
+is fruitful to have a generic module to use such definitions.
+
+The so-called Boundary Scan Definition Language, or BSDL for short, specifies 
which
+registers are accessible over JTAG, and how they are related to pins that are 
usually
+made available externally.  It specifies scan bits to be inputs, outputs or 
bidirectional
+or, very interesting, which internal scan bits are used to control others; 
this is
+often used to set output lines into high-impedance mode where external signals 
win over
+the internally generated ones.  In other words, it makes pins behave like 
inputs.
+
+When doing a boundary scan, pin values are clocked into the chip while the 
older pin
+values are clocked out.  While this serial shift process is taking place, the 
pins
+will be held to their old values.  So by sending proper values to a chip, it is
+possible to set its external pins to desired values, and when making another 
round
+it is possible to read in the values on input and high-impedance pins.  All in 
all,
+the JTAG interface enables us to control chips on the PCB which can handle 
elongated
+signaling from the processor chip.
+
+In all this, the internal structure of the processor is no required knowledge; 
only
+its boundary scan definition is, and that is usually public.  There are 
quicker ways
+of accessing (say) a flash chip on a bus if the processor co-operates, but 
when faced
+with nothing but the BSDL definition, this generic approach may be the only 
chance
+we have of accessing chips on the PCB under program control.
+
+
+Reading flash
+-------------
+
+To read the contents of a flash memory, the pins of a processor are set and 
reset as
+decreed by the datasheet of the chip (or our intuition, our measurements, ...) 
and
+specifically we set an address to be read on the chip's address lines.  We 
clock
+it into the chip and apply it to the pins.  The second run of the same process 
will
+clock out the value read on the data pins.
+
+Mostly, a bus uses strobe signals, such as a MEMREAD pulse that temporary 
changes
+from its default setting.  If this is the case, clocking in the values to the 
chip
+happens in a few more stages: first all data, then the same data with read 
strobe
+signals inverted, then the same data with the strobe back to normal while the 
data
+is being clocked out.
+
+The cycle for a read therefore comprises of:
+
+1. Clock all signals to the chip, including address lines but with inactive 
strobe signals;
+
+2. Clock the same to the chip, but now with activated read strobe signals;
+
+3. Clock the same to the chip, with read strobe made inactive again; at the 
same time,
+   clock the read values out of the chip by reading the data bits.
+
+
+
+Writing flash
+-------------
+
+TODO
+
+
+
+Specification commands
+----------------------
+
+The following command creates a target xyz for TAP xy.z::
+
+       target create xyz generic_bsdl -chain-position xy.z
+
+A target continues to read in a BSDL file holding the chip's boundary scan
+definition:
+
+       xy.z bsdlfile /path/to/somechip.bsdl
+
+Output and bidirectional bits can be set to their resting state which may be
+set, reset or float::
+
+       xy.z force float K L M
+       xy.z force set   N O P
+       xy.z force reset Q R S(*)
+
+Note the form S(*) which covers all elements of an array, so S(0), S(1), and 
so on.
+If it is needed to revert these forced settings of pins at some later stage, 
then
+a statement can be issued for that:
+
+       xy.z force none
+
+A few signals must be specified explicitly, to allow control over them by 
programs
+such as memory dumpers; these are the address and data lines::
+
+       xy.z define address A(*)
+       xy.z define data D(*)
+
+Strobe signals can be setup for reading and writing operations separately.
+The duration of all these strobe signals will last considerably longer than
+under live control by the chip.  Strobes are defined as follows::
+
+       xy.z define readstrobe  MEMSEL
+       xy.z define writestrobe MEMSEL RD_NOTWR
+
+It is good practice to have read_not_write signals set to a resting state that 
represents
+reading, and only pulse them to writing mode with a strobe.  The same is also 
true for
+chip-select or bus-select kind of signals signals.
+
+
+Performance
+-----------
+
+The overall performance of flash chip access through this method depends on 
the speeds
+that can be achieved over thus JTAG interface.  Generally, the number of bits 
that
+constitute a boundary scan must be clocked in several times for a single 
operation,
+so there is quite a bit of overhead.
+
+For example, consider using a 6 MHz interface to access a 1 MB flash at 16 
bits, if the
+total boundary scan contains 114 bits.  Let's assume about 125 bits of data 
are actually
+passed around per boundary scan.  Reading takes 3 boundary scans (375 bits) 
and since the
+1 MB flash can be loaded in 16 bit words, 512*1024 of those boundary scan 
series must be
+made (196608000 bits).  At 6 MHz, that would take up 33 seconds.
+
+Note that the logic of this procedure will only work if the chip that is being 
boarded is
+at rest.  The PCB probably provides ways of doing that, not in the last place 
by holding
+the system reset signal active by pressing a reset button.  Where supported, 
the JTAG
+cable or the boundary scan logiccould be used to achieve a halted system.
+
diff -Nur openocd-0.4.0-orig/src/jtag/core.c 
openocd-0.4.0-plus_bsdl/src/jtag/core.c
--- openocd-0.4.0-orig/src/jtag/core.c  2010-02-21 20:17:07.000000000 +0000
+++ openocd-0.4.0-plus_bsdl/src/jtag/core.c     2010-10-06 21:55:40.000000000 
+0000
@@ -335,6 +335,7 @@
static void jtag_checks(void)
 {
+printf ("jtag_trst=%d\n", jtag_trst);
        assert(jtag_trst == 0);
 }
diff -Nur openocd-0.4.0-orig/src/target/Makefile.am openocd-0.4.0-plus_bsdl/src/target/Makefile.am
--- openocd-0.4.0-orig/src/target/Makefile.am   2010-02-21 20:17:07.000000000 
+0000
+++ openocd-0.4.0-plus_bsdl/src/target/Makefile.am      2010-09-22 
14:40:37.000000000 +0000
@@ -35,7 +35,8 @@
        $(MIPS32_SRC) \
        avrt.c \
        dsp563xx.c \
-       dsp563xx_once.c
+       dsp563xx_once.c \
+       generic_bsdl.c
TARGET_CORE_SRC = \
        algorithm.c \
@@ -44,7 +45,8 @@
        breakpoints.c \
        target.c \
        target_request.c \
-       testee.c
+       testee.c \
+       generic_bsdl.c
ARMV4_5_SRC = \
        armv4_5.c \
diff -Nur openocd-0.4.0-orig/src/target/Makefile.in 
openocd-0.4.0-plus_bsdl/src/target/Makefile.in
--- openocd-0.4.0-orig/src/target/Makefile.in   2010-02-21 20:39:55.000000000 
+0000
+++ openocd-0.4.0-plus_bsdl/src/target/Makefile.in      2010-09-22 
14:41:01.000000000 +0000
@@ -75,7 +75,7 @@
 am_libtarget_la_OBJECTS = $(am__objects_1) $(am__objects_3) \
        $(am__objects_5) $(am__objects_6) $(am__objects_7) \
        $(am__objects_8) $(am__objects_9) avrt.lo dsp563xx.lo \
-       dsp563xx_once.lo
+       dsp563xx_once.lo generic_bsdl.lo
 libtarget_la_OBJECTS = $(am_libtarget_la_OBJECTS)
 DEFAULT_INCLUDES = -I. at am__isrc 
<https://lists.berlios.de/mailman/listinfo/openocd-development>@ 
-I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
diff -Nur openocd-0.4.0-orig/src/target/generic_bsdl.c 
openocd-0.4.0-plus_bsdl/src/target/generic_bsdl.c
--- openocd-0.4.0-orig/src/target/generic_bsdl.c        1970-01-01 
00:00:00.000000000 +0000
+++ openocd-0.4.0-plus_bsdl/src/target/generic_bsdl.c   2010-10-06 
21:59:04.000000000 +0000
@@ -0,0 +1,873 @@
+/*
+ * GENERIC BSDL flash and command handling.
+ *
+ * This BSDL interface forms a generic target template that can be applied to 
any TAP that
+ * hosts a BSDL-compliant chip.  Any chip, really.
+ *
+ * The use of this interface is twofold:
+ *  (1) set pins and see how other react (possibly interactive with poking at 
the hardware)
+ *  (2) generic access to external flash chips by only altering a chip's pins
+ *
+ * This code is shared by OpenFortress Digital signatures, under the same 
licensing rules
+ * as the rest of OpenOCD.  http://openfortress.nl/
+ *
+ * From: Rick van Rein <rick at openfortress.nl 
<https://lists.berlios.de/mailman/listinfo/openocd-development>>
+ */
+ +
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <helper/types.h>
+#include <helper/jim.h>
+#include <helper/time_support.h>
+#include <helper/log.h>
+#include <helper/command.h>
+
+#include <jtag/jtag.h>
+
+#include <target/register.h>
+#include <target/target.h>
+#include <target/target_type.h>
+
+
+
+
+/*
+ *     DATA STRUCTURES
+ */
+
+
+/* Normal scanbits are not very exciting.  It gets interesting when their
+ * values are controlled by another scanbit.  A controlled scanbit refers
+ * to its controlling bit, and indicates whether it is controlled when
+ * that bit is ZERO, or ONE.  Also, it indicates if control causes the
+ * scanbit to be SET, RESET or FLOATed.
+ */
+
+enum scanbittype {
+       SBT_IN,
+       SBT_OUT,
+       SBT_BIDIR,
+       SBT_CONTROL,
+};
+
+#define SBF_CONTROL_BY_ONE     0x00000001
+#define SBF_CONTROL_BY_ZERO    0x00000002
+
+#define SBF_DEFAULT_SET                0x00000010
+#define SBF_DEFAULT_RESET      0x00000020
+
+#define SBF_CONTROLLED_SET     0x00000100
+#define SBF_CONTROLLED_RESET   0x00000200
+#define SBF_CONTROLLED_FLOAT   0x00000400
+
+#define SBF_FORCE_SET          0x00001000
+#define SBF_FORCE_RESET                0x00002000
+#define SBF_FORCE_FLOAT                0x00004000
+
+#define SBF_DEFINE_READSTROBE  0x00000001
+#define SBF_DEFINE_WRITESTROBE 0x00000002
+#define SBF_DEFINE_ADDRESSLINE 0x00000004
+#define SBF_DEFINE_DATALINE    0x00000008
+
+#define SBF_CURRENTLY_SET      0x00000008
+
+struct scanbit {
+       char *sb_name;
+       enum scanbittype sb_type;
+       struct scanbit *sb_controller;
+       uint32_t sb_flags;
+       uint16_t sb_linebit;
+};
+
+struct businfo {
+       uint16_t bus_first;
+       uint16_t bus_size;
+};
+
+struct bsdl_info {
+       unsigned int num_scanbits;
+       struct scanbit *all_scanbits;
+       uint32_t instr_sample;
+       struct businfo bus_address, bus_data;
+};
+
+
+//TODO:ONEDAY// #define target_bsdl_info(tgt) ((struct bsdl_info *) 
(tgt)->arch_info)
+#define target_bsdl_info(tgt) (&bsdl_info_tms320vc5401pge)
+
+
+/*
+ *     TODO -- TODO    TODO -- TODO    TODO -- TODO    TODO -- TODO    TODO -- 
TODO
+ *
+ *     STATIC DEFINITIONS FOR ONE PARTICULAR CHIP TYPE -- IN LIEU OF A BSDL 
PARSER
+ *
+ *     TODO -- TODO    TODO -- TODO    TODO -- TODO    TODO -- TODO    TODO -- 
TODO
+ */
+
+static struct scanbit sb_tms320vc5401pge [] = {
+       { "HCS_NEG", SBT_IN, NULL, 0, 0 },
+       { "HPIENA", SBT_IN, NULL, 0, 0 },
+       { "HBIL", SBT_IN, NULL, 0, 0 },
+       { "HRW_NEG", SBT_IN, NULL, 0, 0 },
+       { "HAS_NEG", SBT_IN, NULL, 0, 0 },
+       { "HCNTL(0)", SBT_IN, NULL, 0, 0 },
+       { "HCNTL(1)", SBT_IN, NULL, 0, 0 },
+       { "HDS1_NEG", SBT_IN, NULL, 0, 0 },
+       { "HDS2_NEG", SBT_IN, NULL, 0, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { "HD(0)", SBT_BIDIR, &sb_tms320vc5401pge [9], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "HD(1)", SBT_BIDIR, &sb_tms320vc5401pge [10], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "HD(2)", SBT_BIDIR, &sb_tms320vc5401pge [11], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "HD(3)", SBT_BIDIR, &sb_tms320vc5401pge [12], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "HD(4)", SBT_BIDIR, &sb_tms320vc5401pge [13], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "HD(5)", SBT_BIDIR, &sb_tms320vc5401pge [14], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "HD(6)", SBT_BIDIR, &sb_tms320vc5401pge [15], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "HD(7)", SBT_BIDIR, &sb_tms320vc5401pge [16], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "HINT", SBT_OUT, &sb_tms320vc5401pge [63], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "HRDY", SBT_OUT, &sb_tms320vc5401pge [63], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { "BFSX(1)", SBT_BIDIR, &sb_tms320vc5401pge [29], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "BDX(1)", SBT_OUT, &sb_tms320vc5401pge [28], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "BFSR(1)", SBT_BIDIR, &sb_tms320vc5401pge [31], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "BDR(1)", SBT_IN, NULL, 0, 0 },
+       { "BCLKR(1)", SBT_BIDIR, &sb_tms320vc5401pge [27], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "BCLKX(1)", SBT_BIDIR, &sb_tms320vc5401pge [30], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { "BFSX(0)", SBT_BIDIR, &sb_tms320vc5401pge [40], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "BDX(0)", SBT_OUT, &sb_tms320vc5401pge [39], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "BFSR(0)", SBT_BIDIR, &sb_tms320vc5401pge [42], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "BDR(0)", SBT_IN, NULL, 0, 0 },
+       { "BCLKR(0)", SBT_BIDIR, &sb_tms320vc5401pge [38], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "BCLKX(0)", SBT_BIDIR, &sb_tms320vc5401pge [41], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "CLKMD(3)", SBT_IN, NULL, 0, 0 },
+       { "CLKMD(2)", SBT_IN, NULL, 0, 0 },
+       { "CLKMD(1)", SBT_IN, NULL, 0, 0 },
+       { "NMI_NEG", SBT_IN, NULL, 0, 0 },
+       { "INT_NEG(3)", SBT_IN, NULL, 0, 0 },
+       { "INT_NEG(2)", SBT_IN, NULL, 0, 0 },
+       { "INT_NEG(1)", SBT_IN, NULL, 0, 0 },
+       { "INT_NEG(0)", SBT_IN, NULL, 0, 0 },
+       { "READY", SBT_IN, NULL, 0, 0 },
+       { "RS_NEG", SBT_IN, NULL, 0, 0 },
+       { "MP_MC_NEG", SBT_IN, NULL, 0, 0 },
+       { "BIO_NEG", SBT_IN, NULL, 0, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { "HOLD_NEG", SBT_IN, NULL, 0, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { NULL, SBT_CONTROL, NULL, SBF_DEFAULT_SET, 0 },
+       { "A(16)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "A(17)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "A(18)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "A(19)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "D(0)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 0 },
+       { "D(1)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 1 },
+       { "D(2)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 2 },
+       { "D(3)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 3 },
+       { "D(4)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 4 },
+       { "D(5)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 5 },
+       { "D(6)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 6 },
+       { "D(7)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 7 },
+       { "D(8)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 8 },
+       { "D(9)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 9 },
+       { "D(10)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 10 },
+       { "D(11)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 11 },
+       { "D(12)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 12 },
+       { "D(13)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 13 },
+       { "D(14)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 14 },
+       { "D(15)", SBT_BIDIR, &sb_tms320vc5401pge [64], SBF_DEFINE_DATALINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 15 },
+       { "TOUT0", SBT_OUT, &sb_tms320vc5401pge [63], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "CLKOUT", SBT_OUT, &sb_tms320vc5401pge [63], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "IAQ_NEG", SBT_OUT, &sb_tms320vc5401pge [63], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "MSC_NEG", SBT_OUT, &sb_tms320vc5401pge [63], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "HOLDA_NEG", SBT_OUT, &sb_tms320vc5401pge [63], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "IOSTRB_NEG", SBT_OUT, &sb_tms320vc5401pge [61], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "R_W_NEG", SBT_OUT, &sb_tms320vc5401pge [61], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "MSTRB_NEG", SBT_OUT, &sb_tms320vc5401pge [61], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "IS_NEG", SBT_OUT, &sb_tms320vc5401pge [61], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "PS_NEG", SBT_OUT, &sb_tms320vc5401pge [61], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "DS_NEG", SBT_OUT, &sb_tms320vc5401pge [61], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "XF", SBT_OUT, &sb_tms320vc5401pge [63], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "IACK_NEG", SBT_OUT, &sb_tms320vc5401pge [63], SBF_CONTROL_BY_ONE | 
SBF_CONTROLLED_FLOAT, 0 },
+       { "A(0)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 0 },
+       { "A(1)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 1 },
+       { "A(2)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 2 },
+       { "A(3)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 3 },
+       { "A(4)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 4 },
+       { "A(5)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 5 },
+       { "A(6)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 6 },
+       { "A(7)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 7 },
+       { "A(8)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 8 },
+       { "A(9)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 9 },
+       { "A(10)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 10 },
+       { "A(11)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 11 },
+       { "A(12)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 12 },
+       { "A(13)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 13 },
+       { "A(14)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 14 },
+       { "A(15)", SBT_OUT, &sb_tms320vc5401pge [61], SBF_DEFINE_ADDRESSLINE | 
SBF_CONTROL_BY_ONE | SBF_CONTROLLED_FLOAT, 15 },
+};
+
+static struct bsdl_info bsdl_info_tms320vc5401pge = {
+       114, sb_tms320vc5401pge, 0x00000002,
+       { 0, 16 },
+       { 0, 16 },
+};
+
+
+/*
+ *     RESET OPERATIONS
+ */
+
+
+/*
+ *     JTAG OPERATIONS
+ */
+
+#ifdef TODO_FUTURE_OPERATION_PERHAPS
+static int bsdl_get_data_size (struct target *tgt, uint32_t *bits) {
+       /* TODO: Logic is flawed for some not-per-byte chips, like TMS320C54x */
+       uint8_t fst = target_bsdl_info(tgt)->bus_address.bus_first;
+       uint8_t snd = target_bsdl_info(tgt)->bus_data.bus_size;
+       if (fst < 255) {
+               *bits = 8 << fst;
+               if ((snd < 255) && (snd - 3 > fst)) {
+                       *bits = 1 << snd;
+               }
+               return ERROR_OK;
+       } else if (snd < 255) {
+               *bits = 1 << snd;
+               return ERROR_OK;
+       } else {
+               return ERROR_FAIL;
+       }
+}
+#endif
+
+#ifdef TODO_FUTURE_OPERATION_PERHAPS
+static int bsdl_get_address_size (struct target *tgt, uint32_t *bits) {
+       uint8_t siz = target_bsdl_info(tgt)->bus_address.bus_size;
+       if (siz < 255) {
+               *bits = siz;
+               return ERROR_OK;
+       } else {
+               return ERROR_FAIL;
+       }
+}
+#endif
+
+static int bsdl_read_word (struct target *tgt, uint32_t addr, uint32_t *data) {
+       struct bsdl_info *bi = target_bsdl_info (tgt);
+       struct scan_field irfield, drfield [3];
+       uint8_t instr[4];
+       uint16_t i, j;
+       int retval;
+       bool strobe, readnow;
+       /*
+        * 0. Determine current values for each scanbit.  Do not keep track
+        *    of floating values here, because those cannot be clocked in or
+        *    out.  Instead, the control bits in the JTAG chain will do this
+        *    for us.
+        */
+       for (j=0; j<bi->num_scanbits; j++) {
+               register uint32_t flags = bi->all_scanbits [j].sb_flags;
+               register bool bitvalue;
+               /* 0.1. Setup default value as current value */
+               if (flags & SBF_DEFAULT_SET) {
+                       bitvalue = 1;
+               } else {
+                       bitvalue = 0;
+               }
+               /* 0.2. Override with address/data line value */
+               if (flags & SBF_DEFINE_ADDRESSLINE) {
+                       // TODO: Insert address line bit
+               }
+               if (flags & SBF_DEFINE_DATALINE) {
+                       // TODO: Insert data line bit (for writes, otherwise 
set to 1)
+               }
+               /* 0.3. Override with SBF_FORCE_xxx */
+               if (flags & SBF_FORCE_SET) {
+                       bitvalue = 1;
+               } else if (flags & SBF_FORCE_RESET) {
+                       bitvalue = 0;
+               }
+               /* 0.4. Override with SBF_CONTROL_xxx is left to the control 
bit hardware */
+               ;
+               /* 0.5. Store outcome in scanbit flags field */
+               if (bitvalue) {
+                       bi->all_scanbits [j].sb_flags |=  SBF_CURRENTLY_SET;
+               } else {
+                       bi->all_scanbits [j].sb_flags &= ~SBF_CURRENTLY_SET;
+               }
+       }
+       /*
+        * 1. Setup JTAG for single chip access to boundary scan register
+        */
+       irfield.tap = tgt->tap;
+       irfield.num_bits = irfield.tap->ir_length;
+       irfield.out_value = instr;
+       buf_set_u32 (irfield.out_value, 0, irfield.num_bits, bi->instr_sample);
+       irfield.in_value = NULL;
+// printf ("idle or... %d\n", jtag_add_statemove (TAP_IDLE));
+// printf ("irshift or... %d\n", jtag_add_statemove (TAP_IRSHIFT));
+// printf ("execute or... %d\n", jtag_execute_queue ());
+       jtag_add_ir_scan (1, &irfield, jtag_get_end_state ()); /* Other TAPs 
enter BYPASS */
+       /*
+        * 2. Setup neutral bits, fill address bus, float data bus  (makes 
drfield [0])
+        * 4. As 2. but flip readstrobe pins                        (makes 
drfield [1])
+        * 6. As 2. (so: As 4. but flip readstrobe pins once more)  (makes 
drfield [2])
+        */
+       for (i=0; i<3; i++) {
+               strobe  = (i==1);
+               readnow = (i==2);
+               drfield [i].tap = tgt->tap;
+               drfield [i].num_bits = bi->num_scanbits;
+               /*
+                * Allocate appropriate fields, using calloc() to zero the 
bytes.
+                */
+               // TODO: drfield [i].out_value = calloc (DIV_ROUND_UP 
(bi->num_scanbits, 8), 1) || exit (1);
+               drfield [i].out_value = calloc (DIV_ROUND_UP (bi->num_scanbits, 
8), 1);
+               if (readnow) {
+                       // TODO: drfield [i].in_value = calloc (DIV_ROUND_UP 
(bi->num_scanbits, 8), 1) || exit (1);
+                       drfield [i].in_value = calloc (DIV_ROUND_UP 
(bi->num_scanbits, 8), 1);
+               } else {
+                       drfield [i].in_value = NULL;
+               }
+               /*
+                * Fill up the buffers with the various bits.  Bits are read 
and written from
+                * left to right, that is the bytes from xxx_value [0] to the 
last, where the
+                * highest-value bits of the last byte xxx_value [N-1] contain 
the last few bits.
+                */
+               for (j=0; j<bi->num_scanbits; j++) {
+                       register uint32_t flags = bi->all_scanbits [j].sb_flags;
+                       register bool bitvalue = (flags & SBF_CURRENTLY_SET) != 
0;
+                       /* Invert strobe bits if this is the strobe phase being 
written */
+                       if (strobe && (flags & SBF_DEFINE_READSTROBE)) {
+                               bitvalue = !bitvalue;
+                       }
+                       /* If the bit must be set, make it so in the JTAG 
clock-out bit set */
+                       if (bitvalue) {
+                               drfield [i].out_value [j >> 3] |= 0x80 >> (j & 
0x0007);
+                       }
+               }
+       }
+       /*
+        * 3. JTAG cycle on 2.
+        * 5. JTAG cycle on 4.
+        * 7. JTAG cycle on 6, collecting data bus from what is clocked out
+        */
+       printf ("drshift or... %d\n", jtag_add_statemove (TAP_DRSHIFT));
+       jtag_add_dr_scan (3, drfield, jtag_get_end_state ()); /* TAP selected 
by IR scan */
+       /*
+        * 8. Harvest results from previous actions, notably data bus from last 
DR scan
+        */
+       retval = jtag_execute_queue ();
+       if (retval != ERROR_OK) {
+               jtag_error_clear ();
+               return retval;
+       }
+       // TODO:HARVEST_DATA_FROM_drfield[2].in_value
+       // TODO:return ERROR_OK;
+       return ERROR_FAIL;      /* Not implemented yet */
+}
+
+static int bsdl_write_word (struct target *tgt, uint32_t addr, uint32_t *data, 
uint8_t bits) {
+       return ERROR_FAIL;      /* Not implemented yet */
+}
+
+
+/*
+ *     MEMORY ACCESS OPERATIONS
+ */
+
+static int bsdl_virt2phys (struct target *target, uint32_t address, uint32_t 
*physical) {
+       *physical = address;
+       return ERROR_OK;
+}
+
+static int bsdl_read_memory (struct target *tgt, uint32_t adr, uint32_t sz, 
uint32_t count, uint8_t *buf) {
+       uint32_t dta;
+       uint32_t szi;
+       int ok;
+       while (count-- > 0) {
+               szi = sz;
+               ok = bsdl_read_word (tgt, adr, &dta);
+               if (ok != ERROR_OK) {
+                       return ok;
+               }
+               while (szi-- > 0) {
+                       *buf++ = dta >> (szi << 3);
+               }
+               adr += sz;
+       }
+       return ERROR_OK;
+}
+
+static int bsdl_write_memory (struct target *tgt, uint32_t adr, uint32_t sz, 
uint32_t count, uint8_t *buf) {
+       uint32_t dta;
+       uint32_t szi;
+       int ok;
+       while (count-- > 0) {
+               szi = sz;
+               ok = bsdl_write_word (tgt, adr, &dta, sz << 3);
+               if (ok != ERROR_OK) {
+                       return ok;
+               }
+               while (szi-- > 0) {
+                       *buf++ = dta >> (szi << 3);
+               }
+               adr += sz;
+       }
+       return ERROR_OK;
+}
+
+static int bsdl_bulk_write_memory (struct target *tgt, uint32_t adr, uint32_t 
count, uint8_t *buf) {
+       fputs ("Not implemented yet: bsdl_bulk_write_memory()\n", stderr);
+       return ERROR_FAIL;
+}
+
+static int bsdl_checksum_memory (struct target *tgt, uint32_t adr, uint32_t 
count, uint32_t *csum) {
+       fputs ("Not implemented yet: bsdl_checksum_memory()\n", stderr);
+       return ERROR_FAIL;
+}
+
+static int bsdl_blank_check_memory (struct target *tgt, uint32_t adr, uint32_t 
count, uint32_t *blank) {
+       fputs ("Not implemented yet: bsdl_blank_check_memory()\n", stderr);
+       return ERROR_FAIL;
+}
+
+static int bsdl_mmu (struct target *tgt, int * enabled) {
+       *enabled = 0;
+       return ERROR_OK;
+}
+
+
+/*
+ *     COMMAND INTERFACE OPERATIONS
+ */
+
+static int bsdl_target_create (struct target *tgt, Jim_Interp *interp) {
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER (bsdl_loadfile) {
+       command_print (CMD_CTX, "Not implemented yet: bsdl_loadfile()\n");
+       return ERROR_FAIL;
+}
+
+COMMAND_HANDLER (bsdl_loadfile_urjtag) {
+       command_print (CMD_CTX, "Not implemented yet: 
bsdl_loadfile_urjtag()\n");
+       return ERROR_FAIL;
+}
+
+COMMAND_HELPER (bsdl_forcepins, unsigned int wish, unsigned int unwish) {
+       struct target *tgt;
+       int retval = ERROR_OK;
+       struct scanbit *thisbit;
+       int bits2go;
+       unsigned int thisarg;
+
+       /* Find the target and its boundary scan info */
+       tgt = get_current_target (CMD_CTX);
+
+       /* Iterate over the bits and assign the intended flag */
+       for (thisarg=0; thisarg<CMD_ARGC; thisarg++) {
+               const char *bitstr = CMD_ARGV [thisarg];
+               int bitlen = strlen (bitstr);
+               bool found = 0;
+               /* Scan bit names ending in (*) count as a wildcard match */
+               if ((bitlen > 3) && !strcmp (bitstr+bitlen-3, "(*)")) {
+                       bitlen -= 2;    /* Compare scan bit names up to and 
including '(' */
+               } else {
+                       bitlen ++;      /* Include '\0' but for safety use 
strncmp() instead of memcmp() */
+               }
+               thisbit = target_bsdl_info (tgt)->all_scanbits;
+               bits2go = target_bsdl_info (tgt)->num_scanbits;
+               while (bits2go > 0) {
+                       /* For each of the bits, check if the name matches 
bitstr/bitlen */
+                       if ((thisbit->sb_name != NULL) && !strncmp (bitstr, 
thisbit->sb_name, bitlen)) {
+                               if (wish == SBF_FORCE_FLOAT) {
+                                       if ((!thisbit->sb_controller) || 
!(thisbit->sb_flags & SBF_CONTROLLED_FLOAT))  {
+                                               command_print (CMD_CTX, "Error: Bit 
%s cannot be floated\n",
+                                                               
thisbit->sb_name);
+                                       } else {
+                                               int newflag = 
thisbit->sb_controller->sb_flags;
+                                               if (thisbit->sb_flags & 
SBF_CONTROL_BY_ONE) {
+                                                       newflag |= 
SBF_FORCE_SET;
+                                               } else {
+                                                       newflag |= 
SBF_FORCE_RESET;
+                                               }
+                                               if (((SBF_FORCE_SET | 
SBF_FORCE_RESET) & ~newflag) != 0) {
+                                                       
thisbit->sb_controller->sb_flags = newflag;
+                                               } else {
+                                                       command_print (CMD_CTX, "It 
is not possible to force set and reset %s's controller %s\n",
+                                                                       thisbit->sb_name, 
thisbit->sb_controller->sb_name? thisbit->sb_controller->sb_name: "");
+                                               }
+                                       }
+                               }
+                               if (thisbit->sb_flags & unwish) {
+                                       command_print (CMD_CTX, "Info: Overruling 
older setting for %s\n",
+                                                               
thisbit->sb_name);
+                               }
+                               thisbit->sb_flags = (thisbit->sb_flags & 
~unwish) | wish;
+                               found++;
+                       }
+                       bits2go--;
+                       thisbit++;
+               }
+               if (found == 0) {
+                       command_print (CMD_CTX, "Error: Found no scan bits matching 
%s\n",
+                                       bitstr);
+                       retval = ERROR_FAIL;
+               } else if (found > 1) {
+                       command_print (CMD_CTX, "Info: Changed %d scanbits matching 
%s\n",
+                                       found, bitstr);
+               }
+       }
+
+       /* Check if any bits have been implicitly set to "float" */
+       thisbit = target_bsdl_info (tgt)->all_scanbits;
+       bits2go = target_bsdl_info (tgt)->num_scanbits;
+       while (bits2go > 0) {
+               if (thisbit->sb_controller) {
+                       if (thisbit->sb_controller->sb_flags & (SBF_FORCE_SET | 
SBF_FORCE_RESET)) {
+                               if (!thisbit->sb_flags & SBF_FORCE_FLOAT) {
+                                       thisbit->sb_flags |= SBF_FORCE_FLOAT;
+                                       command_print (CMD_CTX, "Warning: Implicit 
selection of float "
+                                                       "mode on %s\n", 
thisbit->sb_name);
+                               }
+                       }
+               }
+               thisbit++;
+               bits2go--;
+       }
+
+       /* Return the end result */
+       return retval;
+}
+
+COMMAND_HANDLER (bsdl_forcepins_set) {
+       return CALL_COMMAND_HANDLER (bsdl_forcepins, SBF_FORCE_SET, 
SBF_FORCE_RESET);
+}
+
+COMMAND_HANDLER (bsdl_forcepins_reset) {
+       return CALL_COMMAND_HANDLER (bsdl_forcepins, SBF_FORCE_RESET, 
SBF_FORCE_SET);
+}
+
+COMMAND_HANDLER (bsdl_forcepins_float) {
+       return CALL_COMMAND_HANDLER (bsdl_forcepins, SBF_FORCE_FLOAT, 0);
+}
+
+COMMAND_HANDLER (bsdl_forcenone) {
+       struct target *tgt;
+       struct scanbit *thisbit;
+       int bits2go;
+
+       /* Find the target and its boundary scan info */
+       tgt = get_current_target (CMD_CTX);
+
+       /* Iterate over scanbits and clean any forcing flags */
+       thisbit = target_bsdl_info (tgt)->all_scanbits;
+       bits2go = target_bsdl_info (tgt)->num_scanbits;
+       while (bits2go > 0) {
+               thisbit->sb_flags &= ~ (SBF_FORCE_SET | SBF_FORCE_RESET | 
SBF_FORCE_FLOAT);
+               thisbit++;
+               bits2go--;
+       }
+
+       /* Return the end result */
+       return ERROR_OK;
+}
+
+
+COMMAND_HELPER (bsdl_strobepins, uint32_t strobeflag) {
+       struct target *tgt;
+       int retval = ERROR_OK;
+       struct scanbit *thisbit;
+       int bits2go;
+       unsigned int thisarg;
+
+       /* Find the target and its boundary scan info */
+       tgt = get_current_target (CMD_CTX);
+
+       /* Iterate over the bits and assign the intended flag */
+       for (thisarg=0; thisarg<CMD_ARGC; thisarg++) {
+               const char *bitstr = CMD_ARGV [thisarg];
+               int bitlen = strlen (bitstr);
+               bool found = 0;
+               /* Scan bit names ending in (*) count as a wildcard match */
+               if ((bitlen > 3) && !strcmp (bitstr+bitlen-3, "(*)")) {
+                       bitlen -= 2;    /* Compare scan bit names up to and 
including '(' */
+               } else {
+                       bitlen ++;      /* Include '\0' but for safety use 
strncmp() instead of memcmp() */
+               }
+               thisbit = target_bsdl_info (tgt)->all_scanbits;
+               bits2go = target_bsdl_info (tgt)->num_scanbits;
+               while (bits2go > 0) {
+                       /* For each of the bits, check if the name matches 
bitstr/bitlen */
+                       if ((thisbit->sb_name != NULL) && !strncmp (bitstr, 
thisbit->sb_name, bitlen)) {
+                               thisbit->sb_flags |= strobeflag;
+                               found++;
+                       }
+                       bits2go--;
+                       thisbit++;
+               }
+               if (found == 0) {
+                       command_print (CMD_CTX, "Error: Found no scan bits matching 
%s\n",
+                                       bitstr);
+                       retval = ERROR_FAIL;
+               } else if (found > 1) {
+                       command_print (CMD_CTX, "Info: Changed %d scanbits matching 
%s\n",
+                                       found, bitstr);
+               }
+       }
+
+       /* Return the end result */
+       return retval;
+}
+
+COMMAND_HANDLER (bsdl_define_readstrobe) {
+       return CALL_COMMAND_HANDLER (bsdl_strobepins, SBF_DEFINE_READSTROBE);
+}
+
+COMMAND_HANDLER (bsdl_define_writestrobe) {
+       return CALL_COMMAND_HANDLER (bsdl_strobepins, SBF_DEFINE_WRITESTROBE);
+}
+
+COMMAND_HELPER (bsdl_buspins, struct target *tgt, struct businfo *bus, 
uint32_t bustp) {
+       int retval = ERROR_OK;
+       const char *bitstr;
+       int bitlen;
+       unsigned int testbit;
+       /* Check arguments */
+       if (CMD_ARGC != 1) {
+               retval = ERROR_INVALID_ARGUMENTS;
+       }
+       bitstr = CMD_ARGV [0];
+       bitlen = strlen (bitstr);
+       if ((bitlen < 4) || (strcmp (bitstr+bitlen-3, "(*)"))) {
+               command_print (CMD_CTX, "Please specify BUS(*) instead of 
%s\n", bitstr);
+               retval = ERROR_INVALID_ARGUMENTS;
+       }
+       if (bitlen > 100) {
+               command_print (CMD_CTX, "Scan bit names should not exceed 100 
positions\n");
+               retval = ERROR_INVALID_ARGUMENTS;
+       }
+       if (retval != ERROR_OK) {
+               return retval;
+       }
+       /* Construct the bus */
+       bus->bus_first = 255;
+       bus->bus_size = 255;
+       for (testbit=0; testbit < target_bsdl_info(tgt)->num_scanbits; 
testbit++) {
+               char testarea [120];
+               struct scanbit *thisbit = target_bsdl_info(tgt)->all_scanbits;
+               int bits2go = target_bsdl_info(tgt)->num_scanbits;
+               strcpy (testarea, bitstr);
+               snprintf (testarea + bitlen - 3, 110+3-bitlen, "(%d)", testbit);
+               while (bits2go > 0) {
+                       if (thisbit->sb_name && !strcmp (testarea, 
thisbit->sb_name)) {
+                               if (bus->bus_first == 255) {
+                                       bus->bus_first = testbit;
+                               } else if (bus->bus_size != testbit) {
+                                       command_print (CMD_CTX, "Error: Bus pins are 
not incrementally numbered");
+                                       retval = ERROR_FAIL;
+                               }
+                               if (thisbit->sb_flags & (SBF_DEFINE_ADDRESSLINE | 
SBF_DEFINE_DATALINE) & ~bustp) {
+                                       command_print (CMD_CTX, "Error: A pin cannot 
be part of data bus as well as address bus\n");
+                                       retval = ERROR_FAIL;
+                               } else {
+                                       thisbit->sb_flags |= bustp;
+                               }
+                               bus->bus_size = testbit + 1;
+                               thisbit->sb_linebit = testbit;
+                       }
+                       thisbit++;
+                       bits2go--;
+               }
+       }
+       /* Return if we were successful overall */
+       return retval;
+}
+
+COMMAND_HANDLER (bsdl_define_address) {
+       struct target *tgt = get_current_target (CMD_CTX);
+       struct businfo *bus = &target_bsdl_info(tgt)->bus_address;
+       return CALL_COMMAND_HANDLER (bsdl_buspins, tgt, bus, 
SBF_DEFINE_ADDRESSLINE);
+}
+
+COMMAND_HANDLER (bsdl_define_data) {
+       struct target *tgt = get_current_target (CMD_CTX);
+       struct businfo *bus = &target_bsdl_info(tgt)->bus_data;
+       return CALL_COMMAND_HANDLER (bsdl_buspins, tgt, bus, 
SBF_DEFINE_DATALINE);
+}
+
+
+/*
+ *     GENERIC ROUTINES
+ */
+
+
+#if 0
+COMMAND_HANDLER (bsdl_noop) {
+       return ERROR_OK;
+}
+#endif
+
+int bsdl_init (struct command_context *cmd_ctx, struct target *target) {
+       return ERROR_OK;
+}
+
+
+int bsdl_poll (struct target *target) {
+       return ERROR_OK;
+}
+
+/*
+ *     DRIVER DESCRIPTIVE STRUCTURES
+ */
+
+static const struct command_registration bsdl_commands_define[] = {
+       {
+               .name = "address",
+               .usage = "pinname...",
+               .help = "When accessing memory, place the target address on these 
pins",
+               .handler = bsdl_define_address,
+               .mode = COMMAND_ANY,
+       },
+       {
+               .name = "data",
+               .usage = "pinname...",
+               .help = "When accessing memory, exchange data over these pins",
+               .handler = bsdl_define_data,
+               .mode = COMMAND_ANY,
+       },
+       {
+               .name = "readstrobe",
+               .usage = "pinname...",
+               .help = "When reading from memory, temporarily change these pins to 
send a strobe signal",
+               .handler = bsdl_define_readstrobe,
+               .mode = COMMAND_ANY,
+       },
+       {
+               .name = "writestrobe",
+               .usage = "pinname...",
+               .help = "When writing to memory, temporarily change these pins to 
send a strobe signal",
+               .handler = bsdl_define_writestrobe,
+               .mode = COMMAND_ANY,
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration bsdl_commands_force[] = {
+       {
+               .name = "set",
+               .usage = "pinname...",
+               .help = "During future boundary scans, make sure to set the named 
pins to 1",
+               .handler = bsdl_forcepins_set,
+               .mode = COMMAND_ANY,
+       },
+       {
+               .name = "reset",
+               .usage = "pinname...",
+               .help = "During future boundary scans, make sure to set the named 
pins to 0",
+               .handler = bsdl_forcepins_reset,
+               .mode = COMMAND_ANY,
+       },
+       {
+               .name = "float",
+               .usage = "pinname...",
+               .help = "During future boundary scans, make sure to make the named 
pins float",
+               .handler = bsdl_forcepins_float,
+               .mode = COMMAND_ANY,
+       },
+       {
+               .name = "none",
+               .usage = "",
+               .help = "During future boundary scans, do not force any pin 
values",
+               .handler = bsdl_forcenone,
+               .mode = COMMAND_ANY,
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration bsdl_commands[] = {
+       {
+               .name = "bsdlfile",
+               .usage = "filename",
+               .help = "Load BSDL description from named file",
+               .handler = bsdl_loadfile,
+               .mode = COMMAND_ANY,
+       },
+       {
+               .name = "urjtagfile",
+               .usage = "filename",
+               .help = "DEPRECATED: Load JTAG description from named file, created 
by UrJTAG's bsdl2jtag",
+               .handler = bsdl_loadfile_urjtag,
+               .mode = COMMAND_ANY,
+       },
+       {
+               .name = "force",
+               .usage = "'set' ... | 'reset' ... | 'float' ... | 'none'",
+               .help = "Commands to force the state of pins during upcoming 
boundary scans",
+               .chain = bsdl_commands_force,
+               .mode = COMMAND_ANY,
+       },
+       {
+               .name = "define",
+               .usage = "'address' ... | 'data' ... | 'readstrobe' ... | 
'writestrobe' ...",
+               .help = "Commands to define the functions of pins",
+               .chain = bsdl_commands_define,
+               .mode = COMMAND_ANY,
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+const struct target_type generic_bsdl_target = {
+
+       /* Constants */
+       .name = "generic_bsdl",
+       .commands = bsdl_commands,
+
+       /* Reset */
+
+       /* JTAG */
+
+       /* Memory */
+       .read_memory = bsdl_read_memory,
+       .read_memory_imp = bsdl_read_memory,
+       .read_phys_memory = bsdl_read_memory,
+       .write_memory = bsdl_write_memory,
+       .write_memory_imp = bsdl_write_memory,
+       .write_phys_memory = bsdl_write_memory,
+       .bulk_write_memory = bsdl_bulk_write_memory,
+       .checksum_memory = bsdl_checksum_memory,
+       .blank_check_memory = bsdl_blank_check_memory,
+       .mmu = bsdl_mmu,
+       .virt2phys = bsdl_virt2phys,
+
+       /* Commands */
+       .target_create = bsdl_target_create,
+
+       /* General setup */
+       .init_target = bsdl_init,
+       .poll = bsdl_poll,
+
+};
+
diff -Nur openocd-0.4.0-orig/src/target/target.c 
openocd-0.4.0-plus_bsdl/src/target/target.c
--- openocd-0.4.0-orig/src/target/target.c      2010-02-21 20:17:07.000000000 
+0000
+++ openocd-0.4.0-plus_bsdl/src/target/target.c 2010-10-06 11:02:01.000000000 
+0000
@@ -68,6 +68,7 @@
 extern struct target_type avr_target;
 extern struct target_type dsp563xx_target;
 extern struct target_type testee_target;
+extern struct target_type generic_bsdl_target;
struct target_type *target_types[] =
 {
@@ -88,6 +89,7 @@
        &avr_target,
        &dsp563xx_target,
        &testee_target,
+       &generic_bsdl_target,
        NULL,
 };
@@ -3905,7 +3907,7 @@
        Jim_GetOptInfo goi;
        Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
- if ((goi.argc == 2) || (goi.argc == 3))
+       if ((goi.argc == 3) || (goi.argc == 4))
        {
                Jim_SetResult_sprintf(goi.interp,
                                "usage: %s <address> [<count>]", cmd_name);
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to