FreeCalypso > hg > freecalypso-tools
diff loadtools/flmisc.c @ 0:e7502631a0f9
initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 11 Jun 2016 00:13:35 +0000 |
parents | |
children | 0dd2c87c1b63 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/loadtools/flmisc.c Sat Jun 11 00:13:35 2016 +0000 @@ -0,0 +1,311 @@ +/* + * Miscellaneous flash commands (fc-loadtool) are implemented here + */ + +#include <sys/types.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "flash.h" + +extern struct flash_bank_info flash_bank_info[2]; + +flashcmd_blankchk(argc, argv, bank) + char **argv; +{ + struct flash_bank_info *bi; + u_long offset, len; + char *strtoul_endp; + char *targv[4], targ_start[10], targ_len[10]; + + 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; + if (flash_get_cfi(bank) < 0) + return(-1); + bi = flash_bank_info + bank; + if (offset >= bi->geom->total_size) { + fprintf(stderr, + "error: specified offset exceeds flash bank size (0x%lx)\n", + (u_long) bi->geom->total_size); + return(-1); + } + len = strtoul(argv[3], &strtoul_endp, 16); + if (*strtoul_endp) + goto inv; + if (len > bi->geom->total_size - offset) { + fprintf(stderr, + "error: specified offset+length exceed flash bank size (0x%lx)\n", + (u_long) bi->geom->total_size); + return(-1); + } + /* reset flash to read mode */ + if (bi->ops->reset_cmd(bi) < 0) + return(-1); + sprintf(targ_start, "%lx", (u_long) bi->base_addr + offset); + sprintf(targ_len, "%lx", len); + targv[0] = "blankchk"; + targv[1] = targ_start; + targv[2] = targ_len; + targv[3] = 0; + tpinterf_make_cmd(targv); + if (tpinterf_send_cmd() < 0) + return(-1); + return tpinterf_pass_output(10); /* 10 s timeout */ +} + +flashcmd_dump2file(argc, argv, bank) + char **argv; +{ + struct flash_bank_info *bi; + u_long offset, dumplen, maxlen; + char *strtoul_endp; + int format; + + if (argc < 3 || argc > 5) { +inv: fprintf(stderr, "usage: %s %s outfile [offset [length]]\n", + argv[0], argv[1]); + return(-1); + } + if (flash_get_cfi(bank) < 0) + return(-1); + bi = flash_bank_info + bank; + if (argc >= 4) { + offset = strtoul(argv[3], &strtoul_endp, 16); + if (*strtoul_endp) + goto inv; + if (offset >= bi->geom->total_size) { + fprintf(stderr, + "error: specified offset exceeds flash bank size (0x%lx)\n", + (u_long) bi->geom->total_size); + return(-1); + } + } else + offset = 0; + maxlen = bi->geom->total_size - offset; + if (argc >= 5) { + dumplen = strtoul(argv[4], &strtoul_endp, 16); + if (*strtoul_endp) + goto inv; + if (dumplen > maxlen) { + fprintf(stderr, + "error: specified offset+length exceed flash bank size (0x%lx)\n", + (u_long) bi->geom->total_size); + return(-1); + } + } else + dumplen = maxlen; + switch (argv[1][5]) { + case 'b': + format = 0; + break; + case 's': + format = 1; + break; + default: + fprintf(stderr, + "internal bug: bad format in flashcmd_dump2file()\n"); + return(-1); + } + /* reset flash to read mode */ + if (bi->ops->reset_cmd(bi) < 0) + return(-1); + return loadtool_memdump(bi->base_addr + offset, dumplen, argv[2], + format); +} + +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; + if (flash_get_cfi(bank) < 0) + return(-1); + bi = flash_bank_info + bank; + if (offset >= bi->geom->total_size) { + fprintf(stderr, + "error: specified offset exceeds flash bank size (0x%lx)\n", + (u_long) bi->geom->total_size); + return(-1); + } + len = strtoul(argv[3], &strtoul_endp, 16); + if (*strtoul_endp) + goto inv; + if (len > bi->geom->total_size - offset) { + fprintf(stderr, + "error: specified offset+length exceed flash bank size (0x%lx)\n", + (u_long) bi->geom->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); + stat = flash_id_check(bank, 0); + if (stat) + return(stat); + printf("Erasing %d sector(s)\n", endsec - startsec); + for (sp = startsec; sp < endsec; sp++) { + stat = bi->ops->erase_sector(bi, sp); + if (stat) + return(stat); + putchar('.'); + fflush(stdout); + } + putchar('\n'); + return(0); +} + +flashcmd_quickprog(argc, argv, bank) + char **argv; +{ + struct flash_bank_info *bi; + char *targv[4], targ_base[10]; + int stat; + + if (argc != 4) { + fprintf(stderr, "usage: %s %s hex-offset hex-data-string\n", + argv[0], argv[1]); + return(-1); + } + if (flash_get_cfi(bank) < 0) + return(-1); + bi = flash_bank_info + bank; + sprintf(targ_base, "%lx", (u_long) bi->base_addr); + targv[0] = bi->ops->loadagent_setbase_cmd; + targv[1] = targ_base; + targv[2] = 0; + tpinterf_make_cmd(targv); + if (tpinterf_send_cmd() < 0) + return(-1); + stat = tpinterf_pass_output(1); + if (stat) + return(stat); + targv[0] = bi->ops->loadagent_program_cmd; + targv[1] = argv[2]; + targv[2] = argv[3]; + targv[3] = 0; + if (tpinterf_make_cmd(targv) < 0) { + fprintf(stderr, + "error: unable to form AMFW/INFW target command\n"); + return(-1); + } + if (tpinterf_send_cmd() < 0) + return(-1); + return tpinterf_pass_output(1); +} + +flashcmd_reset(argc, argv, bank) + char **argv; +{ + struct flash_bank_info *bi; + + if (argc > 2) { + fprintf(stderr, "error: too many arguments\n"); + return(-1); + } + if (flash_get_cfi(bank) < 0) + return(-1); + bi = flash_bank_info + bank; + return bi->ops->reset_cmd(bi); +} + +flashcmd_status(argc, argv, bank) + char **argv; +{ + struct flash_bank_info *bi; + + if (argc > 2) { + fprintf(stderr, "error: too many arguments\n"); + return(-1); + } + if (flash_get_cfi(bank) < 0) + return(-1); + bi = flash_bank_info + bank; + return bi->ops->status_cmd(bi); +} + +flashcmd_unlock(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 (flash_get_cfi(bank) < 0) + return(-1); + bi = flash_bank_info + bank; + if (!bi->ops->needs_unlock) { + fprintf(stderr, + "This operation is not applicable to the selected flash type\n"); + return(-1); + } + 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; + if (offset >= bi->geom->total_size) { + fprintf(stderr, + "error: specified offset exceeds flash bank size (0x%lx)\n", + (u_long) bi->geom->total_size); + return(-1); + } + len = strtoul(argv[3], &strtoul_endp, 16); + if (*strtoul_endp) + goto inv; + if (len > bi->geom->total_size - offset) { + fprintf(stderr, + "error: specified offset+length exceed flash bank size (0x%lx)\n", + (u_long) bi->geom->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("Unlocking %d sector(s)\n", endsec - startsec); + for (sp = startsec; sp < endsec; sp++) { + stat = bi->ops->unlock_sector(bi, sp); + if (stat) + return(stat); + putchar('.'); + fflush(stdout); + } + putchar('\n'); + return(0); +}