]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/ibl.git/blob - src/util/romparse/romparse.c
Added two stage load for c6455 and c6474
[keystone-rtos/ibl.git] / src / util / romparse / romparse.c
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)
24 /*************************************************************************************
25  * Declaration: The base address of the i2c ROM being created. This is just
26  *              the I2C bus address. The default is 0x50
27  *************************************************************************************/
28 int i2cRomBase = 0x50;
30 /*************************************************************************************
31  * Declaration: The flex input file is assigned based on the command line
32  *************************************************************************************/
33 extern FILE *yyin;
35 /*************************************************************************************
36  * Declaration: Keep track of lines in the parse
37  *************************************************************************************/
38 int line = 1;
40 /*************************************************************************************
41  * Declaration: currentType identifies the current parse mode, either SECTION
42  *              or LAYOUT.
43  *************************************************************************************/
44 int currentType;
46 /*************************************************************************************
47  * Declaration: The boot parameter tables. The current table is copied into position
48  *              when the section parse is complete.
49  *************************************************************************************/
50 BOOT_PARAMS_T boot_params[NUM_BOOT_PARAM_TABLES];
51 BOOT_PARAMS_T current_table;
52 int           current_file;       /* Identifies the program file in the current table */
53 int           ctable_index = -1;  /* Destination of current table */
54 int           max_index    =  0;  /* maximum table index, used for compacting output */
56 /************************************************************************************
57  * Declaration: Layout tables. 
58  ************************************************************************************/
59 layout_t  layouts[MAX_LAYOUTS];   /* Array of layout structures */                
60 int       currentLayout;          /* Currently active layout    */
62 /************************************************************************************
63  * Declaration: Pads
64  ************************************************************************************/
65 pad_t pads[MAX_PADS];             /* Array of pad structures */
66 int   currentPad;                 /* Currently active pad    */
68 /************************************************************************************
69  * Declaration: The structure storing the program data files, and the number of
70  *              programs used.
71  ************************************************************************************/
72 progFile_t progFile[NUM_BOOT_PARAM_TABLES];
73 int        nProgFiles = 0;
75 /************************************************************************************
76  * Declaration: The PCI parameter structure
77  ************************************************************************************/
78 pciFile_t pciFile;
79 int       pciSet = 0;
81 /*************************************************************************************
82  * Declaration: The array that tracks the ordering of pad and layout structures
83  *************************************************************************************/
84 padLayoutOrder_t padLayoutOrder[MAX_PADS+MAX_LAYOUTS];
85 int currentPL = 0;
87 /*************************************************************************************
88  * Declaration: The next free address in the ROM for general data usage. For the
89  *              start address there is room for the initial boot parameter tables, 
90  *              plus room for the PCI eeai config.
91  *************************************************************************************/
92 int romBase = DATA_BASE;
95 /*************************************************************************************
96  * Declaration: Args passed in from the command line
97  *************************************************************************************/
98 char *inputFile;
99 int   compact = 0;
102 /*************************************************************************************
103  * FUNCTION PURPOSE: flex/bison required support functions.
104  *************************************************************************************
105  * DESCRIPTION: yyerror and yywrap are required to support flex and/or bison parsing
106  *              of the parameter description file. yyerror directly reports the
107  *              error, yywrap is unused.
108  *************************************************************************************/
109 void yyerror (char *s)
111   fprintf (stderr, "flex/bison error is %s at line %d\n", s, line);
112 } /* yyerror */
114 void yywrap (void)
116 } /* yywrap */
118 /*************************************************************************************
119  * FUNCTION PURPOSE: Initialize a boot table
120  *************************************************************************************
121  * DESCRIPTION: Sets a boot parameter table to 0s
122  *************************************************************************************/
123 void initTable (BOOT_PARAMS_T *current_table)
125   memset (current_table, 0, sizeof(BOOT_PARAMS_T));
128 /*************************************************************************************
129  * FUNCTION PURPOSE: Initialize the program data file table
130  *************************************************************************************
131  * DESCRIPTION: The size and tags are all setup
132  *************************************************************************************/
133 void initProgFile (void)
135   int i, j;
137   for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++)  {
138     progFile[i].sizeBytes = 0;
139     progFile[i].align     = 0;
141     for (j = 0; j < NUM_BOOT_PARAM_TABLES; j++)
142       progFile[i].tag[j] = -1;
144   }
149 /*************************************************************************************
150  * FUNCTION PURPOSE: Set the currently active parse type
151  *************************************************************************************
152  * DESCRIPTION: Indicates if the subsequent parameters belong to a section or
153  *              a layout
154  *************************************************************************************/
155 void rBegin (int blockType)
157     currentType = blockType;
160 /*************************************************************************************
161  * FUNCTION PURPOSE: Initialize a layout structure
162  *************************************************************************************
163  * DESCRIPTION: The layout is set to the initial state
164  *************************************************************************************/
165 void initLayout (layout_t *cl)
168   cl->nPlt     = 0;
169   cl->dev_addr = i2cRomBase;
170   cl->address  = 0;
171   cl->align    = 0;
175 /*************************************************************************************
176  * FUNCTION PURPOSE: Complete a layout
177  *************************************************************************************
178  * DESCRIPTION: The parser has found a complete layout specification. Complete
179  *              a layout structure
180  *************************************************************************************/
181 void setLayout (void)
183   int i;
184   int currentAlign;
185   int newAlign;
187   for (i = 0; i < layouts[currentLayout].nPlt; i++)  {
189     if (layouts[currentLayout].plt[i].type == PLT_FILE)  {
191       currentAlign = progFile[layouts[currentLayout].plt[i].index].align;
192       newAlign     = layouts[currentLayout].align;
194       if (newAlign > currentAlign)
195         progFile[layouts[currentLayout].plt[i].index].align = newAlign;
196     }
198   }
201   padLayoutOrder[currentPL].type  = LAYOUT;
202   padLayoutOrder[currentPL].index = currentLayout;
203   currentPL += 1;
204     
205   currentLayout += 1;      /* Advance to the next layout */
207   if (currentLayout < MAX_LAYOUTS)
208     initLayout (&layouts[currentLayout]);
210 }    
212 /*************************************************************************************
213  * FUNCTION PURPOSE: Initialize a pad structure
214  *************************************************************************************
215  * DESCRIPTION: A pad structure is set to the default state
216  *************************************************************************************/
217 void initPad (pad_t *p)
219   p->id       = -1;
220   p->address  = 0;
221   p->dev_addr = i2cRomBase;
222   p->len      = 0;
226 /**************************************************************************************
227  * FUNCTION PURPOSE: Complete a pad
228  **************************************************************************************
229  * DESCRIPTION: The parser has found a complete pad specification. Complete the pad
230  *              structure
231  **************************************************************************************/
232 void setPad (void)
235   padLayoutOrder[currentPL].type  = PAD;
236   padLayoutOrder[currentPL].index = currentPad;
237   currentPL += 1;
239   currentPad += 1;
241   if (currentPad < MAX_PADS)
242     initPad (&pads[currentPad]);
247 /*************************************************************************************
248  * FUNCTION PURPOSE: Complete a section
249  *************************************************************************************
250  * DESCRIPTION: The parser has detected a complete section. Copy the section into
251  *              it's correct table location.
252  *************************************************************************************/
253 void section (void)
255   int i;
257   /* It's an error if no section value has been declared */
258   if (ctable_index == -1)  {
259     fprintf (stderr, "romparse: the section did not have a boot paramter index specified\n");
260     exit (-1);
261   }
263   /* Make sure the table is in range */
264   if (ctable_index >= NUM_BOOT_PARAM_TABLES)  {
265     fprintf (stderr, "romparse: The section index is too large (max %d)\n", NUM_BOOT_PARAM_TABLES-1);
266     exit (-1);
267   }
269   /* The length must be set. Currently this program only supports I2C mode, so the
270    * length is fixed */
271   current_table.common.length   = 30;
272   current_table.common.checksum = 0;
274   /* Copy the table */
275   memcpy (&boot_params[ctable_index], &current_table, sizeof (BOOT_PARAMS_T));
276   initTable (&current_table);
278   /* Track the maximum table index */
279   if (ctable_index > max_index)
280     max_index = ctable_index;
282   /* If the section referenced a data file, link the data file back to this section */
283   if (current_file >= 0)  {
284     for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++)  {
285       if (progFile[current_file].tag[i] < 0)
286         progFile[current_file].tag[i] = ctable_index;
287         break;
288     }
289   }
291   ctable_index = -1;
292   current_file = -1;
294 } /* section */
296 /***************************************************************************************
297  * FUNCTION PURPOSE: Open a ccs hex file and read in the data.
298  ***************************************************************************************
299  * DESCRIPTION: Reads a ccs hex format data file, loads the file into the
300  *              next program file structure. Returns the index of the just loaded
301  *              table.
302  ***************************************************************************************/
303 int openProgFile (char *fname)
305   FILE *str;
306   int a, b, c, d, e;
307   int i;
308   char iline[132];
310   /* Store the file name */
311   strcpy (progFile[nProgFiles].fname, fname);
313   /* Open the data file */
314   str = fopen (fname, "r");
315   if (str == NULL)  {
316     fprintf (stderr, "romparse: Could not open file %s\n", fname);
317     exit (-1);
318   }
320   /* Read the one line ccs header. The length field in terms of lines */
321   fgets (iline, 132, str);
322   sscanf (iline, "%x %x %x %x %x", &a, &b, &c, &d, &e);
323   progFile[nProgFiles].sizeBytes = e * 4; /* Length was in 4 byte words */
325   /* Read in the data */
326   for (i = 0; i < e; i++)  {
327     fgets (iline, 132, str);
328     sscanf (&(iline[2]), "%x", &((progFile[nProgFiles]).data[i]));
329   }
331   fclose (str);
333   i = nProgFiles;
334   nProgFiles += 1;
336   return (i);
338 } /* openProgFile */
340 /***************************************************************************************
341  * FUNCTION PURPOSE: Load the PCI paramter section
342  ***************************************************************************************
343  * DESCRIPTION: Loads the PCI parameter section and stores it in the rom. */
344 int setPciParams (char *fname)
346   FILE *str;
347   int a, b, c, d, e;
348   int i;
349   char iline[132];
350   char *z;
352   if (pciSet)  {
353     fprintf (stderr, "romparse: PCI parameters specified more then once\n");
354     exit (-1);
355   }
357   /* the input string still contains the quotes. Remove them here */
358   z = &fname[1];
359   *strchr (z, '"') = '\0';
361   /* Store the file name */
362   strcpy (pciFile.fname, z);
364   /* Open the data file */
365   str = fopen (z, "r");
366   if (str == NULL)  {
367     fprintf (stderr, "romparse: Could not open pci file %s\n", fname);
368     exit (-1);
369   }
371   /* The address of the pci params is currently fixed */
372   pciFile.addressBytes = PCI_PARAM_BASE;
374   /* Read the one line ccs header. The length field is in terms of lines */
375   fgets (iline, 132, str);
376   sscanf (iline, "%x %x %x %x %x", &a, &b, &c, &d, &e);
377   pciFile.sizeBytes = e * 4;  /* Convert length to bytes */
379   /* Read in the data */
380   for (i = 0; i < e; i++)  {
381     fgets (iline, 132, str);
382     sscanf (&(iline[2]), "%x", &(pciFile.data[i]));
383   }
385   pciSet = 1;
387   return (0);
389 } /* setPciParams */
391  
393 /***************************************************************************************
394  * FUNCTION PURPOSE: Store an assignment
395  ***************************************************************************************
396  * DESCRIPTION: Stores an assigned value into the current boot parameter table
397  ***************************************************************************************/
398 void assignKeyVal (int field, int value)
401   switch (currentType)   {
404     case SECTION:
407       switch (field)  {
409         case BOOT_MODE:        current_table.common.boot_mode = value;
410                                break;
412         case PARAM_INDEX:      ctable_index = value;
413                                break;
415         case OPTIONS:          current_table.i2c.options = value;
416                                break;
418         case MULTI_I2C_ID:     current_table.i2c.multi_i2c_id = value;
419                                break;
421         case MY_I2C_ID:        current_table.i2c.my_i2c_id = value;
422                                break;
424         case CORE_FREQ_MHZ:    current_table.i2c.core_freq_mhz = value;
425                                break;
427         case I2C_CLK_FREQ_KHZ: current_table.i2c.i2c_clk_freq_khz = value;
428                                break;
430         case NEXT_DEV_ADDR:    current_table.i2c.next_dev_addr = value;
431                                break;
432                                
434         case NEXT_DEV_ADDR_EXT: current_table.i2c.next_dev_addr_ext = value;
435                                 break;
437         case ADDRESS_DELAY:    current_table.i2c.address_delay = value;
438                                break;
440 #ifndef c6455         
441         case SWPLL:            current_table.i2c.swPll = value;
442                                break;
443 #endif
445         case DEV_ADDR_EXT:     current_table.i2c.dev_addr_ext = value;
446                                break;
448         case DEV_ADDR:         current_table.i2c.dev_addr = value;
449                                break;
452         default:
453             fprintf (stderr, "romparse: Invalid assignment in section specification (line %d)\n", line);
454             break;
456       }
458       break;
461     case LAYOUT:
463       if (currentLayout >= MAX_LAYOUTS)  { 
464         fprintf (stderr, "romparse: Too many layout sections (max = %d)\n", MAX_LAYOUTS);
465         exit (-1);
466       }
469       switch (field)  {
471         case DEV_ADDR_EXT: layouts[currentLayout].dev_addr = value;
472                            break;
474         case DEV_ADDR:     layouts[currentLayout].address = value;
475                            break;
477         case ALIGN:        layouts[currentLayout].align = value;
478                            break;
480         case PAD_FILE_ID:   if (layouts[currentLayout].nPlt >= MAX_LAYOUT_FILES)  {
481                               fprintf (stderr, "romparse: line %d: number of layout entries exceeds maximum of %d\n", line, MAX_LAYOUT_FILES);
482                               exit (-1);
483                             }
484                             layouts[currentLayout].plt[layouts[currentLayout].nPlt].type  = PLT_PAD;
485                             layouts[currentLayout].plt[layouts[currentLayout].nPlt].index = value;
486                             layouts[currentLayout].nPlt += 1;
487                             break;
490         default:
491             fprintf (stderr, "romparase: Invalid assignment in layout specification (line %d)\n", line);
492             break;
494       }
495       break;
498     case PAD:
500       if (currentPad >= MAX_PADS)  {
501         fprintf (stderr, "romparse: Too many pad sections (max = %d)\n", MAX_PADS);
502         exit (-1);
503       }
505       switch (field)  {
507         case DEV_ADDR_EXT: pads[currentPad].dev_addr = value;
508                            break;
510         case DEV_ADDR:  pads[currentPad].address = value;
511                         break;
513         case LENGTH:    pads[currentPad].len = value;
514                         break;
516         case PAD_FILE_ID: pads[currentPad].id = value;
517                           break;
519         default:
520           fprintf (stderr, "romparse: Invalid assignment in pad specificaiton (line %d)\n", line);
521           break;
523       }
524       break;
526    }
529 } /* assignKeyVal */
532 /*******************************************************************************
533  * FUNCTION PURPOSE: Parse a string input.
534  *******************************************************************************
535  * DESCRIPTION: Takes a string input. Currently only the i2c exe file name can be 
536  *              assigned a string. 
537  *******************************************************************************/
538 void assignKeyStr (int value, char *y)
540   int i;
541   char *z;
543   /* The special case of a 0 (plus the quotes) length string means an empty entry for a layout */
544   if (strlen(y) == 2)  {
546     if (currentType == LAYOUT)  {
547       if (layouts[currentLayout].nPlt <= MAX_LAYOUT_FILES)  {
548         layouts[currentLayout].plt[layouts[currentLayout].nPlt].type  = PLT_FILE;
549         layouts[currentLayout].plt[layouts[currentLayout].nPlt].index = -1;
550         layouts[currentLayout].nPlt += 1;
552       }  else  {
553         fprintf (stderr, "romparse: line %d: Max number (%d) of layout specification exceeded\n", line, MAX_LAYOUT_FILES);
554       }
555     }  else
556          fprintf (stderr, "romparse: Number of layout sections exceeded (max = %d)\n", MAX_LAYOUTS);
558     return;
559   }
562   /* the input string still contains the quotes. Remove them here */
563   z = &y[1];
564   *strchr (z, '"') = '\0';
566   /* Check if the file name is already open */
567   for (i = 0; i < nProgFiles; i++)  {
569     if (!strcmp (z, progFile[i].fname))  {
571       /* Found a match */
573       if (currentType == SECTION)  {
575         current_file = i;
577         if (current_table.i2c.dev_addr_ext == 0)
578           current_table.i2c.dev_addr_ext = i2cRomBase;  /* hard coded to i2c rom slave address */
580       }  else  {   /* LAYOUT */
582         if (currentLayout < MAX_LAYOUTS)  {
583           if (layouts[currentLayout].nPlt <= MAX_LAYOUT_FILES)  {
584             layouts[currentLayout].plt[layouts[currentLayout].nPlt].type  = PLT_FILE;
585             layouts[currentLayout].plt[layouts[currentLayout].nPlt].index = i;
586             layouts[currentLayout].nPlt += 1;
588           }  else  {
589             fprintf (stderr, "romparse: line %d: Max number (%d) of layout specification exceeded\n", line, MAX_LAYOUT_FILES);
590           }
591         }  else
592           fprintf (stderr, "romparse: Number of layout sections exceeded (max = %d)\n", MAX_LAYOUTS);
594       }
595         
597       return;
598     }
600   }
602   /* Open and read the ccs file, set the ROM address */
603   i = openProgFile (z);
604   if (i >= 0) {
606     if (currentType == SECTION)  {
608       current_file = i;
609       if (current_table.i2c.dev_addr_ext == 0)
610           current_table.i2c.dev_addr_ext = i2cRomBase;
612     }  else  {  /* LAYOUT */
613         
614         if (currentLayout < MAX_LAYOUTS)  {
615           if (layouts[currentLayout].nPlt <= MAX_LAYOUT_FILES)  {
616             layouts[currentLayout].plt[layouts[currentLayout].nPlt].type  = PLT_FILE;
617             layouts[currentLayout].plt[layouts[currentLayout].nPlt].index = i;
618             layouts[currentLayout].nPlt += 1;
620           }  else  {
621             fprintf (stderr, "romparse: line %d: Max number (%d) of layout specification exceeded\n", line, MAX_LAYOUT_FILES);
622           }
623         }  else
624           fprintf (stderr, "romparse: Number of layout sections exceeded (max = %d)\n", MAX_LAYOUTS);
626     }
627       
628         
629   }
631 } /* assignKeyStr */
633 /************************************************************************************
634  * FUNCTION PURPOSE: Put a 32 bit value into the i2c image memory
635  ************************************************************************************
636  * DESCRIPTION: The 32 bit value is placed in memory in big endian format. The
637  *              new offset is returned (4 bytes more then the input offset)
638  ************************************************************************************/
639 unsigned int imageWord (unsigned int base, unsigned int start, unsigned char *image, unsigned int value)
641     image[base-start+0] = (value >> 24) & 0xff;
642     image[base-start+1] = (value >> 16) & 0xff;
643     image[base-start+2] = (value >>  8) & 0xff;
644     image[base-start+3] = (value >>  0) & 0xff;
646     return (base + 4);
650 /************************************************************************************
651  * FUNCTION PURPOSE: Create a 32 bit value from the image array
652  ************************************************************************************
653  * DESCRIPTION: A 32 bit word in big endian format is created
654  ************************************************************************************/
655 unsigned int formWord (unsigned int p, unsigned char *image)
657   unsigned int v;
659   v = (image[p+0] << 24) |
660       (image[p+1] << 16) |
661       (image[p+2] <<  8) |
662       (image[p+3] <<  0) ;
664   return (v);
668 /************************************************************************************
669  * FUNCTION PURPOSE: Pad the image array
670  ************************************************************************************
671  * DESCRIPTION: Byte (value 0) are added to the image to reach the desired address
672  *              The desired address is returned.
673  ************************************************************************************/
674 unsigned int imagePad (unsigned int base, unsigned int start, unsigned char *image, unsigned int desired)
676   int i;
678   if (desired < base)  {
679     fprintf (stderr, "romparse: Padd to %d requested, but current base (%d) is already past this point\n",
680              desired, base);
681     exit (-1);
682   }
684   for (i = base; i < desired; i++)
685     image[i-start] = 0;
687   return (desired);
691 /************************************************************************************
692  * FUNCTION PURPOSE: Opens and writes the output file
693  ************************************************************************************
694  * DESCRIPTION: Creates the output file in ccs format.
695  ************************************************************************************/
696 void createOutput (void)
698   FILE *str;
699   int   totalLenBytes;
700   int   i, j, k;
701   int   nTables, len;
702   int   i2cRomStart;
703   unsigned int value, v1, v2;
704   unsigned int base;
705   unsigned char *image;
707   str = fopen ("i2crom.ccs", "w");
708   if (str == NULL)  {
709     fprintf (stderr, "romparse: Could not open output file i2crom.ccs for writing\n");
710     exit (-1);
711   }
713   /* Compact the i2c eeprom to use the minimum memory possible */
714   base    = (i2cRomBase << 16) + PCI_PARAM_BASE;
715   nTables = NUM_BOOT_PARAM_TABLES; 
717   if ((compact != 0) && (pciSet == 0))  {
718     nTables = max_index + 1;
719     base    = (i2cRomBase << 16) + (nTables * 0x80);  /* The number of parameter tables * size of a parameter table */
720   }
722   if (pciSet)
723     base = base + PCI_EEAI_PARAM_SIZE;
726   /* Change the layout index value for pad mapping to a true array index value.
727    * Also reflect the device address from the layout into the pad */
728   for (i = 0; i < currentLayout; i++)  {
729     
730     for (j = 0; j < layouts[i].nPlt; j++)  {
732       if (layouts[i].plt[j].type == PLT_PAD)  {
734         for (k = 0; k < currentPad; k++)  {
736           if (layouts[i].plt[j].index == pads[k].id)  {
737             layouts[i].plt[j].index = k;
738             pads[k].dev_addr = layouts[i].dev_addr;
739           }
740         }
741       }
742     }
743   }
745   /* Pad, layout tables */
746   for (i = 0; i < currentPL; i++)  {
748     j = padLayoutOrder[i].index;
750     if (padLayoutOrder[i].type == LAYOUT)  {
752       /* Determine the size of the table. Four bytes for each file, plus the 4 byte header */ 
753       v1 = (layouts[j].nPlt * 4) + 4;
755       v2 = (layouts[j].dev_addr << 16) + layouts[j].address;
757       if (v2 == 0)
758         base = base + v1;
760       else  {
762         if (base > v2)  {
763           fprintf (stderr, "romparse: fatal error - layout block %d specified a start address of 0x%04x\n", j, (layouts[j].dev_addr << 16) + layouts[j].address);
764           fprintf (stderr, "          but this conflicts with the base mapping (ends at 0x%04x)\n", base);
765           exit (-1);
766         }
768         base = v2 + v1;  /* new base is the base plus the size */
771       }  
772     }  else  {   /* Otherwise this is a pad */
774       if (base > ((pads[j].dev_addr << 16) + pads[j].address))  {
775         fprintf (stderr, "romparse: fatal error - pad block %d specified a start address of 0x%04x\n", j, (pads[j].dev_addr << 16) + pads[j].address);
776         fprintf (stderr, "          but this conflicts with the base mapping (ends at 0x%04x)\n", base);
777         exit (-1);
778       }
780       base = (pads[j].dev_addr << 16) + pads[j].address + pads[j].len;
782     }
783   }
785   for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++)  {
786     if (progFile[i].align > 0)  
787       base = ((base + progFile[i].align - 1) / progFile[i].align) * progFile[i].align;
788     progFile[i].addressBytes = base;
789     base = base + progFile[i].sizeBytes;
790   }
792   /* Setup the base program file addresses. If a parameter set has
793    * been tagged it means that this is an i2c program load */
794   for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++)  {
795     for (j = 0; j < NUM_BOOT_PARAM_TABLES; j++)  {
796       if (progFile[i].tag[j] >= 0)
797         boot_params[progFile[i].tag[j]].i2c.dev_addr = (progFile[i].addressBytes & 0xffff);
798     }
799   }
801   /* Round up the size to a multiple of 4 bytes to fit into a ccs data file */
802   base = (base + 3) & ~3;
804   i2cRomStart = (i2cRomBase << 16);
805       
806   /* The total length of the i2c eeprom is now stored in base */
807   /* Write out the ccs header */
808   fprintf (str, "1651 1 10000 1 %x\n", (base - i2cRomStart) >> 2);
810   /* Create the image in memory */
811   image = malloc ((base - i2cRomStart) * sizeof (unsigned char));
812   if (image == NULL)  {
813     fprintf (stderr, "romparse: malloc failed creating the output image\n");
814     exit (-1);
815   }
817   /* Write out the boot parameter tables. 0x80 bytes will be written out.
818    * There are 16 bits in every parameter field, which is why the index
819    * is from 0 to 0x40 */
820   base = i2cRomBase << 16;
821   for (i = 0; i < nTables; i++)  {
822     for (j = 0; j < (0x80 >> 1); j += 2)  {
823       v1 = boot_params[i].parameter[j];
824       v2 = boot_params[i].parameter[j+1];
825       value = (v1 << 16) | v2;
826       base = imageWord (base, i2cRomStart, image, value);
827     }
828   }
830   /* Write out the PCI parameter base. If none was included then zeros will be
831    * written out */
832   if (pciSet)  {
833     for (i = 0; i < PCI_DATA_LEN_32bit; i++)  {
834       base = imageWord (base, i2cRomStart, image, pciFile.data[i]);
835     }
836   }
839   /* Layout sections */
840   for (i = 0; i < currentLayout; i++)  {
842     v1 = (layouts[i].dev_addr << 16) + layouts[i].address;
844     /* subtract out device address bits */
845     if (v1 > 0)
846       base  = imagePad (base, i2cRomStart, image, v1);
848     len   = (layouts[i].nPlt * 4) + 4;
850     /* Write out the block size and checksum */
851     base = imageWord(base, i2cRomStart, image, len << 16);
853     for (j = 0; j < layouts[i].nPlt; j++)  {
854         
855         if (layouts[i].plt[j].type == PLT_FILE)  {
856           if (layouts[i].plt[j].index == -1)  {
857             base = imageWord (base, i2cRomStart, image, 0xffffffff);
858           } else {
859             base = imageWord (base, i2cRomStart, image, progFile[layouts[i].plt[j].index].addressBytes);
860           } 
861         }  else  {
862           v1 = pads[layouts[i].plt[j].index].dev_addr;
863           v2 = pads[layouts[i].plt[j].index].address;
864           base = imageWord (base, i2cRomStart, image, (v1 << 16) + v2);
865         }
867     }
869   }
870                                 
872   /* Write out each of the program files */
873   for (i = 0; i < nProgFiles; i++)  {
875     v1 = progFile[i].addressBytes;
876     base = imagePad (base, i2cRomStart, image, v1);
878     for (j = 0; j < progFile[i].sizeBytes >> 2; j++)
879       base = imageWord (base, i2cRomStart, image, (progFile[i]).data[j]);
880   }
882   /* Write out the data file */
883   for (i = 0; i < base - i2cRomStart; i += 4) 
884     fprintf (str, "0x%08x\n", formWord (i, image));
886   free (image);
888   /* Close the output file */
889   fclose (str);
891 } /* createOutput  */
893 /************************************************************************************
894  * FUNCTION PURPOSE: Initialize the pci paramter table
895  ************************************************************************************
896  * DESCRIPTION: Zeros the pci parameters
897  ************************************************************************************/
898 void initPciParams (void)
900   memset (&pciFile, 0, sizeof(pciFile_t));
901 } /* initPciParams */
904 /************************************************************************************
905  * FUNCTION PURPOSE: Read an integer value from a string
906  ************************************************************************************
907  * DESCRIPTION: A decimal or hex value is scanned
908  ************************************************************************************/
909 int readVal (char *s)
911   int ret;
913   if ((s[0] == '0') && (s[1] == 'x'))
914     sscanf (&s[2], "%x", &ret);
915   else
916     sscanf (s, "%d", &ret);
918   return (ret);
921   
923 /************************************************************************************
924  * FUNCTION PURPOSE: Parse the input arguments.
925  ************************************************************************************
926  * DESCRIPTION: Returns -1 on invalid args
927  ************************************************************************************/
928 int parseIt (int argc, char *argv[])
930   int i;
932   if (argc < 2)  {
933      fprintf (stderr, "usage: %s [-compact] [-rom_base x] inputfile\n", argv[0]);
934      return (-1);
935   }
937   inputFile = NULL;  
939   for (i = 1; i < argc;  )  {
941     if (!strcmp (argv[i], "-compact"))  {
942       compact = 1;
943       i += 1;
945     } else if (!strcmp (argv[i], "-rom_base"))  {
946       i2cRomBase = readVal (argv[i+1]);
947       i += 2;
949     } else  {
951       if (inputFile != NULL)  {
952         fprintf (stderr, "usage: %s [-compact] inputfile\n", argv[0]);
953         return (-1);
954       }
956       inputFile = argv[i];
957       i += 1;
958     }
959   }
961   return (0);
967 /************************************************************************************
968  * FUNCTION PURPOSE: main function
969  ************************************************************************************
970  * DESCRIPTION: Performs the processing sequence.
971  ************************************************************************************/
972 int main (int argc, char *argv[])
974   int i;
976   /* Initialize the tables */
977   for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++)
978     initTable(&boot_params[i]);
980   initTable (&current_table);
981   current_file = -1;
983   /* Initialize the program file structure */
984   initProgFile ();
986   /* Initialize the PCI param table */
987   initPciParams ();
989   /* Initialize the layout structures */
990   currentLayout = 0;
991   initLayout (&layouts[currentLayout]);
993   /* Parse the input parameters */
994   if (parseIt (argc, argv))
995     return (-1);
997   
998   yyin = fopen (inputFile, "r");
999   if (yyin == NULL)  {
1000     fprintf (stderr, "%s: could not open file %s\n", argv[0], inputFile);
1001     return (-1);
1002   }
1004   /* Parse the input description file */
1005   yyparse();
1008   /* Create the output file */
1009   createOutput ();
1011   return (0);