From e9b917907c2c00676da52d6e6e2ee0552d273f3f Mon Sep 17 00:00:00 2001 From: Marcel Telka Date: Mon, 28 Oct 2002 19:34:25 +0000 Subject: [PATCH] Added support for flashing msbin files. git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@238 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 --- jtag/src/flash.c | 169 +++++++++++++++++++++++++++++++++++++++++++++-- jtag/src/jtag.c | 27 +++++++- 2 files changed, 187 insertions(+), 9 deletions(-) diff --git a/jtag/src/flash.c b/jtag/src/flash.c index 9e7b8c9c..85a6fc80 100644 --- a/jtag/src/flash.c +++ b/jtag/src/flash.c @@ -33,7 +33,9 @@ */ #include +#include #include +#include #include #include "part.h" @@ -46,12 +48,15 @@ int flash_erase_block32( parts *ps, uint32_t adr ); int flash_unlock_block32( parts *ps, uint32_t adr ); int flash_program32( parts *ps, uint32_t adr, uint32_t data ); +cfi_query_structure_t *detect_cfi( parts *ps ); + void -flashmem( parts *ps, FILE *f ) +flashmsbin( parts *ps, FILE *f ) { part *p = ps->parts[0]; int o = 0; uint32_t adr; + cfi_query_structure_t *cfi; printf( "Note: Supported configuration is 2 x 16 bit only\n" ); @@ -71,15 +76,165 @@ flashmem( parts *ps, FILE *f ) part_set_instruction( p, "EXTEST" ); parts_shift_instructions( ps ); - flash_unlock_block32( ps, 0 ); - printf( "block unlocked\n" ); - printf( "erasing block 0: %d\n", flash_erase_block32( ps, 0 ) ); + cfi = detect_cfi( ps ); + + /* test sync bytes */ + { + char sync[8]; + fread( &sync, sizeof (char), 7, f ); + sync[7] = '\0'; + if (strcmp( "B000FF\n", sync ) != 0) { + printf( "Invalid sync sequence!\n" ); + return; + } + } + + /* erase memory blocks */ + { + uint32_t start; + uint32_t len; + int first, last; + + fread( &start, sizeof start, 1, f ); + fread( &len, sizeof len, 1, f ); + first = start / (cfi->device_geometry.erase_block_regions[0].erase_block_size * 2); + last = (start + len - 1) / (cfi->device_geometry.erase_block_regions[0].erase_block_size * 2); + for (; first <= last; first++) { + adr = first * cfi->device_geometry.erase_block_regions[0].erase_block_size * 2; + flash_unlock_block32( ps, adr ); + printf( "block %d unlocked\n", first ); + printf( "erasing block %d: %d\n", first, flash_erase_block32( ps, adr ) ); + } + } printf( "program:\n" ); - adr = 0; + for (;;) { + uint32_t a, l, c; + + fread( &a, sizeof a, 1, f ); + fread( &l, sizeof l, 1, f ); + fread( &c, sizeof c, 1, f ); + if (feof( f )) { + printf( "Error: premature end of file\n" ); + return; + } + printf( "record: start = 0x%08X, len = 0x%08X, checksum = 0x%08X\n", a, l, c ); + if ((a == 0) && (c == 0)) + break; + if (l & 3) { + printf( "Error: Invalid record length!\n" ); + return; + } + + while (l) { + uint32_t data; + + printf( "addr: 0x%08X\r", a ); + fread( &data, sizeof data, 1, f ); + if (flash_program32( ps, a, data )) { + printf( "\nflash error\n" ); + return; + } + a += 4; + l -= 4; + } + } + printf( "\n" ); + + /* Read Array */ + bus_write( ps, 0 << o, 0x00FF00FF ); + + fseek( f, 15, SEEK_SET ); + printf( "verify:\n" ); + + for (;;) { + uint32_t a, l, c; + + fread( &a, sizeof a, 1, f ); + fread( &l, sizeof l, 1, f ); + fread( &c, sizeof c, 1, f ); + if (feof( f )) { + printf( "Error: premature end of file\n" ); + return; + } + printf( "record: start = 0x%08X, len = 0x%08X, checksum = 0x%08X\n", a, l, c ); + if ((a == 0) && (c == 0)) + break; + if (l & 3) { + printf( "Error: Invalid record length!\n" ); + return; + } + + while (l) { + uint32_t data, readed; + + printf( "addr: 0x%08X\r", a ); + fread( &data, sizeof data, 1, f ); + readed = bus_read( ps, a ); + if (data != readed) { + printf( "\nverify error: 0x%08X vs. 0x%08X\n", readed, data ); + return; + } + a += 4; + l -= 4; + } + } + printf( "\n" ); + + printf( "Done.\n" ); +} + +void +flashmem( parts *ps, FILE *f, uint32_t addr ) +{ + part *p = ps->parts[0]; + int o = 0; + uint32_t adr; + cfi_query_structure_t *cfi; + int *erased; + int i; + + printf( "Note: Supported configuration is 2 x 16 bit only\n" ); + + switch (bus_width( ps )) { + case 16: + o = 1; + break; + case 32: + o = 2; + break; + default: + printf( "Error: Unknown bus width!\n" ); + return; + } + + /* EXTEST */ + part_set_instruction( p, "EXTEST" ); + parts_shift_instructions( ps ); + + cfi = detect_cfi( ps ); + erased = malloc( cfi->device_geometry.erase_block_regions[0].number_of_erase_blocks * sizeof *erased ); + if (!erased) { + printf( "Out of memory!\n" ); + return; + } + for (i = 0; i < cfi->device_geometry.erase_block_regions[0].number_of_erase_blocks; i++) + erased[i] = 0; + + printf( "program:\n" ); + adr = addr; while (!feof( f )) { uint32_t data; + int block_no = adr / (cfi->device_geometry.erase_block_regions[0].erase_block_size * 2); printf( "addr: 0x%08X\r", adr ); + + if (!erased[block_no]) { + flash_unlock_block32( ps, adr ); + printf( "block %d unlocked\n", block_no ); + printf( "erasing block %d: %d\n", block_no, flash_erase_block32( ps, adr ) ); + erased[block_no] = 1; + } + fread( &data, sizeof data, 1, f ); if (flash_program32( ps, adr, data )) { printf( "\nflash error\n" ); @@ -94,7 +249,7 @@ flashmem( parts *ps, FILE *f ) fseek( f, 0, SEEK_SET ); printf( "verify:\n" ); - adr = 0; + adr = addr; while (!feof( f )) { uint32_t data; uint32_t readed; @@ -108,6 +263,8 @@ flashmem( parts *ps, FILE *f ) adr += 4; } printf( "\nDone.\n" ); + + free( erased ); } #define CFI_INTEL_ERROR_UNKNOWN 1 diff --git a/jtag/src/jtag.c b/jtag/src/jtag.c index b73ca6ea..bf32a568 100644 --- a/jtag/src/jtag.c +++ b/jtag/src/jtag.c @@ -47,7 +47,8 @@ get_token( char *buf ) } void readmem( parts *ps ); -void flashmem( parts *ps, FILE *f ); +void flashmem( parts *ps, FILE *f, uint32_t addr ); +void flashmsbin( parts *ps, FILE *f ); int main( void ) @@ -114,6 +115,23 @@ main( void ) if (strcmp( t, "flashmem" ) == 0) { FILE *f; + int msbin = 0; + uint32_t addr = 0; + + t = get_token( NULL ); + if (!t) { + printf( "flashmem: Missing argument(s)\n" ); + continue; + } + if (strcmp( t, "msbin" ) != 0) { + if ((sscanf( t, "0x%x", &addr ) != 1) && (sscanf( t, "%d", &addr ) != 1)) { + printf( "error\n" ); + continue; + } + printf( "0x%08X\n", addr ); + } else + msbin = 1; + /* filename */ t = get_token( NULL ); if (!t) { printf( "flashmem: missing filename\n" ); @@ -121,7 +139,7 @@ main( void ) } f = fopen( t, "r" ); if (!f) { - printf( "Unable to open file `%s!'\n", t ); + printf( "Unable to open file `%s'!\n", t ); continue; } t = get_token( NULL ); @@ -130,7 +148,10 @@ main( void ) fclose( f ); continue; } - flashmem( ps, f ); + if (msbin) + flashmsbin( ps, f ); + else + flashmem( ps, f, addr ); fclose( f ); continue; }