summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHao Zhang2011-06-10 09:48:25 -0500
committerHao Zhang2011-06-10 09:48:25 -0500
commitea8f277b358a0fdaae049c00cfe8c67a73c68020 (patch)
tree5d0226cb084f9256f9bcf90033c7cbf1db462dd5 /boot_loader/examples/ethernet/Utilities/bconvert64x.c
parent31ff1345fa2b74b83e55106fef6dfd0d5db3a7e8 (diff)
downloadmcsdk-tools-ea8f277b358a0fdaae049c00cfe8c67a73c68020.tar.gz
mcsdk-tools-ea8f277b358a0fdaae049c00cfe8c67a73c68020.tar.xz
mcsdk-tools-ea8f277b358a0fdaae049c00cfe8c67a73c68020.zip
Updated changes for GA RC1
Diffstat (limited to 'boot_loader/examples/ethernet/Utilities/bconvert64x.c')
-rw-r--r--boot_loader/examples/ethernet/Utilities/bconvert64x.c701
1 files changed, 701 insertions, 0 deletions
diff --git a/boot_loader/examples/ethernet/Utilities/bconvert64x.c b/boot_loader/examples/ethernet/Utilities/bconvert64x.c
new file mode 100644
index 0000000..c6b1b27
--- /dev/null
+++ b/boot_loader/examples/ethernet/Utilities/bconvert64x.c
@@ -0,0 +1,701 @@
1/******************************************************************************
2 * Copyright (c) 2011 Texas Instruments Incorporated - http://www.ti.com
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 *****************************************************************************/
33
34/************************************************************************************
35 * FILE PURPOSE: Convert a hex6x boot table file into the format required
36 * by the c6x chip boot loader.
37 ************************************************************************************
38 * FILE NAME: bconvert.c
39 *
40 * DESCRIPTION: Converts a boot table. The boot table format is:
41 *
42 * /--------------------------------------------------------\
43 * | 32 bit entry point address |
44 * +--------------------------------------------------------+
45 * | 32 bit section byte count | \
46 * +--------------------------------------------------------+ \
47 * | 32 bit section byte start address | \
48 * +-------------+-------------+-------------+--------------+ repeat each section
49 * | Data byte | Data byte | Data byte | Data byte | /
50 * +-------------+-------------+-------------+--------------+ /
51 * | Data byte | Data byte | Data byte | Data byte | /
52 * +-------------+-------------+-------------+--------------+
53 * | 32 bit zero byte count (end of boot table) |
54 * \--------------------------------------------------------/
55 *
56 *
57 * The C6x boot loader expects all 32 bit values to be in big endian
58 * (most significant byte arrives first). Data bytes are also arranged to be 32 bit
59 * big endian represented.
60 *
61 * This program handles conversion of data values that are in sections that are
62 * not multiples of 4 bytes. For example, a program compiled in big endian format
63 * with a 1 byte section will have the following table entry (address 0x22222222), value
64 * 0x33
65 *
66 * 00 00 00 01 22 22 22 22 33 00 00 00
67 *
68 * The same file compiled with little endian mode will have the entry
69 *
70 * 00 00 00 01 22 22 22 22 00 00 00 33
71 *
72 *
73 * Since the boot loader has no idea what endianness the code was compiled for, this
74 * program performs an endian conversion on any section that does not have a length
75 * that is a multiple of 4 bytes, if the little endian option is specified. Nothing
76 * is changed for the big endian mode.
77 *
78 * Invokation:
79 *
80 * bconvert -be|-le [input_file] [output_file]
81 *
82 ***************************************************************************************/
83
84#include "stdio.h"
85#include "malloc.h"
86#include "string.h"
87
88/* Global variable storing the invokation name */
89char *invok;
90
91/* Error values */
92enum {
93 ERR_PARSE_TOO_MANY_ARGS = 1000,
94 ERR_PARSE_NO_ENDIAN,
95 ERR_PARSE_INPUT_OPEN_FAIL,
96 ERR_PARSE_OUTPUT_OPEN_FAIL,
97 ERR_READ_BFILE_INITIAL_MALLOC_FAIL,
98 ERR_READ_BFILE_REALLOC_FAIL,
99 ERR_VALUE32_SIZE_ERR,
100 ERR_VALUE16_SIZE_ERR,
101 ERR_DATA32_SIZE_ERR,
102 ERR_REG32_PARSE_ERROR,
103 ERR_DATA32_REMAIN_ERR
104};
105
106enum {
107 LITTLE,
108 BIG
109};
110
111/************************************************************************************
112 * FUNTION PURPOSE: Send an error string
113 ************************************************************************************
114 * DESCRIPTION: Prints an error to stderr
115 ************************************************************************************/
116void showErr (int errflag)
117{
118 char *s;
119
120 switch (errflag) {
121 case ERR_PARSE_TOO_MANY_ARGS:
122 s = "Parse error: too many args specified";
123 break;
124
125 case ERR_PARSE_NO_ENDIAN:
126 s = "Parse error: no endian mode specified";
127 break;
128
129 case ERR_PARSE_INPUT_OPEN_FAIL:
130 s = "File error: failed to open specified input file";
131 break;
132
133 case ERR_PARSE_OUTPUT_OPEN_FAIL:
134 s = "File error: Failed to open specified output file";
135 break;
136
137 case ERR_READ_BFILE_INITIAL_MALLOC_FAIL:
138 s = "Memory error: Initial malloc call failed";
139 break;
140
141 case ERR_READ_BFILE_REALLOC_FAIL:
142 s = "Memory error: Subsequent realloc call failed";
143 break;
144
145 case ERR_VALUE32_SIZE_ERR:
146 s = "Data format error: End of data on 32 bit value read";
147 break;
148
149 case ERR_VALUE16_SIZE_ERR:
150 s = "Data format error: End of data on 16 bit value read";
151 break;
152
153 case ERR_REG32_PARSE_ERROR:
154 s = "Parse error: error parsing after reg32 arg";
155 break;
156
157 case ERR_DATA32_REMAIN_ERR:
158 s = "Parse error: A remainder size greater then four was found";
159 break;
160
161 default:
162 s = "Unspecified error";
163 break;
164
165 }
166
167 fprintf (stderr, "%s: %s\n", invok, s);
168
169} /* showErr */
170
171
172/*************************************************************************************
173 * FUNCTION PURPOSE: Check if a string is prefixed with "0x".
174 *************************************************************************************
175 * DESCRIPTION: Returns non-zero if the string begins with "0x"
176 *************************************************************************************/
177int isChex (char *s)
178{
179 if ((s[0] == '0') && (s[1] == 'x'))
180 return (1);
181
182 return (0);
183
184} /* isChex */
185
186
187
188/*************************************************************************************
189 * FUNCTION PURPOSE: Parse the input parameters
190 *************************************************************************************
191 * DESCRIPTION: Checks for required args, opens source and destination streams.
192 *************************************************************************************/
193int parseit (int argc, char *argv[], FILE **fin, FILE **fout, int *endian)
194{
195 int inspec = 0;
196 int outspec = 0;
197 int espec = 0;
198 int c = 1;
199
200 char *iname;
201 char *oname;
202
203 *endian = -1;
204
205 /* Store the invokation name */
206 invok = argv[0];
207
208 while (c < argc) {
209
210 /* -be | -le */
211 if (!espec) {
212 if (!strcmp (argv[c], "-be")) {
213 *endian = BIG;
214 espec = 1;
215 c += 1;
216 continue;
217 } else if (!strcmp (argv[c], "-le")) {
218 *endian = LITTLE;
219 espec = 1;
220 c += 1;
221 continue;
222 }
223 }
224
225
226 /* input file */
227 if (!inspec) {
228 inspec = 1;
229 iname = argv[c];
230 c += 1;
231 continue;
232 }
233
234 /* output file */
235 if (!outspec) {
236 outspec = 1;
237 oname = argv[c];
238 c += 1;
239 continue;
240 }
241
242 /* Don't know what to do with the arg */
243 return (ERR_PARSE_TOO_MANY_ARGS);
244
245 }
246
247
248 /* Make sure endian is known */
249 if (!espec)
250 return (ERR_PARSE_NO_ENDIAN);
251
252 /* Open input file if not stdin */
253 if (inspec) {
254 *fin = fopen (iname, "r");
255 if (*fin == NULL)
256 return (ERR_PARSE_INPUT_OPEN_FAIL);
257 }
258
259 /* Open output file if not stdin */
260 if (outspec) {
261 *fout = fopen (oname, "w");
262 if (*fout == NULL)
263 return (ERR_PARSE_OUTPUT_OPEN_FAIL);
264 }
265
266 return (0);
267
268} /* parseit */
269
270
271
272/***************************************************************************************
273 * FUNCTION PURPOSE: Check if data is ascii
274 ***************************************************************************************
275 * DESCRIPTION: Returns 1 if a byte is 0-9, a-f, 0 otherwise
276 ***************************************************************************************/
277int asciiByte (unsigned char c)
278{
279 if ((c >= '0') && (c <= '9'))
280 return (1);
281
282 if ((c >= 'A') && (c <= 'F'))
283 return (1);
284
285 return (0);
286} /* asciiByte */
287
288/**************************************************************************************
289 * FUNCTION PURPOSE: Returns the binary equivalent of an ascii byte
290 **************************************************************************************
291 * DESCRIPTION: Conversion from ascii to binary
292 **************************************************************************************/
293int toNum (unsigned char c)
294{
295 if ((c >= '0') && (c <= '9'))
296 return (c - '0');
297
298 return (c - 'A' + 10);
299
300} /* toNum */
301
302
303/**********************************************************************************
304 * FUNCTION PURPOSE: Read a line from a file, toss it
305 **********************************************************************************
306 * DESCRIPTION: Reads a line, including the newline character, and throws it away.
307 **********************************************************************************/
308void stripLine (FILE *s)
309{
310 char iline[132];
311
312 fgets (iline, 131, s);
313
314} /* stripLine */
315
316/************************************************************************************
317 * FILE PURPOSE: Read the hex55 data file
318 ************************************************************************************
319 * DESCRIPTION: Reads the input data file. Strips the first two lines, reads
320 * the byte stream.
321 ************************************************************************************/
322#define MALLOC_BLOCK_SIZE 512000
323unsigned char *readBFile (FILE *fin, unsigned *n, int *errcode)
324{
325 unsigned char *d;
326 unsigned allocSize;
327 unsigned m;
328 unsigned char x, y;
329
330 /* Create a block of data */
331 allocSize = MALLOC_BLOCK_SIZE;
332 d = malloc (allocSize * sizeof (unsigned char));
333 if (d == NULL) {
334 *errcode = ERR_READ_BFILE_INITIAL_MALLOC_FAIL;
335 if (fin != stdin)
336 fclose (fin);
337 return (NULL);
338 }
339
340 /* Strip the 1st two lines */
341 stripLine (fin);
342 stripLine (fin);
343
344 *errcode = 0;
345 m = 0;
346
347 for (;;) {
348
349 /* Read the 1st ascii char */
350 do {
351 x = fgetc (fin);
352 if (x == (unsigned char)EOF) {
353 *errcode = 0;
354 *n = m;
355 if (fin != stdin)
356 fclose (fin);
357 return (d);
358 }
359 } while (!asciiByte(x));
360
361 /* Read the next ascii char */
362 y = fgetc(fin);
363 if (y == (unsigned char)EOF) {
364 *errcode = 0;
365 *n = m;
366 if (fin != stdin)
367 fclose (fin);
368 return (d);
369 }
370
371 /* Convert the two characters into a byte */
372 if (asciiByte(y))
373 d[m++] = (toNum(x) << 4) | toNum(y);
374
375 /* Verify memory bounds */
376 if (m >= allocSize) {
377 allocSize += MALLOC_BLOCK_SIZE;
378 d= realloc (d, allocSize);
379 if (d== NULL) {
380 *errcode = ERR_READ_BFILE_REALLOC_FAIL;
381 if (fin != stdin)
382 fclose (fin);
383 return (NULL);
384 }
385 }
386
387 } /* end for */
388
389} /* readBFile */
390
391/**************************************************************************************
392 * FUNCTION PURPOSE: converts four bytes into an unsigned value
393 **************************************************************************************
394 * DESCRIPTION: Converts bytes to a value
395 **************************************************************************************/
396unsigned value32bitAdd (int endian, unsigned char *data, unsigned n, unsigned *p, int *errflag, unsigned add)
397{
398 unsigned v;
399 unsigned w;
400 unsigned q;
401
402 /* Verify that there are 4 values still in the character array */
403 if ((*p + 4) > n) {
404 *errflag = ERR_VALUE32_SIZE_ERR;
405 return (0);
406 }
407
408 /* Store the original pointer */
409 q = w = *p;
410
411 v = (unsigned)data[w+0] << 24 |
412 (unsigned)data[w+1] << 16 |
413 (unsigned)data[w+2] << 8 |
414 (unsigned)data[w+3] << 0 ;
415
416 *errflag = 0;
417
418 /* Add any additional value */
419 v = v + add;
420
421 /* Write the data back in big endian format */
422 data[q+0] = (v >> 24) & 0xff;
423 data[q+1] = (v >> 16) & 0xff;
424 data[q+2] = (v >> 8) & 0xff;
425 data[q+3] = (v >> 0) & 0xff;
426
427 *p = q+4;
428 return (v);
429
430} /* value32bitAdd */
431
432/**************************************************************************************
433 * FUNCTION PURPOSE: converts four bytes into an unsigned value
434 **************************************************************************************
435 * DESCRIPTION: Converts bytes to a value, depending on the endian configuration.
436 **************************************************************************************/
437unsigned value32bit (int endian, unsigned char *data, unsigned n, unsigned *p, int *errflag)
438{
439 return (value32bitAdd (endian, data, n, p, errflag, 0));
440
441} /* value32bit */
442
443
444
445
446/*********************************************************************************
447 * FUNCTION PURPOSE: Convert up to four bytes to big endian
448 *********************************************************************************
449 * DESCRIPTION: Data bytes are converted.
450 *********************************************************************************/
451#define SWAP(x,y,z) (z)=(x);(x)=(y);(y)=(z)
452void data32bit (int endian, unsigned char *data, unsigned n, unsigned *p, unsigned m, int *errflag)
453{
454
455 /* Calculate the number of bytes to convert, limited to four bytes */
456 if (m > 4)
457 m = 4;
458
459 /* return an error if there are not enough values in the array */
460 if ((*p + m) >= n) {
461 *errflag = ERR_DATA32_SIZE_ERR;
462 return;
463 }
464
465 /* Clear the error flag */
466 *errflag = 0;
467
468
469 /* The data is always already in big endian, there is nothing to do but advance the pointer */
470 *p += m;
471
472} /* data32bit */
473
474void remain32bit (int endian, unsigned char *data, unsigned n, unsigned *p, unsigned m, int *errflag)
475{
476 unsigned w;
477 unsigned char h;
478
479 /* return an error if the size is greater then or equal to 4 */
480 if (m >= 4) {
481 *errflag = ERR_DATA32_REMAIN_ERR;
482 return;
483 }
484
485 /* return an error if there are not enough values in the array */
486 if ((*p + m) >= n) {
487 *errflag = ERR_DATA32_SIZE_ERR;
488 return;
489 }
490
491 w = *p;
492
493 /* Only swap if endianness is little */
494 if (endian == LITTLE) {
495 /* Swap the next four bytes */
496 SWAP(data[w+0], data[w+3], h);
497 SWAP(data[w+1], data[w+2], h);
498 }
499
500 /* Update the full four elements */
501 *p = *p + 4;
502
503
504} /* remain32bit */
505
506
507/*********************************************************************************
508 * FUNCTION PURPOSE: Convert 2 bytes into an unsigned value
509 *********************************************************************************
510 * DESCRIPTION: Converts the next two bytes into an unsigned value based on
511 * the endian configuration.
512 *********************************************************************************/
513unsigned value16bit (int endian, unsigned char *data, unsigned n, unsigned *p, int *errflag)
514{
515 unsigned v;
516 unsigned q;
517
518 /* Verify that there are 4 values still in the character array */
519 if ((*p + 2) > n) {
520 *errflag = ERR_VALUE16_SIZE_ERR;
521 return (0);
522 }
523
524 /* Store the original pointer */
525 q = *p;
526
527 /* convert based on endianness. For little endain the 16 bit words are actually
528 * big endian, but the bytes in those words are not */
529 if (endian == BIG) {
530 v = data[(*p)++] << 8 |
531 data[(*p)++] << 0 ;
532
533 } else {
534 v = data[(*p)++] << 0 |
535 data[(*p)++] << 8 ;
536 }
537
538 *errflag = 0;
539
540 /* Write the data back in big endian format */
541 data[q++] = (v >> 8) & 0xff;
542 data[q++] = (v >> 0) & 0xff;
543
544 return (v);
545
546} /* value16bit */
547
548/**************************************************************************************
549 * FUNCTION PURPOSE: Writes a 16 bit value into the array
550 **************************************************************************************
551 * DESCRIPTION: Writes a big endian 16 bit value, increments the array pointer.
552 **************************************************************************************/
553void write16bit (unsigned value, unsigned char *data, unsigned *p)
554{
555 data[(*p)++] = (value >> 8) & 0xff;
556 data[(*p)++] = (value >> 0) & 0xff;
557
558} /* write16bit */
559
560
561/*************************************************************************************
562 * FUNCTION PURPOSE: Write the output file
563 *************************************************************************************
564 * DESCRIPTION: Writes the resulting output.
565 *************************************************************************************/
566void writeBFile (FILE *fout, unsigned char *data, unsigned n)
567{
568 unsigned i;
569
570 /* Write the two line header */
571 fprintf (fout, "%c\n$A000000\n", (unsigned char)2);
572
573 for (i = 0; i < n; i++) {
574 if ( ((i+1)%24) )
575 fprintf (fout, "%02X ", data[i]);
576 else
577 fprintf (fout, "%02X\n", data[i]);
578 }
579
580 /* Write the close character */
581 fprintf (fout, "\n%c", (unsigned char)3);
582
583 if (fout != stdout)
584 fclose (fout);
585
586} /* writeBFile */
587
588
589/**************************************************************************************
590 * FUNCTION PURPOSE: Main
591 **************************************************************************************
592 * DESCRIPTION: Provides the top level program flow.
593 **************************************************************************************/
594int main (int argc, char *argv[])
595{
596 FILE *fin; /* input stream */
597 FILE *fout; /* output stream */
598
599 unsigned char *data; /* The data set */
600 unsigned n; /* Data set size */
601 unsigned p; /* Data index */
602 unsigned v; /* Data value */
603 unsigned n32; /* Number of bytes that form complete 32 bit values */
604 unsigned r32; /* Number of bytes remaining (0-3) */
605
606 int endian; /* Endian */
607 int errflag; /* error indicator */
608 int i, j; /* loop var */
609 int origRegs; /* original reg count */
610 int shift; /* data shift amount */
611
612
613 /* Parse the input */
614 if (errflag = parseit (argc, argv, &fin, &fout, &endian)) {
615 showErr (errflag);
616 return (-1);
617 }
618
619 /* Read the raw data file */
620 data = readBFile (fin, &n, &errflag);
621 if (data == NULL) {
622 showErr (errflag);
623 return(-1);
624 }
625
626 /* Parse the sections */
627 p = 0;
628
629 /* The entry point */
630 v = value32bit (endian, data, n, &p, &errflag);
631 if (errflag) {
632 showErr (errflag);
633 return(-1);
634 }
635
636
637 /* The sections */
638 do {
639
640 /* Get the section byte count */
641 v = value32bit (endian, data, n, &p, &errflag);
642 if (errflag) {
643 showErr (errflag);
644 return(-1);
645 }
646
647 if (v) {
648 /* Convert the start address (adjusts the array index) */
649 value32bit (endian, data, n, &p, &errflag);
650 if (errflag) {
651 showErr (errflag);
652 return(-1);
653 }
654 }
655
656 /* Determine how many bytes form complete 32 bit fields, and how many are left over */
657 n32 = v & 0xfffffffc;
658 r32 = v & 0x00000003;
659
660 /* Convert the data to big endian format */
661 for (i = 0; i < n32; i += 4) {
662 data32bit (endian, data, n, &p, v-i, &errflag);
663 if (errflag) {
664 showErr (errflag);
665 return (-1);
666 }
667 }
668
669 /* Convert any remaining bytes. */
670 if (r32) {
671 remain32bit (endian, data, n, &p, r32, &errflag);
672 if (errflag) {
673 showErr (errflag);
674 return (-1);
675 }
676 }
677
678 } while (v);
679
680 /* Write out the data file */
681 writeBFile (fout, data, n);
682
683 /* Return resources */
684 free (data);
685
686 return (0);
687
688}
689
690
691
692
693
694
695
696
697
698
699
700
701