comparison loadtools/ltdump.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 98474043ecdd
comparison
equal deleted inserted replaced
-1:000000000000 0:e7502631a0f9
1 /*
2 * This module implements the dump2bin and dump2srec functionality
3 * of fc-loadtool.
4 */
5
6 #include <sys/types.h>
7 #include <stdio.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <strings.h>
11 #include <stdlib.h>
12 #include <time.h>
13
14 extern uint32_t crc32_table[];
15 extern char target_response_line[];
16
17 crc32_on_target(area_base, area_len, retptr)
18 u_long area_base, area_len, *retptr;
19 {
20 char arg1[10], arg2[10], *argv[4];
21 int stat;
22 char *strtoul_endp;
23
24 sprintf(arg1, "%lx", area_base);
25 sprintf(arg2, "%lx", area_len);
26 argv[0] = "crc32";
27 argv[1] = arg1;
28 argv[2] = arg2;
29 argv[3] = 0;
30 tpinterf_make_cmd(argv);
31 if (tpinterf_send_cmd() < 0)
32 return(-1);
33 stat = tpinterf_capture_output_oneline(10); /* 10 s timeout */
34 if (stat != 1) {
35 errout: fprintf(stderr, "error: malformed response to crc32 command\n");
36 return(-1);
37 }
38 if (strlen(target_response_line) != 8)
39 goto errout;
40 *retptr = strtoul(target_response_line, &strtoul_endp, 16);
41 if (strtoul_endp != target_response_line + 8)
42 goto errout;
43 return(0);
44 }
45
46 cmd_crc32(argc, argv)
47 char **argv;
48 {
49 u_long area_base, area_len;
50 char *strtoul_endp;
51 u_long crc_result;
52 int stat;
53
54 area_base = strtoul(argv[1], &strtoul_endp, 16);
55 if (*strtoul_endp) {
56 inv: fprintf(stderr, "usage: crc32 hex-start hex-len\n");
57 return(-1);
58 }
59 area_len = strtoul(argv[2], &strtoul_endp, 16);
60 if (*strtoul_endp)
61 goto inv;
62 stat = crc32_on_target(area_base, area_len, &crc_result);
63 if (stat == 0)
64 printf("%08lX\n", crc_result);
65 return(stat);
66 }
67
68 /* the actual dump facility */
69
70 static FILE *dump_outfile;
71 static int dump_save_srec;
72 static uint32_t dump_nextaddr, dump_crcaccum;
73 static uint32_t dump_total_len, dump_progress_len;
74 static u_char dump_binrec[0x86];
75 static time_t dump_last_time;
76
77 static char dumpsrec_s0_line[] = "S007000044554D50C2\n";
78 static char dumpsrec_s7_line[] = "S70500000000FA\n";
79
80 static
81 dump_receiver(line)
82 char *line;
83 {
84 int i, b;
85 u_char sr_cksum;
86 uint32_t addr_from_srec;
87 time_t curtime;
88
89 if (strncmp(line, "S385", 4)) {
90 fprintf(stderr,
91 "error: target response is not the expected S385...\n");
92 return(-1);
93 }
94 for (i = 0; i < 0x86; i++) {
95 b = decode_hex_byte(line + i*2 + 2);
96 if (b < 0) {
97 fprintf(stderr,
98 "data from target: S-record hex decode error\n");
99 return(-1);
100 }
101 dump_binrec[i] = b;
102 }
103 sr_cksum = 0;
104 for (i = 0; i < 0x86; i++)
105 sr_cksum += dump_binrec[i];
106 if (sr_cksum != 0xFF) {
107 fprintf(stderr, "data from target: bad S-record checksum\n");
108 return(-1);
109 }
110 /* basic S-record format OK; now verify the address */
111 addr_from_srec = ((uint32_t) dump_binrec[1] << 24) |
112 ((uint32_t) dump_binrec[2] << 16) |
113 ((uint32_t) dump_binrec[3] << 8) |
114 (uint32_t) dump_binrec[4];
115 if (addr_from_srec != dump_nextaddr) {
116 fprintf(stderr,
117 "error: S3 record from target has the wrong address\n");
118 return(-1);
119 }
120 /* all checks passed - save it */
121 if (dump_save_srec) {
122 if (!dump_progress_len)
123 fputs(dumpsrec_s0_line, dump_outfile);
124 fprintf(dump_outfile, "%s\n", line);
125 } else
126 fwrite(dump_binrec + 5, 1, 0x80, dump_outfile);
127 /* update running CRC */
128 for (i = 0; i < 0x80; i++)
129 dump_crcaccum = crc32_table[dump_crcaccum & 0xFF ^
130 dump_binrec[i+5]] ^
131 (dump_crcaccum >> 8);
132 /* progress indication */
133 dump_progress_len += 0x80;
134 i = dump_progress_len * 100 / dump_total_len;
135 time(&curtime);
136 if (curtime != dump_last_time || i == 100) {
137 printf("\rRx %lu out of %lu bytes (%i%%)",
138 (u_long) dump_progress_len, (u_long) dump_total_len, i);
139 fflush(stdout);
140 }
141 dump_nextaddr += 0x80;
142 dump_last_time = curtime;
143 return(1);
144 }
145
146 loadtool_memdump(start_addr, area_len, filename, fmt_srec)
147 u_long start_addr, area_len;
148 char *filename;
149 {
150 u_long target_crc_init, target_crc_fin;
151 char *target_argv[4], target_arg1[10], target_arg2[10];
152 int stat;
153
154 if (start_addr & 0x7F || area_len & 0x7F) {
155 fprintf(stderr,
156 "error: implementation limit: 128-byte alignment required\n");
157 return(-1);
158 }
159 printf("Requesting initial CRC-32 of the area from target...\n");
160 stat = crc32_on_target(start_addr, area_len, &target_crc_init);
161 if (stat)
162 return(stat);
163 printf("got %08lX\n", target_crc_init);
164 dump_outfile = fopen(filename, "w");
165 if (!dump_outfile) {
166 perror(filename);
167 return(-1);
168 }
169 dump_save_srec = fmt_srec;
170 dump_nextaddr = start_addr;
171 dump_crcaccum = 0xFFFFFFFF;
172 dump_total_len = area_len;
173 dump_progress_len = 0;
174
175 printf("Requesting memory dump...\n");
176 sprintf(target_arg1, "%lx", start_addr);
177 sprintf(target_arg2, "%lx", area_len);
178 target_argv[0] = "DUMP";
179 target_argv[1] = target_arg1;
180 target_argv[2] = target_arg2;
181 target_argv[3] = 0;
182 tpinterf_make_cmd(target_argv);
183 stat = tpinterf_send_cmd();
184 if (stat < 0) {
185 fclose(dump_outfile);
186 return(stat);
187 }
188 stat = tpinterf_capture_output(2, dump_receiver);
189 if (stat < 0) {
190 fclose(dump_outfile);
191 return(stat);
192 }
193 putchar('\n'); /* after last progress line */
194
195 /* sanity checks */
196 if (dump_nextaddr != start_addr + area_len) {
197 fclose(dump_outfile);
198 fprintf(stderr,
199 "error: received dump length does not match expected\n");
200 return(-1);
201 }
202 if (dump_crcaccum != (uint32_t) target_crc_init) {
203 fclose(dump_outfile);
204 fprintf(stderr, "error: CRC mismatch (computed %lX)\n",
205 (u_long) dump_crcaccum);
206 return(-1);
207 }
208 if (fmt_srec)
209 fputs(dumpsrec_s7_line, dump_outfile);
210 fclose(dump_outfile);
211 printf("Requesting another CRC-32 of the area from target...\n");
212 stat = crc32_on_target(start_addr, area_len, &target_crc_fin);
213 if (stat)
214 return(stat);
215 if (target_crc_fin == target_crc_init) {
216 printf("match, dump successful\n");
217 return(0);
218 } else {
219 fprintf(stderr, "mismatch: got %lX this time\n",
220 target_crc_fin);
221 return(-1);
222 }
223 }
224
225 cmd_dump2bin(argc, argv)
226 char **argv;
227 {
228 u_long area_base, area_len;
229 char *strtoul_endp;
230
231 area_base = strtoul(argv[1], &strtoul_endp, 16);
232 if (*strtoul_endp) {
233 inv: fprintf(stderr, "usage: dump2bin hex-start hex-len outfile\n");
234 return(-1);
235 }
236 area_len = strtoul(argv[2], &strtoul_endp, 16);
237 if (*strtoul_endp)
238 goto inv;
239 return loadtool_memdump(area_base, area_len, argv[3], 0);
240 }
241
242 cmd_dump2srec(argc, argv)
243 char **argv;
244 {
245 u_long area_base, area_len;
246 char *strtoul_endp;
247
248 area_base = strtoul(argv[1], &strtoul_endp, 16);
249 if (*strtoul_endp) {
250 inv: fprintf(stderr, "usage: dump2srec hex-start hex-len outfile\n");
251 return(-1);
252 }
253 area_len = strtoul(argv[2], &strtoul_endp, 16);
254 if (*strtoul_endp)
255 goto inv;
256 return loadtool_memdump(area_base, area_len, argv[3], 1);
257 }