Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / support / mdgen / mdmain.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: mdmain.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 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
46 * Use is subject to license terms.
47 */
48
49#pragma ident "@(#)mdmain.c 1.3 07/06/07 SMI"
50
51#include <stdio.h>
52#include <stdlib.h>
53#include <unistd.h>
54#include <fcntl.h>
55#include <sys/types.h>
56#include <ctype.h>
57#include <strings.h>
58
59#include <md/md_impl.h>
60
61#include "basics.h"
62#include "allocate.h"
63#include "fatal.h"
64#include "lexer.h"
65
66#include "dagtypes.h"
67#include "outputtypes.h"
68
69
70#define DBGD(s)
71
72
73
74
75extern void dt_write_hdr(FILE *fd, char *name, md_hdr_t *root);
76
77extern void parse_dag(char *fnamep, FILE *fp);
78void stichin_reqd_properties(void);
79void connect_dag(void);
80#if ENABLE_PROTO /* { */
81void delete_protos(void);
82#endif /* } */
83
84
85enum {
86 Out_binary, Out_text, Out_dot
87} output_type;
88char *output_dot_dagp;
89bool_t output_dot_flag_none = false;
90
91bool_t flag_verbose = false;
92
93
94dag_node_t *dag_listp = NULL;
95dag_node_t *dag_list_endp = NULL;
96
97
98
99
100int
101main(int argc, char **argv)
102{
103 int i;
104 char *fnamep;
105 FILE *fp;
106 char *outfnp; /* output filename */
107
108 output_type = Out_binary;
109
110 for (i = 1; i < argc && argv[i][0] == '-'; i++) {
111 if (strcmp(argv[i], "-h") == 0 ||
112 strcmp(argv[i], "--help") == 0) {
113 fprintf(stderr, "usage: %s "
114 "[--text|--binary|--header|--dot <arc>"
115 "|-t|-b|-H|--d <arc>] [--outfile <fname>]"
116 " <filename>\n", argv[0]);
117 fprintf(stderr,
118 "\t--help : this message\n"
119 "\t-b | --binary : write binary file (default)\n"
120 "\t-o | --outfile : output file (default=stdout)\n"
121 "\t-t | --text : rewrite as text\n"
122 "\t-d | --dot :"
123 " output in dot format using arcs\n"
124 "\t\t-n | --noprop :"
125 " Omit properties in dot format\n"
126 "\t-v | --verbose : be loquacious\n");
127 exit(0);
128 } else
129 if ((strcmp(argv[i], "-b") == 0) ||
130 (strcmp(argv[i], "--binary") == 0)) {
131 output_type = Out_binary;
132 continue;
133 }
134 if ((strcmp(argv[i], "-t") == 0) ||
135 (strcmp(argv[i], "--text") == 0)) {
136 output_type = Out_text;
137 continue;
138 } else
139 if ((strcmp(argv[i], "-d") == 0) ||
140 (strcmp(argv[i], "--dot") == 0)) {
141 output_type = Out_dot;
142 output_dot_dagp = argv[++i];
143 continue;
144 } else
145 if ((strcmp(argv[i], "-n") == 0) ||
146 (strcmp(argv[i], "--noprop") == 0)) {
147 if (output_type != Out_dot) {
148 fprintf(stderr, "Need to specify dot output \
149format before -n/--noprop\n");
150 exit(1);
151 }
152 output_dot_flag_none = true;
153 continue;
154 } else
155 if ((strcmp(argv[i], "-v") == 0) ||
156 (strcmp(argv[i], "--verbose") == 0)) {
157 flag_verbose = true;
158 continue;
159 } else
160 if (strcmp(argv[i], "-o") == 0 ||
161 strcmp(argv[i], "--outfile") == 0) {
162 outfnp = argv[++i];
163 } else
164 if (argv[i][1] == 'o' && argv[i][2] != '\0') {
165 outfnp = &argv[i][2];
166 } else
167 fatal("Unrecognised option %s\n", argv[i]);
168 }
169
170 if ((argc - i) != 1)
171 fatal("Input filename name expected");
172
173 fnamep = argv[i];
174
175 fp = fopen(fnamep, "r");
176 if (fp == NULL)
177 fatal("Cannot open input file %s", fnamep);
178
179 parse_dag(fnamep, fp);
180 fclose(fp);
181
182#if ENABLE_PROTO /* { */
183 /* remove prototypes after parse phase */
184 delete_protos();
185 DBGD(dump_dag_nodes(stderr));
186#endif /* } */
187
188 DBGD(dump_dag_nodes(stderr));
189
190 connect_dag();
191
192 stichin_reqd_properties();
193
194 DBGD(dump_dag_nodes(stderr));
195
196 validate_dag();
197
198 if (outfnp != NULL) {
199 fp = fopen(outfnp, "w");
200 if (fp == NULL) fatal("Opening %s for output", outfnp);
201 } else {
202 fp = stdout;
203 }
204
205 switch (output_type) {
206 case Out_binary:
207 output_bin(fp);
208 break;
209
210 case Out_text:
211 output_text(fp);
212 break;
213
214 case Out_dot:
215 output_dot(fp);
216 break;
217 }
218 fclose(fp);
219
220 return (0);
221}
222
223
224
225
226
227
228void
229validate_dag()
230{
231 /* no validation just yet */
232}
233
234
235
236
237
238
239
240dag_node_t *
241new_dag_node(void)
242{
243 dag_node_t *dnp;
244
245 dnp = Xcalloc(1, dag_node_t);
246
247 dnp->typep = NULL;
248 dnp->namep = NULL;
249#if ENABLE_PROTOTYPES
250 dnp->is_proto = false;
251#endif
252
253 dnp->properties.num = 0;
254 dnp->properties.space = 0;
255 dnp->properties.listp = NULL;
256
257 /* add to list */
258 dnp->prevp = dag_list_endp;
259 dnp->nextp = NULL;
260 if (NULL == dag_listp) {
261 dag_listp = dnp;
262 } else {
263 dag_list_endp->nextp = dnp;
264 }
265 dag_list_endp = dnp;
266
267 return (dnp);
268}
269
270
271pair_entry_t *
272add_pair_entry(pair_list_t *plp)
273{
274 pair_entry_t *pep;
275
276 if (plp->num >= plp->space) {
277 plp->space = plp->num + 5;
278 plp->listp = Xrealloc(plp->listp,
279 plp->space * sizeof (plp->listp[0]));
280 }
281
282 pep = &(plp->listp[plp->num]);
283 plp->num++;
284
285 pep->namep = NULL;
286 pep->utype = PE_none;
287 pep->u.val = 0;
288 pep->u.data.len = 0;
289 return (pep);
290}
291
292
293pair_entry_t *
294find_pair_by_name(pair_list_t *plp, char *namep)
295{
296 pair_entry_t *pep;
297 int i;
298
299 for (i = 0; i < plp->num; i++) {
300 pep = &(plp->listp[i]);
301 if (strcmp(pep->namep, namep) == 0)
302 return (pep);
303 }
304
305 return (NULL);
306}
307
308dag_node_t *
309find_dag_node_by_type(char *namep)
310{
311 dag_node_t *dnp;
312
313 for (dnp = dag_listp; dnp != NULL; dnp = dnp->nextp) {
314 if (strcmp(dnp->typep, namep) == 0)
315 return (dnp);
316 }
317
318 return (NULL);
319}
320
321dag_node_t *
322find_dag_node_by_name(char *namep)
323{
324 dag_node_t *dnp;
325
326 for (dnp = dag_listp; dnp != NULL; dnp = dnp->nextp) {
327 if (strcmp(dnp->namep, namep) == 0)
328 return (dnp);
329 }
330
331 return (NULL);
332}
333
334dag_node_t *
335grab_node(char *message)
336{
337 lexer_tok_t tok;
338 dag_node_t *dnp = NULL;
339
340 tok = lex_get_token();
341 if (tok == T_Token) {
342 dnp = find_dag_node_by_name(lex.strp);
343 if (dnp == NULL) {
344 lex_fatal("%s: %s", message, lex.strp);
345 }
346 } else {
347 lex_fatal("%s: %s", message, lex.strp);
348 }
349 return (dnp);
350}
351
352pair_entry_t *
353grab_prop(char *message, dag_node_t *node)
354{
355 lexer_tok_t tok;
356 pair_entry_t *prop = NULL;
357
358 tok = lex_get_token();
359 if (tok == T_Token) {
360 prop = find_pair_by_name(&node->properties, lex.strp);
361 if (prop == NULL) {
362 lex_fatal("%s: %s property must exist\n",
363 message, lex.strp);
364 }
365 } else {
366 lex_fatal("%s: %s", message, lex.strp);
367 }
368 return (prop);
369}
370
371
372void
373dump_dag_nodes(FILE *fp)
374{
375 dag_node_t *dnp;
376
377 for (dnp = dag_listp; dnp != NULL; dnp = dnp->nextp) {
378 int i;
379 pair_entry_t *pep;
380
381#if ENABLE_PROTO /* { */
382 fprintf(fp, "node %s%s %s {\n", dnp->is_proto ? " proto" : "",
383 dnp->typep, dnp->namep);
384#else /* } { */
385 fprintf(fp, "node %s %s {\n", dnp->typep, dnp->namep);
386#endif /* } */
387
388 pep = dnp->properties.listp;
389 for (i = 0; i < dnp->properties.num; i++) {
390 switch (pep->utype) {
391 case PE_none:
392 fprintf(fp, "\n");
393 break;
394 case PE_string:
395 fprintf(fp, "\t%s = \"%s\";\n", pep->namep,
396 pep->u.strp);
397 break;
398 case PE_int:
399 fprintf(fp, "\t%s = 0x%llx;\n", pep->namep,
400 pep->u.val);
401 break;
402 case PE_arc:
403 fprintf(fp, "\t%s -> %s;\n", pep->namep,
404 pep->u.dnp->namep);
405 break;
406 case PE_noderef:
407 fprintf(fp, "\t%s -> %s;\n", pep->namep,
408 pep->u.strp);
409 break;
410 case PE_data:
411 fprintf(fp, "\t%s = XXXXXXXX;\n", pep->namep);
412 break;
413 default:
414 fprintf(stderr, "%s:%d: Bad Encoding.. %d\n",
415 __FILE__, __LINE__, pep->utype);
416 exit(1);
417 }
418 pep ++;
419 }
420
421 fprintf(fp, "}\n");
422 fflush(fp);
423 }
424}
425
426#if ENABLE_PROTO /* { */
427void
428free_node(dag_node_t *dnp)
429{
430 int i;
431
432 for (i = 0; i < dnp->properties.num; i++) {
433 pair_entry_t *pep;
434
435 pep = &(dnp->properties.listp[i]);
436
437 switch (pep->utype) {
438 case PE_none:
439 fatal("free_node: node %s : %d : PE_none element",
440 dnp->namep, i);
441 case PE_arc:
442 fatal("free_node: node %s : %d : PE_arc element",
443 dnp->namep, i);
444 case PE_int:
445 case PE_data:
446 break;
447 case PE_string:
448 case PE_noderef:
449 Xfree(pep->u.strp);
450 break;
451 default:
452 fatal("free_node: node %s : %d : unknown type %d",
453 dnp->namep, i, pep->utype);
454 }
455 }
456
457 Xfree(dnp->properties.listp);
458 Xfree(dnp);
459}
460
461
462void
463delete_protos(void)
464{
465 bool_t failed;
466 dag_node_t *dnp;
467 dag_node_t **pp;
468
469 pp = &dag_listp;
470 dnp = *pp;
471
472 while (dnp != NULL) {
473 dag_node_t *nextp;
474
475 nextp = dnp->nextp;
476
477 if (dnp->is_proto) {
478 free_node(dnp);
479 } else {
480 *pp = dnp;
481 pp = &(dnp->nextp);
482 }
483 dnp = nextp;
484 }
485
486 *pp = NULL;
487
488}
489#endif /* } */
490
491void
492connect_dag(void)
493{
494 bool_t failed;
495 dag_node_t *dnp;
496 FILE *errfp = stderr;
497 int idx;
498
499 failed = false;
500
501 idx = 0;
502 for (dnp = dag_listp; dnp != NULL; dnp = dnp->nextp, idx++) {
503 int i;
504
505 /* Give this node an id number */
506 dnp->idx = idx;
507
508 /* stitch all property node references */
509 if (dnp->properties.num > 0) {
510 for (i = 0; i < dnp->properties.num; i++) {
511 pair_entry_t *pep;
512
513 pep = &(dnp->properties.listp[i]);
514
515 if (pep->utype == PE_noderef) {
516 dag_node_t *rnp;
517 rnp = find_dag_node_by_name(
518 pep->u.strp);
519 if (NULL != rnp) {
520 Xfree(pep->u.strp);
521 pep->u.dnp = rnp;
522 pep->utype = PE_arc;
523 } else {
524 failed = true;
525 fprintf(errfp, "Referenced "
526 "node %s not found\n",
527 pep->u.strp);
528 }
529 }
530 }
531 }
532 }
533
534 if (failed)
535 goto failed;
536 return;
537
538failed:;
539 fatal("errors found");
540}
541
542
543/*
544 * We must have a "root" node ... look for it,
545 * and hike it to the first entry in the table.
546 */
547void
548stichin_reqd_properties(void)
549{
550 dag_node_t *dnp;
551
552 dnp = find_dag_node_by_type("root");
553 if (dnp == NULL)
554 fatal("A root node is required for a valid description");
555
556 /*
557 * Hike the root node to be the first element.
558 */
559 if (dnp->prevp != NULL) {
560 dnp->prevp->nextp = dnp->nextp;
561 if (dnp->nextp != NULL) {
562 dnp->nextp->prevp = dnp->prevp;
563 } else {
564 dag_list_endp = dnp->prevp;
565 }
566
567 dnp->nextp = dag_listp;
568 dag_listp->prevp = dnp;
569 dag_listp = dnp;
570 }
571}