diff --git a/jtag/ChangeLog b/jtag/ChangeLog index ec55081f..5b59fb5f 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,3 +1,24 @@ +2003-08-13 Marcel Telka + + * include/part.h (struct part): Added new member 'id'. + (part_alloc): Added new parameter 'id'. + * src/detect.c (detect_parts): Added execution JTAG declarations as script. + * src/jtag.c (get_token): Added support for in-line comments. + * src/cmd/Makefile.am (libcmd_a_SOURCES): Added signal.c, bit.c, and register.c. + * src/cmd/bit.c: New file. + * src/cmd/register.c: Ditto. + * src/cmd/signal.c: Ditto. + * src/cmd/cmd.c (cmds): Added cmd_signal, cmd_bit, and cmd_register. + * src/cmd/instruction.c (cmd_instruction_run, cmd_instruction_help, cmd_instruction): Added support + for new instruction declaration. + * src/part/parse.c: File removed. + * src/part/Makefile.am (libpart_a_SOURCES): Removed parse.c. + * src/cmd/detect.c (cmd_detect_run): Fixed possible NULL pointer dereference. + * src/part/part.c (part_alloc): Added new parameter 'id'. + (part_free): Addedd id deallocation. + (part_print): Added support for instructions without data register. + * src/tap/chain.c (chain_shift_data_registers): Ditto. + 2003-08-13 Marcel Telka * data/broadcom/bcm5421s/bcm5421s: Fixed bad pin -> signal changes. diff --git a/jtag/NEWS b/jtag/NEWS index ea13d08f..da75fe00 100644 --- a/jtag/NEWS +++ b/jtag/NEWS @@ -22,7 +22,11 @@ jtag-0.5: more info, thanks to Ramses VI). * Fixed invalid memory allocation size (core dump) in jtag_parse_line() function. * Added new 'include' command. - * Added support for "downto" in bit vectors and "observe_only" (patch 787346, Brad Parker). + * Added new commands 'signal', 'register', 'bit', and enhanced 'instruction' command + to allow create JTAG declarations from command line (or script). + * JTAG declarations are now executed as scripts. + * Added support for "downto" in bit vectors and "observe_only" into bsdl2jtag + (patch 787346, Brad Parker). * Minor bugs fixed. jtag-0.4 (2003-05-29): diff --git a/jtag/include/part.h b/jtag/include/part.h index 7eba83c2..a29a28f1 100644 --- a/jtag/include/part.h +++ b/jtag/include/part.h @@ -39,6 +39,7 @@ typedef struct part part_t; struct part { + tap_register *id; char manufacturer[MAXLEN_MANUFACTURER + 1]; char part[MAXLEN_PART + 1]; char stepping[MAXLEN_STEPPING + 1]; @@ -51,7 +52,7 @@ struct part { bsbit_t **bsbits; }; -part_t *part_alloc( void ); +part_t *part_alloc( const tap_register *id ); void part_free( part_t *p ); part_t *read_part( FILE *f, tap_register_t *idr ); instruction *part_find_instruction( part_t *p, const char *iname ); diff --git a/jtag/src/cmd/Makefile.am b/jtag/src/cmd/Makefile.am index a084319a..697f15ba 100644 --- a/jtag/src/cmd/Makefile.am +++ b/jtag/src/cmd/Makefile.am @@ -30,6 +30,9 @@ libcmd_a_SOURCES = \ cable.c \ discovery.c \ detect.c \ + signal.c \ + bit.c \ + register.c \ print.c \ part.c \ bus.c \ diff --git a/jtag/src/cmd/bit.c b/jtag/src/cmd/bit.c new file mode 100644 index 00000000..f833ee2e --- /dev/null +++ b/jtag/src/cmd/bit.c @@ -0,0 +1,166 @@ +/* + * $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_bit_run( char *params[] ) +{ + part_t *part; + data_register *bsr; + unsigned int bit; + int type; + int safe; + unsigned int control; + + if ((cmd_params( params ) != 5) && (cmd_params( params ) != 8)) + return -1; + + + if (!cmd_test_cable()) + return 1; + + if (!chain->parts) { + printf( _("Run \"detect\" first.\n") ); + return 1; + } + + if (chain->active_part >= chain->parts->len) { + printf( _("%s: no active part\n"), "bit" ); + return 1; + } + + part = chain->parts->parts[chain->active_part]; + bsr = part_find_data_register( part, "BSR" ); + if (bsr == NULL) { + printf( _("missing Boundary Scan Register (BSR)\n") ); + return 1; + } + + /* bit number */ + if (cmd_get_number( params[1], &bit )) + return -1; + + if (bit >= bsr->in->len) { + printf( _("invalid boundary bit number\n") ); + return 1; + } + if (part->bsbits[bit] != NULL) { + printf( _("duplicate bit declaration\n") ); + return 1; + } + + /* bit type */ + if (strlen( params[2] ) != 1) + return -1; + switch (params[2][0]) { + case 'I': + type = BSBIT_INPUT; + break; + case 'O': + type = BSBIT_OUTPUT; + break; + case 'B': + type = BSBIT_BIDIR; + break; + case 'C': + type = BSBIT_CONTROL; + break; + case 'X': + type = BSBIT_INTERNAL; + break; + default: + return -1; + } + + /* default (safe) value */ + if (strlen( params[3] ) != 1) + return -1; + + safe = (params[3][0] == '1') ? 1 : 0; + bsr->in->data[bit] = safe; + + /* allocate bsbit */ + part->bsbits[bit] = bsbit_alloc( bit, params[4], type, part->signals, safe ); + if (part->bsbits[bit] == NULL) { + printf( _("out of memory\n") ); + return 1; + } + + /* test for control bit */ + if (cmd_params( params ) == 5) + return 1; + + /* control bit number */ + if (cmd_get_number( params[5], &control )) + return -1; + if (control >= bsr->in->len) { + printf( _("invalid control bit number\n") ); + return 1; + } + + /* control value */ + if (strlen( params[6] ) != 1) + return -1; + part->bsbits[bit]->control_value = (params[6][0] == '1') ? 1 : 0; + + /* control state */ + if ((strlen( params[7] ) != 1) || (params[7][0] != 'Z')) + return -1; + part->bsbits[bit]->control_state = BSBIT_STATE_Z; + + return 1; +} + +static void +cmd_bit_help( void ) +{ + printf( _( + "Usage: %s NUMBER TYPE DEFAULT SIGNAL [CBIT CVAL CSTATE]\n" + "Define new BSR (Boundary Scan Register) bit for SIGNAL, with\n" + "DEFAULT value.\n" + "\n" + "NUMBER Bit number in the BSR\n" + "TYPE Bit type, valid values are I, O, B, C, and X\n" + "DEFAULT Default (safe) bit value, valid values are 1, 0, ?\n" + "SIGNAL Associated signal name\n" + "CBIT Control bit number\n" + "CVAL Control value\n" + "CSTATE Control state, valid state is only Z\n" + ), "bit" ); +} + +cmd_t cmd_bit = { + "bit", + N_("define new BSR bit"), + cmd_bit_help, + cmd_bit_run +}; diff --git a/jtag/src/cmd/cmd.c b/jtag/src/cmd/cmd.c index 4c703ff7..c955a112 100644 --- a/jtag/src/cmd/cmd.c +++ b/jtag/src/cmd/cmd.c @@ -37,6 +37,9 @@ extern cmd_t cmd_frequency; extern cmd_t cmd_cable; extern cmd_t cmd_discovery; extern cmd_t cmd_detect; +extern cmd_t cmd_signal; +extern cmd_t cmd_bit; +extern cmd_t cmd_register; extern cmd_t cmd_print; extern cmd_t cmd_part; extern cmd_t cmd_bus; @@ -61,6 +64,9 @@ const cmd_t *cmds[] = { &cmd_cable, &cmd_discovery, &cmd_detect, + &cmd_signal, + &cmd_bit, + &cmd_register, &cmd_print, &cmd_part, &cmd_bus, diff --git a/jtag/src/cmd/detect.c b/jtag/src/cmd/detect.c index 0c2b4153..4de64d20 100644 --- a/jtag/src/cmd/detect.c +++ b/jtag/src/cmd/detect.c @@ -47,6 +47,8 @@ cmd_detect_run( char *params[] ) buses_free(); parts_free( chain->parts ); chain->parts = detect_parts( chain, JTAG_DATA_DIR ); + if (!chain->parts) + return 1; if (!chain->parts->len) { parts_free( chain->parts ); chain->parts = NULL; diff --git a/jtag/src/cmd/instruction.c b/jtag/src/cmd/instruction.c index 5f1047f0..fb253138 100644 --- a/jtag/src/cmd/instruction.c +++ b/jtag/src/cmd/instruction.c @@ -25,6 +25,7 @@ #include #include +#include #include "part.h" #include "jtag.h" @@ -34,8 +35,7 @@ static int cmd_instruction_run( char *params[] ) { - if (cmd_params( params ) != 2) - return -1; + part_t *part; if (!cmd_test_cable()) return 1; @@ -50,11 +50,65 @@ cmd_instruction_run( char *params[] ) return 1; } - part_set_instruction( chain->parts->parts[chain->active_part], params[1] ); - if (chain->parts->parts[chain->active_part]->active_instruction == NULL) - printf( _("%s: unknown instruction '%s'\n"), "instruction", params[1] ); + part = chain->parts->parts[chain->active_part]; - return 1; + if (cmd_params( params ) == 2) { + part_set_instruction( part, params[1] ); + if (part->active_instruction == NULL) + printf( _("%s: unknown instruction '%s'\n"), "instruction", params[1] ); + return 1; + } + + if (cmd_params( params ) == 3) { + unsigned int len; + + if (strcmp( params[1], "length" ) != 0) + return -1; + + if (part->instructions != NULL) { + printf( _("instruction length is already set and used\n") ); + return 1; + } + + if (cmd_get_number( params[2], &len )) + return -1; + + part->instruction_length = len; + return 1; + } + + if (cmd_params( params ) == 4) { + instruction *i; + + if (strlen( params[2] ) != part->instruction_length) { + printf( _("invalid instruction length\n") ); + return 1; + } + + if (part_find_instruction( part, params[1] ) != NULL) { + printf( _("Instruction '%s' already defined\n"), params[1] ); + return 1; + } + + i = instruction_alloc( params[1], part->instruction_length, params[2] ); + if (!i) { + printf( _("out of memory\n") ); + return 1; + } + + i->next = part->instructions; + part->instructions = i; + + i->data_register = part_find_data_register( part, params[3] ); + if (i->data_register == NULL) { + printf( _("unknown data register '%s'\n"), params[3] ); + return 1; + } + + return 1; + } + + return -1; } static void @@ -62,15 +116,20 @@ cmd_instruction_help( void ) { printf( _( "Usage: %s INSTRUCTION\n" - "Change active INSTRUCTION for a PART.\n" + "Usage: %s length LENGTH\n" + "Usage: %s INSTRUCTION CODE REGISTER\n" + "Change active INSTRUCTION for a part or declare new instruction.\n" "\n" "INSTRUCTION instruction name (e.g. BYPASS)\n" - ), "instruction" ); + "LENGTH common instruction length\n" + "CODE instruction code (e.g. 11111)\n" + "REGISTER default data register for instruction (e.g. BR)\n" + ), "instruction", "instruction", "instruction" ); } cmd_t cmd_instruction = { "instruction", - N_("change active instruction for a part"), + N_("change active instruction for a part or declare new instruction"), cmd_instruction_help, cmd_instruction_run }; diff --git a/jtag/src/cmd/register.c b/jtag/src/cmd/register.c new file mode 100644 index 00000000..595b01be --- /dev/null +++ b/jtag/src/cmd/register.c @@ -0,0 +1,116 @@ +/* + * $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 + +#include "jtag.h" + +#include "cmd.h" + +static int +cmd_register_run( char *params[] ) +{ + part_t *part; + unsigned int len; + data_register *dr; + + if (cmd_params( params ) != 3) + return -1; + + + if (!cmd_test_cable()) + return 1; + + if (!chain->parts) { + printf( _("Run \"detect\" first.\n") ); + return 1; + } + + if (chain->active_part >= chain->parts->len) { + printf( _("%s: no active part\n"), "register" ); + return 1; + } + + if (cmd_get_number( params[2], &len )) + return -1; + + part = chain->parts->parts[chain->active_part]; + + if (part_find_data_register( part, params[1] ) != NULL) { + printf( _("Data register '%s' already defined\n"), params[1] ); + return 1; + } + + dr = data_register_alloc( params[1], len ); + if (!dr) { + printf( _("out of memory\n") ); + return 1; + } + + dr->next = part->data_registers; + part->data_registers = dr; + + /* Boundary Scan Register */ + if (strcmp( dr->name, "BSR" ) == 0) { + int i; + + part->boundary_length = len; + part->bsbits = malloc( part->boundary_length * sizeof *part->bsbits ); + if (!part->bsbits) { + printf( _("out of memory\n") ); + return 1; + } + for (i = 0; i < part->boundary_length; i++) + part->bsbits[i] = NULL; + } + + /* Device Identification Register */ + if (strcmp( dr->name, "DIR" ) == 0) + register_init( dr->out, register_get_string( part->id ) ); + + return 1; +} + +static void +cmd_register_help( void ) +{ + printf( _( + "Usage: %s NAME LENGTH\n" + "Define new data register with specified NAME and LENGTH.\n" + "\n" + "NAME Data register name\n" + "LENGTH Data register length\n" + ), "register" ); +} + +cmd_t cmd_register = { + "register", + N_("define new data register for a part"), + cmd_register_help, + cmd_register_run +}; diff --git a/jtag/src/cmd/signal.c b/jtag/src/cmd/signal.c new file mode 100644 index 00000000..de741ab0 --- /dev/null +++ b/jtag/src/cmd/signal.c @@ -0,0 +1,93 @@ +/* + * $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 + +#include "jtag.h" + +#include "cmd.h" + +static int +cmd_signal_run( char *params[] ) +{ + part_t *part; + signal_t *s; + + if (cmd_params( params ) < 2) + return -1; + + + if (!cmd_test_cable()) + return 1; + + if (!chain->parts) { + printf( _("Run \"detect\" first.\n") ); + return 1; + } + + if (chain->active_part >= chain->parts->len) { + printf( _("%s: no active part\n"), "signal" ); + return 1; + } + + part = chain->parts->parts[chain->active_part]; + if (part_find_signal( part, params[1] ) != NULL) { + printf( _("Signal '%s' already defined\n"), params[1] ); + return 1; + } + + s = signal_alloc( params[1] ); + if (!s) { + printf( _("out of memory\n") ); + return 1; + } + + s->next = part->signals; + part->signals = s; + + return 1; +} + +static void +cmd_signal_help( void ) +{ + printf( _( + "Usage: %s SIGNAL [PINLIST...]\n" + "Define new signal with name SIGNAL for a part.\n" + "\n" + "SIGNAL New signal name\n" + "PINLIST List of pins for a signal (not used)\n" + ), "signal" ); +} + +cmd_t cmd_signal = { + "signal", + N_("define new signal for a part"), + cmd_signal_help, + cmd_signal_run +}; diff --git a/jtag/src/detect.c b/jtag/src/detect.c index 2bd745d6..5bb83af8 100644 --- a/jtag/src/detect.c +++ b/jtag/src/detect.c @@ -29,6 +29,8 @@ #include #include +#include + #include "register.h" #include "tap.h" #include "cable.h" @@ -162,6 +164,7 @@ parts_t * detect_parts( chain_t *chain, char *db_path ) { char data_path[1024]; + char *cmd[3] = {"script", data_path, NULL}; char manufacturer[MAXLEN_MANUFACTURER + 1]; char partname[MAXLEN_PART + 1]; char stepping[MAXLEN_STEPPING + 1]; @@ -180,6 +183,8 @@ detect_parts( chain_t *chain, char *db_path ) parts_free( ps ); return NULL; } + chain->parts = ps; + chain->active_part = 0; tap_reset( chain ); @@ -188,7 +193,6 @@ detect_parts( chain_t *chain, char *db_path ) tap_register *key; struct id_record idr; char *p; - FILE *f; part_t *part; tap_shift_register( chain, zeros, id, 0 ); @@ -279,20 +283,19 @@ detect_parts( chain_t *chain, char *db_path ) strcat( data_path, idr.name ); printf( _(" Filename: %s\n"), data_path ); - f = fopen( data_path, "r" ); - part = read_part( f, id ); + part = part_alloc( id ); if (part) { + parts_add_part( ps, part ); + chain->active_part = ps->len - 1; strcpy( part->manufacturer, manufacturer ); strcpy( part->part, partname ); strcpy( part->stepping, stepping ); + cmd_run( cmd ); part->active_instruction = part_find_instruction( part, "IDCODE" ); - parts_add_part( ps, part ); } else { - printf( _("%s(%s:%d) Error: part read failed\n"), __FUNCTION__, __FILE__, __LINE__ ); + printf( _("Out of memory\n") ); exit( 1 ); } - if (f) - fclose( f ); } chain_clock( chain, 1, 0 ); /* Exit1-DR */ diff --git a/jtag/src/jtag.c b/jtag/src/jtag.c index 38a739ed..e684ee98 100644 --- a/jtag/src/jtag.c +++ b/jtag/src/jtag.c @@ -47,7 +47,10 @@ int big_endian = 0; static char * get_token( char *buf ) { - return strtok( buf, " \f\n\r\t\v" ); + char *t = strtok( buf, " \f\n\r\t\v" ); + if (t && (*t == '#')) + return NULL; + return t; } #define JTAGDIR ".jtag" diff --git a/jtag/src/part/Makefile.am b/jtag/src/part/Makefile.am index 36c4bf21..19536cd9 100644 --- a/jtag/src/part/Makefile.am +++ b/jtag/src/part/Makefile.am @@ -30,5 +30,4 @@ libpart_a_SOURCES = \ instruction.c \ data_register.c \ bsbit.c \ - part.c \ - parse.c + part.c diff --git a/jtag/src/part/parse.c b/jtag/src/part/parse.c deleted file mode 100644 index 4603fd5f..00000000 --- a/jtag/src/part/parse.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * $Id$ - * - * Copyright (C) 2002 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 , 2002. - * - */ - -#include - -#include -#include -#include - -#include "part.h" -#include "register.h" - -static char * -get_token( char *buf ) -{ - char *t = strtok( buf, " \f\n\r\t\v" ); - if (t && (*t == '#')) - return NULL; - return t; -} - -part_t * -read_part( FILE *f, tap_register *idr ) -{ - int line = 0; - part_t *part; - - if (!f) - return NULL; - - part = part_alloc(); - if (!part) { - printf( _("Out of memory\n") ); - return NULL; - } - - for (;;) { - char *t; - char buf[1024]; - - if (fgets( buf, 1024, f ) == NULL) - break; - - line++; - - t = get_token( buf ); - if (!t) - continue; - - /* signal */ - if (strcmp( t, "pin" ) == 0 || strcmp( t, "signal" ) == 0) { - signal_t *s; - - t = get_token( NULL ); - if (!t) { - printf( _("(%d) parse error\n"), line ); - continue; - } - - s = signal_alloc( t ); - if (!s) { - printf( _("(%d) out of memory\n"), line ); - continue; - } - s->next = part->signals; - part->signals = s; - - continue; - } - - /* register */ - if (strcmp( t, "register" ) == 0) { - char *n = get_token( NULL ); /* register name */ - int l; - data_register *dr; - - t = get_token( NULL ); /* register length */ - if (!n || !t) { - printf( _("(%d) parse error\n"), line ); - continue; - } - - l = strtol( t, &t, 10 ); - if ((t && *t) || (l < 1)) { - printf( _("(%d) invalid register length\n"), line ); - continue; - } - - dr = data_register_alloc( n, l ); - if (!dr) { - printf( _("(%d) out of memory\n"), line ); - continue; - } - - t = get_token( NULL ); - if (t) { - printf( _("(%d) parse error\n"), line ); - continue; - } - - dr->next = part->data_registers; - part->data_registers = dr; - - /* Boundary Scan Register */ - if (strcmp( dr->name, "BSR" ) == 0) { - int i; - - part->boundary_length = l; - part->bsbits = malloc( part->boundary_length * sizeof *part->bsbits ); - if (!part->bsbits) { - printf( _("(%d) out of memory\n"), line ); - continue; - } - for (i = 0; i < part->boundary_length; i++) - part->bsbits[i] = NULL; - } - - /* Device Identification Register */ - if (strcmp( dr->name, "DIR" ) == 0) - register_init( dr->out, register_get_string( idr ) ); - - continue; - } - - /* instruction */ - if (strcmp( t, "instruction" ) == 0) { - t = get_token( NULL ); /* 'length' or instruction name */ - if (!t) { - printf( _("(%d) parse error\n"), line ); - continue; - } - /* we need 'length' first */ - if ((strcmp( t, "length" ) != 0) && (part->instruction_length == 0)) { - printf( _("(%d) instruction length missing\n"), line ); - continue; - } - - if (strcmp( t, "length" ) == 0) { - t = get_token( NULL ); - if (!t) { - printf( _("(%d) parse error\n"), line ); - continue; - } - part->instruction_length = strtol( t, &t, 10 ); - if ((t && *t) || (part->instruction_length < 1)) { - printf( _("(%d) invalid instruction length\n"), line ); - continue; - } - } else { - char *n = t; /* save instruction name */ - instruction *i; - - t = get_token( NULL ); /* instruction bits */ - if (!t || (strlen( t ) != part->instruction_length)) { - printf( _("(%d) parse error\n"), line ); - continue; - } - - i = instruction_alloc( n, part->instruction_length, t ); - if (!i) { - printf( _("(%d) out of memory\n"), line ); - continue; - } - - i->next = part->instructions; - part->instructions = i; - - t = get_token( NULL ); /* data register */ - if (!t) { - printf( _("(%d) parse error\n"), line ); - continue; - } - i->data_register = part_find_data_register( part, t ); - if (!i->data_register) { - printf( _("(%d) unknown data register\n"), line ); - continue; - } - } - - t = get_token( NULL ); - if (t) { - printf( _("(%d) parse error\n"), line ); - continue; - } - - continue; - } - - /* bit */ - if (strcmp( t, "bit" ) == 0) { - int bit; - int type; - int safe; - data_register *bsr = part_find_data_register( part, "BSR" ); - - if (!bsr) { - printf( _("(%d) missing Boundary Scan Register (BSR)\n"), line ); - continue; - } - - /* get bit number */ - t = get_token( NULL ); - bit = strtol( t, &t, 10 ); - if ((t && *t) || (bit < 0) || (bit >= bsr->in->len)) { - printf( _("(%d) invalid boundary bit number\n"), line ); - continue; - } - if (part->bsbits[bit]) { - printf( _("(%d) duplicate bit declaration\n"), line ); - continue; - } - - /* get bit type */ - t = get_token( NULL ); - if (!t || (strlen( t ) != 1)) { - printf( _("(%d) parse error\n"), line ); - continue; - } - switch (*t) { - case 'I': - type = BSBIT_INPUT; - break; - case 'O': - type = BSBIT_OUTPUT; - break; - case 'B': - type = BSBIT_BIDIR; - break; - case 'C': - type = BSBIT_CONTROL; - break; - case 'X': - type = BSBIT_INTERNAL; - break; - default: - printf( _("(%d) parse error\n"), line ); - continue; - } - - /* get safe value */ - t = get_token( NULL ); - if (!t || (strlen( t ) != 1)) { - printf( _("(%d) parse error\n"), line ); - continue; - } - safe = (*t == '1') ? 1 : 0; - bsr->in->data[bit] = safe; - - /* get bit name */ - t = get_token( NULL ); - if (!t) { - printf( _("(%d) parse error\n"), line ); - continue; - } - - /* allocate bsbit */ - part->bsbits[bit] = bsbit_alloc( bit, t, type, part->signals, safe ); - if (!part->bsbits[bit]) { - printf( _("(%d) out of memory\n"), line ); - continue; - } - - /* we have control bit? */ - t = get_token( NULL ); - if (t) { - int control; - - control = strtol( t, &t, 10 ); - if ((t && *t) || (control < 0)) { - printf( _("(%d) invalid control bit number\n"), line ); - continue; - } - part->bsbits[bit]->control = control; - - /* control value */ - t = get_token( NULL ); - if (!t || (strlen( t ) != 1)) { - printf( _("(%d) parse error\n"), line ); - continue; - } - part->bsbits[bit]->control_value = (*t == '1') ? 1 : 0; - - /* control state */ - t = get_token( NULL ); - if (!t || (strlen( t ) != 1)) { - printf( _("(%d) parse error\n"), line ); - continue; - } - if (*t != 'Z') { - printf( _("(%d) parse error\n"), line ); - continue; - } - part->bsbits[bit]->control_state = BSBIT_STATE_Z; - - t = get_token( NULL ); - if (t) { - printf( _("(%d) parse error\n"), line ); - continue; - } - - } - - continue; - } - - printf( _("(%d) parse error\n"), line ); - } - - return part; -} diff --git a/jtag/src/part/part.c b/jtag/src/part/part.c index 306468f2..000b2126 100644 --- a/jtag/src/part/part.c +++ b/jtag/src/part/part.c @@ -32,12 +32,13 @@ /* part */ part_t * -part_alloc( void ) +part_alloc( const tap_register *id ) { part_t *p = malloc( sizeof *p ); if (!p) return NULL; + p->id = register_duplicate( id ); p->manufacturer[0] = '\0'; p->part[0] = '\0'; p->stepping[0] = '\0'; @@ -60,7 +61,10 @@ part_free( part_t *p ) if (!p) return; - /* sirnals */ + /* id */ + free( p->id ); + + /* signals */ while (p->signals) { signal_t *s = p->signals; p->signals = s->next; @@ -213,8 +217,8 @@ part_get_signal( part_t *p, signal_t *s ) void part_print( part_t *p ) { - char *instruction; - char *dr; + char *instruction = NULL; + char *dr = NULL; char format[100]; if (!p) @@ -225,11 +229,13 @@ part_print( part_t *p ) if (p->active_instruction) { instruction = p->active_instruction->name; - dr = p->active_instruction->data_register->name; - } else { + if (p->active_instruction->data_register != NULL) + dr = p->active_instruction->data_register->name; + } + if (instruction == NULL) instruction = _("(none)"); + if (dr == NULL) dr = _("(none)"); - } printf( format, p->manufacturer, p->part, p->stepping, instruction, dr ); } diff --git a/jtag/src/tap/chain.c b/jtag/src/tap/chain.c index c6367ee8..b7ec60ce 100644 --- a/jtag/src/tap/chain.c +++ b/jtag/src/tap/chain.c @@ -134,6 +134,10 @@ chain_shift_data_registers( chain_t *chain, int capture_output ) printf( _("%s(%d) Part without active instruction\n"), __FILE__, __LINE__ ); continue; } + if (!ps->parts[i]->active_instruction->data_register) { + printf( _("%s(%d) Part without data register\n"), __FILE__, __LINE__ ); + continue; + } tap_shift_register( chain, ps->parts[i]->active_instruction->data_register->in, capture_output ? ps->parts[i]->active_instruction->data_register->out : NULL, (i + 1) == ps->len );