Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / tools / bin2srec.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: bin2srec.c
5*
6* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
7*
8* - Do no alter or remove copyright notices
9*
10* - Redistribution and use of this software in source and binary forms, with
11* or without modification, are permitted provided that the following
12* conditions are met:
13*
14* - Redistribution of source code must retain the above copyright notice,
15* this list of conditions and the following disclaimer.
16*
17* - Redistribution in binary form must reproduce the above copyright notice,
18* this list of conditions and the following disclaimer in the
19* documentation and/or other materials provided with the distribution.
20*
21* Neither the name of Sun Microsystems, Inc. or the names of contributors
22* may be used to endorse or promote products derived from this software
23* without specific prior written permission.
24*
25* This software is provided "AS IS," without a warranty of any kind.
26* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
27* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
28* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
29* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
30* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
32* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
33* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
34* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
35* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
36* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37*
38* You acknowledge that this software is not designed, licensed or
39* intended for use in the design, construction, operation or maintenance of
40* any nuclear facility.
41*
42* ========== Copyright Header End ============================================
43*/
44#pragma ident "@(#)bin2srec.c 1.1 02/12/18 SMI"
45/* purpose: Convert a binary file to a file containing S-records.
46/* copyright: Copyright 2002 Sun Microsystems, Inc. All rights reserved */
47/* copyright: Use is subject to license terms. */
48
49#include <sys/types.h>
50#include <string.h>
51#include <stdio.h>
52#include <fcntl.h>
53#include <ctype.h>
54#include <sys/sysmacros.h>
55#include <sys/stat.h>
56#include <sys/fs/udf_volume.h>
57
58#define SREC_LINESZ 76
59#define SREC_1STCHAR_OFF 10
60#define LINESZ 32
61
62#define KSIZE 1024
63
64int do_sumcheck = 0;
65int sumcheck = 0;
66
67usage(char **argv) {
68 printf("usage: %s -i <input_file> -o <output_file>\n"
69 " [-f <fill to K-bytes>] [-p <fill byte pattern for -f>] "
70 "[-s]\n", argv[0]);
71 exit(-1);
72}
73
74char srecln[SREC_LINESZ+2];
75
76/***************************************************************************
77 *
78 * build_line(uchar_t *ubp, int linesz, int addr)
79 *
80 * Build one S-record line in the "srecln" buffer.
81 *
82 * Input:
83 * uchar_t *ubp = the current binary file pointer
84 * int linesz = the # of bytes to convert (<=32)
85 * int addr = the address to use in the S-record
86 * Output:
87 * int = the string length of the S-record line
88 *
89 ***************************************************************************/
90build_line(uchar_t *ubp, int linesz, int addr)
91{
92 int i, j, checksum;
93 uchar_t invert_checksum, ulnsz = (linesz+4); /* line + 4 byte header */
94
95 /*
96 * Checksum includes line size (byte0) plus 3 bytes of address
97 * (bytes 1-3) + each data byte.
98 */
99 checksum = (linesz+4) + ((addr >> 16) & 0xff) +
100 ((addr >> 8) & 0xff) + (addr & 0xff);
101
102 memset(srecln, 0, SREC_LINESZ+2);
103 sprintf(srecln, "S2%02x%06x", ulnsz, addr);
104
105 /*
106 * Convert the line of binary to ASCII.
107 */
108 for (i = 0, j = SREC_1STCHAR_OFF; i < linesz; i++) {
109 sprintf(&srecln[j], "%02x", ubp[i]);
110 checksum += ubp[i];
111 sumcheck += ubp[i];
112 j += 2;
113 }
114 invert_checksum = ~checksum;
115 sprintf((char *)&srecln[j], "%02x\n", invert_checksum);
116
117 for (i = 0; i < strlen(srecln); i++) {
118 uchar_t val = toupper((int)srecln[i]);
119
120 srecln[i] = val;
121 }
122
123 return(strlen(srecln));
124}
125
126/***************************************************************************
127 *
128 * The purpose of this utility is to build a S-record file from a binary file.
129 *
130 * Inputs:
131 * -i <binary filename>
132 * -o <S-record output filename>
133 * [-f <fill to K-bytes>] = Fill to upto this K-byte limit
134 * [-p <fill byte pattern>] = Fill byte for -f (default=0)
135 * [-s] = Display Prom-Burner sumcheck, sum of all data bytes.
136 *
137 * Output:
138 *
139 ***************************************************************************/
140
141main(argc, argv)
142char **argv;
143{
144 int ifd, ofd;
145 int bx, ifilesz;
146 int address;
147 char *bp;
148 struct stat stat;
149 char *ifilename = NULL;
150 char *ofilename = NULL;
151 int opt;
152 int i, j, x, wrtsz;
153 extern int getopt();
154 extern int optind;
155 extern char *optarg;
156 int kfill = 0;
157 uchar_t kfill_pat = 0;
158
159 while ((opt = getopt(argc, argv, "iosvfp" )) != EOF) {
160 switch (opt) {
161 case 'i':
162 ifilename = argv[optind++];
163 break;
164 case 'o':
165 ofilename = argv[optind++];
166 break;
167 case 'f':
168 kfill = strtol(argv[optind++], 0 , 0);
169 kfill *= KSIZE;
170 break;
171 case 'p':
172 kfill_pat = strtol(argv[optind++], 0 , 0);
173 break;
174 case 's':
175 do_sumcheck = 1;
176 break;
177 default:
178 fprintf(stderr, "Illegal command: '%c'.\n", opt);
179 usage(argv);
180
181 }
182 }
183 if ((!ifilename) || (!ofilename)) usage(argv);
184
185 /*
186 * open the binary file.
187 */
188 if ((ifd = open(ifilename, O_RDONLY)) < 0) {
189 perror("open");
190 exit(-1);
191 }
192 if (fstat(ifd, &stat) == -1) {
193 perror("fstat");
194 exit(-1);
195 }
196 ifilesz = stat.st_size; /* size of binary file */
197 if (!ifilesz) {
198 fprintf(stderr, "binary file: No data!\n");
199 exit(-1);
200 }
201 /*
202 * Check for kfill > ifilesz. If not, clear kfill and continue
203 * to use ifilesz. Otherwise, malloc up to the KB limit and
204 * pre-set with the fill pattern. The binary file will read into
205 * beginning of the buffer with the fill pattern upto the KB limit.
206 */
207 if (kfill <= ifilesz) {
208 kfill = 0;
209 bp = (char *)malloc(ifilesz);
210 } else {
211 bp = (char *)malloc(kfill);
212 memset(bp, kfill_pat, kfill);
213 }
214 if (!bp) {
215 fprintf(stderr, "malloc: no space!\n");
216 exit(-1);
217 }
218
219 bx = read(ifd, bp, ifilesz); /* read in binary file */
220 close(ifd);
221 if (bx != ifilesz) {
222 perror("binary file read");
223 fprintf(stderr, "binary file: size %d, only read %d\n",
224 ifilesz, bx);
225 exit(-1);
226 }
227 if (kfill) { /* If kfill, switch to the KB limit. */
228 ifilesz = kfill;
229 }
230 /*
231 * Create the SREC output file.
232 */
233 if ((ofd = open(ofilename, O_RDWR | O_CREAT, 0777)) < 0) {
234 perror("open output file");
235 exit(-1);
236 }
237 if (ftruncate(ofd, 0)) {
238 perror("ftruncate");
239 exit(-1);
240 }
241 /*
242 * Build the S-Record file from the binary file one line at a time
243 */
244 strcpy(srecln, "S204000000FB\n"); /* start of S-record file */
245 bx = write(ofd, srecln, strlen(srecln));
246 if (bx != strlen(srecln)) {
247 perror("write S-record header");
248 exit(-1);
249 }
250 for (i = 0, j = LINESZ; i < ifilesz; i += LINESZ, j += LINESZ) {
251 j = (j > ifilesz) ? ifilesz : j;
252 x = j - i;
253 if (!x) break;
254 wrtsz = build_line((uchar_t *)&bp[i], x, i);
255
256 bx = write(ofd, srecln, wrtsz);
257 if (bx != wrtsz) {
258 perror("S-record file write");
259 fprintf(stderr, "size %d, only read %d\n", wrtsz, bx);
260 exit(-1);
261 }
262 }
263 strcpy(srecln, "S804000000FB\n"); /* end of S-record file */
264 bx = write(ofd, srecln, strlen(srecln));
265 if (bx != strlen(srecln)) {
266 perror("write S-record tail");
267 exit(-1);
268 }
269 close(ofd);
270 if (do_sumcheck) printf("Total PROM SumCheck: %08x\n", sumcheck);
271 exit(0);
272}