FreeCalypso > hg > fc-magnetite
view helpers/srec4ram.c @ 639:026c98f757a6
tpudrv12.h & targets/gtm900.h: our current support is for MGC2GSMT version only
As it turns out, there exist two different Huawei-made hw platforms both
bearing the marketing name GTM900-B: one is MG01GSMT, the other is MGC2GSMT.
The two are NOT fw-compatible: aside from flash chip differences which
should be handled by autodetection, the two hw platforms are already known
to have different RFFEs with different control signals, and there may be
other differences not yet known. Our current gtm900 build target is for
MGC2GSMT only; we do not yet have a specimen of MG01GSMT on hand, hence
no support for that version will be possible until and unless someone
provides one.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 30 Jan 2020 18:19:01 +0000 |
parents | 40b08f6cb2b8 |
children |
line wrap: on
line source
/* * This ad hoc utility is used as part of building RAM-loadable * firmware images for targets with large RAM. It reads the ramimage.m0 * S-record file produced by TI's hex470 post-linker and re-emits it * in another SREC form that is suitable for feeding to fc-xram. */ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> char *infname; FILE *inf, *outf; char srecbuf[80]; u_char srecbin[40], srecout[40]; int lineno; decode_hex_byte(s) char *s; { register int u, l; if (!isxdigit(s[0]) || !isxdigit(s[1])) return(-1); if (isdigit(s[0])) u = s[0] - '0'; else if (isupper(s[0])) u = s[0] - 'A' + 10; else u = s[0] - 'a' + 10; if (isdigit(s[1])) l = s[1] - '0'; else if (isupper(s[1])) l = s[1] - 'A' + 10; else l = s[1] - 'a' + 10; return((u << 4) | l); } srec2bin() { register int i, l, b; l = decode_hex_byte(srecbuf + 2); if (l < 1) { fprintf(stderr, "%s line %d: S-record length octet is bad\n", infname, lineno); exit(1); } srecbin[0] = l; if (l > 35) { fprintf(stderr, "%s line %d: S-record is longer than expected\n", infname, lineno); exit(1); } for (i = 1; i <= l; i++) { b = decode_hex_byte(srecbuf + i*2 + 2); if (b < 0) { fprintf(stderr, "%s line %d: hex decode error\n", infname, lineno); exit(1); } srecbin[i] = b; } return(0); } srec_cksum() { u_char accum; register int i, len; len = srecbin[0] + 1; accum = 0; for (i = 0; i < len; i++) accum += srecbin[i]; if (accum != 0xFF) { fprintf(stderr, "%s line %d: bad checksum\n", infname, lineno); exit(1); } return(0); } emit_output_srec(type, buf) u_char *buf; { int i; u_char accum = 0; putc('S', outf); putc(type, outf); for (i = 0; i < buf[0]; i++) { fprintf(outf, "%02X", buf[i]); accum += buf[i]; } fprintf(outf, "%02X\n", ~accum & 0xFF); return 0; } transform_s3() { int datalen; u_char *sp, *dp; int i; if (srecbin[0] < 6) { fprintf(stderr, "%s line %d: S3 record is too short\n", infname, lineno); exit(1); } datalen = srecbin[0] - 5; if (datalen & 1) { fprintf(stderr, "%s line %d: odd data length\n", infname, lineno); exit(1); } sp = srecbin; dp = srecout; for (i = 0; i < 5; i++) *dp++ = *sp++; for (i = 0; i < datalen; i += 2) { dp[0] = sp[1]; dp[1] = sp[0]; sp += 2; dp += 2; } return 0; } generate_vectors_record() { u_char *dp; u_long addr; int i; srecout[0] = 28 + 5; srecout[1] = 0x00; srecout[2] = 0x80; srecout[3] = 0x00; srecout[4] = 0x00; dp = srecout + 5; for (i = 0; i < 7; i++) { addr = 0x01004000 + i * 4; *dp++ = addr; *dp++ = addr >> 8; *dp++ = addr >> 16; *dp++ = addr >> 24; } emit_output_srec('3', srecout); return 0; } generate_jump_record() { srecout[0] = 5; srecout[1] = 0x01; srecout[2] = 0x00; srecout[3] = 0x40; srecout[4] = 0x58; emit_output_srec('7', srecout); return 0; } main(argc, argv) char **argv; { if (argc < 2 || argc > 3) { fprintf(stderr, "usage: %s input.m0 [output.srec]\n", argv[0]); exit(1); } infname = argv[1]; inf = fopen(infname, "r"); if (!inf) { perror(infname); exit(1); } if (argc > 2) { outf = fopen(argv[2], "w"); if (!outf) { perror(argv[2]); exit(1); } } else outf = stdout; for (lineno = 1; ; lineno++) { if (!fgets(srecbuf, sizeof srecbuf, inf)) { fprintf(stderr, "%s: premature EOF\n", infname); exit(1); } if (srecbuf[0] != 'S') { fprintf(stderr, "%s line %d: not an S-record\n", infname, lineno); exit(1); } srec2bin(); srec_cksum(); switch (srecbuf[1]) { case '0': emit_output_srec('0', srecbin); continue; case '3': transform_s3(); emit_output_srec('3', srecout); continue; case '7': break; default: fprintf(stderr, "%s line %d: unexpected S%c record\n", infname, lineno, srecbuf[1]); exit(1); } break; } generate_vectors_record(); generate_jump_record(); exit(0); }