FreeCalypso > hg > freecalypso-tools
view loadtools/chainload.c @ 948:d16222179c67
doc/Rvinterf-tools: document rvinterf -v changes
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 06 Jun 2023 23:17:10 +0000 |
parents | 185c9bf208d3 |
children |
line wrap: on
line source
/* * This module implements the chain-loading of XRAM images via loadagent. */ #include <sys/types.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <time.h> #include <unistd.h> #include "../libserial/baudrate.h" #include "discontig.h" #include "srecreader.h" extern int target_fd; struct srecreader xramimage; extern struct baudrate *current_baud_rate; extern struct baudrate *xram_run_baudrate; extern int xram_jtag_mode; extern uint32_t crc32_table[]; perform_chain_load() { int rc, reclen, too_many_regions; unsigned long rec_count; struct discontig_prog regions[MAX_SREC_REGIONS], *regp; unsigned regcount, reg; char *argv[3], jumparg[10]; u_char scratch[3], expect_conf[3]; time_t start_time, finish_time; unsigned duration, mm, ss; u_long crc_from_target; int i, c; if (open_srec_file(&xramimage) < 0) exit(1); /* enter binary RAM download mode */ argv[0] = "BINML"; argv[1] = 0; tpinterf_make_cmd(argv); if (tpinterf_send_cmd()) exit(1); /* read and send S-record image */ expect_conf[0] = 0x06; regp = regions; regcount = 0; too_many_regions = 0; for (rec_count = 0; ; ) { if (read_s_record(&xramimage) < 0) exit(1); switch (xramimage.record_type) { case '0': if (xramimage.lineno == 1) continue; fprintf(stderr, "%s: S0 record found in line %d (expected in line 1 only)\n", xramimage.filename, xramimage.lineno); exit(1); case '3': case '7': if (s3s7_get_addr_data(&xramimage) < 0) exit(1); break; default: fprintf(stderr, "%s line %d: S%c record type not supported\n", xramimage.filename, xramimage.lineno, xramimage.record_type); exit(1); } if (xramimage.record_type == '7') break; /* must be S3 */ if (xramimage.datalen < 1) { fprintf(stderr, "%s line %d: S3 record has zero data length\n", xramimage.filename, xramimage.lineno); exit(1); } if (!rec_count) { printf("Each \'.\' is %d S-records\n", current_baud_rate->xram_records); time(&start_time); } reclen = xramimage.datalen + 6; if (write(target_fd, xramimage.record, reclen) != reclen) { perror("binary write to target"); exit(1); } rec_count++; /* discontiguous regions and CRC-32 accumulation */ if (!regcount) { regp->start = xramimage.addr; regp->end = xramimage.addr; regp->crc = 0xFFFFFFFF; regcount = 1; } if (xramimage.addr != regp->end) { if (regcount >= MAX_SREC_REGIONS) too_many_regions = 1; else { regp++; regcount++; regp->start = xramimage.addr; regp->end = xramimage.addr; regp->crc = 0xFFFFFFFF; } } if (!too_many_regions) { for (i = 0; i < xramimage.datalen; i++) { c = xramimage.record[i+5]; regp->crc = crc32_table[regp->crc & 0xFF ^ c] ^ (regp->crc >> 8); } regp->end += xramimage.datalen; } /* target sync and progress indication */ if (rec_count % current_baud_rate->xram_records == 0) { scratch[0] = 0x05; /* ENQ */ write(target_fd, scratch, 1); if (collect_binblock_from_target(scratch, 3, 1)) exit(1); expect_conf[1] = rec_count >> 8; expect_conf[2] = rec_count; if (bcmp(scratch, expect_conf, 3)) { fprintf(stderr, "error: expected sync mismatch\n"); exit(1); } putchar('.'); fflush(stdout); } } /* got S7 */ fclose(xramimage.openfile); if (!rec_count) { fprintf(stderr, "%s line %d: S7 without any preceding S3 data records\n", xramimage.filename, xramimage.lineno); exit(1); } putchar('\n'); /* newline after the dots */ scratch[0] = 0x04; /* EOT */ write(target_fd, scratch, 1); if (collect_binblock_from_target(scratch, 1, 1)) exit(1); time(&finish_time); if (scratch[0] != '=') { fprintf(stderr, "error: \'=\' not received as expected\n"); exit(1); } duration = finish_time - start_time; mm = duration / 60; ss = duration - mm * 60; printf("XRAM image transferred in %um%02us\n", mm, ss); printf("Verifying CRC-32 of %u downloaded region(s)\n", regcount); for (reg = 0, regp = regions; reg < regcount; reg++, regp++) { rc = crc32_on_target((u_long) regp->start, (u_long) (regp->end - regp->start), &crc_from_target); if (rc < 0) exit(1); if (crc_from_target != regp->crc) { fprintf(stderr, "error: CRC mismatch!\n"); exit(1); } putchar('.'); fflush(stdout); } putchar('\n'); if (xram_run_baudrate != current_baud_rate) { rc = loadagent_switch_baud(xram_run_baudrate); if (rc) exit(1); } if (xram_jtag_mode) { printf( "Leaving target in loadagent for JTAG; image start address is 0x%08lX\n", (u_long) xramimage.addr); exit(0); } printf("Sending jump command\n"); sprintf(jumparg, "%lX", (u_long) xramimage.addr); argv[0] = "jump"; argv[1] = jumparg; argv[2] = 0; tpinterf_make_cmd(argv); if (tpinterf_send_cmd()) exit(1); printf("Sent \"%s %s\": XRAM image should now be running!\n", argv[0], argv[1]); return(0); }