diff --git a/jtag/ChangeLog b/jtag/ChangeLog index 0fcde2cc..75c0f36a 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,3 +1,13 @@ +2003-05-22 Marcel Telka + + * src/jtag.c: Added new global variable 'big_endian'. + * include/jtag.h: Ditto. + * src/flash.c (flashmem): Added full support for little/big endian. + * src/readmem.c (readmem): Ditto. + * src/cmd/Makefile.am (libcmd_a_SOURCES): Added endian.c. + * src/cmd/cmd.c (cmds): Added new command 'endian'. + * src/cmd/endian.c: New file. + 2003-05-21 Marcel Telka * Makefile.rules: New file. diff --git a/jtag/NEWS b/jtag/NEWS index 5d2fbff2..b48f446b 100644 --- a/jtag/NEWS +++ b/jtag/NEWS @@ -5,6 +5,7 @@ $Id$ * Disabled external bus cycles for PXA250 for addresses above 0x04000000. * Fixed bug in BUSY signal handling in Linux ppdev driver. * Optimized bus drivers to increase bus access speed (readmem, flashmem, ...). + * Added new command 'endian' to configure access mode to external files. * Minor bugs fixed. jtag-0.3.2 (2003-04-04): diff --git a/jtag/TODO b/jtag/TODO index 21a3c15f..3b791fe1 100644 --- a/jtag/TODO +++ b/jtag/TODO @@ -4,5 +4,4 @@ $Id$ * Add support for non-IDCODE-capable parts. * Support for display the result of a boundary scan formated according to the CPU definitions (e.g. MA[0-26] = 0x00001c00). * Remove direct relation between JTAG instruction and data register (e.g. ARM7TDMI). -* Configurable big endian vs. little endian access. * SVF player. diff --git a/jtag/include/jtag.h b/jtag/include/jtag.h index baa9156d..f9347cc8 100644 --- a/jtag/include/jtag.h +++ b/jtag/include/jtag.h @@ -34,6 +34,7 @@ extern chain_t *chain; extern bus_t *bus; +extern int big_endian; int jtag_parse_file( const char *filename ); diff --git a/jtag/src/cmd/Makefile.am b/jtag/src/cmd/Makefile.am index a098173c..39306ab4 100644 --- a/jtag/src/cmd/Makefile.am +++ b/jtag/src/cmd/Makefile.am @@ -39,6 +39,7 @@ libcmd_a_SOURCES = \ dr.c \ get.c \ set.c \ + endian.c \ readmem.c \ detectflash.c \ flashmem.c \ diff --git a/jtag/src/cmd/cmd.c b/jtag/src/cmd/cmd.c index 7f2992b6..89006f9f 100644 --- a/jtag/src/cmd/cmd.c +++ b/jtag/src/cmd/cmd.c @@ -50,6 +50,7 @@ extern cmd_t cmd_shift; extern cmd_t cmd_dr; extern cmd_t cmd_get; extern cmd_t cmd_set; +extern cmd_t cmd_endian; extern cmd_t cmd_readmem; extern cmd_t cmd_detectflash; extern cmd_t cmd_flashmem; @@ -68,6 +69,7 @@ const cmd_t *cmds[] = { &cmd_dr, &cmd_get, &cmd_set, + &cmd_endian, &cmd_readmem, &cmd_detectflash, &cmd_flashmem, diff --git a/jtag/src/cmd/endian.c b/jtag/src/cmd/endian.c new file mode 100644 index 00000000..99527033 --- /dev/null +++ b/jtag/src/cmd/endian.c @@ -0,0 +1,82 @@ +/* + * $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. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gettext.h" +#define _(s) gettext(s) +#define N_(s) gettext_noop(s) +#define P_(s,p,n) ngettext(s,p,n) + +#include +#include + +#include "jtag.h" + +#include "cmd.h" + +static int +cmd_endian_run( char *params[] ) +{ + if (cmd_params( params ) > 2) + return -1; + + if (!params[1]) { + if (big_endian) + printf( _("Endianess for external files: big\n") ); + else + printf( _("Endianess for external files: little\n") ); + return 1; + } + + + if (strcmp( params[1], "little" ) == 0) { + big_endian = 0; + return 1; + } + if (strcmp( params[1], "big" ) == 0) { + big_endian = 1; + return 1; + } + + return -1; +} + +static void +cmd_endian_help( void ) +{ + printf( _( + "Usage: %s\n" + "Set or print endianess for external files.\n" + ), "endian [little|big]" ); +} + +cmd_t cmd_endian = { + "endian", + N_("set/print endianess"), + cmd_endian_help, + cmd_endian_run +}; diff --git a/jtag/src/flash.c b/jtag/src/flash.c index 3d4ce197..84b0a84a 100644 --- a/jtag/src/flash.c +++ b/jtag/src/flash.c @@ -38,12 +38,10 @@ #include #include -#include -/* for ntohs */ - #include "bus.h" #include "flash.h" #include "cfi.h" +#include "jtag.h" extern flash_driver_t amd_32_flash_driver; extern flash_driver_t intel_32_flash_driver; @@ -253,7 +251,7 @@ flashmem( bus_t *bus, FILE *f, uint32_t addr ) while (!feof( f )) { uint32_t data; #define BSIZE 4096 - char b[BSIZE]; + uint8_t b[BSIZE]; int bc = 0, bn = 0; int block_no = adr / (cfi->device_geometry.erase_block_regions[0].erase_block_size * flash_driver->buswidth / 2); @@ -266,12 +264,17 @@ flashmem( bus_t *bus, FILE *f, uint32_t addr ) bn = fread( b, 1, BSIZE, f ); for (bc = 0; bc < bn; bc += flash_driver->buswidth) { + int j; printf( "addr: 0x%08X\r", adr ); fflush( stdout ); - if (flash_driver->buswidth == 2) - data = htons( *((uint16_t *) &b[bc]) ); - else - data = * ((uint32_t *) &b[bc]); + + data = 0; + for (j = 0; j < flash_driver->buswidth; j++) + if (big_endian) + data = (data << 8) | b[bc + j]; + else + data |= b[bc + j] << (j * 8); + if (flash_program( bus, adr, data )) { printf( "\nflash error\n" ); return; @@ -283,22 +286,30 @@ flashmem( bus_t *bus, FILE *f, uint32_t addr ) flash_readarray( bus ); - if (flash_driver->buswidth == 4) { /* TODO: not available in 1 x 16 bit mode */ fseek( f, 0, SEEK_SET ); printf( "verify:\n" ); fflush( stdout ); adr = addr; while (!feof( f )) { + uint8_t buf[16]; uint32_t data; uint32_t readed; + int j; - if (fread( &data, flash_driver->buswidth, 1, f ) != 1) { + if (fread( buf, flash_driver->buswidth, 1, f ) != 1) { if (feof(f)) break; printf( "Error during file read.\n" ); return; } + data = 0; + for (j = 0; j < flash_driver->buswidth; j++) + if (big_endian) + data = (data << 8) | buf[j]; + else + data |= buf[j] << (j * 8); + printf( "addr: 0x%08X\r", adr ); fflush( stdout ); readed = bus_read( bus, adr ); @@ -309,8 +320,6 @@ flashmem( bus_t *bus, FILE *f, uint32_t addr ) adr += flash_driver->buswidth; } printf( "\nDone.\n" ); - } else - printf( "TODO: Verify is not available in 1 x 16 bit mode.\n" ); free( erased ); diff --git a/jtag/src/jtag.c b/jtag/src/jtag.c index 92530db1..30a3da18 100644 --- a/jtag/src/jtag.c +++ b/jtag/src/jtag.c @@ -52,6 +52,7 @@ ssize_t getline( char **lineptr, size_t *n, FILE *stream ); chain_t *chain = NULL; bus_t *bus = NULL; +int big_endian = 0; static char * get_token( char *buf ) diff --git a/jtag/src/readmem.c b/jtag/src/readmem.c index fd8df841..79221ace 100644 --- a/jtag/src/readmem.c +++ b/jtag/src/readmem.c @@ -43,12 +43,10 @@ #include #include -#include -/* for ntohs */ - #include "cfi.h" #include "bus.h" #include "flash.h" +#include "jtag.h" void detectflash( bus_t *bus ) @@ -205,6 +203,8 @@ readmem( bus_t *bus, FILE *f, uint32_t addr, uint32_t len ) int step = 0; uint32_t a; int bc = 0; +#define BSIZE 4096 + uint8_t b[BSIZE]; if (!bus) { printf( "Error: Missing bus driver!\n" ); @@ -234,28 +234,22 @@ readmem( bus_t *bus, FILE *f, uint32_t addr, uint32_t len ) printf( "reading:\n" ); bus_read_start( bus, addr ); for (a = addr + step; a <= addr + len; a += step) { - uint32_t d = 0; - uint16_t d16 = 0; -#define BSIZE 4096 - char b[BSIZE]; + uint32_t data; + int j; + + if (a < addr + len) + data = bus_read_next( bus, a ); + else + data = bus_read_end( bus ); + + for (j = step; j > 0; j--) + if (big_endian) + b[bc++] = (data >> ((j - 1) * 8)) & 0xFF; + else { + b[bc++] = data & 0xFF; + data >>= 8; + } - if (a < addr + len) { - if (step == 2) - d16 = bus_read_next( bus, a ); - else - d = bus_read_next( bus, a ); - } - else { - if (step == 2) - d16 = bus_read_end( bus ); - else - d = bus_read_end( bus ); - } - if (step == 2) - *((uint16_t *) &b[bc]) = ntohs(d16); - else - *((uint32_t *) &b[bc]) = d; - bc += step; if ((bc >= BSIZE) || (a >= (addr + len)) ) { printf( "addr: 0x%08X\r", a ); fwrite( b, bc, 1, f );