FreeCalypso > hg > freecalypso-tools
view loadtools/ltdump.c @ 619:f82551c77e58
libserial-newlnx: ASYNC_LOW_LATENCY patch reverted
Reports from Das Signal indicate that loadtools performance on Debian
is about the same as on Slackware, and that including or omitting the
ASYNC_LOW_LATENCY patch from Serg makes no difference. Because the
patch in question does not appear to be necessary, it is being reverted
until and unless someone other than Serg reports an actual real-world
system on which loadtools operation times are slowed compared to the
Mother's Slackware reference and on which Slackware-like performance
can be restored by setting the ASYNC_LOW_LATENCY flag.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 27 Feb 2020 01:09:48 +0000 |
parents | 98474043ecdd |
children | 5385aca4d813 |
line wrap: on
line source
/* * This module implements the dump2bin and dump2srec functionality * of fc-loadtool. */ #include <sys/types.h> #include <stdio.h> #include <stdint.h> #include <string.h> #include <strings.h> #include <stdlib.h> #include <time.h> extern uint32_t crc32_table[]; extern char target_response_line[]; crc32_on_target(area_base, area_len, retptr) u_long area_base, area_len, *retptr; { char arg1[10], arg2[10], *argv[4]; int stat; char *strtoul_endp; sprintf(arg1, "%lx", area_base); sprintf(arg2, "%lx", area_len); argv[0] = "crc32"; argv[1] = arg1; argv[2] = arg2; argv[3] = 0; tpinterf_make_cmd(argv); if (tpinterf_send_cmd() < 0) return(-1); stat = tpinterf_capture_output_oneline(10); /* 10 s timeout */ if (stat != 1) { errout: fprintf(stderr, "error: malformed response to crc32 command\n"); return(-1); } if (strlen(target_response_line) != 8) goto errout; *retptr = strtoul(target_response_line, &strtoul_endp, 16); if (strtoul_endp != target_response_line + 8) goto errout; return(0); } cmd_crc32(argc, argv) char **argv; { u_long area_base, area_len; char *strtoul_endp; u_long crc_result; int stat; area_base = strtoul(argv[1], &strtoul_endp, 16); if (*strtoul_endp) { inv: fprintf(stderr, "usage: crc32 hex-start hex-len\n"); return(-1); } area_len = strtoul(argv[2], &strtoul_endp, 16); if (*strtoul_endp) goto inv; stat = crc32_on_target(area_base, area_len, &crc_result); if (stat == 0) printf("%08lX\n", crc_result); return(stat); } /* the actual dump facility */ static FILE *dump_outfile; static int dump_save_srec; static uint32_t dump_nextaddr, dump_crcaccum; static uint32_t dump_total_len, dump_progress_len; static u_char dump_binrec[0x86]; static time_t dump_initial_time, dump_last_time; static char dumpsrec_s0_line[] = "S007000044554D50C2\n"; static char dumpsrec_s7_line[] = "S70500000000FA\n"; static dump_receiver(line) char *line; { int i, b; u_char sr_cksum; uint32_t addr_from_srec; time_t curtime; 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) { if (!dump_progress_len) fputs(dumpsrec_s0_line, dump_outfile); 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 */ dump_progress_len += 0x80; i = dump_progress_len * 100 / dump_total_len; time(&curtime); if (curtime != dump_last_time || i == 100) { printf("\rRx %lu out of %lu bytes (%i%%)", (u_long) dump_progress_len, (u_long) dump_total_len, i); fflush(stdout); } dump_nextaddr += 0x80; dump_last_time = curtime; 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]; unsigned duration, mm, ss; int stat; if (!area_len) { fprintf(stderr, "error: dump of zero length is not supported\n"); return(-1); } 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; dump_total_len = area_len; dump_progress_len = 0; printf("Requesting memory dump...\n"); time(&dump_initial_time); 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); if (stat < 0) { fclose(dump_outfile); return(stat); } putchar('\n'); /* after last progress line */ /* sanity checks */ if (dump_nextaddr != start_addr + area_len) { fclose(dump_outfile); fprintf(stderr, "error: received dump length does not match expected\n"); return(-1); } if (dump_crcaccum != (uint32_t) target_crc_init) { fclose(dump_outfile); fprintf(stderr, "error: CRC mismatch (computed %lX)\n", (u_long) dump_crcaccum); return(-1); } if (fmt_srec) fputs(dumpsrec_s7_line, dump_outfile); fclose(dump_outfile); duration = dump_last_time - dump_initial_time; mm = duration / 60; ss = duration - mm * 60; printf("Dump stream received in %um%us\n", mm, ss); 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); }