From 38c56c7c1fe4ecd7e5907cc14c100e4af3a87e20 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Wed, 1 Jan 2014 18:05:16 -0600 Subject: Add initial version of SVF player for Beaglebone Black --- fpga/xilinx/programmer/svfplayer/Makefile | 47 -- .../programmer/svfplayer/beaglebone_black/Makefile | 47 ++ .../svfplayer/beaglebone_black/xsvf-bbb.c | 546 +++++++++++++++++++++ .../programmer/svfplayer/raspberry_pi/Makefile | 47 ++ .../programmer/svfplayer/raspberry_pi/xsvf-rpi.c | 530 ++++++++++++++++++++ fpga/xilinx/programmer/svfplayer/xsvf-rpi.c | 530 -------------------- 6 files changed, 1170 insertions(+), 577 deletions(-) delete mode 100644 fpga/xilinx/programmer/svfplayer/Makefile create mode 100644 fpga/xilinx/programmer/svfplayer/beaglebone_black/Makefile create mode 100644 fpga/xilinx/programmer/svfplayer/beaglebone_black/xsvf-bbb.c create mode 100644 fpga/xilinx/programmer/svfplayer/raspberry_pi/Makefile create mode 100644 fpga/xilinx/programmer/svfplayer/raspberry_pi/xsvf-rpi.c delete mode 100644 fpga/xilinx/programmer/svfplayer/xsvf-rpi.c (limited to 'fpga/xilinx/programmer/svfplayer') diff --git a/fpga/xilinx/programmer/svfplayer/Makefile b/fpga/xilinx/programmer/svfplayer/Makefile deleted file mode 100644 index 176b0a3..0000000 --- a/fpga/xilinx/programmer/svfplayer/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (C) 2012 Timothy Pearson -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -AR = ar -RANLIB = ranlib -CC = gcc - -CFLAGS += -Wall -Os -ggdb -MD -#CFLAGS += -Wextra -Wno-unused-parameter -Werror - -help: - @echo "" - @echo "Usage:" - @echo "" - @echo " $(MAKE) xsvf-rpi" - @echo " .... build xsvf-rpi" - @echo "" - @echo " $(MAKE) all" - @echo " .... build everything" - @echo "" - @echo " $(MAKE) install" - @echo " .... install everything in /usr/" - @echo "" - -all: xsvf-rpi - -install: all - install -Dt /usr/bin/ xsvf-rpi - -xsvf-rpi: /usr/lib/libxsvf.a xsvf-rpi.o - -clean: - rm -f xsvf-rpi.o - --include *.d - diff --git a/fpga/xilinx/programmer/svfplayer/beaglebone_black/Makefile b/fpga/xilinx/programmer/svfplayer/beaglebone_black/Makefile new file mode 100644 index 0000000..5a5701e --- /dev/null +++ b/fpga/xilinx/programmer/svfplayer/beaglebone_black/Makefile @@ -0,0 +1,47 @@ +# Copyright (C) 2013 Timothy Pearson +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +AR = ar +RANLIB = ranlib +CC = gcc + +CFLAGS += -Wall -Os -ggdb -MD +#CFLAGS += -Wextra -Wno-unused-parameter -Werror + +help: + @echo "" + @echo "Usage:" + @echo "" + @echo " $(MAKE) xsvf-bbb" + @echo " .... build xsvf-bbb" + @echo "" + @echo " $(MAKE) all" + @echo " .... build everything" + @echo "" + @echo " $(MAKE) install" + @echo " .... install everything in /usr/" + @echo "" + +all: xsvf-bbb + +install: all + install -Dt /usr/bin/ xsvf-bbb + +xsvf-bbb: /usr/lib/libxsvf.a xsvf-bbb.o + +clean: + rm -f xsvf-bbb.o + +-include *.d + diff --git a/fpga/xilinx/programmer/svfplayer/beaglebone_black/xsvf-bbb.c b/fpga/xilinx/programmer/svfplayer/beaglebone_black/xsvf-bbb.c new file mode 100644 index 0000000..3b314af --- /dev/null +++ b/fpga/xilinx/programmer/svfplayer/beaglebone_black/xsvf-bbb.c @@ -0,0 +1,546 @@ +/* + * Lib(X)SVF - A library for implementing SVF and XSVF JTAG players + * + * Copyright (C) 2013 Timothy Pearson (Beaglebone Black) + * Copyright (C) 2009 RIEGL Research ForschungsGmbH + * Copyright (C) 2009 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "libxsvf.h" + +#include +#include +#include +#include +#include +#include + + +/** BEGIN: Low-Level I/O Implementation **/ + +// Beaglebone Black GPIO driver +// TMS: P9 11 (GPIO 30) +// TDI: P9 13 (GPIO 31) +// TDO: P9 21 (GPIO 3) +// TCK: P9 22 (GPIO 2) + +#include +#include +#include +#include + +#define GPIO0_BASE 0x44E07000 +#define GPIO1_BASE 0x4804C000 +#define GPIO2_BASE 0x481AC000 +#define GPIO3_BASE 0x481AE000 + +#define GPIO_SIZE 0x00000FFF + +// OE: 0 is output, 1 is input +#define GPIO_OE 0x14d +#define GPIO_IN 0x14e +#define GPIO_OUT 0x14f + +#define TMS_PIN (1<<30) +#define TDI_PIN (1<<31) +#define TDO_PIN (1<<3) +#define TCK_PIN (1<<2) + +int mem_fd; +char *gpio_mem, *gpio_map; + +// I/O access +volatile unsigned *gpio; + +static void io_setup(void) +{ + // Enable all GPIO banks + // Without this, access to deactivated banks (i.e. those with no clock source setup) will (logically) fail with SIGBUS + // Idea taken from https://groups.google.com/forum/#!msg/beagleboard/OYFp4EXawiI/Mq6s3sg14HoJ + system("echo 5 > /sys/class/gpio/export"); + system("echo 65 > /sys/class/gpio/export"); + system("echo 105 > /sys/class/gpio/export"); + + /* open /dev/mem */ + if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { + printf("can't open /dev/mem \n"); + exit (-1); + } + + /* mmap GPIO */ + gpio_map = (char *)mmap( + 0, + GPIO_SIZE, + PROT_READ|PROT_WRITE, + MAP_SHARED, + mem_fd, + GPIO0_BASE + ); + + if (gpio_map == MAP_FAILED) { + printf("mmap error %d\n", (int)gpio_map); + exit (-1); + } + + // Always use volatile pointer! + gpio = (volatile unsigned *)gpio_map; + +#if 0 + // DEBUG ONLY + // Prints the contents of the memory mapped control register space + // Originally used to reverse engineer the register offsets #defined at the top of this file + int k; + for (k=0;kuser_data; + if (u->verbose >= 2) { + fprintf(stderr, "[SETUP]\n"); + fflush(stderr); + } + io_setup(); + return 0; +} + +static int h_shutdown(struct libxsvf_host *h) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 2) { + fprintf(stderr, "[SHUTDOWN]\n"); + fflush(stderr); + } + io_shutdown(); + return 0; +} + +static void h_udelay(struct libxsvf_host *h, long usecs, int tms, long num_tck) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 3) { + fprintf(stderr, "[DELAY:%ld, TMS:%d, NUM_TCK:%ld]\n", usecs, tms, num_tck); + fflush(stderr); + } + if (num_tck > 0) { + struct timeval tv1, tv2; + gettimeofday(&tv1, NULL); + io_tms(tms); + while (num_tck > 0) { + io_tck(0); + io_tck(1); + num_tck--; + } + gettimeofday(&tv2, NULL); + if (tv2.tv_sec > tv1.tv_sec) { + usecs -= (1000000 - tv1.tv_usec) + (tv2.tv_sec - tv1.tv_sec - 1) * 1000000; + tv1.tv_usec = 0; + } + usecs -= tv2.tv_usec - tv1.tv_usec; + if (u->verbose >= 3) { + fprintf(stderr, "[DELAY_AFTER_TCK:%ld]\n", usecs > 0 ? usecs : 0); + fflush(stderr); + } + } + if (usecs > 0) { + usleep(usecs); + } +} + +static int h_getbyte(struct libxsvf_host *h) +{ + struct udata_s *u = h->user_data; + return fgetc(u->f); +} + +static int h_pulse_tck(struct libxsvf_host *h, int tms, int tdi, int tdo, int rmask, int sync) +{ + struct udata_s *u = h->user_data; + + io_tms(tms); + + if (tdi >= 0) { + u->bitcount_tdi++; + io_tdi(tdi); + } + + io_tck(0); + io_tck(1); + + int line_tdo = io_tdo(); + int rc = line_tdo >= 0 ? line_tdo : 0; + + if (rmask == 1 && u->retval_i < 256) + u->retval[u->retval_i++] = line_tdo; + + if (tdo >= 0 && line_tdo >= 0) { + u->bitcount_tdo++; + if (tdo != line_tdo) + rc = -1; + } + + if (u->verbose >= 4) { + fprintf(stderr, "[TMS:%d, TDI:%d, TDO_ARG:%d, TDO_LINE:%d, RMASK:%d, RC:%d]\n", tms, tdi, tdo, line_tdo, rmask, rc); + } + + u->clockcount++; + return rc; +} + +static void h_pulse_sck(struct libxsvf_host *h) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 4) { + fprintf(stderr, "[SCK]\n"); + } + io_sck(0); + io_sck(1); +} + +static void h_set_trst(struct libxsvf_host *h, int v) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 4) { + fprintf(stderr, "[TRST:%d]\n", v); + } + io_trst(v); +} + +static int h_set_frequency(struct libxsvf_host *h, int v) +{ + fprintf(stderr, "WARNING: Setting JTAG clock frequency to %d ignored!\n", v); + return 0; +} + +static void h_report_tapstate(struct libxsvf_host *h) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 3) { + fprintf(stderr, "[%s]\n", libxsvf_state2str(h->tap_state)); + } +} + +static void h_report_device(struct libxsvf_host *h, unsigned long idcode) +{ + // struct udata_s *u = h->user_data; + printf("idcode=0x%08lx, revision=0x%01lx, part=0x%04lx, manufactor=0x%03lx\n", idcode, + (idcode >> 28) & 0xf, (idcode >> 12) & 0xffff, (idcode >> 1) & 0x7ff); +} + +static void h_report_status(struct libxsvf_host *h, const char *message) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 2) { + fprintf(stderr, "[STATUS] %s\n", message); + } +} + +static void h_report_error(struct libxsvf_host *h, const char *file, int line, const char *message) +{ + fprintf(stderr, "[%s:%d] %s\n", file, line, message); +} + +static int realloc_maxsize[LIBXSVF_MEM_NUM]; + +static void *h_realloc(struct libxsvf_host *h, void *ptr, int size, enum libxsvf_mem which) +{ + struct udata_s *u = h->user_data; + if (size > realloc_maxsize[which]) + realloc_maxsize[which] = size; + if (u->verbose >= 3) { + fprintf(stderr, "[REALLOC:%s:%d]\n", libxsvf_mem2str(which), size); + } + return realloc(ptr, size); +} + +static struct udata_s u; + +static struct libxsvf_host h = { + .udelay = h_udelay, + .setup = h_setup, + .shutdown = h_shutdown, + .getbyte = h_getbyte, + .pulse_tck = h_pulse_tck, + .pulse_sck = h_pulse_sck, + .set_trst = h_set_trst, + .set_frequency = h_set_frequency, + .report_tapstate = h_report_tapstate, + .report_device = h_report_device, + .report_status = h_report_status, + .report_error = h_report_error, + .realloc = h_realloc, + .user_data = &u +}; + +const char *progname; + +static void copyleft() +{ + static int already_printed = 0; + if (already_printed) + return; + fprintf(stderr, "xsvftool-gpio, part of Lib(X)SVF (http://www.clifford.at/libxsvf/).\n"); + fprintf(stderr, "Copyright (C) 2009 RIEGL Research ForschungsGmbH\n"); + fprintf(stderr, "Copyright (C) 2009 Clifford Wolf \n"); + fprintf(stderr, "Copyright (C) 2013 Timothy Pearson (Beaglebone Black)\n"); + fprintf(stderr, "Lib(X)SVF is free software licensed under the ISC license.\n"); + already_printed = 1; +} + +static void help() +{ + copyleft(); + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: %s [ -r funcname ] [ -v ... ] [ -L | -B ] { -s svf-file | -x xsvf-file | -c } ...\n", progname); + fprintf(stderr, "\n"); + fprintf(stderr, " -r funcname\n"); + fprintf(stderr, " Dump C-code for pseudo-allocator based on example files\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -v, -vv, -vvv, -vvvv\n"); + fprintf(stderr, " Verbose, more verbose and even more verbose\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -L, -B\n"); + fprintf(stderr, " Print RMASK bits as hex value (little or big endian)\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -s svf-file\n"); + fprintf(stderr, " Play the specified SVF file\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -x xsvf-file\n"); + fprintf(stderr, " Play the specified XSVF file\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -c\n"); + fprintf(stderr, " List devices in JTAG chain\n"); + fprintf(stderr, "\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + int rc = 0; + int gotaction = 0; + int hex_mode = 0; + const char *realloc_name = NULL; + int opt, i, j; + + progname = argc >= 1 ? argv[0] : "xvsftool"; + while ((opt = getopt(argc, argv, "r:vLBx:s:c")) != -1) + { + switch (opt) + { + case 'r': + realloc_name = optarg; + break; + case 'v': + copyleft(); + u.verbose++; + break; + case 'x': + case 's': + gotaction = 1; + if (u.verbose) + fprintf(stderr, "Playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg); + if (!strcmp(optarg, "-")) + u.f = stdin; + else + u.f = fopen(optarg, "rb"); + if (u.f == NULL) { + fprintf(stderr, "Can't open %s file `%s': %s\n", opt == 's' ? "SVF" : "XSVF", optarg, strerror(errno)); + rc = 1; + break; + } + if (libxsvf_play(&h, opt == 's' ? LIBXSVF_MODE_SVF : LIBXSVF_MODE_XSVF) < 0) { + fprintf(stderr, "Error while playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg); + rc = 1; + } + if (strcmp(optarg, "-")) + fclose(u.f); + break; + case 'c': + gotaction = 1; + if (libxsvf_play(&h, LIBXSVF_MODE_SCAN) < 0) { + fprintf(stderr, "Error while scanning JTAG chain.\n"); + rc = 1; + } + break; + case 'L': + hex_mode = 1; + break; + case 'B': + hex_mode = 2; + break; + default: + help(); + break; + } + } + + if (!gotaction) + help(); + + if (u.verbose) { + fprintf(stderr, "Total number of clock cycles: %d\n", u.clockcount); + fprintf(stderr, "Number of significant TDI bits: %d\n", u.bitcount_tdi); + fprintf(stderr, "Number of significant TDO bits: %d\n", u.bitcount_tdo); + if (rc == 0) { + fprintf(stderr, "Finished without errors.\n"); + } else { + fprintf(stderr, "Finished with errors!\n"); + } + } + + if (u.retval_i) { + if (hex_mode) { + printf("0x"); + for (i=0; i < u.retval_i; i+=4) { + int val = 0; + for (j=i; j 1 ? j : u.retval_i - j - 1]; + printf("%x", val); + } + } else { + printf("%d rmask bits:", u.retval_i); + for (i=0; i < u.retval_i; i++) + printf(" %d", u.retval[i]); + } + printf("\n"); + } + + if (realloc_name) { + int num = 0; + for (i = 0; i < LIBXSVF_MEM_NUM; i++) { + if (realloc_maxsize[i] > 0) + num = i+1; + } + printf("void *%s(void *h, void *ptr, int size, int which) {\n", realloc_name); + for (i = 0; i < num; i++) { + if (realloc_maxsize[i] > 0) + printf("\tstatic unsigned char buf_%s[%d];\n", libxsvf_mem2str(i), realloc_maxsize[i]); + } + printf("\tstatic unsigned char *buflist[%d] = {", num); + for (i = 0; i < num; i++) { + if (realloc_maxsize[i] > 0) + printf("%sbuf_%s", i ? ", " : " ", libxsvf_mem2str(i)); + else + printf("%s(void*)0", i ? ", " : " "); + } + printf(" };\n\tstatic int sizelist[%d] = {", num); + for (i = 0; i < num; i++) { + if (realloc_maxsize[i] > 0) + printf("%ssizeof(buf_%s)", i ? ", " : " ", libxsvf_mem2str(i)); + else + printf("%s0", i ? ", " : " "); + } + printf(" };\n"); + printf("\treturn which < %d && size <= sizelist[which] ? buflist[which] : (void*)0;\n", num); + printf("};\n"); + } + + return rc; +} + diff --git a/fpga/xilinx/programmer/svfplayer/raspberry_pi/Makefile b/fpga/xilinx/programmer/svfplayer/raspberry_pi/Makefile new file mode 100644 index 0000000..176b0a3 --- /dev/null +++ b/fpga/xilinx/programmer/svfplayer/raspberry_pi/Makefile @@ -0,0 +1,47 @@ +# Copyright (C) 2012 Timothy Pearson +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +AR = ar +RANLIB = ranlib +CC = gcc + +CFLAGS += -Wall -Os -ggdb -MD +#CFLAGS += -Wextra -Wno-unused-parameter -Werror + +help: + @echo "" + @echo "Usage:" + @echo "" + @echo " $(MAKE) xsvf-rpi" + @echo " .... build xsvf-rpi" + @echo "" + @echo " $(MAKE) all" + @echo " .... build everything" + @echo "" + @echo " $(MAKE) install" + @echo " .... install everything in /usr/" + @echo "" + +all: xsvf-rpi + +install: all + install -Dt /usr/bin/ xsvf-rpi + +xsvf-rpi: /usr/lib/libxsvf.a xsvf-rpi.o + +clean: + rm -f xsvf-rpi.o + +-include *.d + diff --git a/fpga/xilinx/programmer/svfplayer/raspberry_pi/xsvf-rpi.c b/fpga/xilinx/programmer/svfplayer/raspberry_pi/xsvf-rpi.c new file mode 100644 index 0000000..034abbc --- /dev/null +++ b/fpga/xilinx/programmer/svfplayer/raspberry_pi/xsvf-rpi.c @@ -0,0 +1,530 @@ +/* + * Lib(X)SVF - A library for implementing SVF and XSVF JTAG players + * + * Copyright (C) 2012 Timothy Pearson (Raspberry Pi) + * Copyright (C) 2009 RIEGL Research ForschungsGmbH + * Copyright (C) 2009 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "libxsvf.h" + +#include +#include +#include +#include +#include +#include + + +/** BEGIN: Low-Level I/O Implementation **/ + +// Raspberry PI GPIO driver +// TMS: 18 +// TDI: 23 +// TDO: 24 +// TCK: 25 + +#include +#include +#include +#include + +#define BCM2708_PERI_BASE 0x20000000 +#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ + +#define PAGE_SIZE (4*1024) +#define BLOCK_SIZE (4*1024) + +int mem_fd; +char *gpio_mem, *gpio_map; +char *spi0_mem, *spi0_map; + +// I/O access +volatile unsigned *gpio; + +// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y) +#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) +#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) +#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) + +#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0 +#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0 + +#define GPLEV0 *(gpio+13) + +static void io_setup(void) +{ + /* open /dev/mem */ + if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { + printf("can't open /dev/mem \n"); + exit (-1); + } + + /* mmap GPIO */ + + // Allocate MAP block + if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) { + printf("allocation error \n"); + exit (-1); + } + + // Make sure pointer is on 4K boundary + if ((unsigned long)gpio_mem % PAGE_SIZE) { + gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE); + } + + // Now map it + gpio_map = (char *)mmap( + (caddr_t)gpio_mem, + BLOCK_SIZE, + PROT_READ|PROT_WRITE, + MAP_SHARED|MAP_FIXED, + mem_fd, + GPIO_BASE + ); + + if ((long)gpio_map < 0) { + printf("mmap error %d\n", (int)gpio_map); + exit (-1); + } + + // Always use volatile pointer! + gpio = (volatile unsigned *)gpio_map; + + // Set GPIO pins 18, 23, 25 to output + INP_GPIO(18); // must use INP_GPIO before we can use OUT_GPIO + INP_GPIO(23); // must use INP_GPIO before we can use OUT_GPIO + INP_GPIO(25); // must use INP_GPIO before we can use OUT_GPIO + + OUT_GPIO(18); // output + OUT_GPIO(23); // output + INP_GPIO(24); // input + OUT_GPIO(25); // output +} + +static void io_shutdown(void) +{ + INP_GPIO(18); + INP_GPIO(23); + INP_GPIO(24); + INP_GPIO(25); +} + +static void io_tms(int val) +{ + if (val) { + GPIO_SET = 1<<18; + } + else { + GPIO_CLR = 1<<18; + } +} + +static void io_tdi(int val) +{ + if (val) { + GPIO_SET = 1<<23; + } + else { + GPIO_CLR = 1<<23; + } +} + +static void io_tck(int val) +{ + if (val) { + GPIO_SET = 1<<25; + } + else { + GPIO_CLR = 1<<25; + } + + // usleep(1); +} + +static void io_sck(int val) +{ + /* not available */ +} + +static void io_trst(int val) +{ + /* not available */ +} + +static int io_tdo() +{ + return (GPLEV0 & (1<<24)) ? 1 : 0; +} + +/** END: Low-Level I/O Implementation **/ + + +struct udata_s { + FILE *f; + int verbose; + int clockcount; + int bitcount_tdi; + int bitcount_tdo; + int retval_i; + int retval[256]; +}; + +static int h_setup(struct libxsvf_host *h) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 2) { + fprintf(stderr, "[SETUP]\n"); + fflush(stderr); + } + io_setup(); + return 0; +} + +static int h_shutdown(struct libxsvf_host *h) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 2) { + fprintf(stderr, "[SHUTDOWN]\n"); + fflush(stderr); + } + io_shutdown(); + return 0; +} + +static void h_udelay(struct libxsvf_host *h, long usecs, int tms, long num_tck) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 3) { + fprintf(stderr, "[DELAY:%ld, TMS:%d, NUM_TCK:%ld]\n", usecs, tms, num_tck); + fflush(stderr); + } + if (num_tck > 0) { + struct timeval tv1, tv2; + gettimeofday(&tv1, NULL); + io_tms(tms); + while (num_tck > 0) { + io_tck(0); + io_tck(1); + num_tck--; + } + gettimeofday(&tv2, NULL); + if (tv2.tv_sec > tv1.tv_sec) { + usecs -= (1000000 - tv1.tv_usec) + (tv2.tv_sec - tv1.tv_sec - 1) * 1000000; + tv1.tv_usec = 0; + } + usecs -= tv2.tv_usec - tv1.tv_usec; + if (u->verbose >= 3) { + fprintf(stderr, "[DELAY_AFTER_TCK:%ld]\n", usecs > 0 ? usecs : 0); + fflush(stderr); + } + } + if (usecs > 0) { + usleep(usecs); + } +} + +static int h_getbyte(struct libxsvf_host *h) +{ + struct udata_s *u = h->user_data; + return fgetc(u->f); +} + +static int h_pulse_tck(struct libxsvf_host *h, int tms, int tdi, int tdo, int rmask, int sync) +{ + struct udata_s *u = h->user_data; + + io_tms(tms); + + if (tdi >= 0) { + u->bitcount_tdi++; + io_tdi(tdi); + } + + io_tck(0); + io_tck(1); + + int line_tdo = io_tdo(); + int rc = line_tdo >= 0 ? line_tdo : 0; + + if (rmask == 1 && u->retval_i < 256) + u->retval[u->retval_i++] = line_tdo; + + if (tdo >= 0 && line_tdo >= 0) { + u->bitcount_tdo++; + if (tdo != line_tdo) + rc = -1; + } + + if (u->verbose >= 4) { + fprintf(stderr, "[TMS:%d, TDI:%d, TDO_ARG:%d, TDO_LINE:%d, RMASK:%d, RC:%d]\n", tms, tdi, tdo, line_tdo, rmask, rc); + } + + u->clockcount++; + return rc; +} + +static void h_pulse_sck(struct libxsvf_host *h) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 4) { + fprintf(stderr, "[SCK]\n"); + } + io_sck(0); + io_sck(1); +} + +static void h_set_trst(struct libxsvf_host *h, int v) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 4) { + fprintf(stderr, "[TRST:%d]\n", v); + } + io_trst(v); +} + +static int h_set_frequency(struct libxsvf_host *h, int v) +{ + fprintf(stderr, "WARNING: Setting JTAG clock frequency to %d ignored!\n", v); + return 0; +} + +static void h_report_tapstate(struct libxsvf_host *h) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 3) { + fprintf(stderr, "[%s]\n", libxsvf_state2str(h->tap_state)); + } +} + +static void h_report_device(struct libxsvf_host *h, unsigned long idcode) +{ + // struct udata_s *u = h->user_data; + printf("idcode=0x%08lx, revision=0x%01lx, part=0x%04lx, manufactor=0x%03lx\n", idcode, + (idcode >> 28) & 0xf, (idcode >> 12) & 0xffff, (idcode >> 1) & 0x7ff); +} + +static void h_report_status(struct libxsvf_host *h, const char *message) +{ + struct udata_s *u = h->user_data; + if (u->verbose >= 2) { + fprintf(stderr, "[STATUS] %s\n", message); + } +} + +static void h_report_error(struct libxsvf_host *h, const char *file, int line, const char *message) +{ + fprintf(stderr, "[%s:%d] %s\n", file, line, message); +} + +static int realloc_maxsize[LIBXSVF_MEM_NUM]; + +static void *h_realloc(struct libxsvf_host *h, void *ptr, int size, enum libxsvf_mem which) +{ + struct udata_s *u = h->user_data; + if (size > realloc_maxsize[which]) + realloc_maxsize[which] = size; + if (u->verbose >= 3) { + fprintf(stderr, "[REALLOC:%s:%d]\n", libxsvf_mem2str(which), size); + } + return realloc(ptr, size); +} + +static struct udata_s u; + +static struct libxsvf_host h = { + .udelay = h_udelay, + .setup = h_setup, + .shutdown = h_shutdown, + .getbyte = h_getbyte, + .pulse_tck = h_pulse_tck, + .pulse_sck = h_pulse_sck, + .set_trst = h_set_trst, + .set_frequency = h_set_frequency, + .report_tapstate = h_report_tapstate, + .report_device = h_report_device, + .report_status = h_report_status, + .report_error = h_report_error, + .realloc = h_realloc, + .user_data = &u +}; + +const char *progname; + +static void copyleft() +{ + static int already_printed = 0; + if (already_printed) + return; + fprintf(stderr, "xsvftool-gpio, part of Lib(X)SVF (http://www.clifford.at/libxsvf/).\n"); + fprintf(stderr, "Copyright (C) 2009 RIEGL Research ForschungsGmbH\n"); + fprintf(stderr, "Copyright (C) 2009 Clifford Wolf \n"); + fprintf(stderr, "Copyright (C) 2012 Timothy Pearson (Raspberry Pi)\n"); + fprintf(stderr, "Lib(X)SVF is free software licensed under the ISC license.\n"); + already_printed = 1; +} + +static void help() +{ + copyleft(); + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: %s [ -r funcname ] [ -v ... ] [ -L | -B ] { -s svf-file | -x xsvf-file | -c } ...\n", progname); + fprintf(stderr, "\n"); + fprintf(stderr, " -r funcname\n"); + fprintf(stderr, " Dump C-code for pseudo-allocator based on example files\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -v, -vv, -vvv, -vvvv\n"); + fprintf(stderr, " Verbose, more verbose and even more verbose\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -L, -B\n"); + fprintf(stderr, " Print RMASK bits as hex value (little or big endian)\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -s svf-file\n"); + fprintf(stderr, " Play the specified SVF file\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -x xsvf-file\n"); + fprintf(stderr, " Play the specified XSVF file\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -c\n"); + fprintf(stderr, " List devices in JTAG chain\n"); + fprintf(stderr, "\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + int rc = 0; + int gotaction = 0; + int hex_mode = 0; + const char *realloc_name = NULL; + int opt, i, j; + + progname = argc >= 1 ? argv[0] : "xvsftool"; + while ((opt = getopt(argc, argv, "r:vLBx:s:c")) != -1) + { + switch (opt) + { + case 'r': + realloc_name = optarg; + break; + case 'v': + copyleft(); + u.verbose++; + break; + case 'x': + case 's': + gotaction = 1; + if (u.verbose) + fprintf(stderr, "Playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg); + if (!strcmp(optarg, "-")) + u.f = stdin; + else + u.f = fopen(optarg, "rb"); + if (u.f == NULL) { + fprintf(stderr, "Can't open %s file `%s': %s\n", opt == 's' ? "SVF" : "XSVF", optarg, strerror(errno)); + rc = 1; + break; + } + if (libxsvf_play(&h, opt == 's' ? LIBXSVF_MODE_SVF : LIBXSVF_MODE_XSVF) < 0) { + fprintf(stderr, "Error while playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg); + rc = 1; + } + if (strcmp(optarg, "-")) + fclose(u.f); + break; + case 'c': + gotaction = 1; + if (libxsvf_play(&h, LIBXSVF_MODE_SCAN) < 0) { + fprintf(stderr, "Error while scanning JTAG chain.\n"); + rc = 1; + } + break; + case 'L': + hex_mode = 1; + break; + case 'B': + hex_mode = 2; + break; + default: + help(); + break; + } + } + + if (!gotaction) + help(); + + if (u.verbose) { + fprintf(stderr, "Total number of clock cycles: %d\n", u.clockcount); + fprintf(stderr, "Number of significant TDI bits: %d\n", u.bitcount_tdi); + fprintf(stderr, "Number of significant TDO bits: %d\n", u.bitcount_tdo); + if (rc == 0) { + fprintf(stderr, "Finished without errors.\n"); + } else { + fprintf(stderr, "Finished with errors!\n"); + } + } + + if (u.retval_i) { + if (hex_mode) { + printf("0x"); + for (i=0; i < u.retval_i; i+=4) { + int val = 0; + for (j=i; j 1 ? j : u.retval_i - j - 1]; + printf("%x", val); + } + } else { + printf("%d rmask bits:", u.retval_i); + for (i=0; i < u.retval_i; i++) + printf(" %d", u.retval[i]); + } + printf("\n"); + } + + if (realloc_name) { + int num = 0; + for (i = 0; i < LIBXSVF_MEM_NUM; i++) { + if (realloc_maxsize[i] > 0) + num = i+1; + } + printf("void *%s(void *h, void *ptr, int size, int which) {\n", realloc_name); + for (i = 0; i < num; i++) { + if (realloc_maxsize[i] > 0) + printf("\tstatic unsigned char buf_%s[%d];\n", libxsvf_mem2str(i), realloc_maxsize[i]); + } + printf("\tstatic unsigned char *buflist[%d] = {", num); + for (i = 0; i < num; i++) { + if (realloc_maxsize[i] > 0) + printf("%sbuf_%s", i ? ", " : " ", libxsvf_mem2str(i)); + else + printf("%s(void*)0", i ? ", " : " "); + } + printf(" };\n\tstatic int sizelist[%d] = {", num); + for (i = 0; i < num; i++) { + if (realloc_maxsize[i] > 0) + printf("%ssizeof(buf_%s)", i ? ", " : " ", libxsvf_mem2str(i)); + else + printf("%s0", i ? ", " : " "); + } + printf(" };\n"); + printf("\treturn which < %d && size <= sizelist[which] ? buflist[which] : (void*)0;\n", num); + printf("};\n"); + } + + return rc; +} + diff --git a/fpga/xilinx/programmer/svfplayer/xsvf-rpi.c b/fpga/xilinx/programmer/svfplayer/xsvf-rpi.c deleted file mode 100644 index 034abbc..0000000 --- a/fpga/xilinx/programmer/svfplayer/xsvf-rpi.c +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Lib(X)SVF - A library for implementing SVF and XSVF JTAG players - * - * Copyright (C) 2012 Timothy Pearson (Raspberry Pi) - * Copyright (C) 2009 RIEGL Research ForschungsGmbH - * Copyright (C) 2009 Clifford Wolf - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "libxsvf.h" - -#include -#include -#include -#include -#include -#include - - -/** BEGIN: Low-Level I/O Implementation **/ - -// Raspberry PI GPIO driver -// TMS: 18 -// TDI: 23 -// TDO: 24 -// TCK: 25 - -#include -#include -#include -#include - -#define BCM2708_PERI_BASE 0x20000000 -#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ - -#define PAGE_SIZE (4*1024) -#define BLOCK_SIZE (4*1024) - -int mem_fd; -char *gpio_mem, *gpio_map; -char *spi0_mem, *spi0_map; - -// I/O access -volatile unsigned *gpio; - -// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y) -#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) -#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) -#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) - -#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0 -#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0 - -#define GPLEV0 *(gpio+13) - -static void io_setup(void) -{ - /* open /dev/mem */ - if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { - printf("can't open /dev/mem \n"); - exit (-1); - } - - /* mmap GPIO */ - - // Allocate MAP block - if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) { - printf("allocation error \n"); - exit (-1); - } - - // Make sure pointer is on 4K boundary - if ((unsigned long)gpio_mem % PAGE_SIZE) { - gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE); - } - - // Now map it - gpio_map = (char *)mmap( - (caddr_t)gpio_mem, - BLOCK_SIZE, - PROT_READ|PROT_WRITE, - MAP_SHARED|MAP_FIXED, - mem_fd, - GPIO_BASE - ); - - if ((long)gpio_map < 0) { - printf("mmap error %d\n", (int)gpio_map); - exit (-1); - } - - // Always use volatile pointer! - gpio = (volatile unsigned *)gpio_map; - - // Set GPIO pins 18, 23, 25 to output - INP_GPIO(18); // must use INP_GPIO before we can use OUT_GPIO - INP_GPIO(23); // must use INP_GPIO before we can use OUT_GPIO - INP_GPIO(25); // must use INP_GPIO before we can use OUT_GPIO - - OUT_GPIO(18); // output - OUT_GPIO(23); // output - INP_GPIO(24); // input - OUT_GPIO(25); // output -} - -static void io_shutdown(void) -{ - INP_GPIO(18); - INP_GPIO(23); - INP_GPIO(24); - INP_GPIO(25); -} - -static void io_tms(int val) -{ - if (val) { - GPIO_SET = 1<<18; - } - else { - GPIO_CLR = 1<<18; - } -} - -static void io_tdi(int val) -{ - if (val) { - GPIO_SET = 1<<23; - } - else { - GPIO_CLR = 1<<23; - } -} - -static void io_tck(int val) -{ - if (val) { - GPIO_SET = 1<<25; - } - else { - GPIO_CLR = 1<<25; - } - - // usleep(1); -} - -static void io_sck(int val) -{ - /* not available */ -} - -static void io_trst(int val) -{ - /* not available */ -} - -static int io_tdo() -{ - return (GPLEV0 & (1<<24)) ? 1 : 0; -} - -/** END: Low-Level I/O Implementation **/ - - -struct udata_s { - FILE *f; - int verbose; - int clockcount; - int bitcount_tdi; - int bitcount_tdo; - int retval_i; - int retval[256]; -}; - -static int h_setup(struct libxsvf_host *h) -{ - struct udata_s *u = h->user_data; - if (u->verbose >= 2) { - fprintf(stderr, "[SETUP]\n"); - fflush(stderr); - } - io_setup(); - return 0; -} - -static int h_shutdown(struct libxsvf_host *h) -{ - struct udata_s *u = h->user_data; - if (u->verbose >= 2) { - fprintf(stderr, "[SHUTDOWN]\n"); - fflush(stderr); - } - io_shutdown(); - return 0; -} - -static void h_udelay(struct libxsvf_host *h, long usecs, int tms, long num_tck) -{ - struct udata_s *u = h->user_data; - if (u->verbose >= 3) { - fprintf(stderr, "[DELAY:%ld, TMS:%d, NUM_TCK:%ld]\n", usecs, tms, num_tck); - fflush(stderr); - } - if (num_tck > 0) { - struct timeval tv1, tv2; - gettimeofday(&tv1, NULL); - io_tms(tms); - while (num_tck > 0) { - io_tck(0); - io_tck(1); - num_tck--; - } - gettimeofday(&tv2, NULL); - if (tv2.tv_sec > tv1.tv_sec) { - usecs -= (1000000 - tv1.tv_usec) + (tv2.tv_sec - tv1.tv_sec - 1) * 1000000; - tv1.tv_usec = 0; - } - usecs -= tv2.tv_usec - tv1.tv_usec; - if (u->verbose >= 3) { - fprintf(stderr, "[DELAY_AFTER_TCK:%ld]\n", usecs > 0 ? usecs : 0); - fflush(stderr); - } - } - if (usecs > 0) { - usleep(usecs); - } -} - -static int h_getbyte(struct libxsvf_host *h) -{ - struct udata_s *u = h->user_data; - return fgetc(u->f); -} - -static int h_pulse_tck(struct libxsvf_host *h, int tms, int tdi, int tdo, int rmask, int sync) -{ - struct udata_s *u = h->user_data; - - io_tms(tms); - - if (tdi >= 0) { - u->bitcount_tdi++; - io_tdi(tdi); - } - - io_tck(0); - io_tck(1); - - int line_tdo = io_tdo(); - int rc = line_tdo >= 0 ? line_tdo : 0; - - if (rmask == 1 && u->retval_i < 256) - u->retval[u->retval_i++] = line_tdo; - - if (tdo >= 0 && line_tdo >= 0) { - u->bitcount_tdo++; - if (tdo != line_tdo) - rc = -1; - } - - if (u->verbose >= 4) { - fprintf(stderr, "[TMS:%d, TDI:%d, TDO_ARG:%d, TDO_LINE:%d, RMASK:%d, RC:%d]\n", tms, tdi, tdo, line_tdo, rmask, rc); - } - - u->clockcount++; - return rc; -} - -static void h_pulse_sck(struct libxsvf_host *h) -{ - struct udata_s *u = h->user_data; - if (u->verbose >= 4) { - fprintf(stderr, "[SCK]\n"); - } - io_sck(0); - io_sck(1); -} - -static void h_set_trst(struct libxsvf_host *h, int v) -{ - struct udata_s *u = h->user_data; - if (u->verbose >= 4) { - fprintf(stderr, "[TRST:%d]\n", v); - } - io_trst(v); -} - -static int h_set_frequency(struct libxsvf_host *h, int v) -{ - fprintf(stderr, "WARNING: Setting JTAG clock frequency to %d ignored!\n", v); - return 0; -} - -static void h_report_tapstate(struct libxsvf_host *h) -{ - struct udata_s *u = h->user_data; - if (u->verbose >= 3) { - fprintf(stderr, "[%s]\n", libxsvf_state2str(h->tap_state)); - } -} - -static void h_report_device(struct libxsvf_host *h, unsigned long idcode) -{ - // struct udata_s *u = h->user_data; - printf("idcode=0x%08lx, revision=0x%01lx, part=0x%04lx, manufactor=0x%03lx\n", idcode, - (idcode >> 28) & 0xf, (idcode >> 12) & 0xffff, (idcode >> 1) & 0x7ff); -} - -static void h_report_status(struct libxsvf_host *h, const char *message) -{ - struct udata_s *u = h->user_data; - if (u->verbose >= 2) { - fprintf(stderr, "[STATUS] %s\n", message); - } -} - -static void h_report_error(struct libxsvf_host *h, const char *file, int line, const char *message) -{ - fprintf(stderr, "[%s:%d] %s\n", file, line, message); -} - -static int realloc_maxsize[LIBXSVF_MEM_NUM]; - -static void *h_realloc(struct libxsvf_host *h, void *ptr, int size, enum libxsvf_mem which) -{ - struct udata_s *u = h->user_data; - if (size > realloc_maxsize[which]) - realloc_maxsize[which] = size; - if (u->verbose >= 3) { - fprintf(stderr, "[REALLOC:%s:%d]\n", libxsvf_mem2str(which), size); - } - return realloc(ptr, size); -} - -static struct udata_s u; - -static struct libxsvf_host h = { - .udelay = h_udelay, - .setup = h_setup, - .shutdown = h_shutdown, - .getbyte = h_getbyte, - .pulse_tck = h_pulse_tck, - .pulse_sck = h_pulse_sck, - .set_trst = h_set_trst, - .set_frequency = h_set_frequency, - .report_tapstate = h_report_tapstate, - .report_device = h_report_device, - .report_status = h_report_status, - .report_error = h_report_error, - .realloc = h_realloc, - .user_data = &u -}; - -const char *progname; - -static void copyleft() -{ - static int already_printed = 0; - if (already_printed) - return; - fprintf(stderr, "xsvftool-gpio, part of Lib(X)SVF (http://www.clifford.at/libxsvf/).\n"); - fprintf(stderr, "Copyright (C) 2009 RIEGL Research ForschungsGmbH\n"); - fprintf(stderr, "Copyright (C) 2009 Clifford Wolf \n"); - fprintf(stderr, "Copyright (C) 2012 Timothy Pearson (Raspberry Pi)\n"); - fprintf(stderr, "Lib(X)SVF is free software licensed under the ISC license.\n"); - already_printed = 1; -} - -static void help() -{ - copyleft(); - fprintf(stderr, "\n"); - fprintf(stderr, "Usage: %s [ -r funcname ] [ -v ... ] [ -L | -B ] { -s svf-file | -x xsvf-file | -c } ...\n", progname); - fprintf(stderr, "\n"); - fprintf(stderr, " -r funcname\n"); - fprintf(stderr, " Dump C-code for pseudo-allocator based on example files\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -v, -vv, -vvv, -vvvv\n"); - fprintf(stderr, " Verbose, more verbose and even more verbose\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -L, -B\n"); - fprintf(stderr, " Print RMASK bits as hex value (little or big endian)\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -s svf-file\n"); - fprintf(stderr, " Play the specified SVF file\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -x xsvf-file\n"); - fprintf(stderr, " Play the specified XSVF file\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -c\n"); - fprintf(stderr, " List devices in JTAG chain\n"); - fprintf(stderr, "\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - int rc = 0; - int gotaction = 0; - int hex_mode = 0; - const char *realloc_name = NULL; - int opt, i, j; - - progname = argc >= 1 ? argv[0] : "xvsftool"; - while ((opt = getopt(argc, argv, "r:vLBx:s:c")) != -1) - { - switch (opt) - { - case 'r': - realloc_name = optarg; - break; - case 'v': - copyleft(); - u.verbose++; - break; - case 'x': - case 's': - gotaction = 1; - if (u.verbose) - fprintf(stderr, "Playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg); - if (!strcmp(optarg, "-")) - u.f = stdin; - else - u.f = fopen(optarg, "rb"); - if (u.f == NULL) { - fprintf(stderr, "Can't open %s file `%s': %s\n", opt == 's' ? "SVF" : "XSVF", optarg, strerror(errno)); - rc = 1; - break; - } - if (libxsvf_play(&h, opt == 's' ? LIBXSVF_MODE_SVF : LIBXSVF_MODE_XSVF) < 0) { - fprintf(stderr, "Error while playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg); - rc = 1; - } - if (strcmp(optarg, "-")) - fclose(u.f); - break; - case 'c': - gotaction = 1; - if (libxsvf_play(&h, LIBXSVF_MODE_SCAN) < 0) { - fprintf(stderr, "Error while scanning JTAG chain.\n"); - rc = 1; - } - break; - case 'L': - hex_mode = 1; - break; - case 'B': - hex_mode = 2; - break; - default: - help(); - break; - } - } - - if (!gotaction) - help(); - - if (u.verbose) { - fprintf(stderr, "Total number of clock cycles: %d\n", u.clockcount); - fprintf(stderr, "Number of significant TDI bits: %d\n", u.bitcount_tdi); - fprintf(stderr, "Number of significant TDO bits: %d\n", u.bitcount_tdo); - if (rc == 0) { - fprintf(stderr, "Finished without errors.\n"); - } else { - fprintf(stderr, "Finished with errors!\n"); - } - } - - if (u.retval_i) { - if (hex_mode) { - printf("0x"); - for (i=0; i < u.retval_i; i+=4) { - int val = 0; - for (j=i; j 1 ? j : u.retval_i - j - 1]; - printf("%x", val); - } - } else { - printf("%d rmask bits:", u.retval_i); - for (i=0; i < u.retval_i; i++) - printf(" %d", u.retval[i]); - } - printf("\n"); - } - - if (realloc_name) { - int num = 0; - for (i = 0; i < LIBXSVF_MEM_NUM; i++) { - if (realloc_maxsize[i] > 0) - num = i+1; - } - printf("void *%s(void *h, void *ptr, int size, int which) {\n", realloc_name); - for (i = 0; i < num; i++) { - if (realloc_maxsize[i] > 0) - printf("\tstatic unsigned char buf_%s[%d];\n", libxsvf_mem2str(i), realloc_maxsize[i]); - } - printf("\tstatic unsigned char *buflist[%d] = {", num); - for (i = 0; i < num; i++) { - if (realloc_maxsize[i] > 0) - printf("%sbuf_%s", i ? ", " : " ", libxsvf_mem2str(i)); - else - printf("%s(void*)0", i ? ", " : " "); - } - printf(" };\n\tstatic int sizelist[%d] = {", num); - for (i = 0; i < num; i++) { - if (realloc_maxsize[i] > 0) - printf("%ssizeof(buf_%s)", i ? ", " : " ", libxsvf_mem2str(i)); - else - printf("%s0", i ? ", " : " "); - } - printf(" };\n"); - printf("\treturn which < %d && size <= sizelist[which] ? buflist[which] : (void*)0;\n", num); - printf("};\n"); - } - - return rc; -} - -- cgit v1.2.3