aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Borneo <borneo.antonio@gmail.com>2020-11-01 12:30:27 +0100
committerAntonio Borneo <borneo.antonio@gmail.com>2021-03-19 21:55:50 +0000
commitb0fe92dba7c01adc25e5fe3552253a4a8c69ae1a (patch)
tree713df4f13e91a8c1517d5510c39176eb15cf5dbc
parent58b95eac48cf0ad3316a911ddc79ce8973b88fd1 (diff)
downloadriscv-openocd-b0fe92dba7c01adc25e5fe3552253a4a8c69ae1a.zip
riscv-openocd-b0fe92dba7c01adc25e5fe3552253a4a8c69ae1a.tar.gz
riscv-openocd-b0fe92dba7c01adc25e5fe3552253a4a8c69ae1a.tar.bz2
zy1000: drop the code, deprecated in v0.10.0
The code for zy1000 has been marked as deprecated in release v0.10.0, 4 years ago. Time to drop it! Change-Id: I08fca2a2bf8f616f031e15fd37dac3197a40ba50 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/6090 Tested-by: jenkins
-rw-r--r--configure.ac43
-rw-r--r--doc/manual/jtag.txt1
-rw-r--r--doc/openocd.texi42
-rw-r--r--src/jtag/Makefile.am4
-rw-r--r--src/jtag/interfaces.c8
-rw-r--r--src/jtag/jtag.h11
-rw-r--r--src/jtag/startup.tcl4
-rw-r--r--src/jtag/zy1000/jtag_minidriver.h182
-rw-r--r--src/jtag/zy1000/zy1000.c1259
-rw-r--r--tcl/board/zy1000.cfg117
10 files changed, 5 insertions, 1666 deletions
diff --git a/configure.ac b/configure.ac
index 215d7a7..71cfe21 100644
--- a/configure.ac
+++ b/configure.ac
@@ -283,14 +283,6 @@ AC_ARG_ENABLE([amtjtagaccel],
AS_HELP_STRING([--enable-amtjtagaccel], [Enable building the Amontec JTAG-Accelerator driver]),
[build_amtjtagaccel=$enableval], [build_amtjtagaccel=no])
-AC_ARG_ENABLE([zy1000_master],
- AS_HELP_STRING([--enable-zy1000-master], [Use ZY1000 JTAG master registers]),
- [build_zy1000_master=$enableval], [build_zy1000_master=no])
-
-AC_ARG_ENABLE([zy1000],
- AS_HELP_STRING([--enable-zy1000], [Enable ZY1000 interface]),
- [build_zy1000=$enableval], [build_zy1000=no])
-
AS_CASE(["${host_cpu}"],
[arm*|aarch64], [
AC_ARG_ENABLE([bcm2835gpio],
@@ -373,16 +365,6 @@ AC_ARG_ENABLE([internal-libjaylink],
[use_internal_libjaylink=$enableval], [use_internal_libjaylink=yes])
build_minidriver=no
-AC_MSG_CHECKING([whether to enable ZY1000 minidriver])
-AS_IF([test "x$build_zy1000" = "xyes"], [
- AS_IF([test "x$build_minidriver" = "xyes"], [
- AC_MSG_ERROR([Multiple minidriver options have been enabled.])
- ])
- AC_DEFINE([HAVE_JTAG_MINIDRIVER_H], [1],
- [Define to 1 if you have the <jtag_minidriver.h> header file.])
- build_minidriver=yes
-])
-AC_MSG_RESULT([$build_zy1000])
AC_ARG_ENABLE([remote-bitbang],
AS_HELP_STRING([--enable-remote-bitbang], [Enable building support for the Remote Bitbang jtag driver]),
@@ -521,18 +503,6 @@ AS_IF([test "x$build_ep93xx" = "xyes"], [
AC_DEFINE([BUILD_EP93XX], [0], [0 if you don't want ep93xx.])
])
-AS_IF([test "x$build_zy1000" = "xyes"], [
- AC_DEFINE([BUILD_ZY1000], [1], [1 if you want ZY1000.])
-], [
- AC_DEFINE([BUILD_ZY1000], [0], [0 if you don't want ZY1000.])
-])
-
-AS_IF([test "x$build_zy1000_master" = "xyes"], [
- AC_DEFINE([BUILD_ZY1000_MASTER], [1], [1 if you want ZY1000 JTAG master registers.])
-], [
- AC_DEFINE([BUILD_ZY1000_MASTER], [0], [0 if you don't want ZY1000 JTAG master registers.])
-])
-
AS_IF([test "x$build_at91rm9200" = "xyes"], [
build_bitbang=yes
AC_DEFINE([BUILD_AT91RM9200], [1], [1 if you want at91rm9200.])
@@ -687,9 +657,6 @@ PKG_CHECK_MODULES([LIBJAYLINK], [libjaylink >= 0.2],
m4_define([PROCESS_ADAPTERS], [
m4_foreach([adapter], [$1], [
- AS_IF([test "x$build_zy1000" = "xyes"], [
- ADAPTER_VAR([adapter])=no
- ])
AS_IF([test $2], [
AS_IF([test "x$ADAPTER_VAR([adapter])" != "xno"], [
AC_DEFINE([BUILD_]ADAPTER_SYM([adapter]), [1], [1 if you want the ]ADAPTER_DESC([adapter]).)
@@ -751,8 +718,6 @@ AM_CONDITIONAL([PARPORT], [test "x$build_parport" = "xyes"])
AM_CONDITIONAL([DUMMY], [test "x$build_dummy" = "xyes"])
AM_CONDITIONAL([GIVEIO], [test "x$parport_use_giveio" = "xyes"])
AM_CONDITIONAL([EP93XX], [test "x$build_ep93xx" = "xyes"])
-AM_CONDITIONAL([ZY1000], [test "x$build_zy1000" = "xyes"])
-AM_CONDITIONAL([ZY1000_MASTER], [test "x$build_zy1000_master" = "xyes"])
AM_CONDITIONAL([AT91RM9200], [test "x$build_at91rm9200" = "xyes"])
AM_CONDITIONAL([BCM2835GPIO], [test "x$build_bcm2835gpio" = "xyes"])
AM_CONDITIONAL([IMX_GPIO], [test "x$build_imx_gpio" = "xyes"])
@@ -867,11 +832,3 @@ m4_foreach([adapter], [USB1_ADAPTERS, USB0_ADAPTERS,
])
])
echo
-
-AS_IF([test "x$build_zy1000" = "xyes" -o "x$build_zy1000_master" = "xyes"], [
- echo 'WARNING! Deprecated configure option (--enable-zy1000, --enable-zy1000-master)'
- echo 'Support for the ZY1000 platform is deprecated and will be removed in the next'
- echo 'release. If you regularly use this platform, please report to the OpenOCD'
- echo 'Mailing List.'
- echo
-])
diff --git a/doc/manual/jtag.txt b/doc/manual/jtag.txt
index 8f0804c..2653fc7 100644
--- a/doc/manual/jtag.txt
+++ b/doc/manual/jtag.txt
@@ -36,7 +36,6 @@ asynchronous transactions.
- declared in @c src/jtag/minidriver.h
- used @a only by the core and minidriver implementations:
- @c jtag_driver.c (in-tree OpenOCD drivers)
- - @c zy1000/build/include/jtag_minidriver.h (ZY1000 minidriver)
- future implementations (on other embedded hosts)
- interface device drivers do @b not need this API.
diff --git a/doc/openocd.texi b/doc/openocd.texi
index f52cfa7..b3fe854 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -298,7 +298,6 @@ The OpenOCD Bug Tracker is hosted on SourceForge:
@cindex dongles
@cindex FTDI
@cindex wiggler
-@cindex zy1000
@cindex printer port
@cindex USB Adapter
@cindex RTCK
@@ -307,12 +306,7 @@ Defined: @b{dongle}: A small device that plugs into a computer and serves as
an adapter .... [snip]
In the OpenOCD case, this generally refers to @b{a small adapter} that
-attaches to your computer via USB or the parallel port. One
-exception is the Ultimate Solutions ZY1000, packaged as a small box you
-attach via an ethernet cable. The ZY1000 has the advantage that it does not
-require any drivers to be installed on the developer PC. It also has
-a built in web interface. It supports RTCK/RCLK or adaptive clocking
-and has a built-in relay to power cycle targets remotely.
+attaches to your computer via USB or the parallel port.
@section Choosing a Dongle
@@ -334,26 +328,6 @@ Ethernet port needed?
RTCK support (also known as ``adaptive clocking'')?
@end enumerate
-@section Stand-alone JTAG Probe
-
-The ZY1000 from Ultimate Solutions is technically not a dongle but a
-stand-alone JTAG probe that, unlike most dongles, doesn't require any drivers
-running on the developer's host computer.
-Once installed on a network using DHCP or a static IP assignment, users can
-access the ZY1000 probe locally or remotely from any host with access to the
-IP address assigned to the probe.
-The ZY1000 provides an intuitive web interface with direct access to the
-OpenOCD debugger.
-Users may also run a GDBSERVER directly on the ZY1000 to take full advantage
-of GCC & GDB to debug any distribution of embedded Linux or NetBSD running on
-the target.
-The ZY1000 supports RTCK & RCLK or adaptive clocking and has a built-in relay
-to power cycle the target remotely.
-
-For more information, visit:
-
-@b{ZY1000} See: @url{http://www.ultsol.com/index.php/component/content/article/8/210-zylin-zy1000-main}
-
@section USB FT2232 Based
There are many USB JTAG dongles on the market, many of them based
@@ -3222,20 +3196,6 @@ The string will be of the format "DDDD:BB:SS.F" such as "0000:65:00.1".
@end deffn
@end deffn
-@deffn {Interface Driver} {ZY1000}
-This is the Zylin ZY1000 JTAG debugger.
-@end deffn
-
-@quotation Note
-This defines some driver-specific commands,
-which are not currently documented here.
-@end quotation
-
-@deffn Command power [@option{on}|@option{off}]
-Turn power switch to target on/off.
-No arguments: print status.
-@end deffn
-
@deffn {Interface Driver} {bcm2835gpio}
This SoC is present in Raspberry Pi which is a cheap single-board computer
exposing some GPIOs on its expansion header.
diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am
index b82914b..8bc87a4 100644
--- a/src/jtag/Makefile.am
+++ b/src/jtag/Makefile.am
@@ -8,10 +8,6 @@ CLEANFILES += %D%/minidriver_imp.h
if MINIDRIVER
-if ZY1000
-JTAG_SRCS += %D%/zy1000/zy1000.c
-JTAG_MINIDRIVER_DIR = %D%/zy1000
-endif
if MINIDRIVER_DUMMY
JTAG_SRCS += %D%/minidummy/minidummy.c
JTAG_MINIDRIVER_DIR = %D%/minidummy
diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c
index 061a78f..d229d8c 100644
--- a/src/jtag/interfaces.c
+++ b/src/jtag/interfaces.c
@@ -42,9 +42,7 @@
* that contain an adapter_driver structure that can added to this list.
*/
-#if BUILD_ZY1000 == 1
-extern struct adapter_driver zy1000_adapter_driver;
-#elif defined(BUILD_MINIDRIVER_DUMMY)
+#if defined(BUILD_MINIDRIVER_DUMMY)
extern struct adapter_driver minidummy_adapter_driver;
#else /* standard drivers */
#if BUILD_PARPORT == 1
@@ -162,9 +160,7 @@ extern struct adapter_driver rshim_dap_adapter_driver;
* or some number of standard driver interfaces, never both.
*/
struct adapter_driver *adapter_drivers[] = {
-#if BUILD_ZY1000 == 1
- &zy1000_adapter_driver,
-#elif defined(BUILD_MINIDRIVER_DUMMY)
+#if defined(BUILD_MINIDRIVER_DUMMY)
&minidummy_adapter_driver,
#else /* standard drivers */
#if BUILD_PARPORT == 1
diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index 2fa5802..044d7c0 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -46,15 +46,6 @@
typedef enum tap_state {
TAP_INVALID = -1,
-#if BUILD_ZY1000
- /* These are the old numbers. Leave as-is for now... */
- TAP_RESET = 0, TAP_IDLE = 8,
- TAP_DRSELECT = 1, TAP_DRCAPTURE = 2, TAP_DRSHIFT = 3, TAP_DREXIT1 = 4,
- TAP_DRPAUSE = 5, TAP_DREXIT2 = 6, TAP_DRUPDATE = 7,
- TAP_IRSELECT = 9, TAP_IRCAPTURE = 10, TAP_IRSHIFT = 11, TAP_IREXIT1 = 12,
- TAP_IRPAUSE = 13, TAP_IREXIT2 = 14, TAP_IRUPDATE = 15,
-
-#else
/* Proper ARM recommended numbers */
TAP_DREXIT2 = 0x0,
TAP_DREXIT1 = 0x1,
@@ -72,8 +63,6 @@ typedef enum tap_state {
TAP_IRUPDATE = 0xd,
TAP_IRCAPTURE = 0xe,
TAP_RESET = 0x0f,
-
-#endif
} tap_state_t;
/**
diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl
index e5c3b0f..f1e69e5 100644
--- a/src/jtag/startup.tcl
+++ b/src/jtag/startup.tcl
@@ -29,7 +29,7 @@ proc init_reset { mode } {
#########
# TODO: power_restore and power_dropout are currently neither
-# documented nor supported except on ZY1000.
+# documented nor supported.
proc power_restore {} {
echo "Sensed power restore, running reset init and halting GDB."
@@ -55,7 +55,7 @@ proc power_dropout {} {
#########
# TODO: srst_deasserted and srst_asserted are currently neither
-# documented nor supported except on ZY1000.
+# documented nor supported.
proc srst_deasserted {} {
echo "Sensed nSRST deasserted, running reset init and halting GDB."
diff --git a/src/jtag/zy1000/jtag_minidriver.h b/src/jtag/zy1000/jtag_minidriver.h
deleted file mode 100644
index 7d1ede5..0000000
--- a/src/jtag/zy1000/jtag_minidriver.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2007-2010 by Øyvind Harboe *
- * *
- * 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, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-/* used to test manual mode */
-#define TEST_MANUAL() 0
-#define VERBOSE(a)
-
-#if BUILD_ZY1000_MASTER
-
-#define ZY1000_PEEK(a, b) do {b = *((volatile uint32_t *)(a)); } while (0)
-#define ZY1000_POKE(a, b) do {*((volatile uint32_t *)(a)) = b; } while (0)
-extern volatile void *zy1000_jtag_master;
-#define ZY1000_JTAG_BASE ((unsigned long)zy1000_jtag_master)
-
-#else
-
-/* redirect this to TCP/IP */
-#define ZY1000_JTAG_BASE 0
-extern void zy1000_tcpout(uint32_t address, uint32_t data);
-extern uint32_t zy1000_tcpin(uint32_t address);
-#define ZY1000_PEEK(a, b) b = zy1000_tcpin(a)
-#define ZY1000_POKE(a, b) zy1000_tcpout(a, b)
-
-#endif
-
-#if BUILD_ZY1000_MASTER
-/* FIFO empty? */
-static inline void waitIdle(void)
-{
- uint32_t empty;
- do {
- ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, empty);
- } while ((empty & 0x100) == 0);
-}
-
-static inline void zy1000_flush_readqueue(void)
-{
- /* Not used w/hardware fifo */
-}
-static inline void zy1000_flush_callbackqueue(void)
-{
- /* Not used w/hardware fifo */
-}
-#else
-extern void waitIdle(void);
-void zy1000_flush_readqueue(void);
-void zy1000_flush_callbackqueue(void);
-void zy1000_jtag_add_callback4(jtag_callback_t callback,
- jtag_callback_data_t data0,
- jtag_callback_data_t data1,
- jtag_callback_data_t data2,
- jtag_callback_data_t data3);
-void zy1000_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0);
-#endif
-
-static inline void waitQueue(void)
-{
-/* waitIdle(); */
-}
-
-static inline void sampleShiftRegister(void)
-{
-#if 0
- uint32_t dummy;
- waitIdle();
- ZY1000_PEEK(ZY1000_JTAG_BASE + 0xc, dummy);
-#endif
-}
-
-static inline void setCurrentState(enum tap_state state)
-{
- uint32_t a;
- a = state;
- int repeat = 0;
- if (state == TAP_RESET) {
- /* The FPGA nor we know the current state of the CPU TAP */
- /* controller. This will move it to TAP for sure. */
- /* */
- /* 5 should be enough here, 7 is what OpenOCD uses */
- repeat = 7;
- }
- waitQueue();
- sampleShiftRegister();
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | a);
-
-}
-
-/*
- * Enter state and cause repeat transitions *out* of that state. So if the endState != state, then
- * the transition from state to endState counts as a transition out of state.
- */
-static inline void shiftValueInner(const enum tap_state state,
- const enum tap_state endState,
- int repeat,
- uint32_t value)
-{
- uint32_t a, b;
- a = state;
- b = endState;
- waitQueue();
- sampleShiftRegister();
- ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value);
-#if 1
-#if TEST_MANUAL()
- if ((state == TAP_DRSHIFT) && (endState != TAP_DRSHIFT)) {
- int i;
- setCurrentState(state);
- for (i = 0; i < repeat; i++) {
- int tms;
- tms = 0;
- if ((i == repeat-1) && (state != endState))
- tms = 1;
- /* shift out value */
- waitIdle();
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, (((value >> i)&1) << 1) | tms);
- }
- waitIdle();
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
- waitIdle();
- /* ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT); // set this state and things
- * break => expected */
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRPAUSE); /* set this and things will
- * work => expected. Not
- * setting this is not
- * sufficient to make things
- * break. */
- setCurrentState(endState);
- } else
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
-
-#else
- /* fast version */
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
-#endif
-#else
- /* maximum debug version */
- if ((repeat > 0) && ((state == TAP_DRSHIFT) || (state == TAP_SI))) {
- int i;
- /* sample shift register for every bit. */
- for (i = 0; i < repeat-1; i++) {
- sampleShiftRegister();
- ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value >> i);
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (1 << 8) | (a << 4) | a);
- }
- sampleShiftRegister();
- ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value >> (repeat-1));
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (1 << 8) | (a << 4) | b);
- } else {
- sampleShiftRegister();
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
- }
- sampleShiftRegister();
-#endif
-}
-
-#if BUILD_ZY1000_MASTER
-#define interface_jtag_add_callback(callback, in) callback(in)
-#define interface_jtag_add_callback4(callback, in, data1, data2, \
- data3) jtag_set_error(callback(in, data1, data2, data3))
-#else
-#define interface_jtag_add_callback(callback, in) zy1000_jtag_add_callback(callback, in)
-#define interface_jtag_add_callback4(callback, in, data1, data2, data3) zy1000_jtag_add_callback4( \
- callback, \
- in, \
- data1, \
- data2, \
- data3)
-#endif
diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c
deleted file mode 100644
index 669e6f4..0000000
--- a/src/jtag/zy1000/zy1000.c
+++ /dev/null
@@ -1,1259 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2007-2010 by Øyvind Harboe *
- * *
- * 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, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-/* This file supports the zy1000 debugger:
- *
- * http://www.ultsol.com/index.php/component/content/article/8/33-zylin-zy1000-jtag-probe
- *
- * The zy1000 is a standalone debugger that has a web interface and
- * requires no drivers on the developer host as all communication
- * is via TCP/IP. The zy1000 gets it performance(~400-700kBytes/s
- * DCC downloads @ 16MHz target) as it has an FPGA to hardware
- * accelerate the JTAG commands, while offering *very* low latency
- * between OpenOCD and the FPGA registers.
- *
- * The disadvantage of the zy1000 is that it has a feeble CPU compared to
- * a PC(ca. 50-500 DMIPS depending on how one counts it), whereas a PC
- * is on the order of 10000 DMIPS(i.e. at a factor of 20-200).
- *
- * The zy1000 revc hardware is using an Altera Nios CPU, whereas the
- * revb is using ARM7 + Xilinx.
- *
- * See Zylin web pages or contact Zylin for more information.
- *
- * The reason this code is in OpenOCD rather than OpenOCD linked with the
- * ZY1000 code is that OpenOCD is the long road towards getting
- * libopenocd into place. libopenocd will support both low performance,
- * low latency systems(embedded) and high performance high latency
- * systems(PCs).
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <pthread.h>
-
-#include <target/embeddedice.h>
-#include <jtag/minidriver.h>
-#include <jtag/interface.h>
-#include <time.h>
-#include <helper/time_support.h>
-
-#include <netinet/tcp.h>
-
-/* Assume we're connecting to a revc w/60MHz clock. */
-#define ZYLIN_KHZ 60000
-
-/* The software needs to check if it's in RCLK mode or not */
-static bool zy1000_rclk;
-
-static int zy1000_khz(int khz, int *jtag_speed)
-{
- if (khz == 0)
- *jtag_speed = 0;
- else {
- int speed;
- /* Round speed up to nearest divisor.
- *
- * E.g. 16000kHz
- * (64000 + 15999) / 16000 = 4
- * (4 + 1) / 2 = 2
- * 2 * 2 = 4
- *
- * 64000 / 4 = 16000
- *
- * E.g. 15999
- * (64000 + 15998) / 15999 = 5
- * (5 + 1) / 2 = 3
- * 3 * 2 = 6
- *
- * 64000 / 6 = 10666
- *
- */
- speed = (ZYLIN_KHZ + (khz - 1)) / khz;
- speed = (speed + 1) / 2;
- speed *= 2;
- if (speed > 8190) {
- /* maximum dividend */
- speed = 8190;
- }
- *jtag_speed = speed;
- }
- return ERROR_OK;
-}
-
-static int zy1000_speed_div(int speed, int *khz)
-{
- if (speed == 0)
- *khz = 0;
- else
- *khz = ZYLIN_KHZ / speed;
-
- return ERROR_OK;
-}
-
-static bool readPowerDropout(void)
-{
- uint32_t state;
- /* sample and clear power dropout */
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x80);
- ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, state);
- bool powerDropout;
- powerDropout = (state & 0x80) != 0;
- return powerDropout;
-}
-
-
-static bool readSRST(void)
-{
- uint32_t state;
- /* sample and clear SRST sensing */
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000040);
- ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, state);
- bool srstAsserted;
- srstAsserted = (state & 0x40) != 0;
- return srstAsserted;
-}
-
-static int zy1000_srst_asserted(int *srst_asserted)
-{
- *srst_asserted = readSRST();
- return ERROR_OK;
-}
-
-static int zy1000_power_dropout(int *dropout)
-{
- *dropout = readPowerDropout();
- return ERROR_OK;
-}
-
-/* Wait for SRST to assert or deassert */
-static void waitSRST(bool asserted)
-{
- bool first = true;
- int64_t start = 0;
- int64_t total = 0;
- const char *mode = asserted ? "assert" : "deassert";
-
- for (;; ) {
- bool srstAsserted = readSRST();
- if ((asserted && srstAsserted) || (!asserted && !srstAsserted)) {
- if (total > 1)
- LOG_USER("SRST took %dms to %s", (int)total, mode);
- break;
- }
-
- if (first) {
- first = false;
- start = timeval_ms();
- }
-
- total = timeval_ms() - start;
-
- keep_alive();
-
- if (total > 5000) {
- LOG_ERROR("SRST took too long to %s: %" PRId64 "ms", mode, total);
- break;
- }
- }
-}
-
-void zy1000_reset(int trst, int srst)
-{
- LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);
-
- /* flush the JTAG FIFO. Not flushing the queue before messing with
- * reset has such interesting bugs as causing hard to reproduce
- * RCLK bugs as RCLK will stop responding when TRST is asserted
- */
- waitIdle();
-
- if (!srst)
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x00000001);
- else {
- /* Danger!!! if clk != 0 when in
- * idle in TAP_IDLE, reset halt on str912 will fail.
- */
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000001);
-
- waitSRST(true);
- }
-
- if (!trst)
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x00000002);
- else {
- /* assert reset */
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000002);
- }
-
- if (trst || (srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) {
- /* we're now in the RESET state until trst is deasserted */
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_RESET);
- } else {
- /* We'll get RCLK failure when we assert TRST, so clear any false positives here */
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x400);
- }
-
- /* wait for srst to float back up */
- if ((!srst && ((jtag_get_reset_config() & RESET_TRST_PULLS_SRST) == 0)) ||
- (!srst && !trst && (jtag_get_reset_config() & RESET_TRST_PULLS_SRST)))
- waitSRST(false);
-}
-
-int zy1000_speed(int speed)
-{
- /* flush JTAG master FIFO before setting speed */
- waitIdle();
-
- zy1000_rclk = false;
-
- if (speed == 0) {
- /*0 means RCLK*/
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x100);
- zy1000_rclk = true;
- LOG_DEBUG("jtag_speed using RCLK");
- } else {
- if (speed > 8190 || speed < 2) {
- LOG_USER(
- "valid ZY1000 jtag_speed=[8190,2]. With divisor is %dkHz / even values between 8190-2, i.e. min %dHz, max %dMHz",
- ZYLIN_KHZ,
- (ZYLIN_KHZ * 1000) / 8190,
- ZYLIN_KHZ / (2 * 1000));
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- int khz;
- speed &= ~1;
- zy1000_speed_div(speed, &khz);
- LOG_USER("jtag_speed %d => JTAG clk=%d kHz", speed, khz);
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x100);
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x1c, speed);
- }
- return ERROR_OK;
-}
-
-static bool savePower;
-
-static void setPower(bool power)
-{
- savePower = power;
- if (power)
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x8);
- else
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x8);
-}
-
-COMMAND_HANDLER(handle_power_command)
-{
- switch (CMD_ARGC) {
- case 1: {
- bool enable;
- COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable);
- setPower(enable);
- }
- /* fall through */
- case 0:
- LOG_INFO("Target power %s", savePower ? "on" : "off");
- break;
- default:
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- return ERROR_OK;
-}
-
-#if !BUILD_ZY1000_MASTER
-static char *tcp_server = "notspecified";
-static int jim_zy1000_server(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
-{
- if (argc != 2)
- return JIM_ERR;
-
- tcp_server = strdup(Jim_GetString(argv[1], NULL));
-
- return JIM_OK;
-}
-#endif
-
-static int zylinjtag_Jim_Command_powerstatus(Jim_Interp *interp,
- int argc,
- Jim_Obj * const *argv)
-{
- if (argc != 1) {
- Jim_WrongNumArgs(interp, 1, argv, "powerstatus");
- return JIM_ERR;
- }
-
- bool dropout = readPowerDropout();
-
- Jim_SetResult(interp, Jim_NewIntObj(interp, dropout));
-
- return JIM_OK;
-}
-
-int zy1000_quit(void)
-{
-
- return ERROR_OK;
-}
-
-int interface_jtag_execute_queue(void)
-{
- uint32_t empty;
-
- waitIdle();
-
- /* We must make sure to write data read back to memory location before we return
- * from this fn
- */
- zy1000_flush_readqueue();
-
- /* and handle any callbacks... */
- zy1000_flush_callbackqueue();
-
- if (zy1000_rclk) {
- /* Only check for errors when using RCLK to speed up
- * jtag over TCP/IP
- */
- ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, empty);
- /* clear JTAG error register */
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x400);
-
- if ((empty&0x400) != 0) {
- LOG_WARNING("RCLK timeout");
- /* the error is informative only as we don't want to break the firmware if there
- * is a false positive.
- */
- /* return ERROR_FAIL; */
- }
- }
- return ERROR_OK;
-}
-
-static void writeShiftValue(uint8_t *data, int bits);
-
-/* here we shuffle N bits out/in */
-static inline void scanBits(const uint8_t *out_value,
- uint8_t *in_value,
- int num_bits,
- bool pause_now,
- tap_state_t shiftState,
- tap_state_t end_state)
-{
- tap_state_t pause_state = shiftState;
- for (int j = 0; j < num_bits; j += 32) {
- int k = num_bits - j;
- if (k > 32) {
- k = 32;
- /* we have more to shift out */
- } else if (pause_now) {
- /* this was the last to shift out this time */
- pause_state = end_state;
- }
-
- /* we have (num_bits + 7)/8 bytes of bits to toggle out. */
- /* bits are pushed out LSB to MSB */
- uint32_t value;
- value = 0;
- if (out_value != NULL) {
- for (int l = 0; l < k; l += 8)
- value |= out_value[(j + l)/8]<<l;
- }
- /* mask away unused bits for easier debugging */
- if (k < 32)
- value &= ~(((uint32_t)0xffffffff) << k);
- else {
- /* Shifting by >= 32 is not defined by the C standard
- * and will in fact shift by &0x1f bits on nios */
- }
-
- shiftValueInner(shiftState, pause_state, k, value);
-
- if (in_value != NULL)
- writeShiftValue(in_value + (j/8), k);
- }
-}
-
-static inline void scanFields(int num_fields,
- const struct scan_field *fields,
- tap_state_t shiftState,
- tap_state_t end_state)
-{
- for (int i = 0; i < num_fields; i++) {
- scanBits(fields[i].out_value,
- fields[i].in_value,
- fields[i].num_bits,
- (i == num_fields-1),
- shiftState,
- end_state);
- }
-}
-
-int interface_jtag_add_ir_scan(struct jtag_tap *active,
- const struct scan_field *fields,
- tap_state_t state)
-{
- int scan_size = 0;
- struct jtag_tap *tap, *nextTap;
- tap_state_t pause_state = TAP_IRSHIFT;
-
- for (tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = nextTap) {
- nextTap = jtag_tap_next_enabled(tap);
- if (nextTap == NULL)
- pause_state = state;
- scan_size = tap->ir_length;
-
- /* search the list */
- if (tap == active) {
- scanFields(1, fields, TAP_IRSHIFT, pause_state);
- /* update device information */
- buf_cpy(fields[0].out_value, tap->cur_instr, scan_size);
-
- tap->bypass = 0;
- } else {
- /* if a device isn't listed, set it to BYPASS */
- assert(scan_size <= 32);
- shiftValueInner(TAP_IRSHIFT, pause_state, scan_size, 0xffffffff);
-
- /* Optimization code will check what the cur_instr is set to, so
- * we must set it to bypass value.
- */
- buf_set_ones(tap->cur_instr, tap->ir_length);
-
- tap->bypass = 1;
- }
- }
-
- return ERROR_OK;
-}
-
-int interface_jtag_add_plain_ir_scan(int num_bits,
- const uint8_t *out_bits,
- uint8_t *in_bits,
- tap_state_t state)
-{
- scanBits(out_bits, in_bits, num_bits, true, TAP_IRSHIFT, state);
- return ERROR_OK;
-}
-
-int interface_jtag_add_dr_scan(struct jtag_tap *active,
- int num_fields,
- const struct scan_field *fields,
- tap_state_t state)
-{
- struct jtag_tap *tap, *nextTap;
- tap_state_t pause_state = TAP_DRSHIFT;
- for (tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = nextTap) {
- nextTap = jtag_tap_next_enabled(tap);
- if (nextTap == NULL)
- pause_state = state;
-
- /* Find a range of fields to write to this tap */
- if (tap == active) {
- assert(!tap->bypass);
-
- scanFields(num_fields, fields, TAP_DRSHIFT, pause_state);
- } else {
- /* Shift out a 0 for disabled tap's */
- assert(tap->bypass);
- shiftValueInner(TAP_DRSHIFT, pause_state, 1, 0);
- }
- }
- return ERROR_OK;
-}
-
-int interface_jtag_add_plain_dr_scan(int num_bits,
- const uint8_t *out_bits,
- uint8_t *in_bits,
- tap_state_t state)
-{
- scanBits(out_bits, in_bits, num_bits, true, TAP_DRSHIFT, state);
- return ERROR_OK;
-}
-
-int interface_jtag_add_tlr(void)
-{
- setCurrentState(TAP_RESET);
- return ERROR_OK;
-}
-
-int interface_jtag_add_reset(int req_trst, int req_srst)
-{
- zy1000_reset(req_trst, req_srst);
- return ERROR_OK;
-}
-
-static int zy1000_jtag_add_clocks(int num_cycles, tap_state_t state, tap_state_t clockstate)
-{
- /* num_cycles can be 0 */
- setCurrentState(clockstate);
-
- /* execute num_cycles, 32 at the time. */
- int i;
- for (i = 0; i < num_cycles; i += 32) {
- int num;
- num = 32;
- if (num_cycles-i < num)
- num = num_cycles-i;
- shiftValueInner(clockstate, clockstate, num, 0);
- }
-
-#if !TEST_MANUAL()
- /* finish in end_state */
- setCurrentState(state);
-#else
- tap_state_t t = TAP_IDLE;
- /* test manual drive code on any target */
- int tms;
- uint8_t tms_scan = tap_get_tms_path(t, state);
- int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
-
- for (i = 0; i < tms_count; i++) {
- tms = (tms_scan >> i) & 1;
- waitIdle();
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms);
- }
- waitIdle();
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, state);
-#endif
-
- return ERROR_OK;
-}
-
-int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
-{
- return zy1000_jtag_add_clocks(num_cycles, state, TAP_IDLE);
-}
-
-int interface_jtag_add_clocks(int num_cycles)
-{
- return zy1000_jtag_add_clocks(num_cycles, cmd_queue_cur_state, cmd_queue_cur_state);
-}
-
-int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state)
-{
- /*wait for the fifo to be empty*/
- waitIdle();
-
- for (unsigned i = 0; i < num_bits; i++) {
- int tms;
-
- if (((seq[i/8] >> (i % 8)) & 1) == 0)
- tms = 0;
- else
- tms = 1;
-
- waitIdle();
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms);
- }
-
- waitIdle();
- if (state != TAP_INVALID)
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, state);
- else {
- /* this would be normal if
- * we are switching to SWD mode */
- }
- return ERROR_OK;
-}
-
-int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
-{
- int state_count;
- int tms = 0;
-
- state_count = 0;
-
- tap_state_t cur_state = cmd_queue_cur_state;
-
- uint8_t seq[16];
- memset(seq, 0, sizeof(seq));
- assert(num_states < (int)((sizeof(seq) * 8)));
-
- while (num_states) {
- if (tap_state_transition(cur_state, false) == path[state_count])
- tms = 0;
- else if (tap_state_transition(cur_state, true) == path[state_count])
- tms = 1;
- else {
- LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
- tap_state_name(cur_state), tap_state_name(path[state_count]));
- exit(-1);
- }
-
- seq[state_count/8] = seq[state_count/8] | (tms << (state_count % 8));
-
- cur_state = path[state_count];
- state_count++;
- num_states--;
- }
-
- return interface_add_tms_seq(state_count, seq, cur_state);
-}
-
-static void jtag_pre_post_bits(struct jtag_tap *tap, int *pre, int *post)
-{
- /* bypass bits before and after */
- int pre_bits = 0;
- int post_bits = 0;
-
- bool found = false;
- struct jtag_tap *cur_tap, *nextTap;
- for (cur_tap = jtag_tap_next_enabled(NULL); cur_tap != NULL; cur_tap = nextTap) {
- nextTap = jtag_tap_next_enabled(cur_tap);
- if (cur_tap == tap)
- found = true;
- else {
- if (found)
- post_bits++;
- else
- pre_bits++;
- }
- }
- *pre = pre_bits;
- *post = post_bits;
-}
-
-void embeddedice_write_dcc(struct jtag_tap *tap,
- int reg_addr,
- const uint8_t *buffer,
- int little,
- int count)
-{
-#if 0
- int i;
- for (i = 0; i < count; i++) {
- embeddedice_write_reg_inner(tap, reg_addr, fast_target_buffer_get_u32(buffer,
- little));
- buffer += 4;
- }
-#else
- int pre_bits;
- int post_bits;
- jtag_pre_post_bits(tap, &pre_bits, &post_bits);
-
- if ((pre_bits > 32) || (post_bits + 6 > 32)) {
- int i;
- for (i = 0; i < count; i++) {
- embeddedice_write_reg_inner(tap, reg_addr,
- fast_target_buffer_get_u32(buffer, little));
- buffer += 4;
- }
- } else {
- int i;
- for (i = 0; i < count; i++) {
- /* Fewer pokes means we get to use the FIFO more efficiently */
- shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, pre_bits, 0);
- shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32,
- fast_target_buffer_get_u32(buffer, little));
- /* Danger! here we need to exit into the TAP_IDLE state to make
- * DCC pick up this value.
- */
- shiftValueInner(TAP_DRSHIFT, TAP_IDLE, 6 + post_bits,
- (reg_addr | (1 << 5)));
- buffer += 4;
- }
- }
-#endif
-}
-
-int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap *tap,
- uint32_t opcode,
- uint32_t *data,
- size_t count)
-{
- /* bypass bits before and after */
- int pre_bits;
- int post_bits;
- jtag_pre_post_bits(tap, &pre_bits, &post_bits);
- post_bits += 2;
-
- if ((pre_bits > 32) || (post_bits > 32)) {
- int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap *tap,
- uint32_t opcode, uint32_t *data, size_t count);
- return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count);
- } else {
- static const uint8_t zero;
-
- /* FIX!!!!!! the target_write_memory() API started this nasty problem
- * with unaligned uint32_t * pointers... */
- const uint8_t *t = (const uint8_t *)data;
-
- while (--count > 0) {
-#if 1
- /* Danger! This code doesn't update cmd_queue_cur_state, so
- * invoking jtag_add_pathmove() before jtag_add_dr_scan() after
- * this loop would fail!
- */
- shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, pre_bits, 0);
-
- uint32_t value;
- value = *t++;
- value |= (*t++<<8);
- value |= (*t++<<16);
- value |= (*t++<<24);
-
- shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, value);
- /* minimum 2 bits */
- shiftValueInner(TAP_DRSHIFT, TAP_DRPAUSE, post_bits, 0);
-
- /* copy & paste from arm11_dbgtap.c */
- /* TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT,
- * TAP_DRCAPTURE, TAP_DRSHIFT */
- /* KLUDGE! we have to flush the fifo or the Nios CPU locks up.
- * This is probably a bug in the Avalon bus(cross clocking bridge?)
- * or in the jtag registers module.
- */
- waitIdle();
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1);
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1);
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1);
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
- /* we don't have to wait for the queue to empty here */
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT);
- waitIdle();
-#else
- static const tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] = {
- TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE,
- TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT
- };
-
- struct scan_field fields[2] = {
- { .num_bits = 32, .out_value = t },
- { .num_bits = 2, .out_value = &zero },
- };
- t += 4;
-
- jtag_add_dr_scan(tap,
- 2,
- fields,
- TAP_IDLE);
-
- jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay),
- arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay);
-#endif
- }
-
- struct scan_field fields[2] = {
- { .num_bits = 32, .out_value = t },
- { .num_bits = 2, .out_value = &zero },
- };
-
- /* This will happen on the last iteration updating cmd_queue_cur_state
- * so we don't have to track it during the common code path
- */
- jtag_add_dr_scan(tap,
- 2,
- fields,
- TAP_IDLE);
-
- return jtag_execute_queue();
- }
-}
-
-static const struct command_registration zy1000_commands[] = {
- {
- .name = "power",
- .handler = handle_power_command,
- .mode = COMMAND_ANY,
- .help = "Turn power switch to target on/off. "
- "With no arguments, prints status.",
- .usage = "('on'|'off)",
- },
-#if !BUILD_ZY1000_MASTER
- {
- .name = "zy1000_server",
- .mode = COMMAND_ANY,
- .jim_handler = jim_zy1000_server,
- .help = "Tcpip address for ZY1000 server.",
- .usage = "address",
- },
-#endif
- {
- .name = "powerstatus",
- .mode = COMMAND_ANY,
- .jim_handler = zylinjtag_Jim_Command_powerstatus,
- .help = "Returns power status of target",
- },
- COMMAND_REGISTRATION_DONE
-};
-
-#if !BUILD_ZY1000_MASTER
-
-static int tcp_ip = -1;
-
-/* Write large packets if we can */
-static size_t out_pos;
-static uint8_t out_buffer[16384];
-static size_t in_pos;
-static size_t in_write;
-static uint8_t in_buffer[16384];
-
-static bool flush_writes(void)
-{
- bool ok = (write(tcp_ip, out_buffer, out_pos) == (int)out_pos);
- out_pos = 0;
- return ok;
-}
-
-static bool writeLong(uint32_t l)
-{
- int i;
- for (i = 0; i < 4; i++) {
- uint8_t c = (l >> (i*8))&0xff;
- out_buffer[out_pos++] = c;
- if (out_pos >= sizeof(out_buffer)) {
- if (!flush_writes())
- return false;
- }
- }
- return true;
-}
-
-static bool readLong(uint32_t *out_data)
-{
- uint32_t data = 0;
- int i;
- for (i = 0; i < 4; i++) {
- uint8_t c;
- if (in_pos == in_write) {
- /* If we have some data that we can send, send them before
- * we wait for more data
- */
- if (out_pos > 0) {
- if (!flush_writes())
- return false;
- }
-
- /* read more */
- int t;
- t = read(tcp_ip, in_buffer, sizeof(in_buffer));
- if (t < 1)
- return false;
- in_write = (size_t) t;
- in_pos = 0;
- }
- c = in_buffer[in_pos++];
-
- data |= (c << (i*8));
- }
- *out_data = data;
- return true;
-}
-
-enum ZY1000_CMD {
- ZY1000_CMD_POKE = 0x0,
- ZY1000_CMD_PEEK = 0x8,
- ZY1000_CMD_SLEEP = 0x1,
- ZY1000_CMD_WAITIDLE = 2
-};
-
-#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
-#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
-
-/* We initialize this late since we need to know the server address
- * first.
- */
-static void tcpip_open(void)
-{
- if (tcp_ip >= 0)
- return;
-
- struct sockaddr_in echoServAddr;/* Echo server address */
-
- /* Create a reliable, stream socket using TCP */
- tcp_ip = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (tcp_ip < 0) {
- fprintf(stderr, "Failed to connect to zy1000 server\n");
- exit(-1);
- }
-
- /* Construct the server address structure */
- memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
- echoServAddr.sin_family = AF_INET; /* Internet address family */
- echoServAddr.sin_addr.s_addr = inet_addr(tcp_server); /* Server IP address */
- echoServAddr.sin_port = htons(7777); /* Server port */
-
- /* Establish the connection to the echo server */
- if (connect(tcp_ip, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) {
- fprintf(stderr, "Failed to connect to zy1000 server\n");
- exit(-1);
- }
-
- int flag = 1;
- setsockopt(tcp_ip, /* socket affected */
- IPPROTO_TCP, /* set option at TCP level */
- TCP_NODELAY, /* name of option */
- (char *)&flag, /* the cast is historical cruft */
- sizeof(int)); /* length of option value */
-
-}
-
-/* send a poke */
-void zy1000_tcpout(uint32_t address, uint32_t data)
-{
- tcpip_open();
- if (!writeLong((ZY1000_CMD_POKE << 24) | address) || !writeLong(data)) {
- fprintf(stderr, "Could not write to zy1000 server\n");
- exit(-1);
- }
-}
-
-/* By sending the wait to the server, we avoid a readback
- * of status. Radically improves performance for this operation
- * with long ping times.
- */
-void waitIdle(void)
-{
- tcpip_open();
- if (!writeLong((ZY1000_CMD_WAITIDLE << 24))) {
- fprintf(stderr, "Could not write to zy1000 server\n");
- exit(-1);
- }
-}
-
-uint32_t zy1000_tcpin(uint32_t address)
-{
- tcpip_open();
-
- zy1000_flush_readqueue();
-
- uint32_t data;
- if (!writeLong((ZY1000_CMD_PEEK << 24) | address) || !readLong(&data)) {
- fprintf(stderr, "Could not read from zy1000 server\n");
- exit(-1);
- }
- return data;
-}
-
-int interface_jtag_add_sleep(uint32_t us)
-{
- tcpip_open();
- if (!writeLong((ZY1000_CMD_SLEEP << 24)) || !writeLong(us)) {
- fprintf(stderr, "Could not read from zy1000 server\n");
- exit(-1);
- }
- return ERROR_OK;
-}
-
-/* queue a readback */
-#define readqueue_size 16384
-static struct {
- uint8_t *dest;
- int bits;
-} readqueue[readqueue_size];
-
-static int readqueue_pos;
-
-/* flush the readqueue, this means reading any data that
- * we're expecting and store them into the final position
- */
-void zy1000_flush_readqueue(void)
-{
- if (readqueue_pos == 0) {
- /* simply debugging by allowing easy breakpoints when there
- * is something to do. */
- return;
- }
- int i;
- tcpip_open();
- for (i = 0; i < readqueue_pos; i++) {
- uint32_t value;
- if (!readLong(&value)) {
- fprintf(stderr, "Could not read from zy1000 server\n");
- exit(-1);
- }
-
- uint8_t *in_value = readqueue[i].dest;
- int k = readqueue[i].bits;
-
- /* we're shifting in data to MSB, shift data to be aligned for returning the value */
- value >>= 32-k;
-
- for (int l = 0; l < k; l += 8)
- in_value[l/8] = (value >> l)&0xff;
- }
- readqueue_pos = 0;
-}
-
-/* By queuing the callback's we avoid flushing the
- * read queue until jtag_execute_queue(). This can
- * reduce latency dramatically for cases where
- * callbacks are used extensively.
-*/
-#define callbackqueue_size 128
-static struct callbackentry {
- jtag_callback_t callback;
- jtag_callback_data_t data0;
- jtag_callback_data_t data1;
- jtag_callback_data_t data2;
- jtag_callback_data_t data3;
-} callbackqueue[callbackqueue_size];
-
-static int callbackqueue_pos;
-
-void zy1000_jtag_add_callback4(jtag_callback_t callback,
- jtag_callback_data_t data0,
- jtag_callback_data_t data1,
- jtag_callback_data_t data2,
- jtag_callback_data_t data3)
-{
- if (callbackqueue_pos >= callbackqueue_size)
- zy1000_flush_callbackqueue();
-
- callbackqueue[callbackqueue_pos].callback = callback;
- callbackqueue[callbackqueue_pos].data0 = data0;
- callbackqueue[callbackqueue_pos].data1 = data1;
- callbackqueue[callbackqueue_pos].data2 = data2;
- callbackqueue[callbackqueue_pos].data3 = data3;
- callbackqueue_pos++;
-
- /* KLUDGE!
- * make callbacks synchronous for now as minidriver requires callback
- * to be synchronous.
- *
- * We can get away with making read and writes asynchronous so we
- * don't completely kill performance.
- */
- zy1000_flush_callbackqueue();
-}
-
-static int zy1000_jtag_convert_to_callback4(jtag_callback_data_t data0,
- jtag_callback_data_t data1,
- jtag_callback_data_t data2,
- jtag_callback_data_t data3)
-{
- ((jtag_callback1_t)data1)(data0);
- return ERROR_OK;
-}
-
-void zy1000_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0)
-{
- zy1000_jtag_add_callback4(zy1000_jtag_convert_to_callback4,
- data0,
- (jtag_callback_data_t)callback,
- 0,
- 0);
-}
-
-void zy1000_flush_callbackqueue(void)
-{
- /* we have to flush the read queue so we have access to
- the data the callbacks will use
- */
- zy1000_flush_readqueue();
- int i;
- for (i = 0; i < callbackqueue_pos; i++) {
- struct callbackentry *entry = &callbackqueue[i];
- jtag_set_error(entry->callback(entry->data0, entry->data1, entry->data2,
- entry->data3));
- }
- callbackqueue_pos = 0;
-}
-
-static void writeShiftValue(uint8_t *data, int bits)
-{
- waitIdle();
-
- if (!writeLong((ZY1000_CMD_PEEK << 24) | (ZY1000_JTAG_BASE + 0xc))) {
- fprintf(stderr, "Could not read from zy1000 server\n");
- exit(-1);
- }
-
- if (readqueue_pos >= readqueue_size)
- zy1000_flush_readqueue();
-
- readqueue[readqueue_pos].dest = data;
- readqueue[readqueue_pos].bits = bits;
- readqueue_pos++;
-
- /* KLUDGE!!! minidriver requires readqueue to be synchronous */
- zy1000_flush_readqueue();
-}
-
-#else
-
-static void writeShiftValue(uint8_t *data, int bits)
-{
- uint32_t value;
- waitIdle();
- ZY1000_PEEK(ZY1000_JTAG_BASE + 0xc, value);
- VERBOSE(LOG_INFO("getShiftValue %08x", value));
-
- /* data in, LSB to MSB */
- /* we're shifting in data to MSB, shift data to be aligned for returning the value */
- value >>= 32 - bits;
-
- for (int l = 0; l < bits; l += 8)
- data[l/8] = (value >> l)&0xff;
-}
-
-#endif
-
-#if BUILD_ZY1000_MASTER
-
-#ifdef WATCHDOG_BASE
-/* If we connect to port 8888 we must send a char every 10s or the board resets itself */
-static void watchdog_server(cyg_addrword_t data)
-{
- int so_reuseaddr_option = 1;
-
- int fd = socket(AF_INET, SOCK_STREAM, 0);
- if (fd == -1) {
- LOG_ERROR("error creating socket: %s", strerror(errno));
- exit(-1);
- }
-
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &so_reuseaddr_option,
- sizeof(int));
-
- struct sockaddr_in sin;
- unsigned int address_size;
- address_size = sizeof(sin);
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = INADDR_ANY;
- sin.sin_port = htons(8888);
-
- if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1) {
- LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
- exit(-1);
- }
-
- if (listen(fd, 1) == -1) {
- LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
- exit(-1);
- }
-
-
- for (;; ) {
- int watchdog_ip = accept(fd, (struct sockaddr *) &sin, &address_size);
-
- /* Start watchdog, must be reset every 10 seconds. */
- HAL_WRITE_UINT32(WATCHDOG_BASE + 4, 4);
-
- if (watchdog_ip < 0) {
- LOG_ERROR("couldn't open watchdog socket: %s", strerror(errno));
- exit(-1);
- }
-
- int flag = 1;
- setsockopt(watchdog_ip, /* socket affected */
- IPPROTO_TCP, /* set option at TCP level */
- TCP_NODELAY, /* name of option */
- (char *)&flag, /* the cast is historical cruft */
- sizeof(int)); /* length of option value */
-
-
- char buf;
- for (;; ) {
- if (read(watchdog_ip, &buf, 1) == 1) {
- /* Reset timer */
- HAL_WRITE_UINT32(WATCHDOG_BASE + 8, 0x1234);
- /* Echo so we can telnet in and see that resetting works */
- write(watchdog_ip, &buf, 1);
- } else {
- /* Stop tickling the watchdog, the CPU will reset in < 10 seconds
- * now.
- */
- return;
- }
-
- }
-
- /* Never reached */
- }
-}
-#endif
-
-#endif
-
-#if BUILD_ZY1000_MASTER
-int interface_jtag_add_sleep(uint32_t us)
-{
- jtag_sleep(us);
- return ERROR_OK;
-}
-#endif
-
-#if BUILD_ZY1000_MASTER
-volatile void *zy1000_jtag_master;
-#include <sys/mman.h>
-#endif
-
-int zy1000_init(void)
-{
-#if BUILD_ZY1000_MASTER
- int fd = open("/dev/mem", O_RDWR | O_SYNC);
- if (fd == -1) {
- LOG_ERROR("No access to /dev/mem");
- return ERROR_FAIL;
- }
-#ifndef REGISTERS_BASE
-#define REGISTERS_BASE 0x9002000
-#define REGISTERS_SPAN 128
-#endif
-
- zy1000_jtag_master = mmap(0,
- REGISTERS_SPAN,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- fd,
- REGISTERS_BASE);
-
- if (zy1000_jtag_master == (void *) -1) {
- close(fd);
- LOG_ERROR("No access to /dev/mem");
- return ERROR_FAIL;
- }
-#endif
-
- ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x30); /* Turn on LED1 & LED2 */
-
- setPower(true); /* on by default */
-
- /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
- zy1000_reset(0, 0);
-
- return ERROR_OK;
-}
-
-static struct jtag_interface zy1000_interface = {
- .supported = DEBUG_CAP_TMS_SEQ,
- .execute_queue = NULL,
-};
-
-struct adapter_driver zy1000_adapter_driver = {
- .name = "ZY1000",
- .transports = jtag_only,
- .commands = zy1000_commands,
-
- .init = zy1000_init,
- .quit = zy1000_quit,
- .speed = zy1000_speed,
- .khz = zy1000_khz,
- .speed_div = zy1000_speed_div,
- .power_dropout = zy1000_power_dropout,
- .srst_asserted = zy1000_srst_asserted,
-
- .jtag_ops = &zy1000_interface,
-};
diff --git a/tcl/board/zy1000.cfg b/tcl/board/zy1000.cfg
deleted file mode 100644
index e0d1ccf..0000000
--- a/tcl/board/zy1000.cfg
+++ /dev/null
@@ -1,117 +0,0 @@
-#Script for ZY1000
-
-#Atmel ties SRST & TRST together, at which point it makes
-#no sense to use TRST, but use TMS instead.
-#
-#The annoying thing with tying SRST & TRST together is that
-#there is no way to halt the CPU *before and during* the
-#SRST reset, which means that the CPU will run a number
-#of cycles before it can be halted(as much as milliseconds).
-reset_config srst_only srst_pulls_trst
-
-
-if { [info exists CHIPNAME] } {
- set _CHIPNAME $CHIPNAME
-} else {
- set _CHIPNAME zy1000
-}
-
-if { [info exists ENDIAN] } {
- set _ENDIAN $ENDIAN
-} else {
- set _ENDIAN little
-}
-
-
-#jtag scan chain
-if { [info exists CPUTAPID] } {
- set _CPUTAPID $CPUTAPID
-} else {
- set _CPUTAPID 0x1f0f0f0f
-}
-jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
-
-set _TARGETNAME $_CHIPNAME.cpu
-target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME
-
-# at CPU CLK <32kHz this must be disabled
-arm7_9 fast_memory_access enable
-arm7_9 dcc_downloads enable
-
-set _FLASHNAME $_CHIPNAME.flash
-flash bank $_FLASHNAME cfi 0x01000000 0x200000 2 2 $_TARGETNAME
-
-$_TARGETNAME configure -event reset-init {
- # Set up chip selects & timings
- mww 0xFFE00000 0x0100273D
- mww 0xFFE00004 0x08002125
- mww 0xFFEe0008 0x02002125
- mww 0xFFE0000c 0x03002125
- mww 0xFFE00010 0x40000000
- mww 0xFFE00014 0x50000000
- mww 0xFFE00018 0x60000000
- mww 0xFFE0001c 0x70000000
- mww 0xFFE00020 0x00000001
- mww 0xFFE00024 0x00000000
-
- # remap
- mww 0xFFFFF124 0xFFFFFFFF
- mww 0xffff0010 0x100
- mww 0xffff0034 0x100
-
- #disable 16x5x UART interrupts
- mww 0x08020004 0
-}
-
-$_TARGETNAME configure -event gdb-attach {
- # Without this gdb-attach will first time as probe will fail
- reset init
-}
-
-# required for usable performance. Used for lots of
-# other things than flash programming.
-$_TARGETNAME configure -work-area-phys 0x00020000 -work-area-size 0x20000 -work-area-backup 0
-
-adapter speed 16000
-
-
-proc production_info {} {
- return "Serial number is official MAC number. Format XXXXXXXXXXXX"
-}
-
-# There is no return value from this procedure. If it is
-# successful it does not throw an exception
-#
-# Progress messages are output via puts
-proc production {firmwarefile serialnumber} {
- if {[string length $serialnumber]!=12} {
- echo "Invalid serial number"
- return
- }
-
- echo "Power cycling target"
- power off
- sleep 3000
- power on
- sleep 1000
- reset init
- flash write_image erase $firmwarefile 0x1000000 bin
- verify_image $firmwarefile 0x1000000 bin
-
- # Big endian... weee!!!!
- echo "Setting MAC number to $serialnumber"
- flash fillw [expr 0x1030000-0x8] "0x[string range $serialnumber 2 3][string range $serialnumber 0 1]0000" 1
- flash fillw [expr 0x1030000-0x4] "0x[string range $serialnumber 10 11][string range $serialnumber 8 9][string range $serialnumber 6 7][string range $serialnumber 4 5]" 1
- echo "Production successful"
-}
-
-
-proc production_test {} {
- power on
- sleep 1000
- target_request debugmsgs enable
- reset run
- sleep 25000
- target_request debugmsgs disable
- return "See IP address above..."
-}