FreeCalypso > hg > freecalypso-tools
comparison loadtools/chainload.c @ 656:9f5a3e9e6294
fc-xram: implemented CRC-32 verification
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 03 Mar 2020 00:08:27 +0000 |
parents | 6bb41b4d39ed |
children | 51bcfb251b23 |
comparison
equal
deleted
inserted
replaced
655:a880f48d6ac0 | 656:9f5a3e9e6294 |
---|---|
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 #include <string.h> | 9 #include <string.h> |
10 #include <strings.h> | 10 #include <strings.h> |
11 #include <time.h> | 11 #include <time.h> |
12 #include "../libserial/baudrate.h" | 12 #include "../libserial/baudrate.h" |
13 #include "discontig.h" | |
13 #include "srecreader.h" | 14 #include "srecreader.h" |
14 | 15 |
15 extern int target_fd; | 16 extern int target_fd; |
16 | 17 |
17 struct srecreader xramimage; | 18 struct srecreader xramimage; |
18 | 19 |
19 extern struct baudrate *current_baud_rate; | 20 extern struct baudrate *current_baud_rate; |
20 extern struct baudrate *xram_run_baudrate; | 21 extern struct baudrate *xram_run_baudrate; |
21 extern int xram_jtag_mode; | 22 extern int xram_jtag_mode; |
23 extern uint32_t crc32_table[]; | |
22 | 24 |
23 perform_chain_load() | 25 perform_chain_load() |
24 { | 26 { |
25 int resp, reclen; | 27 int rc, reclen, too_many_regions; |
26 unsigned long rec_count; | 28 unsigned long rec_count; |
29 struct discontig_prog regions[MAX_SREC_REGIONS], *regp; | |
30 unsigned regcount, reg; | |
27 char *argv[3], jumparg[10]; | 31 char *argv[3], jumparg[10]; |
28 u_char scratch[3], expect_conf[3]; | 32 u_char scratch[3], expect_conf[3]; |
29 time_t start_time, finish_time; | 33 time_t start_time, finish_time; |
30 unsigned duration, mm, ss; | 34 unsigned duration, mm, ss; |
35 u_long crc_from_target; | |
36 int i, c; | |
31 | 37 |
32 if (open_srec_file(&xramimage) < 0) | 38 if (open_srec_file(&xramimage) < 0) |
33 exit(1); | 39 exit(1); |
34 /* enter binary RAM download mode */ | 40 /* enter binary RAM download mode */ |
35 argv[0] = "BINML"; | 41 argv[0] = "BINML"; |
37 tpinterf_make_cmd(argv); | 43 tpinterf_make_cmd(argv); |
38 if (tpinterf_send_cmd()) | 44 if (tpinterf_send_cmd()) |
39 exit(1); | 45 exit(1); |
40 /* read and send S-record image */ | 46 /* read and send S-record image */ |
41 expect_conf[0] = 0x06; | 47 expect_conf[0] = 0x06; |
48 regp = regions; | |
49 regcount = 0; | |
50 too_many_regions = 0; | |
42 for (rec_count = 0; ; ) { | 51 for (rec_count = 0; ; ) { |
43 if (read_s_record(&xramimage) < 0) | 52 if (read_s_record(&xramimage) < 0) |
44 exit(1); | 53 exit(1); |
45 switch (xramimage.record_type) { | 54 switch (xramimage.record_type) { |
46 case '0': | 55 case '0': |
80 if (write(target_fd, xramimage.record, reclen) != reclen) { | 89 if (write(target_fd, xramimage.record, reclen) != reclen) { |
81 perror("binary write to target"); | 90 perror("binary write to target"); |
82 exit(1); | 91 exit(1); |
83 } | 92 } |
84 rec_count++; | 93 rec_count++; |
94 /* discontiguous regions and CRC-32 accumulation */ | |
95 if (!regcount) { | |
96 regp->start = xramimage.addr; | |
97 regp->end = xramimage.addr; | |
98 regp->crc = 0xFFFFFFFF; | |
99 regcount = 1; | |
100 } | |
101 if (xramimage.addr != regp->end) { | |
102 if (regcount >= MAX_SREC_REGIONS) | |
103 too_many_regions = 1; | |
104 else { | |
105 regp++; | |
106 regcount++; | |
107 regp->start = xramimage.addr; | |
108 regp->end = xramimage.addr; | |
109 regp->crc = 0xFFFFFFFF; | |
110 } | |
111 } | |
112 if (!too_many_regions) { | |
113 for (i = 0; i < xramimage.datalen; i++) { | |
114 c = xramimage.record[i+5]; | |
115 regp->crc = crc32_table[regp->crc & 0xFF ^ c] | |
116 ^ (regp->crc >> 8); | |
117 } | |
118 regp->end += xramimage.datalen; | |
119 } | |
120 /* target sync and progress indication */ | |
85 if (rec_count % current_baud_rate->xram_records == 0) { | 121 if (rec_count % current_baud_rate->xram_records == 0) { |
86 scratch[0] = 0x05; /* ENQ */ | 122 scratch[0] = 0x05; /* ENQ */ |
87 write(target_fd, scratch, 1); | 123 write(target_fd, scratch, 1); |
88 if (collect_binblock_from_target(scratch, 3, 1)) | 124 if (collect_binblock_from_target(scratch, 3, 1)) |
89 exit(1); | 125 exit(1); |
118 } | 154 } |
119 duration = finish_time - start_time; | 155 duration = finish_time - start_time; |
120 mm = duration / 60; | 156 mm = duration / 60; |
121 ss = duration - mm * 60; | 157 ss = duration - mm * 60; |
122 printf("XRAM image transferred in %um%us\n", mm, ss); | 158 printf("XRAM image transferred in %um%us\n", mm, ss); |
159 printf("Verifying CRC-32 of %u downloaded region(s)\n", regcount); | |
160 for (reg = 0, regp = regions; reg < regcount; reg++, regp++) { | |
161 rc = crc32_on_target((u_long) regp->start, | |
162 (u_long) (regp->end - regp->start), | |
163 &crc_from_target); | |
164 if (rc < 0) | |
165 exit(1); | |
166 if (crc_from_target != regp->crc) { | |
167 fprintf(stderr, "error: CRC mismatch!\n"); | |
168 exit(1); | |
169 } | |
170 putchar('.'); | |
171 fflush(stdout); | |
172 } | |
173 putchar('\n'); | |
123 if (xram_run_baudrate != current_baud_rate) { | 174 if (xram_run_baudrate != current_baud_rate) { |
124 resp = loadagent_switch_baud(xram_run_baudrate); | 175 rc = loadagent_switch_baud(xram_run_baudrate); |
125 if (resp) | 176 if (rc) |
126 exit(1); | 177 exit(1); |
127 } | 178 } |
128 if (xram_jtag_mode) { | 179 if (xram_jtag_mode) { |
129 printf( | 180 printf( |
130 "Leaving target in loadagent for JTAG; image start address is 0x%08lX\n", | 181 "Leaving target in loadagent for JTAG; image start address is 0x%08lX\n", |