diff --git a/jtag/ChangeLog b/jtag/ChangeLog index 8807bbdb..e30439d6 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,3 +1,23 @@ +2003-08-11 Marcel Telka + + * include/bus.h (buses_t): Added new structure. + * src/jtag.c (bus): Removed global variable. + * src/bus/Makefile.am (libbus_a_SOURCES): Added buses.c. + * src/bus/buses.c: New file. + * src/bus/bcm1250.c (bcm1250_bus_printinfo): New function. + * src/bus/ixp425.c (ixp425_bus_printinfo): Ditto. + * src/bus/pxa2x0.c (pxa2x0_bus_printinfo): Ditto. + * src/bus/sa1110.c (sa1110_bus_printinfo): Ditto. + * src/bus/sh7727.c (sh7727_bus_printinfo): Ditto. + * src/bus/sh7750r.c (sh7750r_bus_printinfo): Ditto. + * src/cmd/Makefile.am (libcmd_a_SOURCES): Added bus.c. + * src/cmd/bus.c: New file. + * src/cmd/cmd.c (cmds): Added cmd_bus. + * src/cmd/detect.c (cmd_detect_run): Added support for multiple buses detection. + * src/cmd/print.c (cmd_print_run): Fixed header printing while syntax error. Added support for printing + list of active buses. + (cmd_print_help): Added new parameter 'bus'. + 2003-08-11 Marcel Telka * configure.ac (AC_INIT): Changed version number to 0.5. diff --git a/jtag/NEWS b/jtag/NEWS index d8dc3004..8850b0b3 100644 --- a/jtag/NEWS +++ b/jtag/NEWS @@ -16,6 +16,7 @@ jtag-0.5: - removed support for report results to file * Added new command 'part', syntax changes for 'set', 'get', 'dr', 'instruction', and 'print' commands. + * Added support for multiple buses, added new 'bus' command to change active bus. * Added initial JTAG declarations for Broadcom BCM3310 (see support request 770145 for more info, thanks to Ramses VI). * Fixed invalid memory allocation size (core dump) in jtag_parse_line() function. diff --git a/jtag/include/bus.h b/jtag/include/bus.h index 3a0deac3..15981847 100644 --- a/jtag/include/bus.h +++ b/jtag/include/bus.h @@ -31,6 +31,17 @@ #include +typedef struct { + int len; + bus_t **buses; +} buses_t; + +extern buses_t buses; + +void buses_free( void ); +void buses_add( bus_t *abus ); +void buses_delete( bus_t *abus ); + bus_t *new_sa1110_bus( chain_t *chain, int pn ); bus_t *new_pxa250_bus( chain_t *chain, int pn ); bus_t *new_ixp425_bus( chain_t *chain, int pn ); diff --git a/jtag/src/bus/Makefile.am b/jtag/src/bus/Makefile.am index 7ffbd9c0..3feb4d99 100644 --- a/jtag/src/bus/Makefile.am +++ b/jtag/src/bus/Makefile.am @@ -26,6 +26,7 @@ include $(top_srcdir)/Makefile.rules noinst_LIBRARIES = libbus.a libbus_a_SOURCES = \ + buses.c \ bcm1250.c \ ixp425.c \ pxa2x0.c \ diff --git a/jtag/src/bus/bcm1250.c b/jtag/src/bus/bcm1250.c index 664d4eef..f39a2bc3 100644 --- a/jtag/src/bus/bcm1250.c +++ b/jtag/src/bus/bcm1250.c @@ -2,6 +2,8 @@ /* * $Id$ * + * Copyright (C) 2003 ETC s.r.o. + * * 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 @@ -18,6 +20,7 @@ * 02111-1307, USA. * * Written by Matan Ziv-Av. + * MOdified by Marcel Telka , 2003. * */ @@ -87,6 +90,17 @@ setup_data( bus_t *bus, uint32_t d ) } #ifndef USE_BCM_EJTAG +static void +bcm1250_bus_printinfo( void ) +{ + int i; + + for (i = 0; i < CHAIN->parts->len; i++) + if (PART == CHAIN->parts->parts[i]) + break; + printf( _("Broadcom BCM1250 compatibile bus driver via BSR (JTAG part No. %d)\n"), i ); +} + void bcm1250_bus_read_start( bus_t *bus, uint32_t adr ) { @@ -248,6 +262,7 @@ bcm1250_bus_free( bus_t *bus ) static const bus_t bcm1250_bus = { NULL, + bcm1250_bus_printinfo, bcm1250_bus_prepare, bcm1250_bus_width, bcm1250_bus_read_start, diff --git a/jtag/src/bus/buses.c b/jtag/src/bus/buses.c new file mode 100644 index 00000000..a75b3a93 --- /dev/null +++ b/jtag/src/bus/buses.c @@ -0,0 +1,90 @@ +/* + * $Id$ + * + * Copyright (C) 2003 ETC s.r.o. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by Marcel Telka , 2003. + * + */ + +#include + +#include + +#include "bus.h" + +bus_t *bus = NULL; +buses_t buses = {0, NULL}; + +void buses_free( void ) +{ + int i; + + for (i = 0; i < buses.len; i++) + bus_free( buses.buses[i] ); + + free( buses.buses ); + buses.len = 0; + buses.buses = NULL; + bus = NULL; +} + +void buses_add( bus_t *abus ) +{ + bus_t **b; + + if (abus == NULL) + return; + + b = realloc( buses.buses, (buses.len + 1) * sizeof (bus_t *) ); + if (b == NULL) { + printf( _("Out of memory\n") ); + return; + } + buses.buses = b; + buses.buses[buses.len++] = abus; + if (bus == NULL) + bus = abus; +} + +void buses_delete( bus_t *abus ) +{ + int i; + bus_t **b; + + for (i = 0; i < buses.len; i++) + if (abus == buses.buses[i]) + break; + if (i >= buses.len) + return; + + while (i + 1 < buses.len) { + buses.buses[i] = buses.buses[i + 1]; + i++; + } + buses.len--; + b = realloc( buses.buses, buses.len * sizeof (bus_t *) ); + if ((b != NULL) || (buses.len == 0)) + buses.buses = b; + + if (bus != abus) + return; + + if (buses.len > 0) + bus = buses.buses[0]; +} diff --git a/jtag/src/bus/ixp425.c b/jtag/src/bus/ixp425.c index 6ffea92c..5eeeb2c0 100644 --- a/jtag/src/bus/ixp425.c +++ b/jtag/src/bus/ixp425.c @@ -112,6 +112,17 @@ setup_data( bus_t *bus, uint32_t d ) part_set_signal( p, EX_DATA[i], 1, (d >> i) & 1 ); } +static void +ixp425_bus_printinfo( void ) +{ + int i; + + for (i = 0; i < CHAIN->parts->len; i++) + if (PART == CHAIN->parts->parts[i]) + break; + printf( _("Intel IXP425 compatibile bus driver via BSR (JTAG part No. %d)\n"), i ); +} + static void ixp425_bus_prepare( bus_t *bus ) { @@ -216,6 +227,7 @@ ixp425_bus_free( bus_t *bus ) static const bus_t ixp425_bus = { NULL, + ixp425_bus_printinfo, ixp425_bus_prepare, ixp425_bus_width, ixp425_bus_read_start, diff --git a/jtag/src/bus/pxa2x0.c b/jtag/src/bus/pxa2x0.c index e4c0759d..cad2dfbc 100644 --- a/jtag/src/bus/pxa2x0.c +++ b/jtag/src/bus/pxa2x0.c @@ -97,6 +97,17 @@ setup_data( bus_t *bus, uint32_t d ) part_set_signal( p, MD[i], 1, (d >> i) & 1 ); } +static void +pxa2x0_bus_printinfo( void ) +{ + int i; + + for (i = 0; i < CHAIN->parts->len; i++) + if (PART == CHAIN->parts->parts[i]) + break; + printf( _("Intel PXA2x0 compatibile bus driver via BSR (JTAG part No. %d)\n"), i ); +} + static void pxa250_bus_prepare( bus_t *bus ) { @@ -254,6 +265,7 @@ pxa250_bus_free( bus_t *bus ) static const bus_t pxa250_bus = { NULL, + pxa2x0_bus_printinfo, pxa250_bus_prepare, pxa250_bus_width, pxa250_bus_read_start, diff --git a/jtag/src/bus/sa1110.c b/jtag/src/bus/sa1110.c index f045c0ec..44f8ef90 100644 --- a/jtag/src/bus/sa1110.c +++ b/jtag/src/bus/sa1110.c @@ -87,6 +87,17 @@ setup_data( bus_t *bus, uint32_t d ) part_set_signal( p, D[i], 1, (d >> i) & 1 ); } +static void +sa1110_bus_printinfo( void ) +{ + int i; + + for (i = 0; i < CHAIN->parts->len; i++) + if (PART == CHAIN->parts->parts[i]) + break; + printf( _("Intel SA-1110 compatibile bus driver via BSR (JTAG part No. %d)\n"), i ); +} + static void sa1110_bus_prepare( bus_t *bus ) { @@ -221,6 +232,7 @@ sa1110_bus_free( bus_t *bus ) static const bus_t sa1110_bus = { NULL, + sa1110_bus_printinfo, sa1110_bus_prepare, sa1110_bus_width, sa1110_bus_read_start, diff --git a/jtag/src/bus/sh7727.c b/jtag/src/bus/sh7727.c index 86a1e5e6..72680ad7 100644 --- a/jtag/src/bus/sh7727.c +++ b/jtag/src/bus/sh7727.c @@ -88,6 +88,17 @@ setup_data( bus_t *bus, uint32_t d ) part_set_signal( p, D[i], 1, (d >> i) & 1 ); } +static void +sh7727_bus_printinfo( void ) +{ + int i; + + for (i = 0; i < CHAIN->parts->len; i++) + if (PART == CHAIN->parts->parts[i]) + break; + printf( _("Hitachi SH7727 compatibile bus driver via BSR (JTAG part No. %d)\n"), i ); +} + static void sh7727_bus_prepare( bus_t *bus ) { @@ -244,6 +255,7 @@ sh7727_bus_free( bus_t *bus ) static const bus_t sh7727_bus = { NULL, + sh7727_bus_printinfo, sh7727_bus_prepare, sh7727_bus_width, sh7727_bus_read_start, diff --git a/jtag/src/bus/sh7750r.c b/jtag/src/bus/sh7750r.c index 2bb4689d..55f2e447 100644 --- a/jtag/src/bus/sh7750r.c +++ b/jtag/src/bus/sh7750r.c @@ -88,6 +88,17 @@ setup_data( bus_t *bus, uint32_t d ) part_set_signal( p, D[i], 1, (d >> i) & 1 ); } +static void +sh7750r_bus_printinfo( void ) +{ + int i; + + for (i = 0; i < CHAIN->parts->len; i++) + if (PART == CHAIN->parts->parts[i]) + break; + printf( _("Hitachi SH7750R compatibile bus driver via BSR (JTAG part No. %d)\n"), i ); +} + static void sh7750r_bus_prepare( bus_t *bus ) { @@ -243,6 +254,7 @@ sh7750r_bus_free( bus_t *bus ) static const bus_t sh7750r_bus = { NULL, + sh7750r_bus_printinfo, sh7750r_bus_prepare, sh7750r_bus_width, sh7750r_bus_read_start, diff --git a/jtag/src/cmd/Makefile.am b/jtag/src/cmd/Makefile.am index e8f4e3ac..2be0346a 100644 --- a/jtag/src/cmd/Makefile.am +++ b/jtag/src/cmd/Makefile.am @@ -32,6 +32,7 @@ libcmd_a_SOURCES = \ detect.c \ print.c \ part.c \ + bus.c \ instruction.c \ shift.c \ dr.c \ diff --git a/jtag/src/cmd/bus.c b/jtag/src/cmd/bus.c new file mode 100644 index 00000000..05aff910 --- /dev/null +++ b/jtag/src/cmd/bus.c @@ -0,0 +1,79 @@ +/* + * $Id$ + * + * Copyright (C) 2003 ETC s.r.o. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by Marcel Telka , 2003. + * + */ + +#include + +#include +#include + +#include "jtag.h" + +#include "cmd.h" + +static int +cmd_bus_run( char *params[] ) +{ + unsigned int n; + + if (cmd_params( params ) != 2) + return -1; + + if (!cmd_test_cable()) + return 1; + + if (!chain->parts) { + printf( _("Run \"detect\" first.\n") ); + return 1; + } + + if (cmd_get_number( params[1], &n )) + return -1; + + if (n >= buses.len) { + printf( _("%s: invalid bus number\n"), "bus" ); + return 1; + } + + bus = buses.buses[n]; + + return 1; +} + +static void +cmd_bus_help( void ) +{ + printf( _( + "Usage: %s BUS\n" + "Change active bus.\n" + "\n" + "BUS bus number\n" + ), "bus" ); +} + +cmd_t cmd_bus = { + "bus", + N_("change active bus"), + cmd_bus_help, + cmd_bus_run +}; diff --git a/jtag/src/cmd/cmd.c b/jtag/src/cmd/cmd.c index d4c16aad..88f3d07f 100644 --- a/jtag/src/cmd/cmd.c +++ b/jtag/src/cmd/cmd.c @@ -39,6 +39,7 @@ extern cmd_t cmd_discovery; extern cmd_t cmd_detect; extern cmd_t cmd_print; extern cmd_t cmd_part; +extern cmd_t cmd_bus; extern cmd_t cmd_instruction; extern cmd_t cmd_shift; extern cmd_t cmd_dr; @@ -61,6 +62,7 @@ const cmd_t *cmds[] = { &cmd_detect, &cmd_print, &cmd_part, + &cmd_bus, &cmd_instruction, &cmd_shift, &cmd_dr, diff --git a/jtag/src/cmd/detect.c b/jtag/src/cmd/detect.c index c7f32d55..0c2b4153 100644 --- a/jtag/src/cmd/detect.c +++ b/jtag/src/cmd/detect.c @@ -36,16 +36,15 @@ static int cmd_detect_run( char *params[] ) { + int i; + if (cmd_params( params ) != 1) return -1; if (!cmd_test_cable()) return 1; - if (bus) { - bus->free( bus ); - bus = NULL; - } + buses_free(); parts_free( chain->parts ); chain->parts = detect_parts( chain, JTAG_DATA_DIR ); if (!chain->parts->len) { @@ -58,18 +57,21 @@ cmd_detect_run( char *params[] ) chain_shift_data_registers( chain, 1 ); parts_set_instruction( chain->parts, "BYPASS" ); chain_shift_instructions( chain ); - if (strcmp( chain->parts->parts[0]->part, "SA1110" ) == 0) - bus = new_sa1110_bus( chain, 0 ); - if (strcmp( chain->parts->parts[0]->part, "PXA250" ) == 0) - bus = new_pxa250_bus( chain, 0 ); - if (strcmp( chain->parts->parts[0]->part, "IXP425" ) == 0) - bus = new_ixp425_bus( chain, 0 ); - if (strcmp( chain->parts->parts[0]->part, "SH7727" ) == 0) - bus = new_sh7727_bus( chain, 0 ); - if (strcmp( chain->parts->parts[0]->part, "SH7750R" ) == 0) - bus = new_sh7750r_bus( chain, 0 ); - if (strcmp( chain->parts->parts[0]->part, "BCM1250" ) == 0) - bus = new_bcm1250_bus( chain, 0 ); + + for (i = 0; i < chain->parts->len; i++) { + if (strcmp( chain->parts->parts[i]->part, "SA1110" ) == 0) + buses_add( new_sa1110_bus( chain, i ) ); + if (strcmp( chain->parts->parts[i]->part, "PXA250" ) == 0) + buses_add( new_pxa250_bus( chain, i ) ); + if (strcmp( chain->parts->parts[i]->part, "IXP425" ) == 0) + buses_add( new_ixp425_bus( chain, i ) ); + if (strcmp( chain->parts->parts[i]->part, "SH7727" ) == 0) + buses_add( new_sh7727_bus( chain, i ) ); + if (strcmp( chain->parts->parts[i]->part, "SH7750R" ) == 0) + buses_add( new_sh7750r_bus( chain, i ) ); + if (strcmp( chain->parts->parts[i]->part, "BCM1250" ) == 0) + buses_add( new_bcm1250_bus( chain, i ) ); + } return 1; } diff --git a/jtag/src/cmd/print.c b/jtag/src/cmd/print.c index ceaf9b78..f336018c 100644 --- a/jtag/src/cmd/print.c +++ b/jtag/src/cmd/print.c @@ -38,6 +38,7 @@ cmd_print_run( char *params[] ) char format[100]; char header[100]; int i; + int noheader = 0; if (cmd_params( params ) > 2) return -1; @@ -50,14 +51,23 @@ cmd_print_run( char *params[] ) return 1; } - snprintf( format, 100, _(" No. %%-%ds %%-%ds %%-%ds %%-%ds %%-%ds\n"), MAXLEN_MANUFACTURER, MAXLEN_PART, MAXLEN_STEPPING, - MAXLEN_INSTRUCTION, MAXLEN_DATA_REGISTER ); - snprintf( header, 100, format, _("Manufacturer"), _("Part"), _("Stepping"), _("Instruction"), _("Register") ); - printf( header ); + if (cmd_params( params ) == 2) { + if ((strcmp( params[1], "chain" ) != 0) && (strcmp( params[1], "bus") != 0)) + return -1; + if (strcmp( params[1], "bus") == 0) + noheader = 1; + } + + if (noheader == 0) { + snprintf( format, 100, _(" No. %%-%ds %%-%ds %%-%ds %%-%ds %%-%ds\n"), MAXLEN_MANUFACTURER, MAXLEN_PART, MAXLEN_STEPPING, + MAXLEN_INSTRUCTION, MAXLEN_DATA_REGISTER ); + snprintf( header, 100, format, _("Manufacturer"), _("Part"), _("Stepping"), _("Instruction"), _("Register") ); + printf( header ); - for (i = 0; i < strlen( header ); i++ ) - putchar( '-' ); - putchar( '\n' ); + for (i = 0; i < strlen( header ); i++ ) + putchar( '-' ); + putchar( '\n' ); + } if (cmd_params( params ) == 1) { if (chain->parts->len > chain->active_part) { @@ -67,10 +77,17 @@ cmd_print_run( char *params[] ) return 1; } - if (strcmp( params[1], "chain" ) != 0) - return -1; + if (strcmp( params[1], "chain" ) == 0) { + parts_print( chain->parts ); + return 1; + } - parts_print( chain->parts ); + for (i = 0; i < buses.len; i++) { + if (buses.buses[i] == bus) + printf( _("*") ); + printf( _("%d: "), i ); + bus_printinfo( buses.buses[i] ); + } return 1; } @@ -79,7 +96,7 @@ static void cmd_print_help( void ) { printf( _( - "Usage: %s [chain]\n" + "Usage: %s [chain|bus]\n" "Display JTAG chain status.\n" "\n" "Display list of the parts connected to the JTAG chain including\n" diff --git a/jtag/src/jtag.c b/jtag/src/jtag.c index 827fd865..38a739ed 100644 --- a/jtag/src/jtag.c +++ b/jtag/src/jtag.c @@ -42,7 +42,6 @@ ssize_t getline( char **lineptr, size_t *n, FILE *stream ); #endif chain_t *chain = NULL; -bus_t *bus = NULL; int big_endian = 0; static char *