diff --git a/jtag/include/jtag.h b/jtag/include/jtag.h index 6ea57404..2616fee0 100644 --- a/jtag/include/jtag.h +++ b/jtag/include/jtag.h @@ -45,6 +45,7 @@ int detect_register_size( chain_t *chain ); void discovery( chain_t *chain ); void readmem( bus_t *bus, FILE *f, uint32_t addr, uint32_t len ); +void writemem( bus_t *bus, FILE *f, uint32_t addr, uint32_t len ); void flasherase( bus_t *bus, uint32_t addr, int number ); diff --git a/jtag/src/Makefile.am b/jtag/src/Makefile.am index ff67b4d6..7040ce1d 100644 --- a/jtag/src/Makefile.am +++ b/jtag/src/Makefile.am @@ -40,6 +40,7 @@ jtag_SOURCES = \ detect.c \ discovery.c \ readmem.c \ + writemem.c \ flash.c bsdl2jtag_SOURCES = \ diff --git a/jtag/src/cmd/Makefile.am b/jtag/src/cmd/Makefile.am index 05ec267b..b70b71da 100644 --- a/jtag/src/cmd/Makefile.am +++ b/jtag/src/cmd/Makefile.am @@ -47,6 +47,7 @@ libcmd_a_SOURCES = \ endian.c \ peekpoke.c \ readmem.c \ + writemem.c \ flashmem.c \ eraseflash.c \ script.c \ diff --git a/jtag/src/cmd/cmd.c b/jtag/src/cmd/cmd.c index 61f36b70..778bb551 100644 --- a/jtag/src/cmd/cmd.c +++ b/jtag/src/cmd/cmd.c @@ -55,6 +55,7 @@ extern cmd_t cmd_endian; extern cmd_t cmd_peek; extern cmd_t cmd_poke; extern cmd_t cmd_readmem; +extern cmd_t cmd_writemem; extern cmd_t cmd_detectflash; extern cmd_t cmd_flashmem; extern cmd_t cmd_eraseflash; @@ -87,6 +88,7 @@ const cmd_t *cmds[] = { &cmd_peek, &cmd_poke, &cmd_readmem, + &cmd_writemem, &cmd_detectflash, &cmd_flashmem, &cmd_eraseflash, diff --git a/jtag/src/cmd/writemem.c b/jtag/src/cmd/writemem.c new file mode 100644 index 00000000..e39761b1 --- /dev/null +++ b/jtag/src/cmd/writemem.c @@ -0,0 +1,82 @@ +/* + * $Id$ + * + * Written by Kent Palmkvist , 2005 + * + * 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. + * + */ + +#include "sysdep.h" + +#include +#include + +#include "jtag.h" + +#include "cmd.h" + +static int +cmd_writemem_run( char *params[] ) +{ + uint32_t adr; + uint32_t len; + FILE *f; + + if (cmd_params( params ) != 4) + return -1; + + if (!bus) { + printf( _("Error: Bus driver missing.\n") ); + return 1; + } + + if (cmd_get_number( params[1], &adr) || cmd_get_number( params[2], &len)) + return -1; + + f = fopen( params[3], "r" ); + if (!f) { + printf( _("Unable to open file `%s'!\n"), params[3] ); + return 1; + } + writemem( bus, f, adr, len ); + fclose( f ); + + return 1; +} + +static void +cmd_writemem_help( void ) +{ + printf( _( + "Usage: %s ADDR LEN FILENAME\n" + "Write to device memory starting at ADDR the FILENAME file.\n" + "\n" + "ADDR start address of the written memory area\n" + "LEN written memory length\n" + "FILENAME name of the input file\n" + "\n" + "ADDR and LEN could be in decimal or hexadecimal (prefixed with 0x) form.\n" + "NOTE: This is NOT useful for FLASH programming!\n" + ), "writemem" ); +} + +cmd_t cmd_writemem = { + "writemem", + N_("write content of file to the memory"), + cmd_writemem_help, + cmd_writemem_run +}; diff --git a/jtag/src/writemem.c b/jtag/src/writemem.c new file mode 100644 index 00000000..4a32d277 --- /dev/null +++ b/jtag/src/writemem.c @@ -0,0 +1,123 @@ +/* + * $Id$ + * + * Written by Kent Palmkvist (kentp@isy.liu.se>, 2005. + * + * 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. + * + * + */ + +#include "sysdep.h" + +#include +#include +#include +#include +#include + +#include "bus.h" +#include "flash.h" +#include "jtag.h" + +void +writemem( bus_t *bus, FILE *f, uint32_t addr, uint32_t len ) +{ + uint32_t step; + uint64_t a; + int bc = 0; + int bidx = 0; +#define BSIZE 4096 + uint8_t b[BSIZE]; + bus_area_t area; + uint64_t end; + + if (!bus) { + printf( _("Error: Missing bus driver!\n") ); + return; + } + + bus_prepare( bus ); + + if (bus_area( bus, addr, &area ) != 0) { + printf( _("Error: Bus width detection failed\n") ); + return; + } + step = area.width / 8; + + if (step == 0) { + printf( _("Unknown bus width!\n") ); + return; + } + + addr = addr & (~(step - 1)); + len = (len + step - 1) & (~(step - 1)); + + printf( _("address: 0x%08X\n"), addr ); + printf( _("length: 0x%08X\n"), len ); + + if (len == 0) { + printf( _("length is 0.\n") ); + return; + } + + a = addr; + end = a + len; + printf( _("writing:\n") ); + + for (; a < end; a += step) { + uint32_t data; + int j; + + /* Read one block of data */ + if ( bc < step ) { + printf( _("addr: 0x%08X"), a ); + printf( "\r" ); + fflush( stdout ); + if (bc != 0) + printf( _("Data not on word boundary, NOT SUPPORTED!"), bc); + if feof(f) { + printf( _("Unexpected end of file!\n")); + printf( _("Addr: 0x%08X\n"), a); + break; + } + bc = fread( b, 1, BSIZE, f ); + if (!bc) { + printf( _("Short read: bc=0x%X\n"), bc); + } + bidx = 0; + + } + + /* Write a word at time */ + data = 0; + for (j = step; j > 0; j--) { + if (big_endian) { + data |= b[bidx++]; + data <<= 8; + bc--; + } else { + data |= (b[bidx++] << ((step - j) * 8)); + bc--; + } + } + + bus_write( bus, a, data ); + + } + + printf( _("\nDone.\n") ); +}