This is an automated email from Gerrit. Jatin Muddu ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4092
-- gerrit commit 8f153f525c67ff9fd259a3da4b3b2cd289dc9994 Author: jatinmuddu <[email protected]> Date: Wed Apr 5 11:47:30 2017 +0530 Adding Avago Pilot4 JTAG Master Interface driver Pilot4 is an SOC based on ARM. It is used as a Baseboard Management Controller on servers. Pilot4 also has JTAG Master interface. Using this, Pilot4 can be used as a JTAG Master. The included driver interfaces with Pilot4 JTAG master interface. Change-Id: I787de07693575ae89e0ce58014c008c3e53f9efd Signed-off-by: jatinmuddu <[email protected]> diff --git a/README b/README index 581082e..12a48cc 100644 --- a/README +++ b/README @@ -296,6 +296,43 @@ if you want to use giveio instead of ioperm parallel port access method. +======================================= +Using Avago Pilot JTAG Master Interface +======================================= +Avago Pilot JTAG Master Interface Driver should be built if you +intend to use OpenOCD on Avago Pilot ASIC. Once OpenOCD is +built with this driver, OpenOCD can be used to debug JTAG targets +connected to Avago Pilot JTAG Master Interface. + +These instructions help to build and use the Avago Pilot JTAG +Master Interface driver + +Building the Avago Pilot JTAG Master Interface driver +------------------------------------------------------ + +NOTE: arm-eabi Toolchain and the following exports are needed + +export PATH=$PATH:/<toolchain path>/bin/" +export LIBUSB1_CFLAGS= +export PKG_CONFIG= +export libusb_CFLAGS= +export libusb_LIBS= + +Then run configure like so: + +MAKEINFO=true ./configure --enable-avago_pilot --build=x86 \ +--host=arm-emulex-linux-gnueabi \ +--with-sysroot=<toolchain path>/arm-emulex-linux-gnueabi/sysroot/ \ +--disable-internal-libjaylink + +followed by 'make' + +If you see autoconf/libtool related errors then run these +commands first then start to build the driver. + +make distclean +autoreconf -ivf + ========================== Obtaining OpenOCD From GIT ========================== diff --git a/configure.ac b/configure.ac index 6e60733..9ea4ea8 100644 --- a/configure.ac +++ b/configure.ac @@ -137,6 +137,9 @@ m4_define([LIBFTDI_ADAPTERS], m4_define([LIBJAYLINK_ADAPTERS], [[[jlink], [SEGGER J-Link Programmer], [JLINK]]]) +m4_define([AVAGO_ADAPTER], + [[[avago_pilot], [Avago Pilot Debugger], [AVAGO_PILOT]]]) + AC_ARG_ENABLE([doxygen-html], AS_HELP_STRING([--disable-doxygen-html], @@ -244,7 +247,8 @@ AC_ARG_ADAPTERS([ USB0_ADAPTERS, HIDAPI_ADAPTERS, LIBFTDI_ADAPTERS, - LIBJAYLINK_ADAPTERS + LIBJAYLINK_ADAPTERS, + AVAGO_ADAPTER ],[auto]) AC_ARG_ENABLE([parport], @@ -277,6 +281,10 @@ AC_ARG_ENABLE([zy1000], AS_HELP_STRING([--enable-zy1000], [Enable ZY1000 interface]), [build_zy1000=$enableval], [build_zy1000=no]) +AC_ARG_ENABLE([avago_pilot], + AS_HELP_STRING([--enable-avago_pilot], [Enable Avago Pilot interface]), + [build_avago_pilot=$enableval], [build_avago_pilot=no]) + AC_ARG_ENABLE([ioutil], AS_HELP_STRING([--enable-ioutil], [Enable ioutil functions - useful for standalone OpenOCD implementations]), [build_ioutil=$enableval], [build_ioutil=no]) @@ -498,6 +506,12 @@ AS_IF([test "x$build_zy1000_master" = "xyes"], [ AC_DEFINE([BUILD_ZY1000_MASTER], [0], [0 if you don't want ZY1000 JTAG master registers.]) ]) +AS_IF([test "x$build_avago_pilot" = "xyes"], [ + AC_DEFINE([BUILD_AVAGO_PILOT], [1], [1 if you want AVAGO PILOT.]) +], [ + AC_DEFINE([BUILD_AVAGO_PILOT], [0], [0 if you don't want AVAGO PILOT.]) +]) + AS_IF([test "x$build_at91rm9200" = "xyes"], [ build_bitbang=yes AC_DEFINE([BUILD_AT91RM9200], [1], [1 if you want at91rm9200.]) @@ -638,6 +652,7 @@ PROCESS_ADAPTERS([USB1_ADAPTERS], ["x$use_libusb1" = "xyes"], [libusb-1.x]) PROCESS_ADAPTERS([USB_ADAPTERS], ["x$use_libusb1" = "xyes" -o "x$use_libusb0" = "xyes"], [libusb-1.x or libusb-0.1]) PROCESS_ADAPTERS([USB0_ADAPTERS], ["x$use_libusb0" = "xyes"], [libusb-0.1]) PROCESS_ADAPTERS([HIDAPI_ADAPTERS], ["x$use_hidapi" = "xyes"], [hidapi]) +PROCESS_ADAPTERS([AVAGO_ADAPTERS], ["x$use_avago" = "xyes"], [avagopilot]) PROCESS_ADAPTERS([LIBFTDI_ADAPTERS], ["x$use_libftdi" = "xyes"], [libftdi]) PROCESS_ADAPTERS([LIBJAYLINK_ADAPTERS], ["x$use_libusb1" = "xyes" -a "x$use_internal_libjaylink" = "xyes" -o "x$use_libjaylink" = "xyes"], [libusb-1.x or libjaylink-0.1]) @@ -678,6 +693,7 @@ 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([AVAGO_PILOT], [test "x$build_avago_pilot" = "xyes"]) AM_CONDITIONAL([IOUTIL], [test "x$build_ioutil" = "xyes"]) AM_CONDITIONAL([AT91RM9200], [test "x$build_at91rm9200" = "xyes"]) AM_CONDITIONAL([BCM2835GPIO], [test "x$build_bcm2835gpio" = "xyes"]) @@ -768,7 +784,7 @@ echo echo OpenOCD configuration summary echo -------------------------------------------------- m4_foreach([adapter], [USB1_ADAPTERS, USB_ADAPTERS, USB0_ADAPTERS, - HIDAPI_ADAPTERS, LIBFTDI_ADAPTERS, LIBJAYLINK_ADAPTERS], + HIDAPI_ADAPTERS, AVAGO_ADAPTER, LIBFTDI_ADAPTERS, LIBJAYLINK_ADAPTERS], [s=m4_format(["%-40s"], ADAPTER_DESC([adapter])) AS_CASE([$ADAPTER_VAR([adapter])], [auto], [ diff --git a/doc/openocd.texi b/doc/openocd.texi index c3053b7..3da4627 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -599,6 +599,9 @@ produced, PDF schematics are easily found and it is easy to make. @* A JTAG driver acting as a client for the JTAG VPI server interface. @* Link: @url{http://github.com/fjullien/jtag_vpi} +@item @b{avago_pilot} +@* A driver which supports Avago Pilot JTAG Master Interface. + @end itemize @node About Jim-Tcl diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index e411412..bcf3aad 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -101,6 +101,9 @@ endif if USBPROG DRIVERFILES += %D%/usbprog.c endif +if AVAGO_PILOT +DRIVERFILES += %D%/avago_pilot.c +endif if RLINK DRIVERFILES += %D%/rlink.c %D%/rlink_speed_table.c endif diff --git a/src/jtag/drivers/avago_pilot.c b/src/jtag/drivers/avago_pilot.c new file mode 100644 index 0000000..0683775 --- /dev/null +++ b/src/jtag/drivers/avago_pilot.c @@ -0,0 +1,590 @@ +/******************************************************************************* + * + * Copyright (C) 2015-2016 Avago Technologies. All rights reserved. + * + * 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. ALL EXPRESS + * OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED + * WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS + * ARE HELD TO BE LEGALLY INVALID. See the GNU General Public License for more + * details, a copy of which can be found in the file COPYING included + * with this package. + * + ********************************************************************************/ +/********************************************************************************* + * This code supports the JTAG Master in the Pilot4 ASIC, this code currenlty + * supports NON-DISCRETE mode, the advantage of this mode is that the state mach- + * -ne is maintained by the hardware itself, relieving the users of the hardwork + * Ain't it cool!! + *********************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <jtag/interface.h> +#include <jtag/swd.h> +#include <jtag/commands.h> + +#include <stdio.h> +#include <sys/mman.h> +#include <fcntl.h> + +#define PRINTF DEBUG_JTAG_IO + + +#define JTAG_BASE 0x40429100 +#define CONF_A (avago_master + 0x0) +#define CONF_B (avago_master + 0x4) +#define STS (avago_master + 0x8) +#define COMMAND (avago_master + 0xC) +#define TDO (avago_master + 0x10) +#define TDI (avago_master + 0x14) +#define COUNTER (avago_master + 0x18) +#define DIS_CTRL (avago_master + 0x1C) +#define AVAGO_MAX_SPEED 7800 +int fd; +void *avago_master_void; +unsigned char *avago_master; + +#define AVAGO_TAP_BUFFER_SIZE 2048 +static uint8_t tdi_buffer[AVAGO_TAP_BUFFER_SIZE]; +#define IOR(A) (*((volatile unsigned char *) A)) +#define IOW(A, B) (*(volatile unsigned char *)A) = B + + +# ifdef _DEBUG_JTAG_IO_ +void dump_scan_command(struct scan_command *scan) +{ + int i; + PRINTF("Scan command dump\n"); + struct scan_field *fld = scan->fields; + if (scan->ir_scan) + PRINTF(" IR SCAN PRESENT\n"); + else + PRINTF(" IR SCAN NOT PRESENT\n"); + + PRINTF(" Number of fields is %d\n", scan->num_fields); + PRINTF(" End state is %x\n", scan->end_state); + for (i = 0; i < scan->num_fields; i++) { + PRINTF(" Num of bits for %d field is %d\n", i, fld->num_bits); + fld++; + } +} +# endif + + +void wait_for_idle(void) +{ + int count = 0; + /* Make sure we are not busy */ + while (((IOR(STS)) & 0xE7) != 0x0) { + /* PRINTF("Busy %x\n", IOR(STS)); */ + usleep(50); + count++; + if (count > 100000) { + printf("wait_for_idle bailing out\n"); + exit(255); + } + + } +} +void wait_for_mode(void) +{ + int count = 0; + unsigned char b; + b = IOR(CONF_B); + switch (b) { + case 0xA0: + count = 4; + break; + case 0xC0: + count = 8; + break; + case 0xE0: + count = 16; + break; + case 0x10: + count = 32; + break; + case 0x30: + count = 64; + break; + case 0x50: + count = 128; + break; + case 0x70: + count = 256; + break; + case 0x90: + count = 512; + break; + case 0xb0: + count = 1024; + break; + case 0xd0: + case 0x00: + case 0xF0: + count = 2048; + break; + case 0x80: + count = 2; + break; + case 0x60: + count = 1; + break; + default: + break; + } + while (count) { + b = IOR(STS); + count--; + } +} +void wait_for_tdo(void) +{ + int count = 0; + while ((IOR(STS) & 0x40) != 0x00) { + usleep(50); + count++; + if (count > 100000) { + printf("wait_for_tdo bailing out\n"); + exit(255); + } + } +} +void wait_for_tdi(void) +{ + int count = 0; + while ((IOR(STS) & 0x80) == 0x00) { + usleep(50); + count++; + if (count > 100000) { + printf("wait_for_tdi bailing out\n"); + exit(255); + } + } +} + +static inline void avago_debug_buffer(uint8_t *buffer, int length) +{ + /* TBD: This is a debug function */ +} +static int avago_field_execute_in(uint8_t *buffer, unsigned int scan_size, unsigned char cmd, unsigned char ir_scan) +{ + unsigned char *in = buffer; + unsigned int num_bytes = DIV_ROUND_UP(scan_size, 8); + unsigned int i = 0; + PRINTF("Entered %s num_bytes is %d bits is %d\n", __func__, num_bytes, scan_size); + + wait_for_idle(); + + /* printf("COMMAND register is ZERO%x\n", IOR(COMMAND)); */ + PRINTF("Writing to counter register\n"); + IOW(COUNTER, (scan_size & 0xFF)); + IOW(COUNTER, (scan_size & 0xFF00) >> 8); + IOW(COUNTER, (scan_size & 0xFF0000) >> 16); + IOW(COUNTER, (scan_size & 0xFF000000) >> 24); + IOW(COMMAND, cmd); + + wait_for_mode(); + + while (i < num_bytes) { + wait_for_tdi(); + tdi_buffer[i] = IOR(TDI); + i++; + } + memcpy(in, tdi_buffer, i); + return 0; +} +static int avago_field_execute_out(uint8_t *buffer, unsigned int scan_size, unsigned char cmd, unsigned char ir_scan) +{ + unsigned char *out = buffer; + unsigned int num_bytes = (scan_size+7)/8; + unsigned int i = 0; + PRINTF("Entered %s num_bytes is %d bits is %d\n", __func__, num_bytes, scan_size); + + wait_for_idle(); + + /* printf("COMMAND register is ZERO%x\n", IOR(COMMAND)); */ + PRINTF("Writing to counter register\n"); + IOW(COUNTER, (scan_size & 0xFF)); + IOW(COUNTER, (scan_size & 0xFF00) >> 8); + IOW(COUNTER, (scan_size & 0xFF0000) >> 16); + IOW(COUNTER, (scan_size & 0xFF000000) >> 24); + IOW(COMMAND, cmd); + + wait_for_mode(); + + while (i < num_bytes) { + wait_for_tdo(); + IOW(TDO, out[i]); + i++; + } + return 0; +} +static int avago_field_execute_in_out(uint8_t *buffer, unsigned int scan_size, unsigned char cmd, unsigned char ir_scan) +{ + unsigned char *out = buffer; + unsigned char *in = buffer; + unsigned int num_bytes = (scan_size+7)/8; + unsigned int i = 0; + unsigned int j = 0; + PRINTF("Entered %s num_bytes is %d bits is %u\n", __func__, num_bytes, scan_size); + + wait_for_idle(); + + PRINTF("Writing to counter register\n"); + IOW(COUNTER, (scan_size & 0xFF)); + IOW(COUNTER, (scan_size & 0xFF00) >> 8); + IOW(COUNTER, (scan_size & 0xFF0000) >> 16); + IOW(COUNTER, (scan_size & 0xFF000000) >> 24); + IOW(COMMAND, cmd); + + wait_for_mode(); + + while (num_bytes) { + wait_for_tdo(); + IOW(TDO, out[i]); + i++; + if ((i >= 1) || (i == num_bytes)) + break; + } + while (i < num_bytes) { + wait_for_tdi(); + tdi_buffer[j] = IOR(TDI); + j++; + PRINTF(" Status register is %x\n", IOR(STS)); + wait_for_tdo(); + IOW(TDO, out[i]); + i++; + } + while (j < i) { + wait_for_tdi(); + tdi_buffer[j] = IOR(TDI); + j++; + } + memcpy(in, tdi_buffer, j); + PRINTF(" Status register is 3 %x\n", IOR(STS)); + return 0; +} +static int avago_tap_execute(void) +{ + PRINTF(" Entered %s\n", __func__); + return ERROR_OK; +} +#if 1 +/* Ideally all the state transitions needed should be taken care by the HW state machine + * handler in the hardware. However just to cater to any special transtions it will come + * Handy !!*/ +static void avago_state_move(void) +{ + int i; + uint8_t tms = 0; + uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); + uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); + PRINTF(" Entered %s\n", __func__); + PRINTF(" state move scan bits is %d data is %x\n", tms_scan_bits, tms_scan); + IOW(CONF_A, 2); +#if 1 + for (i = 0; i < tms_scan_bits; i++) { + tms = ((tms_scan >> i) & 1) << 2; + IOW(DIS_CTRL, tms); + IOR(DIS_CTRL); + /* avago_tap_append_step(tms, 0); */ + } + IOW(CONF_A, 0); + + tap_set_state(tap_get_end_state()); +#endif +} +#endif +static void avago_end_state(tap_state_t state) +{ + PRINTF(" Entered %s\n", __func__); + if (tap_is_state_stable(state)) + tap_set_end_state(state); + else { + LOG_ERROR("BUG: %i is not a valid end state", state); + exit(-1); + } +} +static int avago_quit(void) +{ + PRINTF(" Entered %s\n", __func__); + munmap(avago_master_void, 4096); + return ERROR_OK; +} +static int avago_init(void) +{ + PRINTF(" Entered %s\n", __func__); + /* jtag_config_khz(AVAGO_MAX_SPEED); */ + fd = open("/dev/mem", O_RDWR | O_SYNC); + if (fd < 0) + PRINTF("Mapping failed\n"); + + avago_master_void = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED, fd, (JTAG_BASE&~0xfff)); + if (avago_master_void == MAP_FAILED) { + PRINTF("Mapping failed Exitting\n"); + exit(255); + } + + avago_master = (unsigned char *) avago_master_void; + avago_master += 0x100; /*Adjusting the pointer to point to the start of the JTAG master base.*/ + + close(fd); + return ERROR_OK; +} + + +struct avago_freq_info { + int freq; + unsigned char regb_val; +}; + +/* This array should be in descending order of freq */ +static const struct avago_freq_info g_avago_freq_map[] = { + {31200, 0x40}, + {15620, 0x60}, + {7800, 0x80}, + {3900, 0xA0}, + {1950, 0xC0}, + {976, 0xE0}, + {488, 0x10}, + {244, 0x30}, + {122, 0x50}, + {61, 0x70}, + {30, 0x90}, + {15, 0xB0}, + {7, 0xD0} +}; + + +static int avago_speed_div(int speed, int *khz) +{ + PRINTF("Entered %s\n", __func__); + + /* Use 7800 as the default if invalid speed is provided */ + if ((speed < 0) || (speed >= (ssize_t)(ARRAY_SIZE(g_avago_freq_map)))) + speed = 2; + + *khz = g_avago_freq_map[speed].freq; + + return ERROR_OK; +} + + +static int avago_khz(int khz, int *jtag_speed) +{ + int i = 0; + + PRINTF("Entered %s\n", __func__); + + /* Search for exact match or the nearest (lower) frequency in the + table. This is why the table should be in descending order */ + for (i = 0; i < (ssize_t)(ARRAY_SIZE(g_avago_freq_map)); i++) { + /* Speed identifier is the index in the array itself */ + if (g_avago_freq_map[i].freq <= khz) { + *jtag_speed = i; + return ERROR_OK; + } + } + + /* This is the default frequency */ + *jtag_speed = 2; + + return ERROR_OK; +} + + +static int avago_speed(int speed) +{ + PRINTF("Entered %s\n", __func__); + + if ((speed < 0) || (speed >= (ssize_t)(ARRAY_SIZE(g_avago_freq_map)))) + return ERROR_FAIL; + + PRINTF("Setting speed: %d %d\n", speed, g_avago_freq_map[speed].freq); + + IOW(CONF_B, g_avago_freq_map[speed].regb_val); + + return ERROR_OK; +} + + +static void avago_execute_scan(struct jtag_command *cmd) +{ + int scan_size; + enum scan_type type; + /* int i,j; */ + uint8_t *buffer; + PRINTF(" Entered %s\n", __func__); + + # ifdef _DEBUG_JTAG_IO_ + dump_scan_command(cmd->cmd.scan); + # endif + + PRINTF("scan end in %s", tap_state_name(cmd->cmd.scan->end_state)); + + avago_end_state(cmd->cmd.scan->end_state); + type = jtag_scan_type(cmd->cmd.scan); + scan_size = jtag_scan_size(cmd->cmd.scan); + jtag_build_buffer(cmd->cmd.scan, &buffer); + if (cmd->cmd.scan->ir_scan) { + if (type == SCAN_IN) { + PRINTF("SCAN TYPE %x\n", IOR(COMMAND)); + avago_field_execute_in(buffer, scan_size, 0x1A, 1); + } else if (type == SCAN_OUT) { + PRINTF("SCAN TYPE %x\n", IOR(COMMAND)); + avago_field_execute_out(buffer, scan_size, 0x1C, 1); + } else if (type == (SCAN_IN | SCAN_OUT)) { + PRINTF("SCAN TYPE %x\n", IOR(COMMAND)); + avago_field_execute_in_out(buffer, scan_size, 0x18, 1); + } else { + PRINTF("Error Scan type\n"); + exit(255); + } + } else { + if (type == SCAN_IN) { + PRINTF("SCAN TYPE %x\n", IOR(COMMAND)); + avago_field_execute_in(buffer, scan_size, 0x1B, 0); + } else if (type == SCAN_OUT) { + PRINTF("SCAN TYPE %x\n", IOR(COMMAND)); + avago_field_execute_out(buffer, scan_size, 0x1D, 0); + } else if (type == (SCAN_IN | SCAN_OUT)) { + PRINTF("SCAN TYPE %x\n", IOR(COMMAND)); + avago_field_execute_in_out(buffer, scan_size, 0x19, 0); + } else { + PRINTF("Error Scan type\n"); + exit(255); + } + } + jtag_read_buffer(buffer, cmd->cmd.scan); +#if 0 + for (i = 0; i < cmd->cmd.scan->num_fields; i++) { + if (cmd->cmd.scan->fields[i].in_value != NULL) { + for (j = 0; j < ((cmd->cmd.scan->fields[i].num_bits+7)/8); j++) + PRINTF("Received %x\n", cmd->cmd.scan->fields[i].in_value[j]); + } else { + PRINTF("NO, %d\n", i); + } + } + for (i = 0; i < ((scan_size+7)/8); i++) + PRINTF("Received %x\n", buffer[i]); +#endif +} + +static void avago_execute_runtest(struct jtag_command *cmd) +{ + PRINTF(" Entered %s\n", __func__); + PRINTF("runtest %i cycles, end in %i", + cmd->cmd.runtest->num_cycles, + cmd->cmd.runtest->end_state); +} +static void avago_execute_statemove(struct jtag_command *cmd) +{ + PRINTF(" Entered %s\n", __func__); + PRINTF("statemove end in %i", cmd->cmd.statemove->end_state); + DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state); +#if 1 + avago_end_state(cmd->cmd.statemove->end_state); + avago_state_move(); +#endif +} +static void avago_execute_pathmove(struct jtag_command *cmd) +{ + PRINTF(" Entered %s\n", __func__); + PRINTF("pathmove: %i states, end in %i", + cmd->cmd.pathmove->num_states, + cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); + DEBUG_JTAG_IO("pathmove: %i states, end in %i", + cmd->cmd.pathmove->num_states, + cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); +} +static void avago_execute_reset(struct jtag_command *cmd) +{ + PRINTF("reset trst: %i srst %i", + cmd->cmd.reset->trst, cmd->cmd.reset->srst); + DEBUG_JTAG_IO("reset trst: %i srst %i", + cmd->cmd.reset->trst, cmd->cmd.reset->srst); +#if 0 + avago_tap_execute(); + avago_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); + avago_tap_execute(); +#endif +} +static void avago_execute_sleep(struct jtag_command *cmd) +{ + PRINTF(" Entered %s\n", __func__); + PRINTF("sleep %" PRIi32 "", cmd->cmd.sleep->us); + DEBUG_JTAG_IO("sleep %" PRIi32 "", cmd->cmd.sleep->us); + avago_tap_execute(); + jtag_sleep(cmd->cmd.sleep->us); +} +static void avago_execute_command(struct jtag_command *cmd) +{ + PRINTF(" Entered %s\n", __func__); + switch (cmd->type) { + case JTAG_RUNTEST: + PRINTF(" JTAG_RUNTEST\n"); + avago_execute_runtest(cmd); + break; + case JTAG_TLR_RESET: + PRINTF(" JTAG_TLR_RESET\n"); + avago_execute_statemove(cmd); + /* May have to issue reset - TBD */ + break; + case JTAG_PATHMOVE: + PRINTF(" JTAG_PATHMOVE\n"); + avago_execute_pathmove(cmd); + break; + case JTAG_SCAN: + PRINTF(" JTAG_SCAN\n"); + avago_execute_scan(cmd); + break; + case JTAG_RESET: + PRINTF(" JTAG_RESET\n"); + avago_execute_reset(cmd); + break; + case JTAG_SLEEP: + PRINTF(" JTAG_SLEEP\n"); + avago_execute_sleep(cmd); + break; + default: + LOG_ERROR("BUG: unknown JTAG command type encountered"); + exit(-1); + } +} + +static int avago_execute_queue(void) +{ + struct jtag_command *cmd = jtag_command_queue; + PRINTF(" Entered %s\n", __func__); + + while (cmd != NULL) { + avago_execute_command(cmd); + cmd = cmd->next; + } + + return avago_tap_execute(); +} + + + +static const char * const avago_transports[] = { "jtag", NULL }; + +struct jtag_interface avago_interface = { + .name = "avago", + .transports = avago_transports, + + .execute_queue = avago_execute_queue, + .speed = avago_speed, + .speed_div = avago_speed_div, + .khz = avago_khz, + .init = avago_init, + .quit = avago_quit, +}; diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index ad656a8..a0a8ed5 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -84,6 +84,9 @@ extern struct jtag_interface openjtag_interface; #if BUILD_JLINK == 1 extern struct jtag_interface jlink_interface; #endif +#if BUILD_AVAGO_PILOT == 1 +extern struct jtag_interface avago_interface; +#endif #if BUILD_VSLLINK == 1 extern struct jtag_interface vsllink_interface; #endif @@ -216,6 +219,9 @@ struct jtag_interface *jtag_interfaces[] = { #if BUILD_CMSIS_DAP == 1 &cmsis_dap_interface, #endif +#if BUILD_AVAGO_PILOT == 1 + &avago_interface, +#endif #endif /* standard drivers */ NULL, }; diff --git a/tcl/interface/avago_pilot.cfg b/tcl/interface/avago_pilot.cfg new file mode 100644 index 0000000..9458b65 --- /dev/null +++ b/tcl/interface/avago_pilot.cfg @@ -0,0 +1,6 @@ +# +# Avago Pilot's JTAG Master +# +# + +interface avago diff --git a/tcl/target/pilot4.cfg b/tcl/target/pilot4.cfg new file mode 100644 index 0000000..67a4247 --- /dev/null +++ b/tcl/target/pilot4.cfg @@ -0,0 +1,45 @@ +# +# Pilot4 ASIC OpenOCD config file +# The following frequencies are supported by the Avago Pilot4 JTAG Master adapter +# these can be selected using the "adapter_khz" as mentioned below +# 31200Khz +# 15620Khz +# 7800Khz +# 3900Khz +# 1950Khz +# 976Khz +# 488Khz +# 244Khz +# 122Khz +# 61Khz +# 30Khz +# 15Khz +# 7Khz + +set _CHIPNAME pilot4 +set _TARGETNAME $_CHIPNAME.cpu + +jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477 + +target create ${_TARGETNAME}0 cortex_a -chain-position $_CHIPNAME.dap \ + -coreid 0 -dbgbase 0x80110000 +target create ${_TARGETNAME}1 cortex_a -chain-position $_CHIPNAME.dap \ + -coreid 1 -dbgbase 0x80112000 +target smp ${_TARGETNAME}0 ${_TARGETNAME}1 + + +reset_config trst_and_srst srst_pulls_trst + +adapter_khz 7800 + +${_TARGETNAME}0 configure -event reset-assert-post "cortex_a dbginit" +${_TARGETNAME}1 configure -event reset-assert-post "cortex_a dbginit" + +pilot4.cpu0 configure -event gdb-attach { + echo "GDB attach called" + halt + dap apsel 1 + dap apcsw 1 + halt +} + -- ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
