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", | 
