Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / tools / makedi.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: makedi.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/*
45 * id: @(#)makedi.c 1.12 06/02/16
46 * purpose:
47 * copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
48 * copyright: Use is subject to license terms.
49 */
50
51#include <sys/types.h>
52#include <sys/stat.h>
53#include <fcntl.h>
54#include <string.h>
55#include <stdio.h>
56#include <stdlib.h>
57#include <unistd.h>
58
59#include <sys/dropins.h>
60
61#define MAX_DI (4*1048*1024)
62
63static int compress = 0;
64static int verbose = 0;
65static int list = 0;
66static int group_mode = 0;
67
68static uchar_t *prom;
69
70int comp(unsigned char *src, int size, unsigned char *dest);
71
72static void
73usage(char *name)
74{
75 char *msg =
76 "%s: [-c] [-v] input1 name1 .. inputn namen\n"
77 " -g : group mode using src,dropin-name pairs\n"
78 " -a : create level2 using existing dropins\n"
79 " -c : compress dropins\n"
80 " -v : verbose mode\n"
81 " -t : list targets\n"
82 " -s : list sources\n"
83 " -d : list dependancies\n"
84 " -o : create a dropin from data\n"
85 " -O : overwrite any existing header\n"
86 "\n"
87 "for compress mode, each input will produce a file input.di\n"
88 "group mode changes the format of the args a little\n"
89 "-g <output> name input0 name0 .. intputn namen\n"
90 "-a <output> name input0 input1 .. inputn\n"
91 "-o <output> <srcfile> <diname>\n";
92
93 fprintf(stderr, msg, name);
94 exit(1);
95}
96
97static int
98make_dropin(char *name, unsigned char *prom, unsigned char *buffer, int size)
99{
100 int crc, i, clen, dlen, compressed;
101 unsigned char *pptr;
102 obmd_t *di = (obmd_t *)prom;
103 unsigned char *dataptr = prom+OBMD_HDR;
104
105 memset((void *) prom, 0, OBMD_HDR);
106 compressed = compress;
107 if (compress) {
108 compresshdr *chdr = (compresshdr *) dataptr;
109 /* The magic number is always COMP */
110 chdr->magic = COMP_MAGIC;
111 /*
112 * This is the compression type
113 * currently COMP for compress
114 */
115 chdr->type = COMP_MAGIC;
116 chdr->decomp_size = size;
117
118 clen = comp(buffer, size, dataptr+sizeof (compresshdr));
119
120 /* Now adjust the data size */
121 clen += sizeof (compresshdr);
122 chdr->comp_size = clen;
123
124 if (clen >= size) {
125 /*
126 * Compression didn't help this and in fact
127 * has added some bytes, so we undo the compression.
128 */
129 compressed = 0;
130 clen = size;
131 memcpy((void *) dataptr, (void *) buffer, size);
132 }
133 } else {
134 clen = size;
135 memcpy((void *) dataptr, (void *) buffer, size);
136 }
137
138 strncpy(di->magic, "OBMD", 4);
139 di->size = clen;
140 di->res0 = 0;
141 di->res1 = 0;
142 di->chksum = 0;
143 if (strlen(name) > 15) {
144 fprintf(stderr, "Error: dropin name > 15 characters\n");
145 fprintf(stderr, "Error: -> %s\n", name);
146 exit(1);
147 }
148 memset(di->name, 0, 16);
149 strncpy(di->name, name, 15);
150 crc = checksum((ushort_t *)di, clen+OBMD_HDR);
151 di->chksum = crc;
152
153 if (verbose) {
154 printf(" Name: %s size = %lx", di->name, di->size);
155 if (compressed)
156 printf(" (-%d%%)", ((size-clen)*100)/size);
157 printf(" checksum = %x ", di->chksum);
158 }
159 dlen = OBMD_HDR+clen;
160 pptr = prom+dlen;
161 if (dlen&3) {
162 if (verbose) printf("(+%d)", (dlen&3));
163
164 for (i = (3-(dlen&3)); i >= 0; i--, dlen++) *(pptr+i) = 1;
165 }
166 if (verbose) printf("\n");
167 return (dlen);
168}
169
170char *
171make_dropin_name(char *name)
172{
173 static char outname[40];
174 char *dot;
175
176 dot = strrchr(name, '/');
177 if (dot)
178 strcpy(outname, dot+1);
179 else
180 strcpy(outname, name);
181 dot = strrchr(outname, '.');
182 if (dot) *dot = 0;
183 strcat(outname, ".di");
184 return (outname);
185}
186
187
188void
189write_dropin(char *argv[], char *name, unsigned char *prom, int dlen)
190{
191 int ofd;
192
193 ofd = open(name, O_CREAT|O_TRUNC|O_RDWR, 0666);
194 if (ofd < 0) {
195 fprintf(stderr, "%s: Can't open output file %s\n",
196 argv[0], name);
197 exit(1);
198 } else {
199 if (dlen > MAX_DI) {
200 fprintf(stderr, "%s: Output %s exceeds %d bytes\n",
201 argv[0], name, MAX_DI);
202 exit(1);
203 }
204 if (write(ofd, prom, dlen) != dlen) {
205 fprintf(stderr, "%s: Short write on %s\n",
206 argv[0], name);
207 exit(1);
208 }
209 close(ofd);
210 }
211}
212
213/*
214 * makedi [-c] <source> <dropin-name> [<source> <dropin-name>]
215 */
216
217void
218main(int argc, char **argv)
219{
220 int ifd, ofd;
221 int i;
222 int pad = 512;
223 struct stat statbuf;
224 int c;
225 char *group_name;
226 char *group_file, *outfile = NULL;
227 uchar_t *holding, *insert_pt;
228 extern char *optarg;
229 extern int optind;
230 obmd_t *di;
231 int arg_step = 2;
232 int append_mode = 0;
233 int overwrite = 0;
234 int diupdate = 1;
235
236 while ((c = getopt(argc, argv, "acCOvstdgGo:")) != EOF)
237 switch (c) {
238 case 'a':
239 append_mode = 1;
240 arg_step = 1;
241 break;
242
243 case 's':
244 list = 's';
245 break;
246
247 case 't':
248 list = 't';
249 break;
250
251 case 'd':
252 list = 'd';
253 break;
254
255 case 'v':
256 verbose++;
257 break;
258
259 case 'c':
260 group_mode = 0;
261 compress = 1;
262 break;
263
264 case 'C':
265 group_mode = 0;
266 compress = 0;
267 break;
268
269 case 'O':
270 overwrite = 1;
271 break;
272
273 case 'g':
274 compress = 0;
275 group_mode = 1;
276 break;
277
278 case 'o':
279 outfile = optarg;
280 diupdate = 0;
281 break;
282
283 default:
284 usage(argv[0]);
285 }
286
287 if (list) compress = 0, verbose = 0;
288 if (append_mode) {
289 if (list) list = 'd';
290 }
291
292 insert_pt = prom = (uchar_t *)malloc(MAX_DI);
293 if (prom == NULL) {
294 fprintf(stderr, "Malloc failed for dropin image\n");
295 exit(1);
296 }
297
298 holding = (uchar_t *)malloc(MAX_DI);
299 if (holding == NULL) {
300 fprintf(stderr, "Malloc failed for holding buffer\n");
301 exit(1);
302 }
303
304 /* Fill with FF */
305 memset((void *) prom, 0xff, MAX_DI);
306 if (group_mode || append_mode) {
307 if (argv[optind] == NULL) {
308 fprintf(stderr, "%s: Missing group name\n", argv[0]);
309 exit(1);
310 }
311 group_file = strdup(make_dropin_name(argv[optind]));
312 group_name = argv[optind+1];
313 if (argv[optind+1] == NULL) {
314 fprintf(stderr, "%s: Missing dropin name for %s\n",
315 argv[0], argv[optind]);
316 exit(1);
317 }
318 optind += 2;
319 /*
320 * reserve space for the dropin header and marker
321 */
322 insert_pt += sizeof (obme_t);
323 }
324
325 di = (obmd_t *)holding;
326 for (i = optind; i < argc; i += arg_step) {
327 int dlen, len, tmp;
328 char *outname;
329
330 if ((!append_mode) && (argv[i+1] == NULL)) {
331 fprintf(stderr, "%s: Missing dropin name for %s\n",
332 argv[0], argv[i]);
333 exit(1);
334 }
335
336 if (outfile == NULL) {
337 outname = make_dropin_name(argv[i]);
338 } else {
339 outname = outfile;
340 }
341
342 if (list) {
343 switch (list) {
344 case 't':
345 if (group_mode) {
346 static int once = 0;
347 if (!once++)
348 printf("%s ", group_file);
349 } else {
350 printf("%s ", outname);
351 }
352 break;
353
354 case 's':
355 printf("%s ", argv[i]);
356 break;
357
358 case 'd':
359 if (group_mode || append_mode)
360 printf("%s: %s\n",
361 group_file, argv[i]);
362 else
363 printf("%s: %s\n", outname, argv[i]);
364 break;
365 }
366 continue;
367 }
368
369 if (verbose > 1) printf("Loading: %s\n", argv[i]);
370 ifd = open(argv[i], O_RDONLY);
371 if (ifd < 0) {
372 fprintf(stderr,
373 "%s: Can't open input file %s\n",
374 argv[0], argv[i]);
375 exit(1);
376 }
377 fstat(ifd, &statbuf);
378 len = statbuf.st_size;
379 if (len > MAX_DI) {
380 fprintf(stderr, "%s: Input %s exceeds %d bytes\n",
381 argv[0], argv[i], MAX_DI);
382 exit(1);
383 }
384 memset((void *) holding, 0xff, MAX_DI);
385 tmp = read(ifd, holding, len);
386 if (tmp != len) {
387 fprintf(stderr, "%s: Short read on %s\n",
388 argv[0], argv[i]);
389 exit(1);
390 }
391 close(ifd);
392 if (verbose) {
393 if (group_mode || append_mode)
394 printf("Including: %s,", argv[i]);
395 else
396 printf("Writing: %s,", outname);
397 }
398
399 if (diupdate && (strncmp(di->magic, "OBMD", 4) == 0)) {
400 unsigned int *dataptr;
401
402 dataptr = (uint_t *)((uchar_t *)di + sizeof (obmd_t));
403
404 if ((dataptr[0] == COMP_MAGIC) &&
405 (dataptr[1] == di->size)) {
406 /*
407 * We can do nothing with dropins that are
408 * already compressed
409 */
410 dlen = len;
411 if (verbose) {
412 printf(" Name: %s size = %lx (COMP)",
413 di->name, di->size);
414 printf(" checksum = %x\n", di->chksum);
415 }
416 if ((group_mode) || (append_mode)) {
417 memcpy((void *) insert_pt,
418 (void *) holding, len);
419 }
420 } else {
421 char *diname;
422
423 /*
424 * Strip the dropin header off to leave the
425 * raw data and then compress it
426 */
427 len -= OBMD_HDR;
428 if (append_mode)
429 diname = strdup(di->name);
430 else
431 diname = argv[i+1];
432 memcpy((void *) holding,
433 (void *) (holding+OBMD_HDR),
434 len);
435 dlen = make_dropin(diname,
436 insert_pt, holding, len);
437 }
438 } else {
439 if (append_mode) {
440 fprintf(stderr,
441 "%s: append_mode requires you to provide"
442 " a dropin list (%s)\n",
443 argv[0], argv[optind]);
444 exit(1);
445 } else {
446 if (overwrite) {
447 dlen = make_dropin(argv[i+1],
448 insert_pt, (holding + OBMD_HDR),
449 (len - OBMD_HDR));
450 } else {
451 dlen = make_dropin(argv[i+1],
452 insert_pt, holding, len);
453 }
454 }
455 }
456
457 if (group_mode || append_mode) {
458 insert_pt += (dlen + 3) & ~3;
459 } else {
460 write_dropin(argv, outname, prom, dlen);
461 }
462 }
463 if (group_mode || append_mode) {
464 int flen;
465 char *outname;
466 int bytes;
467
468 bytes = insert_pt - prom;
469 if (bytes&3) {
470 for (i = (4-(bytes&3)); i > 0; i--, bytes++)
471 *insert_pt++ = 1;
472 }
473 for (i = 4; i > 0; i--, bytes++) *insert_pt++ = 0xff;
474 if (verbose) printf("Writing: %s,", group_file);
475 strncpy((char *)prom, "OBME", 4);
476 memcpy((void *)holding, (void *)prom, bytes);
477 flen = make_dropin(group_name, prom, holding, bytes);
478 write_dropin(argv, group_file, prom, flen);
479 }
480 free(holding);
481 free(prom);
482 exit(0);
483}