comparison loadtools/romload.c @ 636:3172e3111ab7

loadtools/romload.c: implemented grouping of S-records into bigger blocks
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 01 Mar 2020 05:40:29 +0000
parents 4dca8542f569
children 46d7ed4ee634
comparison
equal deleted inserted replaced
635:d9b01a171baf 636:3172e3111ab7
45 0x00, 0x01, 0xD4, 0xC0 /* UART timeout */ 45 0x00, 0x01, 0xD4, 0xC0 /* UART timeout */
46 /* I've chosen the same value as what the */ 46 /* I've chosen the same value as what the */
47 /* boot ROM runs with before getting this cmd */ 47 /* boot ROM runs with before getting this cmd */
48 }; 48 };
49 49
50 static u_char write_cmd[10] = {'<', 'w', 0x01, 0x01, 0x00}; 50 static u_char write_cmd[1024] = {'<', 'w', 0x01, 0x01};
51 static u_char cksum_cmd[3] = {'<', 'c'}; 51 static u_char cksum_cmd[3] = {'<', 'c'};
52 static u_char branch_cmd[6] = {'<', 'b'}; 52 static u_char branch_cmd[6] = {'<', 'b'};
53
54 static uint32_t write_cmd_endaddr;
55 static unsigned write_cmd_datalen;
56 static unsigned write_block_count;
57 static uint16_t image_cksum;
58
59 #define MAX_WRITE_LEN 0x3F6
53 60
54 #define INTERMEDIATE_TIMEOUT 500 /* ms to wait for responses */ 61 #define INTERMEDIATE_TIMEOUT 500 /* ms to wait for responses */
55 #define SERIAL_FLUSH_DELAY 200 /* also in ms */ 62 #define SERIAL_FLUSH_DELAY 200 /* also in ms */
56 63
57 /* 64 /*
186 compute_block_cksum() 193 compute_block_cksum()
187 { 194 {
188 uint32_t sum; 195 uint32_t sum;
189 int i, llen; 196 int i, llen;
190 197
191 sum = iramimage.datalen + 5; 198 sum = write_cmd_datalen + 5;
192 llen = iramimage.datalen + 4; 199 llen = write_cmd_datalen + 4;
193 for (i = 0; i < llen; i++) 200 for (i = 0; i < llen; i++)
194 sum += iramimage.record[i+1]; 201 sum += write_cmd[i+6];
195 return sum; 202 return sum;
196 } 203 }
197 204
205 static void
206 send_write_cmd()
207 {
208 int resp;
209
210 write_cmd[4] = write_cmd_datalen >> 8;
211 write_cmd[5] = write_cmd_datalen & 0xFF;
212 write(target_fd, write_cmd, write_cmd_datalen + 10);
213 /* update our checksum accumulator */
214 image_cksum += ~compute_block_cksum() & 0xFF;
215 /* collect response */
216 resp = expect_response(INTERMEDIATE_TIMEOUT);
217 if (resp != 'w') {
218 fprintf(stderr, "Block #%lu: ", write_block_count);
219 if (resp < 0)
220 fprintf(stderr, "No response to <w command\n");
221 else if (isprint(resp))
222 fprintf(stderr,
223 "Got >%c in response to <w command; expected >w\n",
224 resp);
225 else
226 fprintf(stderr,
227 "Got > %02X in response to <w command; expected >w\n",
228 resp);
229 exit(1);
230 }
231 putchar('.');
232 fflush(stdout);
233 write_block_count++;
234 }
235
198 perform_romload() 236 perform_romload()
199 { 237 {
200 int resp; 238 int resp;
201 uint16_t image_cksum;
202 unsigned long rec_count; 239 unsigned long rec_count;
203 u_char addresp[2]; 240 u_char addresp[2];
204 static int zero = 0; 241 static int zero = 0;
205 242
206 if (open_srec_file(&iramimage) < 0) 243 if (open_srec_file(&iramimage) < 0)
238 romload_baud_rate->name); 275 romload_baud_rate->name);
239 set_serial_baudrate(romload_baud_rate); 276 set_serial_baudrate(romload_baud_rate);
240 usleep(SERIAL_FLUSH_DELAY * 1000); 277 usleep(SERIAL_FLUSH_DELAY * 1000);
241 tcflush(target_fd, TCIFLUSH); 278 tcflush(target_fd, TCIFLUSH);
242 279
280 write_cmd_datalen = 0;
281 write_block_count = 0;
243 image_cksum = 0; 282 image_cksum = 0;
244 for (rec_count = 0; ; ) { 283 for (rec_count = 0; ; ) {
245 if (read_s_record(&iramimage) < 0) 284 if (read_s_record(&iramimage) < 0)
246 exit(1); 285 exit(1);
247 switch (iramimage.record_type) { 286 switch (iramimage.record_type) {
271 fprintf(stderr, 310 fprintf(stderr,
272 "%s line %d: S3 record has zero data length\n", 311 "%s line %d: S3 record has zero data length\n",
273 iramimage.filename, iramimage.lineno); 312 iramimage.filename, iramimage.lineno);
274 exit(1); 313 exit(1);
275 } 314 }
276 /* form <w command */ 315 /* get to work */
277 if (!rec_count) 316 if (!rec_count)
278 printf("Sending image payload\n"); 317 printf("Sending image payload\n");
279 write_cmd[5] = iramimage.datalen; 318 if (write_cmd_datalen &&
280 bcopy(iramimage.record + 1, write_cmd + 6, 4); 319 (iramimage.addr != write_cmd_endaddr ||
281 write(target_fd, write_cmd, sizeof write_cmd); 320 write_cmd_datalen + iramimage.datalen > MAX_WRITE_LEN)) {
282 write(target_fd, iramimage.record + 5, iramimage.datalen); 321 send_write_cmd();
283 /* update our checksum accumulator */ 322 write_cmd_datalen = 0;
284 image_cksum += ~compute_block_cksum() & 0xFF; 323 }
285 /* collect response */ 324 if (!write_cmd_datalen) {
286 resp = expect_response(INTERMEDIATE_TIMEOUT); 325 bcopy(iramimage.record + 1, write_cmd + 6, 4);
287 if (resp != 'w') { 326 write_cmd_endaddr = iramimage.addr;
288 fprintf(stderr, "Block #%lu: ", rec_count); 327 }
289 if (resp < 0) 328 bcopy(iramimage.record + 5, write_cmd + 10 + write_cmd_datalen,
290 fprintf(stderr, "No response to <w command\n"); 329 iramimage.datalen);
291 else if (isprint(resp)) 330 write_cmd_endaddr += iramimage.datalen;
292 fprintf(stderr, 331 write_cmd_datalen += iramimage.datalen;
293 "Got >%c in response to <w command; expected >w\n",
294 resp);
295 else
296 fprintf(stderr,
297 "Got > %02X in response to <w command; expected >w\n",
298 resp);
299 exit(1);
300 }
301 putchar('.');
302 fflush(stdout);
303 rec_count++; 332 rec_count++;
304 } 333 }
305 /* got S7 */ 334 /* got S7 */
306 fclose(iramimage.openfile); 335 fclose(iramimage.openfile);
307 if (!rec_count) { 336 if (!rec_count) {
308 fprintf(stderr, 337 fprintf(stderr,
309 "%s line %d: S7 without any preceding S3 data records\n", 338 "%s line %d: S7 without any preceding S3 data records\n",
310 iramimage.filename, iramimage.lineno); 339 iramimage.filename, iramimage.lineno);
311 exit(1); 340 exit(1);
312 } 341 }
342 send_write_cmd(); /* last block */
343 putchar('\n'); /* end line of dots */
313 344
314 /* send <c */ 345 /* send <c */
315 printf("Sending checksum\n"); 346 printf("Sending checksum\n");
316 cksum_cmd[2] = ~image_cksum & 0xFF; 347 cksum_cmd[2] = ~image_cksum & 0xFF;
317 write(target_fd, cksum_cmd, sizeof cksum_cmd); 348 write(target_fd, cksum_cmd, sizeof cksum_cmd);