comparison loadtools/ltdump.c @ 641:b4070292640a

fc-loadtool: dump facility changed to use BINDUMP
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 01 Mar 2020 20:06:21 +0000
parents 5385aca4d813
children 141372e0d28f
comparison
equal deleted inserted replaced
640:5385aca4d813 641:b4070292640a
2 * This module implements the dump2bin and dump2srec functionality 2 * This module implements the dump2bin and dump2srec functionality
3 * of fc-loadtool. 3 * of fc-loadtool.
4 */ 4 */
5 5
6 #include <sys/types.h> 6 #include <sys/types.h>
7 #include <sys/time.h>
8 #include <sys/errno.h>
7 #include <stdio.h> 9 #include <stdio.h>
8 #include <stdint.h> 10 #include <stdint.h>
9 #include <string.h> 11 #include <string.h>
10 #include <strings.h> 12 #include <strings.h>
11 #include <stdlib.h> 13 #include <stdlib.h>
12 #include <time.h> 14 #include <time.h>
13 15
16 extern int errno;
17
18 extern int target_fd;
14 extern uint32_t crc32_table[]; 19 extern uint32_t crc32_table[];
15
16 static FILE *dump_outfile;
17 static int dump_save_srec;
18 static uint32_t dump_nextaddr, dump_crcaccum;
19 static uint32_t dump_total_len, dump_progress_len;
20 static u_char dump_binrec[0x86];
21 static time_t dump_initial_time, dump_last_time;
22 20
23 static char dumpsrec_s0_line[] = "S007000044554D50C2\n"; 21 static char dumpsrec_s0_line[] = "S007000044554D50C2\n";
24 static char dumpsrec_s7_line[] = "S70500000000FA\n"; 22 static char dumpsrec_s7_line[] = "S70500000000FA\n";
25 23
26 static 24 collect_binblock_from_target(buf, expect_len, timeout)
27 dump_receiver(line) 25 u_char *buf;
28 char *line; 26 unsigned expect_len;
29 { 27 {
30 int i, b; 28 fd_set fds;
31 u_char sr_cksum; 29 struct timeval tv;
32 uint32_t addr_from_srec; 30 unsigned rcvd;
33 time_t curtime; 31 int cc;
34 32
35 if (strncmp(line, "S385", 4)) { 33 for (rcvd = 0; rcvd < expect_len; ) {
36 fprintf(stderr, 34 FD_ZERO(&fds);
37 "error: target response is not the expected S385...\n"); 35 FD_SET(target_fd, &fds);
38 return(-1); 36 tv.tv_sec = timeout;
39 } 37 tv.tv_usec = 0;
40 for (i = 0; i < 0x86; i++) { 38 cc = select(target_fd+1, &fds, NULL, NULL, &tv);
41 b = decode_hex_byte(line + i*2 + 2); 39 if (cc < 0) {
42 if (b < 0) { 40 if (errno == EINTR)
41 continue;
42 perror("select");
43 return(-1);
44 }
45 if (cc < 1) {
43 fprintf(stderr, 46 fprintf(stderr,
44 "data from target: S-record hex decode error\n"); 47 "error: timeout waiting for binary block\n");
45 return(-1); 48 return(-1);
46 } 49 }
47 dump_binrec[i] = b; 50 cc = read(target_fd, buf + rcvd, expect_len - rcvd);
48 } 51 if (cc <= 0) {
49 sr_cksum = 0; 52 perror("read after successful select");
50 for (i = 0; i < 0x86; i++) 53 return(-1);
51 sr_cksum += dump_binrec[i]; 54 }
52 if (sr_cksum != 0xFF) { 55 rcvd += cc;
53 fprintf(stderr, "data from target: bad S-record checksum\n"); 56 }
54 return(-1); 57 return(0);
55 } 58 }
56 /* basic S-record format OK; now verify the address */ 59
57 addr_from_srec = ((uint32_t) dump_binrec[1] << 24) | 60 write_block_in_srec(buf, addr, blklen, outfile)
58 ((uint32_t) dump_binrec[2] << 16) | 61 u_char *buf;
59 ((uint32_t) dump_binrec[3] << 8) | 62 uint32_t addr;
60 (uint32_t) dump_binrec[4]; 63 unsigned blklen;
61 if (addr_from_srec != dump_nextaddr) { 64 FILE *outfile;
62 fprintf(stderr, 65 {
63 "error: S3 record from target has the wrong address\n"); 66 unsigned remain, reclen, n;
64 return(-1); 67 u_char binrec[38], accum;
65 } 68
66 /* all checks passed - save it */ 69 for (remain = blklen; remain; remain -= reclen) {
67 if (dump_save_srec) { 70 reclen = 32;
68 if (!dump_progress_len) 71 if (remain < reclen)
69 fputs(dumpsrec_s0_line, dump_outfile); 72 reclen = remain;
70 fprintf(dump_outfile, "%s\n", line); 73 binrec[0] = reclen + 5;
71 } else 74 binrec[1] = addr >> 24;
72 fwrite(dump_binrec + 5, 1, 0x80, dump_outfile); 75 binrec[2] = addr >> 16;
73 /* update running CRC */ 76 binrec[3] = addr >> 8;
74 for (i = 0; i < 0x80; i++) 77 binrec[4] = addr;
75 dump_crcaccum = crc32_table[dump_crcaccum & 0xFF ^ 78 bcopy(buf, binrec + 5, reclen);
76 dump_binrec[i+5]] ^ 79 accum = 0;
77 (dump_crcaccum >> 8); 80 for (n = 0; n < reclen + 5; n++)
78 /* progress indication */ 81 accum += binrec[n];
79 dump_progress_len += 0x80; 82 binrec[n] = ~accum;
80 i = dump_progress_len * 100 / dump_total_len; 83 putc('S', outfile);
81 time(&curtime); 84 putc('3', outfile);
82 if (curtime != dump_last_time || i == 100) { 85 for (n = 0; n < reclen + 6; n++)
83 printf("\rRx %lu out of %lu bytes (%i%%)", 86 fprintf(outfile, "%02X", binrec[n]);
84 (u_long) dump_progress_len, (u_long) dump_total_len, i); 87 putc('\n', outfile);
85 fflush(stdout); 88 buf += reclen;
86 } 89 addr += reclen;
87 dump_nextaddr += 0x80; 90 }
88 dump_last_time = curtime;
89 return(1);
90 } 91 }
91 92
92 loadtool_memdump(start_addr, area_len, filename, fmt_srec) 93 loadtool_memdump(start_addr, area_len, filename, fmt_srec)
93 u_long start_addr, area_len; 94 u_long start_addr, area_len;
94 char *filename; 95 char *filename;
95 { 96 {
96 u_long target_crc_init, target_crc_fin; 97 u_long target_crc_init, target_crc_fin;
98 FILE *dump_outfile;
99 uint32_t dump_nextaddr, dump_crcaccum;
100 uint32_t dump_total_len, dump_progress_len, dump_remain;
101 unsigned blklen, n;
97 char *target_argv[4], target_arg1[10], target_arg2[10]; 102 char *target_argv[4], target_arg1[10], target_arg2[10];
103 u_char recvbuf[8192], expect_blkhdr[8];
104 time_t dump_initial_time, dump_last_time, curtime;
98 unsigned duration, mm, ss; 105 unsigned duration, mm, ss;
99 int stat; 106 int rc;
100 107
101 if (!area_len) {
102 fprintf(stderr,
103 "error: dump of zero length is not supported\n");
104 return(-1);
105 }
106 if (start_addr & 0x7F || area_len & 0x7F) {
107 fprintf(stderr,
108 "error: implementation limit: 128-byte alignment required\n");
109 return(-1);
110 }
111 printf("Requesting initial CRC-32 of the area from target...\n"); 108 printf("Requesting initial CRC-32 of the area from target...\n");
112 stat = crc32_on_target(start_addr, area_len, &target_crc_init); 109 rc = crc32_on_target(start_addr, area_len, &target_crc_init);
113 if (stat) 110 if (rc)
114 return(stat); 111 return(rc);
115 printf("got %08lX\n", target_crc_init); 112 printf("got %08lX\n", target_crc_init);
116 dump_outfile = fopen(filename, "w"); 113 dump_outfile = fopen(filename, "w");
117 if (!dump_outfile) { 114 if (!dump_outfile) {
118 perror(filename); 115 perror(filename);
119 return(-1); 116 return(-1);
120 } 117 }
121 dump_save_srec = fmt_srec;
122 dump_nextaddr = start_addr; 118 dump_nextaddr = start_addr;
123 dump_crcaccum = 0xFFFFFFFF; 119 dump_crcaccum = 0xFFFFFFFF;
124 dump_total_len = area_len; 120 dump_total_len = area_len;
125 dump_progress_len = 0; 121 dump_progress_len = 0;
126 122
127 printf("Requesting memory dump...\n"); 123 printf("Requesting memory dump...\n");
128 time(&dump_initial_time); 124 time(&dump_initial_time);
129 sprintf(target_arg1, "%lx", start_addr); 125 sprintf(target_arg1, "%lx", start_addr);
130 sprintf(target_arg2, "%lx", area_len); 126 sprintf(target_arg2, "%lx", area_len);
131 target_argv[0] = "DUMP"; 127 target_argv[0] = "BINDUMP";
132 target_argv[1] = target_arg1; 128 target_argv[1] = target_arg1;
133 target_argv[2] = target_arg2; 129 target_argv[2] = target_arg2;
134 target_argv[3] = 0; 130 target_argv[3] = 0;
135 tpinterf_make_cmd(target_argv); 131 tpinterf_make_cmd(target_argv);
136 stat = tpinterf_send_cmd(); 132 rc = tpinterf_send_cmd();
137 if (stat < 0) { 133 if (rc < 0) {
138 fclose(dump_outfile); 134 fclose(dump_outfile);
139 return(stat); 135 return(rc);
140 } 136 }
141 stat = tpinterf_capture_output(2, dump_receiver); 137 expect_blkhdr[0] = 0x55;
142 if (stat < 0) { 138 expect_blkhdr[1] = 0xAA;
143 fclose(dump_outfile); 139 for (dump_remain = dump_total_len; dump_remain; dump_remain -= blklen) {
144 return(stat); 140 blklen = 8192;
141 if (dump_remain < blklen)
142 blklen = dump_remain;
143 rc = collect_binblock_from_target(recvbuf, 8, 2);
144 if (rc < 0) {
145 fclose(dump_outfile);
146 return(rc);
147 }
148 expect_blkhdr[2] = dump_nextaddr >> 24;
149 expect_blkhdr[3] = dump_nextaddr >> 16;
150 expect_blkhdr[4] = dump_nextaddr >> 8;
151 expect_blkhdr[5] = dump_nextaddr;
152 expect_blkhdr[6] = blklen >> 8;
153 expect_blkhdr[7] = blklen;
154 if (bcmp(recvbuf, expect_blkhdr, 8)) {
155 fprintf(stderr,
156 "error: expected block header mismatch\n");
157 fclose(dump_outfile);
158 return(rc);
159 }
160 rc = collect_binblock_from_target(recvbuf, blklen, 2);
161 if (rc < 0) {
162 fclose(dump_outfile);
163 return(rc);
164 }
165 /* save the bits */
166 if (fmt_srec) {
167 if (!dump_progress_len)
168 fputs(dumpsrec_s0_line, dump_outfile);
169 write_block_in_srec(recvbuf, dump_nextaddr, blklen,
170 dump_outfile);
171 } else
172 fwrite(recvbuf, 1, blklen, dump_outfile);
173 /* update running CRC */
174 for (n = 0; n < blklen; n++)
175 dump_crcaccum = crc32_table[dump_crcaccum & 0xFF ^
176 recvbuf[n]] ^
177 (dump_crcaccum >> 8);
178 /* progress indication */
179 dump_progress_len += blklen;
180 n = dump_progress_len * 100 / dump_total_len;
181 time(&curtime);
182 if (curtime != dump_last_time || n == 100) {
183 printf("\rRx %lu out of %lu bytes (%u%%)",
184 (u_long) dump_progress_len,
185 (u_long) dump_total_len, n);
186 fflush(stdout);
187 }
188 dump_nextaddr += blklen;
189 dump_last_time = curtime;
145 } 190 }
146 putchar('\n'); /* after last progress line */ 191 putchar('\n'); /* after last progress line */
147
148 /* sanity checks */ 192 /* sanity checks */
149 if (dump_nextaddr != start_addr + area_len) { 193 if (dump_nextaddr != start_addr + area_len) {
150 fclose(dump_outfile); 194 fclose(dump_outfile);
151 fprintf(stderr, 195 fprintf(stderr,
152 "error: received dump length does not match expected\n"); 196 "error: received dump length does not match expected\n");
159 return(-1); 203 return(-1);
160 } 204 }
161 if (fmt_srec) 205 if (fmt_srec)
162 fputs(dumpsrec_s7_line, dump_outfile); 206 fputs(dumpsrec_s7_line, dump_outfile);
163 fclose(dump_outfile); 207 fclose(dump_outfile);
208
209 /* collect '=' at the end */
210 rc = collect_binblock_from_target(recvbuf, 1, 1);
211 if (rc < 0)
212 return(rc);
213 time(&dump_last_time);
214 if (recvbuf[0] != '=') {
215 fprintf(stderr, "error: \'=\' not received at the end\n");
216 return(-1);
217 }
164 duration = dump_last_time - dump_initial_time; 218 duration = dump_last_time - dump_initial_time;
165 mm = duration / 60; 219 mm = duration / 60;
166 ss = duration - mm * 60; 220 ss = duration - mm * 60;
167 printf("Dump stream received in %um%us\n", mm, ss); 221 printf("Dump stream received in %um%us\n", mm, ss);
168 222
169 printf("Requesting another CRC-32 of the area from target...\n"); 223 printf("Requesting another CRC-32 of the area from target...\n");
170 stat = crc32_on_target(start_addr, area_len, &target_crc_fin); 224 rc = crc32_on_target(start_addr, area_len, &target_crc_fin);
171 if (stat) 225 if (rc)
172 return(stat); 226 return(rc);
173 if (target_crc_fin == target_crc_init) { 227 if (target_crc_fin == target_crc_init) {
174 printf("match, dump successful\n"); 228 printf("match, dump successful\n");
175 return(0); 229 return(0);
176 } else { 230 } else {
177 fprintf(stderr, "mismatch: got %lX this time\n", 231 fprintf(stderr, "mismatch: got %lX this time\n",