0b27ca9bdc6f3b83c668ea3d580b2ae1b4ec7072
[openwrt.git] / target / linux / image / ar7 / src / srec2bin.c
1 /*-----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (C) 1999-2000 by Texas Instruments, Inc. All rights reserved. */
4 /* */
5 /* IMPORTANT - READ CAREFULLY BEFORE PROCEEDING TO USE SOFTWARE. */
6 /* */
7 /* This document is displayed for you to read prior to using the software */
8 /* and documentation. By using the software and documentation, or opening */
9 /* the sealed packet containing the software, or proceeding to download the */
10 /* software from a Bulletin Board System(BBS) or a WEB Server, you agree to */
11 /* abide by the following Texas Instruments License Agreement. If you choose */
12 /* not to agree with these provisions, promptly discontinue use of the */
13 /* software and documentation and return the material to the place you */
14 /* obtained it. */
15 /* */
16 /* Texas Instruments License Agreement */
17 /* */
18 /* 1. License - Texas Instruments (hereinafter "TI"), grants you a license */
19 /* to use the software program and documentation in this package ("Licensed */
20 /* Materials") for Texas Instruments broadband products. */
21 /* */
22 /* 2. Restrictions - You may not reverse-assemble or reverse-compile the */
23 /* Licensed Materials provided in object code or executable format. You may */
24 /* not sublicense, transfer, assign, rent, or lease the Licensed Materials */
25 /* or this Agreement without written permission from TI. */
26 /* */
27 /* 3. Copyright - The Licensed Materials are copyrighted. Accordingly, you */
28 /* may either make one copy of the Licensed Materials for backup and/or */
29 /* archival purposes or copy the Licensed Materials to another medium and */
30 /* keep the original Licensed Materials for backup and/or archival purposes. */
31 /* */
32 /* 4. Runtime and Applications Software - You may create modified or */
33 /* derivative programs of software identified as Runtime Libraries or */
34 /* Applications Software, which, in source code form, remain subject to this */
35 /* Agreement, but object code versions of such derivative programs are not */
36 /* subject to this Agreement. */
37 /* */
38 /* 5. Warranty - TI warrants the media to be free from defects in material */
39 /* and workmanship and that the software will substantially conform to the */
40 /* related documentation for a period of ninety (90) days after the date of */
41 /* your purchase. TI does not warrant that the Licensed Materials will be */
42 /* free from error or will meet your specific requirements. */
43 /* */
44 /* 6. Remedies - If you find defects in the media or that the software does */
45 /* not conform to the enclosed documentation, you may return the Licensed */
46 /* Materials along with the purchase receipt, postage prepaid, to the */
47 /* following address within the warranty period and receive a refund. */
48 /* */
49 /* TEXAS INSTRUMENTS */
50 /* Application Specific Products, MS 8650 */
51 /* c/o ADAM2 Application Manager */
52 /* 12500 TI Boulevard */
53 /* Dallas, TX 75243 - U.S.A. */
54 /* */
55 /* 7. Limitations - TI makes no warranty or condition, either expressed or */
56 /* implied, including, but not limited to, any implied warranties of */
57 /* merchantability and fitness for a particular purpose, regarding the */
58 /* licensed materials. */
59 /* */
60 /* Neither TI nor any applicable licensor will be liable for any indirect, */
61 /* incidental or consequential damages, including but not limited to loss of */
62 /* profits. */
63 /* */
64 /* 8. Term - The license is effective until terminated. You may terminate */
65 /* it at any other time by destroying the program together with all copies, */
66 /* modifications and merged portions in any form. It also will terminate if */
67 /* you fail to comply with any term or condition of this Agreement. */
68 /* */
69 /* 9. Export Control - The re-export of United States origin software and */
70 /* documentation is subject to the U.S. Export Administration Regulations or */
71 /* your equivalent local regulations. Compliance with such regulations is */
72 /* your responsibility. */
73 /* */
74 /* *** IMPORTANT NOTICE *** */
75 /* */
76 /* Texas Instruments (TI) reserves the right to make changes to or to */
77 /* discontinue any semiconductor product or service identified in this */
78 /* publication without notice. TI advises its customers to obtain the latest */
79 /* version of the relevant information to verify, before placing orders, */
80 /* that the information being relied upon is current. */
81 /* */
82 /* TI warrants performance of its semiconductor products and related */
83 /* software to current specifications in accordance with TI's standard */
84 /* warranty. Testing and other quality control techniques are utilized to */
85 /* the extent TI deems necessary to support this warranty. Unless mandated */
86 /* by government requirements, specific testing of all parameters of each */
87 /* device is not necessarily performed. */
88 /* */
89 /* Please be aware that Texas Instruments products are not intended for use */
90 /* in life-support appliances, devices, or systems. Use of a TI product in */
91 /* such applications without the written approval of the appropriate TI */
92 /* officer is prohibited. Certain applications using semiconductor devices */
93 /* may involve potential risks of injury, property damage, or loss of life. */
94 /* In order to minimize these risks, adequate design and operating */
95 /* safeguards should be provided by the customer to minimize inherent or */
96 /* procedural hazards. Inclusion of TI products in such applications is */
97 /* understood to be fully at the risk of the customer using TI devices or */
98 /* systems. */
99 /* */
100 /* TI assumes no liability for TI applications assistance, customer product */
101 /* design, software performance, or infringement of patents or services */
102 /* described herein. Nor does TI warrant or represent that license, either */
103 /* expressed or implied, is granted under any patent right, copyright, mask */
104 /* work right, or other intellectual property right of TI covering or */
105 /* relating to any combination, machine, or process in which such */
106 /* semiconductor products or services might be or are used. */
107 /* */
108 /* All company and/or product names are trademarks and/or registered */
109 /* trademarks of their respective manaufacturers. */
110 /* */
111 /*-----------------------------------------------------------------------------*/
112
113 //
114
115 // #include <string.h>
116 #include <stdio.h>
117 #include <ctype.h>
118
119 //Rev 0.1 Original
120 // 8 Jan 2001 MJH Added code to write data to Binary file
121 // note: outputfile is name.bin, where name is first part
122 // of input file. ie tmp.rec -> tmp.bin
123 //
124 // srec2bin <input SREC file> <Output Binary File> <If Present, Big Endian>
125 //
126 // TAG
127 // bit32u TAG_BIG = 0xDEADBE42;
128 // bit32u TAG_LITTLE = 0xFEEDFA42;
129 //
130 // File Structure
131 //
132 // TAG : 32 Bits
133 // [DATA RECORDS]
134 //
135 // Data Records Structure
136 //
137 // LENGTH : 32 Bits <- Length of DATA, excludes ADDRESS and CHECKSUM
138 // ADDRESS : 32 Bits
139 // DATA : 8 Bits * LENGTH
140 // CHECKSUM: 32 Bits <- 0 - (Sum of Length --> End of Data)
141 //
142 // Note : If Length == 0, Address will be Program Start
143 //
144 //
145 //
146 //
147 //
148
149 #define MajRevNum 0
150 #define MinRevNum 2
151
152
153 #define EndianSwitch(x) ((x >> 24) | (x << 24) | ((x << 8) & (0x00FF0000)) | ((x >> 8) & (0x0000FF00)) )
154
155 typedef unsigned char bit8u;
156 typedef unsigned int bit32u;
157 typedef int bit32;
158
159 #define FALSE 0
160 #define TRUE (!FALSE)
161
162
163 bit32u CheckSum;
164 int RecStart;
165 int debug;
166 int verbose;
167
168 FILE *OpenOutputFile( char *Name );
169 FILE *fOut;
170 bit32u RecLength=0;
171
172 bit32u AddressCurrent;
173
174 bit32u gh(char *cp,int nibs);
175
176 int BigEndian;
177
178 int inputline;
179
180 // char buf[16*1024];
181
182 char buffer[2048];
183 char *cur_ptr;
184 int cur_line=0;
185 int cur_len=0;
186
187 int s1s2s3_total=0;
188
189 bit32u PBVal;
190 int PBValid;
191 bit32u PBAdr;
192
193
194 void dumpfTell(char *s, bit32u Value)
195 {
196 int Length;
197 Length = (int) RecLength;
198 if (debug)
199 printf("[%s ] ftell()[0x%08lX] Length[0x%4X] Length[%4d] Value[0x%08x]\n",
200 s, ftell(fOut), Length, Length, Value);
201 }
202
203 void DispHex(bit32u Hex)
204 {
205 // printf("%X", Hex);
206 }
207
208 void WaitDisplay(void)
209 {
210 static int Count=0;
211 static int Index=0;
212 char iline[]={"-\\|/"};
213
214 Count++;
215 if ((Count % 32)==0)
216 {
217 if (verbose)
218 printf("%c%c",iline[Index++],8);
219 Index &= 3;
220 }
221 }
222
223
224 void binOut32 ( bit32u Data )
225 {
226 // On UNIX machine all 32bit writes need ENDIAN switched
227 // Data = EndianSwitch(Data);
228 // fwrite( &Data, sizeof(bit32u), 1, fOut);
229
230 char sdat[4];
231 int i;
232
233 for(i=0;i<4;i++)
234 sdat[i]=(char)(Data>>(i*8));
235 fwrite( sdat, 1, 4, fOut);
236 dumpfTell("Out32" , Data);
237 }
238
239 // Only update RecLength on Byte Writes
240 // All 32 bit writes will be for Length etc
241
242 void binOut8 ( bit8u Data )
243 {
244 int n;
245 dumpfTell("B4Data" , (bit32u) (Data & 0xFF) );
246 n = fwrite( &Data, sizeof(bit8u), 1, fOut);
247 if (n != 1)
248 printf("Error in writing %X for Address 0x%8X\n", Data, AddressCurrent);
249 RecLength += 1;
250 }
251
252 // Currently ONLY used for outputting Program Start
253
254 void binRecStart(bit32u Address)
255 {
256 RecLength = 0;
257 CheckSum = Address;
258 RecStart = TRUE;
259
260 if (debug)
261 printf("[RecStart] CheckSum[0x%08X] Length[%4d] Address[0x%08X]\n",
262 CheckSum, RecLength, Address);
263
264
265 dumpfTell("RecLength", RecLength);
266 binOut32( RecLength );
267 dumpfTell("Address", Address);
268 binOut32( Address );
269 }
270
271 void binRecEnd(void)
272 {
273 long RecEnd;
274
275 if (!RecStart) // if no record started, do not end it
276 {
277 return;
278 }
279
280 RecStart = FALSE;
281
282
283 RecEnd = ftell(fOut); // Save Current position
284
285 if (debug)
286 printf("[RecEnd ] CheckSum[0x%08X] Length[%4d] Length[0x%X] RecEnd[0x%08lX]\n",
287 CheckSum, RecLength, RecLength, RecEnd);
288
289 fseek( fOut, -(RecLength), SEEK_CUR); // move back Start Of Data
290
291 dumpfTell("Data ", -1);
292
293 fseek( fOut, -4, SEEK_CUR); // move back Start Of Address
294
295 dumpfTell("Address ", -1);
296
297 fseek( fOut, -4, SEEK_CUR); // move back Start Of Length
298
299 dumpfTell("Length ", -1);
300
301 binOut32( RecLength );
302
303 fseek( fOut, RecEnd, SEEK_SET); // move to end of Record
304
305 CheckSum += RecLength;
306
307 CheckSum = ~CheckSum + 1; // Two's complement
308
309 binOut32( CheckSum );
310
311 if (verbose)
312 printf("[Created Record of %d Bytes with CheckSum [0x%8X]\n", RecLength, CheckSum);
313 }
314
315 void binRecOutProgramStart(bit32u Address)
316 {
317 if (Address != (AddressCurrent+1))
318 {
319 binRecEnd();
320 binRecStart(Address);
321 }
322 AddressCurrent = Address;
323 }
324 void binRecOutByte(bit32u Address, bit8u Data)
325 {
326 // If Address is one after Current Address, output Byte
327 // If not, close out last record, update Length, write checksum
328 // Then Start New Record, updating Current Address
329
330 if (Address != (AddressCurrent+1))
331 {
332 binRecEnd();
333 binRecStart(Address);
334 }
335 AddressCurrent = Address;
336 CheckSum += Data;
337 binOut8( Data );
338 }
339
340 //=============================================================================
341 // SUPPORT FUNCTIONS
342 //=============================================================================
343 int readline(FILE *fil,char *buf,int len)
344 {
345 int rlen;
346
347 rlen=0;
348 if (len==0) return(0);
349 while(1)
350 {
351 if (cur_len==0)
352 {
353 cur_len=fread(buffer, 1, sizeof(buffer), fil);
354 if (cur_len==0)
355 {
356 if (rlen)
357 {
358 *buf=0;
359 return(rlen);
360 }
361 return(-1);
362 }
363 cur_ptr=buffer;
364 }
365 if (cur_len)
366 {
367 if (*cur_ptr=='\n')
368 {
369 *buf=0;
370 cur_ptr++;
371 cur_len--;
372 return(rlen);
373 }
374 else
375 {
376 if ((len>1)&&(*cur_ptr!='\r'))
377 {
378 *buf++=*cur_ptr++;
379 len--;
380 }
381 else
382 cur_ptr++;
383
384 rlen++;
385 cur_len--;
386 }
387 }
388 else
389 {
390 *buf=0;
391 cur_ptr++;
392 cur_len--;
393 return(rlen);
394 }
395 }
396 }
397
398
399 int SRLerrorout(char *c1,char *c2)
400 {
401 printf("\nERROR: %s - '%s'.",c1,c2);
402 return(FALSE);
403 }
404
405
406 int checksum(char *cp,int count)
407 {
408 char *scp;
409 int cksum;
410 int dum;
411
412 scp=cp;
413 while(*scp)
414 {
415 if (!isxdigit(*scp++))
416 return(SRLerrorout("Invalid hex digits",cp));
417 }
418 scp=cp;
419
420 cksum=count;
421
422 while(count)
423 {
424 cksum += gh(scp,2);
425 if (count == 2)
426 dum = ~cksum;
427 scp += 2;
428 count--;
429 }
430 cksum&=0x0ff;
431 // printf("\nCk:%02x",cksum);
432 return(cksum==0x0ff);
433 }
434
435 bit32u gh(char *cp,int nibs)
436 {
437 int i;
438 bit32u j;
439
440 j=0;
441
442 for(i=0;i<nibs;i++)
443 {
444 j<<=4;
445 if ((*cp>='a')&&(*cp<='z')) *cp &= 0x5f;
446 if ((*cp>='0')&&(*cp<='9'))
447 j += (*cp-0x30);
448 else
449 if ((*cp>='A')&&(*cp<='F'))
450 j += (*cp-0x37);
451 else
452 SRLerrorout("Bad Hex char", cp);
453 cp++;
454 }
455 return(j);
456 }
457
458
459 //=============================================================================
460 // PROCESS SREC LINE
461 //=============================================================================
462
463 int srecLine(char *pSrecLine)
464 {
465 char *scp,ch;
466 int itmp,count,dat;
467 bit32u adr;
468 static bit32u RecordCounter=0;
469
470 cur_line++;
471 scp=pSrecLine;
472
473 if (*pSrecLine!='S')
474 return(SRLerrorout("Not an Srecord file",scp));
475 pSrecLine++;
476 if (strlen(pSrecLine)<4)
477 return(SRLerrorout("Srecord too short",scp));
478
479 ch=*pSrecLine++;
480
481 count=gh(pSrecLine,2);
482
483 pSrecLine += 2;
484
485 // if(debug)
486 // printf("count %d, strlen(pSrecLine) = %d, pSrecLine =[%s]\n", count, strlen(pSrecLine), pSrecLine);
487 RecordCounter++;
488 DispHex(RecordCounter);
489
490 if ((count*2) != strlen(pSrecLine)) return(SRLerrorout("Count field larger than record",scp));
491
492 if (!checksum(pSrecLine, count)) return(SRLerrorout("Bad Checksum",scp));
493
494 switch(ch)
495 {
496 case '0': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp));
497 itmp=gh(pSrecLine,4); pSrecLine+=4; count-=2;
498 if (itmp) return(SRLerrorout("Srecord 1 address not zero",scp));
499 break;
500 case '1': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp));
501 return(SRLerrorout("Srecord Not valid for MIPS",scp));
502 break;
503 case '2': if (count<4) return(SRLerrorout("Invalid Srecord count field",scp));
504 return(SRLerrorout("Srecord Not valid for MIPS",scp));
505 break;
506 case '3': if (count<5) return(SRLerrorout("Invalid Srecord count field",scp));
507 adr=gh(pSrecLine,8); pSrecLine+=8; count-=4;
508 count--;
509 while(count)
510 {
511 dat=gh(pSrecLine,2); pSrecLine+=2; count--;
512 binRecOutByte(adr, (char) (dat & 0xFF));
513 adr++;
514 }
515 s1s2s3_total++;
516 break;
517 case '4': return(SRLerrorout("Invalid Srecord type",scp));
518 break;
519 case '5': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp));
520 itmp=gh(pSrecLine,4); pSrecLine+=4; count-=2;
521 if (itmp|=s1s2s3_total) return(SRLerrorout("Incorrect number of S3 Record processed",scp));
522 break;
523 case '6': return(SRLerrorout("Invalid Srecord type",scp));
524 break;
525 case '7': // PROGRAM START
526 if (count<5) return(SRLerrorout("Invalid Srecord count field",scp));
527 adr=gh(pSrecLine,8); pSrecLine+=8; count-=4;
528 if (count!=1) return(SRLerrorout("Invalid Srecord count field",scp));
529 binRecOutProgramStart(adr);
530 break;
531 case '8': if (count<4) return(SRLerrorout("Invalid Srecord count field",scp));
532 return(SRLerrorout("Srecord Not valid for MIPS",scp));
533 break;
534 case '9': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp));
535 return(SRLerrorout("Srecord Not valid for MIPS",scp));
536 break;
537 default:
538 break;
539 }
540 return(TRUE);
541 }
542
543
544 //=============================================================================
545 // MAIN LOGIC, READS IN LINE AND OUTPUTS BINARY
546 //=============================================================================
547
548 int srec2bin(int argc,char *argv[],int verbose)
549 {
550 int i,rlen,sts;
551 FILE *fp;
552 char ac;
553 char buff[256];
554 bit32u TAG_BIG = 0xDEADBE42;
555 bit32u TAG_LITTLE = 0xFEEDFA42;
556
557 bit32u Tag;
558
559
560 if(argc < 3)
561 {
562 printf("\nError: <srec2bin <srec input file> <bin output file>\n\n");
563 return(0);
564 }
565
566 if (argc > 3) BigEndian=TRUE; else BigEndian=FALSE;
567
568 if (BigEndian)
569 Tag = TAG_BIG;
570 else
571 Tag = TAG_LITTLE;
572
573 if (verbose)
574 printf("\nEndian: %s, Tag is 0x%8X\n",(BigEndian)?"BIG":"LITTLE", Tag);
575
576 fp = fopen(argv[1],"rt");
577
578 if (fp==NULL)
579 {
580 printf("\nError: Opening input file, %s.", argv[1]);
581 return(0);
582 }
583
584 fOut = fopen( argv[2], "wb");
585
586 if (fOut==NULL)
587 {
588 printf("\nError: Opening Output file, %s.", argv[2]);
589 if(fp) fclose(fp);
590 return(0);
591 }
592
593 RecStart = FALSE;
594
595 AddressCurrent = 0xFFFFFFFFL;
596
597 // Setup Tag
598
599 dumpfTell("Tag", Tag);
600
601 binOut32(Tag);
602
603
604 inputline=0;
605 sts=TRUE;
606
607 rlen = readline(fp,buff,sizeof buff);
608
609 while( (sts) && (rlen != -1))
610 {
611 if (strlen(buff))
612 {
613 sts &= srecLine(buff);
614 WaitDisplay();
615 }
616 rlen = readline(fp,buff,sizeof buff);
617 }
618
619
620 // printf("PC: 0x%08X, Length 0x%08X, Tag 0x%08X\n", ProgramStart, RecLength, TAG_LITTLE);
621
622 binRecEnd();
623
624 if(fp) fclose(fp);
625 if(fOut) fclose(fOut);
626
627 return(1);
628 }
629
630 main(int argc, char *argv[])
631 {
632 debug = TRUE;
633 debug = FALSE;
634 verbose = FALSE;
635 srec2bin(argc,argv,verbose);
636 return 0;
637 }
638
This page took 0.084768 seconds and 3 git commands to generate.