FreeCalypso > hg > freecalypso-sw
comparison loadtools/ltdump.c @ 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 | 1f035187e98f |
comparison
equal
deleted
inserted
replaced
35:05af070c4b60 | 36:65111e6eee9e |
---|---|
8 #include <stdint.h> | 8 #include <stdint.h> |
9 #include <string.h> | 9 #include <string.h> |
10 #include <strings.h> | 10 #include <strings.h> |
11 #include <stdlib.h> | 11 #include <stdlib.h> |
12 | 12 |
13 extern uint32_t crc32_table[]; | |
13 extern char target_response_line[]; | 14 extern char target_response_line[]; |
14 | 15 |
15 crc32_on_target(area_base, area_len, retptr) | 16 crc32_on_target(area_base, area_len, retptr) |
16 u_long area_base, area_len, *retptr; | 17 u_long area_base, area_len, *retptr; |
17 { | 18 { |
61 if (stat == 0) | 62 if (stat == 0) |
62 printf("%08lX\n", crc_result); | 63 printf("%08lX\n", crc_result); |
63 return(stat); | 64 return(stat); |
64 } | 65 } |
65 | 66 |
67 /* the actual dump facility */ | |
68 | |
69 static FILE *dump_outfile; | |
70 static int dump_save_srec; | |
71 static uint32_t dump_nextaddr, dump_crcaccum; | |
72 static u_char dump_binrec[0x86]; | |
73 | |
74 static | |
75 dump_receiver(line) | |
76 char *line; | |
77 { | |
78 int i, b; | |
79 u_char sr_cksum; | |
80 uint32_t addr_from_srec; | |
81 | |
82 if (strncmp(line, "S385", 4)) { | |
83 fprintf(stderr, | |
84 "error: target response is not the expected S385...\n"); | |
85 return(-1); | |
86 } | |
87 for (i = 0; i < 0x86; i++) { | |
88 b = decode_hex_byte(line + i*2 + 2); | |
89 if (b < 0) { | |
90 fprintf(stderr, | |
91 "data from target: S-record hex decode error\n"); | |
92 return(-1); | |
93 } | |
94 dump_binrec[i] = b; | |
95 } | |
96 sr_cksum = 0; | |
97 for (i = 0; i < 0x86; i++) | |
98 sr_cksum += dump_binrec[i]; | |
99 if (sr_cksum != 0xFF) { | |
100 fprintf(stderr, "data from target: bad S-record checksum\n"); | |
101 return(-1); | |
102 } | |
103 /* basic S-record format OK; now verify the address */ | |
104 addr_from_srec = ((uint32_t) dump_binrec[1] << 24) | | |
105 ((uint32_t) dump_binrec[2] << 16) | | |
106 ((uint32_t) dump_binrec[3] << 8) | | |
107 (uint32_t) dump_binrec[4]; | |
108 if (addr_from_srec != dump_nextaddr) { | |
109 fprintf(stderr, | |
110 "error: S3 record from target has the wrong address\n"); | |
111 return(-1); | |
112 } | |
113 /* all checks passed - save it */ | |
114 if (dump_save_srec) | |
115 fprintf(dump_outfile, "%s\n", line); | |
116 else | |
117 fwrite(dump_binrec + 5, 1, 0x80, dump_outfile); | |
118 /* update running CRC */ | |
119 for (i = 0; i < 0x80; i++) | |
120 dump_crcaccum = crc32_table[dump_crcaccum & 0xFF ^ | |
121 dump_binrec[i+5]] ^ | |
122 (dump_crcaccum >> 8); | |
123 /* progress indication */ | |
124 putchar('.'); | |
125 fflush(stdout); | |
126 dump_nextaddr += 0x80; | |
127 return(1); | |
128 } | |
129 | |
130 loadtool_memdump(start_addr, area_len, filename, fmt_srec) | |
131 u_long start_addr, area_len; | |
132 char *filename; | |
133 { | |
134 u_long target_crc_init, target_crc_fin; | |
135 char *target_argv[4], target_arg1[10], target_arg2[10]; | |
136 int stat; | |
137 | |
138 if (start_addr & 0x7F || area_len & 0x7F) { | |
139 fprintf(stderr, | |
140 "error: implementation limit: 128-byte alignment required\n"); | |
141 return(-1); | |
142 } | |
143 printf("Requesting initial CRC-32 of the area from target...\n"); | |
144 stat = crc32_on_target(start_addr, area_len, &target_crc_init); | |
145 if (stat) | |
146 return(stat); | |
147 printf("got %08lX\n", target_crc_init); | |
148 dump_outfile = fopen(filename, "w"); | |
149 if (!dump_outfile) { | |
150 perror(filename); | |
151 return(-1); | |
152 } | |
153 dump_save_srec = fmt_srec; | |
154 dump_nextaddr = start_addr; | |
155 dump_crcaccum = 0xFFFFFFFF; | |
156 | |
157 printf("Requesting memory dump...\n"); | |
158 sprintf(target_arg1, "%lx", start_addr); | |
159 sprintf(target_arg2, "%lx", area_len); | |
160 target_argv[0] = "DUMP"; | |
161 target_argv[1] = target_arg1; | |
162 target_argv[2] = target_arg2; | |
163 target_argv[3] = 0; | |
164 tpinterf_make_cmd(target_argv); | |
165 stat = tpinterf_send_cmd(); | |
166 if (stat < 0) { | |
167 fclose(dump_outfile); | |
168 return(stat); | |
169 } | |
170 stat = tpinterf_capture_output(2, dump_receiver); | |
171 fclose(dump_outfile); | |
172 if (stat < 0) | |
173 return(stat); | |
174 putchar('\n'); /* after lots of dots */ | |
175 | |
176 /* sanity checks */ | |
177 if (dump_nextaddr != start_addr + area_len) { | |
178 fprintf(stderr, | |
179 "error: received dump length does not match expected\n"); | |
180 return(-1); | |
181 } | |
182 if (dump_crcaccum != (uint32_t) target_crc_init) { | |
183 fprintf(stderr, "error: CRC mismatch (computed %lX)\n", | |
184 (u_long) dump_crcaccum); | |
185 return(-1); | |
186 } | |
187 printf("Requesting another CRC-32 of the area from target...\n"); | |
188 stat = crc32_on_target(start_addr, area_len, &target_crc_fin); | |
189 if (stat) | |
190 return(stat); | |
191 if (target_crc_fin == target_crc_init) { | |
192 printf("match, dump successful\n"); | |
193 return(0); | |
194 } else { | |
195 fprintf(stderr, "mismatch: got %lX this time\n", | |
196 target_crc_fin); | |
197 return(-1); | |
198 } | |
199 } | |
200 | |
66 cmd_dump2bin(argc, argv) | 201 cmd_dump2bin(argc, argv) |
67 char **argv; | 202 char **argv; |
68 { | 203 { |
69 | 204 u_long area_base, area_len; |
70 | 205 char *strtoul_endp; |
71 } | 206 |
207 area_base = strtoul(argv[1], &strtoul_endp, 16); | |
208 if (*strtoul_endp) { | |
209 inv: fprintf(stderr, "usage: dump2bin hex-start hex-len outfile\n"); | |
210 return(-1); | |
211 } | |
212 area_len = strtoul(argv[2], &strtoul_endp, 16); | |
213 if (*strtoul_endp) | |
214 goto inv; | |
215 return loadtool_memdump(area_base, area_len, argv[3], 0); | |
216 } | |
217 | |
218 cmd_dump2srec(argc, argv) | |
219 char **argv; | |
220 { | |
221 u_long area_base, area_len; | |
222 char *strtoul_endp; | |
223 | |
224 area_base = strtoul(argv[1], &strtoul_endp, 16); | |
225 if (*strtoul_endp) { | |
226 inv: fprintf(stderr, "usage: dump2srec hex-start hex-len outfile\n"); | |
227 return(-1); | |
228 } | |
229 area_len = strtoul(argv[2], &strtoul_endp, 16); | |
230 if (*strtoul_endp) | |
231 goto inv; | |
232 return loadtool_memdump(area_base, area_len, argv[3], 1); | |
233 } |