af925c2d0111df4911bbd115ed84cbd5d809feab
1 /*************************************************************************************
2 * FILE PURPOSE: Create an I2C rom with multiple boot parameter sections and
3 * programs
4 *************************************************************************************
5 * FILE NAME: romparse.c
6 *
7 * DESCRIPTION: Creates a ccs hex file which contains the i2c eprom boot parameter
8 * tables as well as any code.
9 *
10 *************************************************************************************/
11 #include <stdio.h>
12 #include <string.h>
13 #include <malloc.h>
14 #include "rparse.tab.h"
15 #include "romparse.h"
17 /*************************************************************************************
18 * Definition: fixed i2c map locations
19 *************************************************************************************/
20 #define PCI_PARAM_BASE (NUM_BOOT_PARAM_TABLES * 0x80)
21 #define DATA_BASE (PCI_PARAM_BASE + PCI_EEAI_PARAM_SIZE)
25 /*************************************************************************************
26 * Declaration: The flex input file is assigned based on the command line
27 *************************************************************************************/
28 extern FILE *yyin;
30 /*************************************************************************************
31 * Declaration: Keep track of lines in the parse
32 *************************************************************************************/
33 int line = 1;
35 /*************************************************************************************
36 * Declaration: currentType identifies the current parse mode, either SECTION
37 * or LAYOUT.
38 *************************************************************************************/
39 int currentType;
41 /*************************************************************************************
42 * Declaration: The boot parameter tables. The current table is copied into position
43 * when the section parse is complete.
44 *************************************************************************************/
45 BOOT_PARAMS_T boot_params[NUM_BOOT_PARAM_TABLES];
46 BOOT_PARAMS_T current_table;
47 int current_file; /* Identifies the program file in the current table */
48 int ctable_index = -1; /* Destination of current table */
49 int max_index = 0; /* maximum table index, used for compacting output */
51 /************************************************************************************
52 * Declaration: Layout tables.
53 ************************************************************************************/
54 layout_t layouts[MAX_LAYOUTS]; /* Array of layout structures */
55 int currentLayout; /* Currently active layout */
57 /************************************************************************************
58 * Declaration: Pads
59 ************************************************************************************/
60 pad_t pads[MAX_PADS]; /* Array of pad structures */
61 int currentPad; /* Currently active pad */
63 /************************************************************************************
64 * Declaration: The structure storing the program data files, and the number of
65 * programs used.
66 ************************************************************************************/
67 progFile_t progFile[NUM_BOOT_PARAM_TABLES];
68 int nProgFiles = 0;
70 /************************************************************************************
71 * Declaration: The PCI parameter structure
72 ************************************************************************************/
73 pciFile_t pciFile;
74 int pciSet = 0;
76 /*************************************************************************************
77 * Declaration: The array that tracks the ordering of pad and layout structures
78 *************************************************************************************/
79 padLayoutOrder_t padLayoutOrder[MAX_PADS+MAX_LAYOUTS];
80 int currentPL = 0;
82 /*************************************************************************************
83 * Declaration: The next free address in the ROM for general data usage. For the
84 * start address there is room for the initial boot parameter tables,
85 * plus room for the PCI eeai config.
86 *************************************************************************************/
87 int romBase = DATA_BASE;
90 /*************************************************************************************
91 * Declaration: Args passed in from the command line
92 *************************************************************************************/
93 char *inputFile;
94 int compact = 0;
97 /*************************************************************************************
98 * FUNCTION PURPOSE: flex/bison required support functions.
99 *************************************************************************************
100 * DESCRIPTION: yyerror and yywrap are required to support flex and/or bison parsing
101 * of the parameter description file. yyerror directly reports the
102 * error, yywrap is unused.
103 *************************************************************************************/
104 void yyerror (char *s)
105 {
106 fprintf (stderr, "flex/bison error is %s at line %d\n", s, line);
107 } /* yyerror */
109 void yywrap (void)
110 {
111 } /* yywrap */
113 /*************************************************************************************
114 * FUNCTION PURPOSE: Initialize a boot table
115 *************************************************************************************
116 * DESCRIPTION: Sets a boot parameter table to 0s
117 *************************************************************************************/
118 void initTable (BOOT_PARAMS_T *current_table)
119 {
120 memset (current_table, 0, sizeof(BOOT_PARAMS_T));
121 }
123 /*************************************************************************************
124 * FUNCTION PURPOSE: Initialize the program data file table
125 *************************************************************************************
126 * DESCRIPTION: The size and tags are all setup
127 *************************************************************************************/
128 void initProgFile (void)
129 {
130 int i, j;
132 for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++) {
133 progFile[i].sizeBytes = 0;
134 progFile[i].align = 0;
136 for (j = 0; j < NUM_BOOT_PARAM_TABLES; j++)
137 progFile[i].tag[j] = -1;
139 }
141 }
144 /*************************************************************************************
145 * FUNCTION PURPOSE: Set the currently active parse type
146 *************************************************************************************
147 * DESCRIPTION: Indicates if the subsequent parameters belong to a section or
148 * a layout
149 *************************************************************************************/
150 void rBegin (int blockType)
151 {
152 currentType = blockType;
153 }
155 /*************************************************************************************
156 * FUNCTION PURPOSE: Initialize a layout structure
157 *************************************************************************************
158 * DESCRIPTION: The layout is set to the initial state
159 *************************************************************************************/
160 void initLayout (layout_t *cl)
161 {
163 cl->nPlt = 0;
164 cl->dev_addr = 0x50;
165 cl->address = 0;
166 cl->align = 0;
168 }
170 /*************************************************************************************
171 * FUNCTION PURPOSE: Complete a layout
172 *************************************************************************************
173 * DESCRIPTION: The parser has found a complete layout specification. Complete
174 * a layout structure
175 *************************************************************************************/
176 void setLayout (void)
177 {
178 int i;
179 int currentAlign;
180 int newAlign;
182 for (i = 0; i < layouts[currentLayout].nPlt; i++) {
184 if (layouts[currentLayout].plt[i].type == PLT_FILE) {
186 currentAlign = progFile[layouts[currentLayout].plt[i].index].align;
187 newAlign = layouts[currentLayout].align;
189 if (newAlign > currentAlign)
190 progFile[layouts[currentLayout].plt[i].index].align = newAlign;
191 }
193 }
196 padLayoutOrder[currentPL].type = LAYOUT;
197 padLayoutOrder[currentPL].index = currentLayout;
198 currentPL += 1;
200 currentLayout += 1; /* Advance to the next layout */
202 if (currentLayout < MAX_LAYOUTS)
203 initLayout (&layouts[currentLayout]);
205 }
207 /*************************************************************************************
208 * FUNCTION PURPOSE: Initialize a pad structure
209 *************************************************************************************
210 * DESCRIPTION: A pad structure is set to the default state
211 *************************************************************************************/
212 void initPad (pad_t *p)
213 {
214 p->id = -1;
215 p->address = 0;
216 p->dev_addr = 0x50;
217 p->len = 0;
218 }
221 /**************************************************************************************
222 * FUNCTION PURPOSE: Complete a pad
223 **************************************************************************************
224 * DESCRIPTION: The parser has found a complete pad specification. Complete the pad
225 * structure
226 **************************************************************************************/
227 void setPad (void)
228 {
230 padLayoutOrder[currentPL].type = PAD;
231 padLayoutOrder[currentPL].index = currentPad;
232 currentPL += 1;
234 currentPad += 1;
236 if (currentPad < MAX_PADS)
237 initPad (&pads[currentPad]);
239 }
242 /*************************************************************************************
243 * FUNCTION PURPOSE: Complete a section
244 *************************************************************************************
245 * DESCRIPTION: The parser has detected a complete section. Copy the section into
246 * it's correct table location.
247 *************************************************************************************/
248 void section (void)
249 {
250 int i;
252 /* It's an error if no section value has been declared */
253 if (ctable_index == -1) {
254 fprintf (stderr, "romparse: the section did not have a boot paramter index specified\n");
255 exit (-1);
256 }
258 /* Make sure the table is in range */
259 if (ctable_index >= NUM_BOOT_PARAM_TABLES) {
260 fprintf (stderr, "romparse: The section index is too large (max %d)\n", NUM_BOOT_PARAM_TABLES-1);
261 exit (-1);
262 }
264 /* The length must be set. Currently this program only supports I2C mode, so the
265 * length is fixed */
266 current_table.common.length = 30;
267 current_table.common.checksum = 0;
269 /* Copy the table */
270 memcpy (&boot_params[ctable_index], ¤t_table, sizeof (BOOT_PARAMS_T));
271 initTable (¤t_table);
273 /* Track the maximum table index */
274 if (ctable_index > max_index)
275 max_index = ctable_index;
277 /* If the section referenced a data file, link the data file back to this section */
278 if (current_file >= 0) {
279 for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++) {
280 if (progFile[current_file].tag[i] < 0)
281 progFile[current_file].tag[i] = ctable_index;
282 break;
283 }
284 }
286 ctable_index = -1;
287 current_file = -1;
289 } /* section */
291 /***************************************************************************************
292 * FUNCTION PURPOSE: Open a ccs hex file and read in the data.
293 ***************************************************************************************
294 * DESCRIPTION: Reads a ccs hex format data file, loads the file into the
295 * next program file structure. Returns the index of the just loaded
296 * table.
297 ***************************************************************************************/
298 int openProgFile (char *fname)
299 {
300 FILE *str;
301 int a, b, c, d, e;
302 int i;
303 char iline[132];
305 /* Store the file name */
306 strcpy (progFile[nProgFiles].fname, fname);
308 /* Open the data file */
309 str = fopen (fname, "r");
310 if (str == NULL) {
311 fprintf (stderr, "romparse: Could not open file %s\n", fname);
312 exit (-1);
313 }
315 /* Read the one line ccs header. The length field in terms of lines */
316 fgets (iline, 132, str);
317 sscanf (iline, "%x %x %x %x %x", &a, &b, &c, &d, &e);
318 progFile[nProgFiles].sizeBytes = e * 4; /* Length was in 4 byte words */
320 /* Read in the data */
321 for (i = 0; i < e; i++) {
322 fgets (iline, 132, str);
323 sscanf (&(iline[2]), "%x", &((progFile[nProgFiles]).data[i]));
324 }
326 fclose (str);
328 i = nProgFiles;
329 nProgFiles += 1;
331 return (i);
333 } /* openProgFile */
335 /***************************************************************************************
336 * FUNCTION PURPOSE: Load the PCI paramter section
337 ***************************************************************************************
338 * DESCRIPTION: Loads the PCI parameter section and stores it in the rom. */
339 int setPciParams (char *fname)
340 {
341 FILE *str;
342 int a, b, c, d, e;
343 int i;
344 char iline[132];
345 char *z;
347 if (pciSet) {
348 fprintf (stderr, "romparse: PCI parameters specified more then once\n");
349 exit (-1);
350 }
352 /* the input string still contains the quotes. Remove them here */
353 z = &fname[1];
354 *strchr (z, '"') = '\0';
356 /* Store the file name */
357 strcpy (pciFile.fname, z);
359 /* Open the data file */
360 str = fopen (z, "r");
361 if (str == NULL) {
362 fprintf (stderr, "romparse: Could not open pci file %s\n", fname);
363 exit (-1);
364 }
366 /* The address of the pci params is currently fixed */
367 pciFile.addressBytes = PCI_PARAM_BASE;
369 /* Read the one line ccs header. The length field is in terms of lines */
370 fgets (iline, 132, str);
371 sscanf (iline, "%x %x %x %x %x", &a, &b, &c, &d, &e);
372 pciFile.sizeBytes = e * 4; /* Convert length to bytes */
374 /* Read in the data */
375 for (i = 0; i < e; i++) {
376 fgets (iline, 132, str);
377 sscanf (&(iline[2]), "%x", &(pciFile.data[i]));
378 }
380 pciSet = 1;
382 return (0);
384 } /* setPciParams */
388 /***************************************************************************************
389 * FUNCTION PURPOSE: Store an assignment
390 ***************************************************************************************
391 * DESCRIPTION: Stores an assigned value into the current boot parameter table
392 ***************************************************************************************/
393 void assignKeyVal (int field, int value)
394 {
396 switch (currentType) {
399 case SECTION:
402 switch (field) {
404 case BOOT_MODE: current_table.common.boot_mode = value;
405 break;
407 case PARAM_INDEX: ctable_index = value;
408 break;
410 case OPTIONS: current_table.i2c.options = value;
411 break;
413 case MULTI_I2C_ID: current_table.i2c.multi_i2c_id = value;
414 break;
416 case MY_I2C_ID: current_table.i2c.my_i2c_id = value;
417 break;
419 case CORE_FREQ_MHZ: current_table.i2c.core_freq_mhz = value;
420 break;
422 case I2C_CLK_FREQ_KHZ: current_table.i2c.i2c_clk_freq_khz = value;
423 break;
425 case NEXT_DEV_ADDR: current_table.i2c.next_dev_addr = value;
426 break;
429 case NEXT_DEV_ADDR_EXT: current_table.i2c.next_dev_addr_ext = value;
430 break;
432 case ADDRESS_DELAY: current_table.i2c.address_delay = value;
433 break;
435 #ifndef c6455
436 case SWPLL: current_table.i2c.swPll = value;
437 break;
438 #endif
440 case DEV_ADDR_EXT: current_table.i2c.dev_addr_ext = value;
441 break;
443 case DEV_ADDR: current_table.i2c.dev_addr = value;
444 break;
447 default:
448 fprintf (stderr, "romparse: Invalid assignment in section specification (line %d)\n", line);
449 break;
451 }
453 break;
456 case LAYOUT:
458 if (currentLayout >= MAX_LAYOUTS) {
459 fprintf (stderr, "romparse: Too many layout sections (max = %d)\n", MAX_LAYOUTS);
460 exit (-1);
461 }
464 switch (field) {
466 case DEV_ADDR_EXT: layouts[currentLayout].dev_addr = value;
467 break;
469 case DEV_ADDR: layouts[currentLayout].address = value;
470 break;
472 case ALIGN: layouts[currentLayout].align = value;
473 break;
475 case PAD_FILE_ID: if (layouts[currentLayout].nPlt >= MAX_LAYOUT_FILES) {
476 fprintf (stderr, "romparse: line %d: number of layout entries exceeds maximum of %d\n", line, MAX_LAYOUT_FILES);
477 exit (-1);
478 }
479 layouts[currentLayout].plt[layouts[currentLayout].nPlt].type = PLT_PAD;
480 layouts[currentLayout].plt[layouts[currentLayout].nPlt].index = value;
481 layouts[currentLayout].nPlt += 1;
482 break;
485 default:
486 fprintf (stderr, "romparase: Invalid assignment in layout specification (line %d)\n", line);
487 break;
489 }
490 break;
493 case PAD:
495 if (currentPad >= MAX_PADS) {
496 fprintf (stderr, "romparse: Too many pad sections (max = %d)\n", MAX_PADS);
497 exit (-1);
498 }
500 switch (field) {
502 case DEV_ADDR: pads[currentPad].address = value;
503 break;
505 case LENGTH: pads[currentPad].len = value;
506 break;
508 case PAD_FILE_ID: pads[currentPad].id = value;
509 break;
511 default:
512 fprintf (stderr, "romparse: Invalid assignment in pad specificaiton (line %d)\n", line);
513 break;
515 }
516 break;
518 }
521 } /* assignKeyVal */
524 /*******************************************************************************
525 * FUNCTION PURPOSE: Parse a string input.
526 *******************************************************************************
527 * DESCRIPTION: Takes a string input. Currently only the i2c exe file name can be
528 * assigned a string.
529 *******************************************************************************/
530 void assignKeyStr (int value, char *y)
531 {
532 int i;
533 char *z;
535 /* The special case of a 0 (plus the quotes) length string means an empty entry for a layout */
536 if (strlen(y) == 2) {
538 if (currentType == LAYOUT) {
539 if (layouts[currentLayout].nPlt <= MAX_LAYOUT_FILES) {
540 layouts[currentLayout].plt[layouts[currentLayout].nPlt].type = PLT_FILE;
541 layouts[currentLayout].plt[layouts[currentLayout].nPlt].index = -1;
542 layouts[currentLayout].nPlt += 1;
544 } else {
545 fprintf (stderr, "romparse: line %d: Max number (%d) of layout specification exceeded\n", line, MAX_LAYOUT_FILES);
546 }
547 } else
548 fprintf (stderr, "romparse: Number of layout sections exceeded (max = %d)\n", MAX_LAYOUTS);
550 return;
551 }
554 /* the input string still contains the quotes. Remove them here */
555 z = &y[1];
556 *strchr (z, '"') = '\0';
558 /* Check if the file name is already open */
559 for (i = 0; i < nProgFiles; i++) {
561 if (!strcmp (z, progFile[i].fname)) {
563 /* Found a match */
565 if (currentType == SECTION) {
567 current_file = i;
569 if (current_table.i2c.dev_addr_ext == 0)
570 current_table.i2c.dev_addr_ext = 0x50; /* hard coded to i2c rom slave address */
572 } else { /* LAYOUT */
574 if (currentLayout < MAX_LAYOUTS) {
575 if (layouts[currentLayout].nPlt <= MAX_LAYOUT_FILES) {
576 layouts[currentLayout].plt[layouts[currentLayout].nPlt].type = PLT_FILE;
577 layouts[currentLayout].plt[layouts[currentLayout].nPlt].index = i;
578 layouts[currentLayout].nPlt += 1;
580 } else {
581 fprintf (stderr, "romparse: line %d: Max number (%d) of layout specification exceeded\n", line, MAX_LAYOUT_FILES);
582 }
583 } else
584 fprintf (stderr, "romparse: Number of layout sections exceeded (max = %d)\n", MAX_LAYOUTS);
586 }
589 return;
590 }
592 }
594 /* Open and read the ccs file, set the ROM address */
595 i = openProgFile (z);
596 if (i >= 0) {
598 if (currentType == SECTION) {
600 current_file = i;
601 if (current_table.i2c.dev_addr_ext == 0)
602 current_table.i2c.dev_addr_ext = 0x50;
604 } else { /* LAYOUT */
606 if (currentLayout < MAX_LAYOUTS) {
607 if (layouts[currentLayout].nPlt <= MAX_LAYOUT_FILES) {
608 layouts[currentLayout].plt[layouts[currentLayout].nPlt].type = PLT_FILE;
609 layouts[currentLayout].plt[layouts[currentLayout].nPlt].index = i;
610 layouts[currentLayout].nPlt += 1;
612 } else {
613 fprintf (stderr, "romparse: line %d: Max number (%d) of layout specification exceeded\n", line, MAX_LAYOUT_FILES);
614 }
615 } else
616 fprintf (stderr, "romparse: Number of layout sections exceeded (max = %d)\n", MAX_LAYOUTS);
618 }
621 }
623 } /* assignKeyStr */
625 /************************************************************************************
626 * FUNCTION PURPOSE: Put a 32 bit value into the i2c image memory
627 ************************************************************************************
628 * DESCRIPTION: The 32 bit value is placed in memory in big endian format. The
629 * new offset is returned (4 bytes more then the input offset)
630 ************************************************************************************/
631 unsigned int imageWord (unsigned int base, unsigned char *image, unsigned int value)
632 {
633 image[base+0] = (value >> 24) & 0xff;
634 image[base+1] = (value >> 16) & 0xff;
635 image[base+2] = (value >> 8) & 0xff;
636 image[base+3] = (value >> 0) & 0xff;
638 return (base + 4);
640 }
642 /************************************************************************************
643 * FUNCTION PURPOSE: Create a 32 bit value from the image array
644 ************************************************************************************
645 * DESCRIPTION: A 32 bit word in big endian format is created
646 ************************************************************************************/
647 unsigned int formWord (unsigned int p, unsigned char *image)
648 {
649 unsigned int v;
651 v = (image[p+0] << 24) |
652 (image[p+1] << 16) |
653 (image[p+2] << 8) |
654 (image[p+3] << 0) ;
656 return (v);
658 }
660 /************************************************************************************
661 * FUNCTION PURPOSE: Pad the image array
662 ************************************************************************************
663 * DESCRIPTION: Byte (value 0) are added to the image to reach the desired address
664 * The desired address is returned.
665 ************************************************************************************/
666 unsigned int imagePad (unsigned int base, unsigned char *image, unsigned int desired)
667 {
668 int i;
670 if (desired < base) {
671 fprintf (stderr, "romparse: Padd to %d requested, but current base (%d) is already past this point\n",
672 desired, base);
673 exit (-1);
674 }
676 for (i = base; i < desired; i++)
677 image[i] = 0;
679 return (desired);
681 }
683 /************************************************************************************
684 * FUNCTION PURPOSE: Opens and writes the output file
685 ************************************************************************************
686 * DESCRIPTION: Creates the output file in ccs format.
687 ************************************************************************************/
688 void createOutput (void)
689 {
690 FILE *str;
691 int totalLenBytes;
692 int i, j, k;
693 int nTables, len;
694 unsigned int value, v1, v2;
695 unsigned int base, obase;
696 unsigned char *image;
698 str = fopen ("i2crom.ccs", "w");
699 if (str == NULL) {
700 fprintf (stderr, "romparse: Could not open output file i2crom.ccs for writing\n");
701 exit (-1);
702 }
704 /* Compact the i2c eeprom to use the minimum memory possible */
705 base = PCI_PARAM_BASE;
706 nTables = NUM_BOOT_PARAM_TABLES;
708 if ((compact != 0) && (pciSet == 0)) {
709 nTables = max_index + 1;
710 base = nTables * 0x80; /* The number of parameter tables * size of a parameter table */
711 }
713 if (pciSet)
714 base = base + PCI_EEAI_PARAM_SIZE;
717 /* Change the layout index value for pad mapping to a true array index value.
718 * Also reflect the device address from the layout into the pad */
719 for (i = 0; i < currentLayout; i++) {
721 for (j = 0; j < layouts[i].nPlt; j++) {
723 if (layouts[i].plt[j].type == PLT_PAD) {
725 for (k = 0; k < currentPad; k++) {
727 if (layouts[i].plt[j].index == pads[k].id) {
728 layouts[i].plt[j].index = k;
729 pads[k].dev_addr = layouts[i].dev_addr;
730 }
731 }
732 }
733 }
734 }
736 /* Pad, layout tables */
737 for (i = 0; i < currentPL; i++) {
739 j = padLayoutOrder[i].index;
741 if (padLayoutOrder[i].type == LAYOUT) {
743 /* Determine the size of the table. Four bytes for each file, plus the 4 byte header */
744 v1 = (layouts[j].nPlt * 4) + 4;
746 v2 = (layouts[j].dev_addr << 16) + layouts[j].address;
748 if (v2 == 0)
749 base = base + v1;
751 else {
753 /* Mask out device address bits but extend past 64k */
754 v2 = v2 & I2C_ADDR_MASK;
756 if (base > v2) {
757 fprintf (stderr, "romparse: fatal error - layout block %d specified a start address of 0x%04x\n", j, layouts[j].address);
758 fprintf (stderr, " but this conflicts with the base mapping (ends at 0x%04x)\n", base);
759 exit (-1);
760 }
762 base = layouts[j].address + v1;
765 }
766 } else { /* Otherwise this is a pad */
768 if (base > pads[j].address) {
769 fprintf (stderr, "romparse: fatal error - pad block %d specified a start address of 0x%04x\n", j, pads[j].address);
770 fprintf (stderr, " but this conflicts with the base mapping (ends at 0x%04x)\n", base);
771 exit (-1);
772 }
774 base = pads[j].address + pads[j].len;
776 }
777 }
779 for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++) {
780 if (progFile[i].align > 0)
781 base = ((base + progFile[i].align - 1) / progFile[i].align) * progFile[i].align;
782 progFile[i].addressBytes = base + (0x50 << 16); /* For now hard code the base address */
783 base = base + progFile[i].sizeBytes;
784 }
786 /* Setup the base program file addresses. If a parameter set has
787 * been tagged it means that this is an i2c program load */
788 for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++) {
789 for (j = 0; j < NUM_BOOT_PARAM_TABLES; j++) {
790 if (progFile[i].tag[j] >= 0)
791 boot_params[progFile[i].tag[j]].i2c.dev_addr = (progFile[i].addressBytes & 0xffff);
792 }
793 }
795 /* Round up the size to a multiple of 4 bytes to fit into a ccs data file */
796 base = (base + 3) & ~3;
799 /* The total length of the i2c eeprom is now stored in base */
800 /* Write out the ccs header */
801 fprintf (str, "1651 1 10000 1 %x\n", base >> 2);
804 /* Create the image in memory */
805 image = malloc (base * sizeof (unsigned char));
806 if (image == NULL) {
807 fprintf (stderr, "romparse: malloc failed creating the output image\n");
808 exit (-1);
809 }
811 /* Write out the boot parameter tables. 0x80 bytes will be written out.
812 * There are 16 bits in every parameter field, which is why the index
813 * is from 0 to 0x40 */
814 base = 0;
815 for (i = 0; i < nTables; i++) {
816 for (j = 0; j < (0x80 >> 1); j += 2) {
817 v1 = boot_params[i].parameter[j];
818 v2 = boot_params[i].parameter[j+1];
819 value = (v1 << 16) | v2;
820 base = imageWord (base, image, value);
821 }
822 }
824 /* Write out the PCI parameter base. If none was included then zeros will be
825 * written out */
826 if (pciSet) {
827 for (i = 0; i < PCI_DATA_LEN_32bit; i++) {
828 base = imageWord (base, image, pciFile.data[i]);
829 }
830 }
833 /* Layout sections */
834 for (i = 0; i < currentLayout; i++) {
836 v1 = (layouts[i].dev_addr << 16) + layouts[i].address;
838 /* Mask out device address bits */
839 v1 = v1 & I2C_ADDR_MASK;
840 if (v1 > 0)
841 base = imagePad (base, image, v1);
842 obase = base;
843 len = (layouts[i].nPlt * 4) + 4;
845 /* Write out the block size and checksum */
846 base = imageWord(base, image, len << 16);
848 for (j = 0; j < layouts[i].nPlt; j++) {
850 if (layouts[i].plt[j].type == PLT_FILE) {
851 if (layouts[i].plt[j].index == -1) {
852 base = imageWord (base, image, 0xffffffff);
853 } else {
854 base = imageWord (base, image, progFile[layouts[i].plt[j].index].addressBytes);
855 }
856 } else {
857 v1 = pads[layouts[i].plt[j].index].dev_addr;
858 v2 = pads[layouts[i].plt[j].index].address;
859 base = imageWord (base, image, (v1 << 16) + v2);
860 }
862 }
864 }
867 /* Write out each of the program files */
868 for (i = 0; i < nProgFiles; i++) {
870 base = imagePad (base, image, (progFile[i].addressBytes & I2C_ADDR_MASK));
872 for (j = 0; j < progFile[i].sizeBytes >> 2; j++)
873 base = imageWord (base, image, (progFile[i]).data[j]);
874 }
876 /* Write out the data file */
877 for (i = 0; i < base; i += 4)
878 fprintf (str, "0x%08x\n", formWord (i, image));
880 free (image);
882 /* Close the output file */
883 fclose (str);
885 } /* createOutput */
887 /************************************************************************************
888 * FUNCTION PURPOSE: Initialize the pci paramter table
889 ************************************************************************************
890 * DESCRIPTION: Zeros the pci parameters
891 ************************************************************************************/
892 void initPciParams (void)
893 {
894 memset (&pciFile, 0, sizeof(pciFile_t));
895 } /* initPciParams */
899 /************************************************************************************
900 * FUNCTION PURPOSE: Parse the input arguments.
901 ************************************************************************************
902 * DESCRIPTION: Returns -1 on invalid args
903 ************************************************************************************/
904 int parseIt (int argc, char *argv[])
905 {
906 int i;
908 if (argc < 2) {
909 fprintf (stderr, "usage: %s [-compact] inputfile\n", argv[0]);
910 return (-1);
911 }
913 inputFile = NULL;
915 for (i = 1; i < argc; ) {
917 if (!strcmp (argv[i], "-compact")) {
918 compact = 1;
919 i += 1;
921 } else {
923 if (inputFile != NULL) {
924 fprintf (stderr, "usage: %s [-compact] inputfile\n", argv[0]);
925 return (-1);
926 }
928 inputFile = argv[i];
929 i += 1;
930 }
931 }
933 return (0);
935 }
939 /************************************************************************************
940 * FUNCTION PURPOSE: main function
941 ************************************************************************************
942 * DESCRIPTION: Performs the processing sequence.
943 ************************************************************************************/
944 int main (int argc, char *argv[])
945 {
946 int i;
948 /* Initialize the tables */
949 for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++)
950 initTable(&boot_params[i]);
952 initTable (¤t_table);
953 current_file = -1;
955 /* Initialize the program file structure */
956 initProgFile ();
958 /* Initialize the PCI param table */
959 initPciParams ();
961 /* Initialize the layout structures */
962 currentLayout = 0;
963 initLayout (&layouts[currentLayout]);
965 /* Parse the input parameters */
966 if (parseIt (argc, argv))
967 return (-1);
970 yyin = fopen (inputFile, "r");
971 if (yyin == NULL) {
972 fprintf (stderr, "%s: could not open file %s\n", argv[0], inputFile);
973 return (-1);
974 }
976 /* Parse the input description file */
977 yyparse();
980 /* Create the output file */
981 createOutput ();
983 return (0);
984 }