FreeCalypso > hg > freecalypso-sw
changeset 36:65111e6eee9e
loadtool: dump2bin and dump2srec implemented
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Mon, 06 May 2013 02:04:56 +0000 |
parents | 05af070c4b60 |
children | 437f9365249c |
files | loadtools/ltdispatch.c loadtools/ltdump.c |
diffstat | 2 files changed, 166 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/loadtools/ltdispatch.c Sun May 05 02:24:56 2013 +0000 +++ b/loadtools/ltdispatch.c Mon May 06 02:04:56 2013 +0000 @@ -9,6 +9,8 @@ #include <stdlib.h> extern int cmd_crc32(); +extern int cmd_dump2bin(); +extern int cmd_dump2srec(); extern int cmd_exec(); extern int cmd_exit(); extern int loadtool_cmd_passthru(); @@ -21,6 +23,8 @@ } cmdtab[] = { {"crc32", 2, 2, cmd_crc32}, {"dump", 2, 2, loadtool_cmd_passthru}, + {"dump2bin", 3, 3, cmd_dump2bin}, + {"dump2srec", 3, 3, cmd_dump2srec}, {"exec", 1, 1, cmd_exec}, {"exit", 0, 1, cmd_exit}, {"quit", 0, 1, cmd_exit},
--- a/loadtools/ltdump.c Sun May 05 02:24:56 2013 +0000 +++ b/loadtools/ltdump.c Mon May 06 02:04:56 2013 +0000 @@ -10,6 +10,7 @@ #include <strings.h> #include <stdlib.h> +extern uint32_t crc32_table[]; extern char target_response_line[]; crc32_on_target(area_base, area_len, retptr) @@ -63,9 +64,170 @@ return(stat); } +/* the actual dump facility */ + +static FILE *dump_outfile; +static int dump_save_srec; +static uint32_t dump_nextaddr, dump_crcaccum; +static u_char dump_binrec[0x86]; + +static +dump_receiver(line) + char *line; +{ + int i, b; + u_char sr_cksum; + uint32_t addr_from_srec; + + if (strncmp(line, "S385", 4)) { + fprintf(stderr, + "error: target response is not the expected S385...\n"); + return(-1); + } + for (i = 0; i < 0x86; i++) { + b = decode_hex_byte(line + i*2 + 2); + if (b < 0) { + fprintf(stderr, + "data from target: S-record hex decode error\n"); + return(-1); + } + dump_binrec[i] = b; + } + sr_cksum = 0; + for (i = 0; i < 0x86; i++) + sr_cksum += dump_binrec[i]; + if (sr_cksum != 0xFF) { + fprintf(stderr, "data from target: bad S-record checksum\n"); + return(-1); + } + /* basic S-record format OK; now verify the address */ + addr_from_srec = ((uint32_t) dump_binrec[1] << 24) | + ((uint32_t) dump_binrec[2] << 16) | + ((uint32_t) dump_binrec[3] << 8) | + (uint32_t) dump_binrec[4]; + if (addr_from_srec != dump_nextaddr) { + fprintf(stderr, + "error: S3 record from target has the wrong address\n"); + return(-1); + } + /* all checks passed - save it */ + if (dump_save_srec) + fprintf(dump_outfile, "%s\n", line); + else + fwrite(dump_binrec + 5, 1, 0x80, dump_outfile); + /* update running CRC */ + for (i = 0; i < 0x80; i++) + dump_crcaccum = crc32_table[dump_crcaccum & 0xFF ^ + dump_binrec[i+5]] ^ + (dump_crcaccum >> 8); + /* progress indication */ + putchar('.'); + fflush(stdout); + dump_nextaddr += 0x80; + return(1); +} + +loadtool_memdump(start_addr, area_len, filename, fmt_srec) + u_long start_addr, area_len; + char *filename; +{ + u_long target_crc_init, target_crc_fin; + char *target_argv[4], target_arg1[10], target_arg2[10]; + int stat; + + if (start_addr & 0x7F || area_len & 0x7F) { + fprintf(stderr, + "error: implementation limit: 128-byte alignment required\n"); + return(-1); + } + printf("Requesting initial CRC-32 of the area from target...\n"); + stat = crc32_on_target(start_addr, area_len, &target_crc_init); + if (stat) + return(stat); + printf("got %08lX\n", target_crc_init); + dump_outfile = fopen(filename, "w"); + if (!dump_outfile) { + perror(filename); + return(-1); + } + dump_save_srec = fmt_srec; + dump_nextaddr = start_addr; + dump_crcaccum = 0xFFFFFFFF; + + printf("Requesting memory dump...\n"); + sprintf(target_arg1, "%lx", start_addr); + sprintf(target_arg2, "%lx", area_len); + target_argv[0] = "DUMP"; + target_argv[1] = target_arg1; + target_argv[2] = target_arg2; + target_argv[3] = 0; + tpinterf_make_cmd(target_argv); + stat = tpinterf_send_cmd(); + if (stat < 0) { + fclose(dump_outfile); + return(stat); + } + stat = tpinterf_capture_output(2, dump_receiver); + fclose(dump_outfile); + if (stat < 0) + return(stat); + putchar('\n'); /* after lots of dots */ + + /* sanity checks */ + if (dump_nextaddr != start_addr + area_len) { + fprintf(stderr, + "error: received dump length does not match expected\n"); + return(-1); + } + if (dump_crcaccum != (uint32_t) target_crc_init) { + fprintf(stderr, "error: CRC mismatch (computed %lX)\n", + (u_long) dump_crcaccum); + return(-1); + } + printf("Requesting another CRC-32 of the area from target...\n"); + stat = crc32_on_target(start_addr, area_len, &target_crc_fin); + if (stat) + return(stat); + if (target_crc_fin == target_crc_init) { + printf("match, dump successful\n"); + return(0); + } else { + fprintf(stderr, "mismatch: got %lX this time\n", + target_crc_fin); + return(-1); + } +} + cmd_dump2bin(argc, argv) char **argv; { + u_long area_base, area_len; + char *strtoul_endp; + area_base = strtoul(argv[1], &strtoul_endp, 16); + if (*strtoul_endp) { +inv: fprintf(stderr, "usage: dump2bin hex-start hex-len outfile\n"); + return(-1); + } + area_len = strtoul(argv[2], &strtoul_endp, 16); + if (*strtoul_endp) + goto inv; + return loadtool_memdump(area_base, area_len, argv[3], 0); +} +cmd_dump2srec(argc, argv) + char **argv; +{ + u_long area_base, area_len; + char *strtoul_endp; + + area_base = strtoul(argv[1], &strtoul_endp, 16); + if (*strtoul_endp) { +inv: fprintf(stderr, "usage: dump2srec hex-start hex-len outfile\n"); + return(-1); + } + area_len = strtoul(argv[2], &strtoul_endp, 16); + if (*strtoul_endp) + goto inv; + return loadtool_memdump(area_base, area_len, argv[3], 1); }