# HG changeset patch # User Michael Spacefalcon # Date 1372308977 0 # Node ID 6fb41cfa773de59aeb44e4141fab66ef49b73833 # Parent a10491da8c3a499da54227fb1d7d2f329e588fd5 fc-loadtool: flash erase implemented, compiles diff -r a10491da8c3a -r 6fb41cfa773d loadtools/Makefile --- a/loadtools/Makefile Mon Jun 24 17:46:15 2013 +0000 +++ b/loadtools/Makefile Thu Jun 27 04:56:17 2013 +0000 @@ -9,10 +9,10 @@ IRAM_OBJS= defpath.o hexdecode.o hwparam.o hwparamstubs.o romload.o \ sercomm.o sertool.o srecreader.o ttypassthru.o -LOADTOOL_OBJS= crc32tab.o defpath.o flutil.o hexdecode.o hwparam.o labaud.o \ - ltdispatch.o ltdump.o ltexit.o ltflash.o ltmain.o ltpassthru.o \ - ltscript.o romload.o sercomm.o srecreader.o tpinterf.o \ - tpinterf2.o +LOADTOOL_OBJS= crc32tab.o defpath.o flerase.o flutil.o hexdecode.o hwparam.o \ + labaud.o ltdispatch.o ltdump.o ltexit.o ltflash.o ltmain.o \ + ltpassthru.o ltscript.o romload.o sercomm.o srecreader.o \ + tpinterf.o tpinterf2.o tpinterf3.o XRAM_OBJS= chainload.o clmain.o defpath.o hexdecode.o hwparam.o \ hwparamstubs.o initscript.o labaud.o romload.o sercomm.o \ diff -r a10491da8c3a -r 6fb41cfa773d loadtools/flerase.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/loadtools/flerase.c Thu Jun 27 04:56:17 2013 +0000 @@ -0,0 +1,110 @@ +/* + * This module implements the flash erase operation + */ + +#include +#include +#include +#include +#include +#include "flash.h" + +extern struct flash_bank_info flash_bank_info[2]; + +do_sector_erase(bi, sp) + struct flash_bank_info *bi; + struct sector_info *sp; +{ + int stat; + uint16_t flstat; + time_t start_time, curtime; + + stat = do_w16(bi->base_addr + sp->start + 0xAAA, 0xAA); + if (stat) { +bad_w16: fprintf(stderr, + "unexpected response to w16 in erase cmd sequence - aborting\n"); + return(-1); + } + stat = do_w16(bi->base_addr + sp->start + 0x554, 0x55); + if (stat) + goto bad_w16; + stat = do_w16(bi->base_addr + sp->start + 0xAAA, 0x80); + if (stat) + goto bad_w16; + stat = do_w16(bi->base_addr + sp->start + 0xAAA, 0xAA); + if (stat) + goto bad_w16; + stat = do_w16(bi->base_addr + sp->start + 0x554, 0x55); + if (stat) + goto bad_w16; + stat = do_w16(bi->base_addr + sp->start + 0xAAA, 0x30); + if (stat) + goto bad_w16; + start_time = time(0); + for (;;) { + stat = do_r16(bi->base_addr + sp->start, &flstat); + if (stat) + return(stat); /* error msg already printed */ + if (flstat == 0xFFFF) + return(0); + curtime = time(0); + if (curtime >= start_time + 20) { + fprintf(stderr, "erase timeout, aborting\n"); + return(-1); + } + } +} + +flashcmd_erase(argc, argv, bank) + char **argv; +{ + struct flash_bank_info *bi; + u_long offset, len; + char *strtoul_endp; + struct sector_info *startsec, *endsec, *sp; + int stat; + + if (argc != 4) { +inv: fprintf(stderr, "usage: %s %s hex-start-offset hex-length\n", + argv[0], argv[1]); + return(-1); + } + offset = strtoul(argv[2], &strtoul_endp, 16); + if (*strtoul_endp) + goto inv; + bi = flash_bank_info + bank; + if (offset >= bi->total_size) { + fprintf(stderr, + "error: specified offset exceeds flash bank size (0x%lx)\n", + (u_long) bi->total_size); + return(-1); + } + len = strtoul(argv[3], &strtoul_endp, 16); + if (*strtoul_endp) + goto inv; + if (len > bi->total_size - offset) { + fprintf(stderr, + "error: specified offset+length exceed flash bank size (0x%lx)\n", + (u_long) bi->total_size); + return(-1); + } + if (!len) { + printf("Zero length specified - nothing to do!\n"); + return(0); + } + /* now enforce sector alignment for both offset and length */ + if (get_flash_sector_table(bank) < 0) + return(-1); + if (get_flash_sector_range(bi, offset, len, &startsec, &endsec) < 0) + return(-1); + printf("Erasing %d sector(s)\n", endsec - startsec); + for (sp = startsec; sp < endsec; sp++) { + stat = do_sector_erase(bi, sp); + if (stat) + return(stat); + putchar('.'); + fflush(stdout); + } + putchar('\n'); + return(0); +} diff -r a10491da8c3a -r 6fb41cfa773d loadtools/flutil.c --- a/loadtools/flutil.c Mon Jun 24 17:46:15 2013 +0000 +++ b/loadtools/flutil.c Thu Jun 27 04:56:17 2013 +0000 @@ -99,3 +99,33 @@ printf("%08lX %lx\n", (u_long) sp->start, (u_long) sp->size); return(0); } + +get_flash_sector_range(bi, useroff, userlen, startp, endp) + struct flash_bank_info *bi; + u_long useroff, userlen; + struct sector_info **startp, **endp; +{ + struct sector_info *sp; + uint32_t remlen; + + for (sp = bi->sectors; sp->size; sp++) + if (sp->start == useroff) + break; + if (!sp->size) { + fprintf(stderr, + "error: specified offset not aligned to a flash sector boundary\n"); + return(-1); + } + *startp = sp; + for (remlen = userlen; remlen; ) { + if (remlen < sp->size) { + fprintf(stderr, + "error: specified length not aligned to a flash sector boundary\n"); + return(-1); + } + remlen -= sp->size; + sp++; + } + *endp = sp; + return(0); +} diff -r a10491da8c3a -r 6fb41cfa773d loadtools/ltflash.c --- a/loadtools/ltflash.c Mon Jun 24 17:46:15 2013 +0000 +++ b/loadtools/ltflash.c Thu Jun 27 04:56:17 2013 +0000 @@ -247,6 +247,7 @@ return(0); } +extern int flashcmd_erase(); extern int flashcmd_sectors(); static struct cmdtab { @@ -256,6 +257,7 @@ {"blankchk", flashcmd_blankchk}, {"dump2bin", flashcmd_dump2file}, {"dump2srec", flashcmd_dump2file}, + {"erase", flashcmd_erase}, {"info", flashcmd_info}, {"sectors", flashcmd_sectors}, {0, 0} diff -r a10491da8c3a -r 6fb41cfa773d loadtools/tpinterf3.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/loadtools/tpinterf3.c Thu Jun 27 04:56:17 2013 +0000 @@ -0,0 +1,60 @@ +/* + * The do_r16() and do_w16() functions implemented in this module + * provide programmatic access to the r16 and w16 commands on the target. + * They will be used to implement some flash operations. + */ + +#include +#include +#include +#include +#include +#include + +extern char target_response_line[]; + +do_r16(addr, retptr) + uint32_t addr; + uint16_t *retptr; +{ + char addr_arg[10], *argv[3]; + int stat; + char *strtoul_endp; + + sprintf(addr_arg, "%lx", (u_long) addr); + argv[0] = "r16"; + argv[1] = addr_arg; + argv[2] = 0; + tpinterf_make_cmd(argv); + if (tpinterf_send_cmd() < 0) + return(-1); + stat = tpinterf_capture_output_oneline(1); + if (stat != 1) { +errout: fprintf(stderr, "error: malformed response to r16 command\n"); + return(-1); + } + if (strlen(target_response_line) != 4) + goto errout; + *retptr = strtoul(target_response_line, &strtoul_endp, 16); + if (strtoul_endp != target_response_line + 4) + goto errout; + return(0); +} + +do_w16(addr, data) + uint32_t addr; + uint16_t data; +{ + char addr_arg[10], data_arg[10], *argv[4]; + + sprintf(addr_arg, "%lx", (u_long) addr); + sprintf(data_arg, "%lx", (u_long) data); + argv[0] = "w16"; + argv[1] = addr_arg; + argv[2] = data_arg; + argv[3] = 0; + tpinterf_make_cmd(argv); + if (tpinterf_send_cmd() < 0) + return(-1); + return tpinterf_pass_output(1); +}