comparison loadtools/flprogsrec.c @ 628:9c5b0629e346

fc-loadtool SREC programming revamp implemented, compiles
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 29 Feb 2020 02:14:30 +0000
parents 97fe41e9242a
children 0f70fe9395c4
comparison
equal deleted inserted replaced
627:d04502de49ed 628:9c5b0629e346
10 #include <time.h> 10 #include <time.h>
11 #include "flash.h" 11 #include "flash.h"
12 #include "srecreader.h" 12 #include "srecreader.h"
13 13
14 extern struct flash_bank_info flash_bank_info[2]; 14 extern struct flash_bank_info flash_bank_info[2];
15 extern uint32_t crc32_table[];
16
17 #define MAX_SREC_REGIONS 256
18
19 read_srec_img_for_flash(imgfile, is_m0, bank_size, reglistp, regcountp,
20 totalp, tmpfilep)
21 char *imgfile;
22 uint32_t bank_size, *totalp;
23 struct discontig_prog *reglistp;
24 unsigned *regcountp;
25 FILE **tmpfilep;
26 {
27 struct srecreader srr;
28 struct discontig_prog *regp;
29 unsigned regcount;
30 uint32_t total_len;
31 char tmpfilename[] = "/tmp/fc-loadtoolXXXXXX";
32 int rc, tmpfd, i, c;
33 FILE *tmpfile;
34
35 printf("Reading S-record image from %s\n", imgfile);
36 srr.filename = imgfile;
37 rc = open_srec_file(&srr);
38 if (rc < 0)
39 return(rc);
40 tmpfd = mkstemp(tmpfilename);
41 if (tmpfd < 0) {
42 fprintf(stderr, "unable to get temp file via mkstemp()\n");
43 fclose(srr.openfile);
44 return(-1);
45 }
46 unlink(tmpfilename);
47 tmpfile = fdopen(tmpfd, "w+");
48 if (!tmpfile) {
49 perror("fdopen");
50 close(tmpfd);
51 fclose(srr.openfile);
52 return(-1);
53 }
54 regp = reglistp;
55 regcount = 0;
56 total_len = 0;
57 for (;;) {
58 if (read_s_record(&srr) < 0) {
59 /* error msg already printed */
60 fclose(srr.openfile);
61 fclose(tmpfile);
62 return(-1);
63 }
64 if (srr.record_type == '0') {
65 if (srr.lineno == 1)
66 continue;
67 fprintf(stderr,
68 "error: S0 record found in line %d of %s (expected in line 1 only)\n",
69 srr.lineno, srr.filename);
70 fclose(srr.openfile);
71 fclose(tmpfile);
72 return(-1);
73 } else if (srr.record_type == '7')
74 break;
75 else if (srr.record_type != '3') {
76 fprintf(stderr,
77 "error: unsupported S%c record type in line %d of %s\n",
78 srr.record_type, srr.lineno, srr.filename);
79 fclose(srr.openfile);
80 fclose(tmpfile);
81 return(-1);
82 }
83 /* must be S3 */
84 if (s3s7_get_addr_data(&srr) < 0) {
85 /* error msg already printed */
86 fclose(srr.openfile);
87 fclose(tmpfile);
88 return(-1);
89 }
90 if (srr.datalen < 1) {
91 fprintf(stderr,
92 "%s line %d: S3 record of zero data length ignored\n",
93 srr.filename, srr.lineno);
94 continue;
95 }
96 if (srr.addr & 1 || srr.datalen & 1) {
97 fprintf(stderr,
98 "%s line %d: violates word alignment requirement\n",
99 srr.filename, srr.lineno);
100 fclose(srr.openfile);
101 fclose(tmpfile);
102 return(-1);
103 }
104 srr.addr &= bank_size - 1;
105 if (srr.addr + srr.datalen > bank_size) {
106 fprintf(stderr,
107 "%s line %d: goes past the end of the flash bank\n",
108 srr.filename, srr.lineno);
109 fclose(srr.openfile);
110 fclose(tmpfile);
111 return(-1);
112 }
113 /* is this the first record of the first region? */
114 if (!regcount) {
115 regp->start = srr.addr;
116 regp->end = srr.addr;
117 regp->crc = 0xFFFFFFFF;
118 regcount = 1;
119 }
120 if (srr.addr < regp->end) {
121 fprintf(stderr, "%s line %d: address going backwards\n",
122 srr.filename, srr.lineno);
123 fclose(srr.openfile);
124 fclose(tmpfile);
125 return(-1);
126 }
127 if (srr.addr != regp->end) {
128 if (regcount >= MAX_SREC_REGIONS) {
129 fprintf(stderr,
130 "error: %s has too many discontiguous regions\n",
131 imgfile);
132 fclose(srr.openfile);
133 fclose(tmpfile);
134 return(-1);
135 }
136 regp++;
137 regcount++;
138 regp->start = srr.addr;
139 regp->end = srr.addr;
140 regp->crc = 0xFFFFFFFF;
141 }
142 /* take in the payload */
143 if (is_m0) {
144 for (i = 0; i < srr.datalen; i += 2) {
145 c = srr.record[i+6];
146 regp->crc = crc32_table[regp->crc & 0xFF ^ c]
147 ^ (regp->crc >> 8);
148 putc(c, tmpfile);
149 c = srr.record[i+5];
150 regp->crc = crc32_table[regp->crc & 0xFF ^ c]
151 ^ (regp->crc >> 8);
152 putc(c, tmpfile);
153 }
154 } else {
155 for (i = 0; i < srr.datalen; i++) {
156 c = srr.record[i+5];
157 regp->crc = crc32_table[regp->crc & 0xFF ^ c]
158 ^ (regp->crc >> 8);
159 putc(c, tmpfile);
160 }
161 }
162 regp->end += srr.datalen;
163 total_len += srr.datalen;
164 }
165 /* got S7 */
166 fclose(srr.openfile);
167 if (!regcount) {
168 fprintf(stderr,
169 "%s line %d: S7 without any preceding S3 data records\n",
170 srr.filename, srr.lineno);
171 fclose(tmpfile);
172 return(-1);
173 }
174 /* good read */
175 if (regcount == 1)
176 printf("Got %lu (0x%lx) bytes in one contiguous region\n",
177 (u_long) total_len, (u_long) total_len);
178 else
179 printf("Got %lu (0x%lx) bytes in %u discontiguous regions\n",
180 (u_long) total_len, (u_long) total_len, regcount);
181 *regcountp = regcount;
182 *totalp = total_len;
183 *tmpfilep = tmpfile;
184 return(0);
185 }
15 186
16 flashcmd_progsrec_gen(bank, imgfile, is_m0) 187 flashcmd_progsrec_gen(bank, imgfile, is_m0)
17 char *imgfile; 188 char *imgfile;
18 { 189 {
19 struct flash_bank_info *bi; 190 struct flash_bank_info *bi;
20 struct srecreader srr; 191 struct discontig_prog regions[MAX_SREC_REGIONS], *regp;
192 unsigned nregions, reg;
193 uint32_t total_len, bytesdone, addr, len;
194 FILE *tmpfile;
21 char *targv[4], shortarg[10], longarg[513]; 195 char *targv[4], shortarg[10], longarg[513];
22 int resp; 196 u_char databuf[256];
23 unsigned long rec_count; 197 int reclen, cc, rc;
24 time_t start_time, finish_time; 198 time_t initial_time, curtime, last_time;
25 unsigned duration, mm, ss; 199 unsigned duration, mm, ss;
200 u_long crc_from_target;
26 201
27 if (flash_detect(bank, 0) < 0) 202 if (flash_detect(bank, 0) < 0)
28 return(-1); 203 return(-1);
29 bi = flash_bank_info + bank; 204 bi = flash_bank_info + bank;
30 srr.filename = imgfile; 205 rc = read_srec_img_for_flash(imgfile, is_m0, bi->geom->total_size,
31 resp = open_srec_file(&srr); 206 regions, &nregions, &total_len, &tmpfile);
32 if (resp < 0) 207 if (rc < 0)
33 return(resp); 208 return(rc);
34 sprintf(shortarg, "%lx", (u_long) bi->base_addr); 209 sprintf(shortarg, "%lx", (u_long) bi->base_addr);
35 targv[0] = bi->ops->loadagent_setbase_cmd; 210 targv[0] = bi->ops->loadagent_setbase_cmd;
36 targv[1] = shortarg; 211 targv[1] = shortarg;
37 targv[2] = 0; 212 targv[2] = 0;
38 printf("Setting flash base address: %s %s\n", targv[0], targv[1]); 213 printf("Setting flash base address: %s %s\n", targv[0], targv[1]);
39 tpinterf_make_cmd(targv); 214 tpinterf_make_cmd(targv);
40 if (tpinterf_send_cmd() < 0) { 215 if (tpinterf_send_cmd() < 0) {
41 fclose(srr.openfile); 216 fclose(tmpfile);
42 return(-1); 217 return(-1);
43 } 218 }
44 resp = tpinterf_pass_output(1); 219 rc = tpinterf_pass_output(1);
45 if (resp) { 220 if (rc) {
46 fclose(srr.openfile); 221 fclose(tmpfile);
47 return(resp); 222 return(rc);
48 } 223 }
49 if (bi->ops->prep_for_program(bi) < 0) { 224 if (bi->ops->prep_for_program(bi) < 0) {
50 fclose(srr.openfile); 225 fclose(tmpfile);
51 return(-1); 226 return(-1);
52 } 227 }
228 rewind(tmpfile);
53 targv[0] = bi->ops->loadagent_program_cmd; 229 targv[0] = bi->ops->loadagent_program_cmd;
54 targv[1] = shortarg; 230 targv[1] = shortarg;
55 targv[2] = longarg; 231 targv[2] = longarg;
56 targv[3] = 0; 232 targv[3] = 0;
57 for (rec_count = 0; ; ) { 233 printf("Programming flash\n");
58 if (read_s_record(&srr) < 0) { 234 bytesdone = 0;
59 /* error msg already printed */ 235 last_time = 0;
60 fclose(srr.openfile); 236 time(&initial_time);
61 return(-1); 237 for (reg = 0, regp = regions; reg < nregions; reg++, regp++) {
62 } 238 addr = regp->start;
63 if (srr.record_type == '0') { 239 len = regp->end - addr;
64 if (srr.lineno == 1) 240 while (len) {
65 continue; 241 if (len >= 256)
66 fprintf(stderr, 242 reclen = 256;
67 "Warning: S0 record found in line %d of %s (expected in line 1 only)\n", 243 else
68 srr.lineno, srr.filename); 244 reclen = len;
69 continue; 245 cc = fread(databuf, 1, reclen, tmpfile);
70 } else if (srr.record_type == '7') { 246 if (cc != reclen) {
71 time(&finish_time); 247 fclose(tmpfile);
72 break; 248 fprintf(stderr,
73 } else if (srr.record_type != '3') { 249 "error reading from temp file!\n");
74 fprintf(stderr, 250 return(-1);
75 "Warning: unsupported S%c record type in line %d of %s\n", 251 }
76 srr.record_type, srr.lineno, srr.filename); 252 sprintf(shortarg, "%lx", addr);
77 continue; 253 build_flashw_hex_string(databuf, longarg, reclen >> 1,
78 } 254 0);
79 /* must be S3 */ 255 tpinterf_make_cmd(targv);
80 if (s3s7_get_addr_data(&srr) < 0) { 256 if (tpinterf_send_cmd() < 0) {
81 /* error msg already printed */ 257 fclose(tmpfile);
82 fclose(srr.openfile); 258 return(-1);
83 return(-1); 259 }
84 } 260 rc = tpinterf_pass_output(8); /* 8 s timeout */
85 if (srr.datalen < 1) { 261 if (rc) {
86 fprintf(stderr, 262 fclose(tmpfile);
87 "%s line %d: S3 record of zero data length ignored\n", 263 return(rc);
88 srr.filename, srr.lineno); 264 }
89 continue; 265 addr += reclen;
90 } 266 len -= reclen;
91 if (srr.addr & 1 || srr.datalen & 1) { 267 bytesdone += reclen;
92 fprintf(stderr, 268 cc = bytesdone * 100 / total_len;
93 "%s line %d: violates word alignment requirement\n", 269 time(&curtime);
94 srr.filename, srr.lineno); 270 if (curtime != last_time || cc == 100) {
95 fclose(srr.openfile); 271 printf("\r0x%lx bytes programmed (%i%%)",
96 return(-1); 272 bytesdone, cc);
97 } 273 fflush(stdout);
98 srr.addr &= bi->geom->total_size - 1; 274 }
99 if (srr.addr + srr.datalen > bi->geom->total_size) { 275 last_time = curtime;
100 fprintf(stderr, 276 }
101 "%s line %d: goes past the end of the flash bank\n", 277 }
102 srr.filename, srr.lineno); 278 putchar('\n');
103 fclose(srr.openfile); 279 fclose(tmpfile);
104 return(-1); 280 duration = last_time - initial_time;
105 }
106 if (!rec_count) {
107 printf("Programming flash, each \'.\' is 100 S-records\n");
108 time(&start_time);
109 }
110 sprintf(shortarg, "%lx", (u_long) srr.addr);
111 build_flashw_hex_string(srr.record + 5, longarg,
112 srr.datalen >> 1, is_m0);
113 tpinterf_make_cmd(targv);
114 if (tpinterf_send_cmd() < 0) {
115 fclose(srr.openfile);
116 return(-1);
117 }
118 resp = tpinterf_pass_output(8); /* 8 s timeout */
119 if (resp) {
120 fclose(srr.openfile);
121 return(resp);
122 }
123 rec_count++;
124 if (rec_count % 100 == 0) {
125 putchar('.');
126 fflush(stdout);
127 }
128 }
129 /* got S7 */
130 fclose(srr.openfile);
131 if (!rec_count) {
132 fprintf(stderr,
133 "%s line %d: S7 without any preceding S3 data records\n",
134 srr.filename, srr.lineno);
135 return(-1);
136 }
137 duration = finish_time - start_time;
138 mm = duration / 60; 281 mm = duration / 60;
139 ss = duration - mm * 60; 282 ss = duration - mm * 60;
140 printf("\nOperation completed in %um%us\n", mm, ss); 283 printf("Operation completed in %um%us\n", mm, ss);
284
285 /* reset flash to read mode */
286 if (bi->ops->reset_cmd(bi) < 0)
287 return(-1);
288 printf("Verifying CRC-32 of %u programmed region(s)\n", nregions);
289 for (reg = 0, regp = regions; reg < nregions; reg++, regp++) {
290 rc = crc32_on_target((u_long) regp->start,
291 (u_long) (regp->end - regp->start),
292 &crc_from_target);
293 if (rc < 0)
294 return(rc);
295 if (crc_from_target != regp->crc) {
296 fprintf(stderr, "error: CRC mismatch!\n");
297 return(-1);
298 }
299 putchar('.');
300 fflush(stdout);
301 }
302 putchar('\n');
141 return(0); 303 return(0);
142 } 304 }
143 305
144 flashcmd_program_srec(argc, argv, bank) 306 flashcmd_program_srec(argc, argv, bank)
145 char **argv; 307 char **argv;