30e19cbd1e167daebd2c41e266e9070ff3c58269
[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 "rparse.tab.h"
14 #include "romparse.h"
16 /*************************************************************************************
17  * Definition: fixed i2c map locations
18  *************************************************************************************/
19 #define PCI_PARAM_BASE  (NUM_BOOT_PARAM_TABLES * 0x80)
20 #define DATA_BASE       (PCI_PARAM_BASE + PCI_EEAI_PARAM_SIZE)
24 /*************************************************************************************
25  * Declaration: The flex input file is assigned based on the command line
26  *************************************************************************************/
27 extern FILE *yyin;
29 /*************************************************************************************
30  * Declaration: The boot parameter tables. The current table is copied into position
31  *              when the section parse is complete.
32  *************************************************************************************/
33 BOOT_PARAMS_T boot_params[NUM_BOOT_PARAM_TABLES];
34 BOOT_PARAMS_T current_table;
35 int           current_file;       /* Identifies the program file in the current table */
36 int           ctable_index = -1;  /* Destination of current table */
37 int           max_index    =  0;  /* maximum table index, used for compacting output */
39 /************************************************************************************
40  * Declaration: The structure storing the program data files, and the number of
41  *              programs used.
42  ************************************************************************************/
43 progFile_t progFile[NUM_BOOT_PARAM_TABLES];
44 int        nProgFiles = 0;
46 /************************************************************************************
47  * Declaration: The PCI parameter structure
48  ************************************************************************************/
49 pciFile_t pciFile;
50 int       pciSet = 0;
52 /*************************************************************************************
53  * Declaration: The next free address in the ROM for general data usage. For the
54  *              start address there is room for the initial boot parameter tables, 
55  *              plus room for the PCI eeai config.
56  *************************************************************************************/
57 int romBase = DATA_BASE;
60 /*************************************************************************************
61  * Declaration: Args passed in from the command line
62  *************************************************************************************/
63 char *inputFile;
64 int   compact = 0;
67 /*************************************************************************************
68  * FUNCTION PURPOSE: flex/bison required support functions.
69  *************************************************************************************
70  * DESCRIPTION: yyerror and yywrap are required to support flex and/or bison parsing
71  *              of the parameter description file. yyerror directly reports the
72  *              error, yywrap is unused.
73  *************************************************************************************/
74 void yyerror (char *s)
75 {
76   fprintf (stderr, "flex/bison error is %s\n", s);
77 } /* yyerror */
79 void yywrap (void)
80 {
81 } /* yywrap */
83 /*************************************************************************************
84  * FUNCTION PURPOSE: Initialize a boot table
85  *************************************************************************************
86  * DESCRIPTION: Sets a boot parameter table to 0s
87  *************************************************************************************/
88 void initTable (BOOT_PARAMS_T *current_table)
89 {
90   memset (current_table, 0, sizeof(BOOT_PARAMS_T));
91 }
93 /*************************************************************************************
94  * FUNCTION PURPOSE: Initialize the program data file table
95  *************************************************************************************
96  * DESCRIPTION: The size and tags are all setup
97  *************************************************************************************/
98 void initProgFile (void)
99 {
100   int i, j;
102   for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++)  {
103     progFile[i].sizeBytes = 0;
105     for (j = 0; j < NUM_BOOT_PARAM_TABLES; j++)
106       progFile[i].tag[j] = -1;
108   }
112 /*************************************************************************************
113  * FUNCTION PURPOSE: Complete a section
114  *************************************************************************************
115  * DESCRIPTION: The parser has detected a complete section. Copy the section into
116  *              it's correct table location.
117  *************************************************************************************/
118 void section (void)
120   int i;
122   /* It's an error if no section value has been declared */
123   if (ctable_index == -1)  {
124     fprintf (stderr, "romparse: the section did not have a boot paramter index specified\n");
125     exit (-1);
126   }
128   /* Make sure the table is in range */
129   if (ctable_index >= NUM_BOOT_PARAM_TABLES)  {
130     fprintf (stderr, "romparse: The section index is too large (max %d)\n", NUM_BOOT_PARAM_TABLES-1);
131     exit (-1);
132   }
134   /* The length must be set. Currently this program only supports I2C mode, so the
135    * length is fixed */
136   current_table.common.length   = 30;
137   current_table.common.checksum = 0;
139   /* Copy the table */
140   memcpy (&boot_params[ctable_index], &current_table, sizeof (BOOT_PARAMS_T));
141   initTable (&current_table);
143   /* Track the maximum table index */
144   if (ctable_index > max_index)
145     max_index = ctable_index;
147   /* If the section referenced a data file, link the data file back to this section */
148   if (current_file >= 0)  {
149     for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++)  {
150       if (progFile[current_file].tag[i] < 0)
151         progFile[current_file].tag[i] = ctable_index;
152         break;
153     }
154   }
156   ctable_index = -1;
157   current_file = -1;
159 } /* section */
161 /***************************************************************************************
162  * FUNCTION PURPOSE: Open a ccs hex file and read in the data.
163  ***************************************************************************************
164  * DESCRIPTION: Reads a ccs hex format data file, loads the file into the
165  *              next program file structure. Returns the index of the just loaded
166  *              table.
167  ***************************************************************************************/
168 int openProgFile (char *fname)
170   FILE *str;
171   int a, b, c, d, e;
172   int i;
173   char iline[132];
175   /* Store the file name */
176   strcpy (progFile[nProgFiles].fname, fname);
178   /* Open the data file */
179   str = fopen (fname, "r");
180   if (str == NULL)  {
181     fprintf (stderr, "romparse: Could not open file %s\n", fname);
182     exit (-1);
183   }
185   /* Put the section at the next available i2c rom address */
186   /* progFile[nProgFiles].addressBytes = romBase; */
188   /* Read the one line ccs header. The length field in terms of lines */
189   fgets (iline, 132, str);
190   sscanf (iline, "%x %x %x %x %x", &a, &b, &c, &d, &e);
191   progFile[nProgFiles].sizeBytes = e * 4; /* Length was in 4 byte words */
193   /* Read in the data */
194   for (i = 0; i < e; i++)  {
195     fgets (iline, 132, str);
196     sscanf (&(iline[2]), "%x", &((progFile[nProgFiles]).data[i]));
197   }
199   fclose (str);
201   /* Update the next free rom base */
202   /* romBase = romBase + progFile[nProgFiles].sizeBytes; */
204   i = nProgFiles;
205   nProgFiles += 1;
207   return (i);
209 } /* openProgFile */
211 /***************************************************************************************
212  * FUNCTION PURPOSE: Load the PCI paramter section
213  ***************************************************************************************
214  * DESCRIPTION: Loads the PCI parameter section and stores it in the rom. */
215 int setPciParams (char *fname)
217   FILE *str;
218   int a, b, c, d, e;
219   int i;
220   char iline[132];
221   char *z;
223   if (pciSet)  {
224     fprintf (stderr, "romparse: PCI parameters specified more then once\n");
225     exit (-1);
226   }
228   /* the input string still contains the quotes. Remove them here */
229   z = &fname[1];
230   *strchr (z, '"') = '\0';
232   /* Store the file name */
233   strcpy (pciFile.fname, z);
235   /* Open the data file */
236   str = fopen (z, "r");
237   if (str == NULL)  {
238     fprintf (stderr, "romparse: Could not open pci file %s\n", fname);
239     exit (-1);
240   }
242   /* The address of the pci params is currently fixed */
243   pciFile.addressBytes = PCI_PARAM_BASE;
245   /* Read the one line ccs header. The length field is in terms of lines */
246   fgets (iline, 132, str);
247   sscanf (iline, "%x %x %x %x %x", &a, &b, &c, &d, &e);
248   pciFile.sizeBytes = e * 4;  /* Convert length to bytes */
250   /* Read in the data */
251   for (i = 0; i < e; i++)  {
252     fgets (iline, 132, str);
253     sscanf (&(iline[2]), "%x", &(pciFile.data[i]));
254   }
256   pciSet = 1;
258   return (0);
260 } /* setPciParams */
262  
264 /***************************************************************************************
265  * FUNCTION PURPOSE: Store an assignment
266  ***************************************************************************************
267  * DESCRIPTION: Stores an assigned value into the current boot parameter table
268  ***************************************************************************************/
269 void assignKeyVal (int field, int value)
271   switch (field)  {
273     case BOOT_MODE:        current_table.common.boot_mode = value;
274                            break;
276     case PARAM_INDEX:      ctable_index = value;
277                            break;
279     case OPTIONS:          current_table.i2c.options = value;
280                            break;
282     case MULTI_I2C_ID:     current_table.i2c.multi_i2c_id = value;
283                            break;
285     case MY_I2C_ID:        current_table.i2c.my_i2c_id = value;
286                            break;
288     case CORE_FREQ_MHZ:    current_table.i2c.core_freq_mhz = value;
289                            break;
291     case I2C_CLK_FREQ_KHZ: current_table.i2c.i2c_clk_freq_khz = value;
292                            break;
294     case NEXT_DEV_ADDR:    current_table.i2c.next_dev_addr = value;
295                            break;
297     case NEXT_DEV_ADDR_EXT: current_table.i2c.next_dev_addr_ext = value;
298                             break;
300     case ADDRESS_DELAY:    current_table.i2c.address_delay = value;
301                            break;
303 #ifndef c6455         
304     case SWPLL:            current_table.i2c.swPll = value;
305                            break;
306 #endif
308     case DEV_ADDR_EXT:     current_table.i2c.dev_addr_ext = value;
309                            break;
311     case DEV_ADDR:         current_table.i2c.dev_addr = value;
312                            break;
315   }
317 } /* assignKeyVal */
320 /*******************************************************************************
321  * FUNCTION PURPOSE: Parse a string input.
322  *******************************************************************************
323  * DESCRIPTION: Takes a string input. Currently only the i2c exe file name can be 
324  *              assigned a string. 
325  *******************************************************************************/
326 void assignKeyStr (int value, char *y)
328   int i;
329   char *z;
332   /* the input string still contains the quotes. Remove them here */
333   z = &y[1];
334   *strchr (z, '"') = '\0';
336   /* Check if the file name is already open */
337   for (i = 0; i < nProgFiles; i++)  {
339     if (!strcmp (z, progFile[i].fname))  {
340       /* Found a match - copy the address */
341       current_file = i;
342       /* current_table.i2c.dev_addr     = progFile[i].addressBytes & 0xffff; */
343       if (current_table.i2c.dev_addr_ext == 0)
344         current_table.i2c.dev_addr_ext = 0x50;  /* hard coded to i2c rom slave address */
345       return;
346     }
348   }
350   /* Open and read the ccs file, set the ROM address */
351   i = openProgFile (z);
352   if (i >= 0) {
353     /* current_table.i2c.dev_addr     = progFile[i].addressBytes & 0xffff; */
354     current_file = i;
355     if (current_table.i2c.dev_addr_ext == 0)
356         current_table.i2c.dev_addr_ext = 0x50;
357   }
359 } /* assignKeyStr */
362 /************************************************************************************
363  * FUNCTION PURPOSE: Opens and writes the output file
364  ************************************************************************************
365  * DESCRIPTION: Creates the output file in ccs format.
366  ************************************************************************************/
367 void createOutput (void)
369   FILE *str;
370   int   totalLenBytes;
371   int   i, j;
372   int   nTables;
373   unsigned int value, v1, v2;
374   unsigned int base;
376   str = fopen ("i2crom.ccs", "w");
377   if (str == NULL)  {
378     fprintf (stderr, "romparse: Could not open output file i2crom.ccs for writing\n");
379     exit (-1);
380   }
382   /* Compact the i2c eeprom to use the minimum memory possible */
383   base    = DATA_BASE;
384   nTables = NUM_BOOT_PARAM_TABLES; 
386   if ((compact != 0) && (pciSet == 0))  {
387     nTables = max_index + 1;
388     base    = nTables * 0x80;  /* The number of parameter tables * size of a parameter table */
389   }
392   for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++)  {
393     progFile[i].addressBytes = base;
394     base = base + progFile[i].sizeBytes;
395   }
397   /* Setup the base program file addresses. If a parameter set has
398    * been tagged it means that this is an i2c program load */
399   for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++)  {
400     for (j = 0; j < NUM_BOOT_PARAM_TABLES; j++)  {
401       if (progFile[i].tag[j] >= 0)
402         boot_params[progFile[i].tag[j]].i2c.dev_addr = progFile[i].addressBytes;
403     }
404   }
405       
406   /* The total length of the i2c eeprom is now stored in base */
407   /* Write out the ccs header */
408   fprintf (str, "1651 1 10000 1 %x\n", base >> 2);
410   /* Write out the boot parameter tables. 0x80 bytes will be written out.
411    * There are 16 bits in every parameter field, which is why the index
412    * is from 0 to 0x40 */
413   for (i = 0; i < nTables; i++)  {
414     for (j = 0; j < (0x80 >> 1); j += 2)  {
415       v1 = boot_params[i].parameter[j];
416       v2 = boot_params[i].parameter[j+1];
417       value = (v1 << 16) | v2;
418       fprintf (str, "0x%08x\n", value);
419     }
420   }
422   /* Write out the PCI parameter base. If none was included then zeros will be
423    * written out */
424   if (pciSet)  {
425     for (i = 0; i < PCI_DATA_LEN_32bit; i++)  {
426       fprintf (str, "0x%08x\n", pciFile.data[i]);
427     }
428   }
429                                 
431   /* Write out each of the program files */
432   for (i = 0; i < nProgFiles; i++)
433     for (j = 0; j < progFile[i].sizeBytes >> 2; j++)
434       fprintf (str, "0x%08x\n", (progFile[i]).data[j]);
437   /* Close the input file */
438   fclose (str);
440 } /* createOutput  */
442 /************************************************************************************
443  * FUNCTION PURPOSE: Initialize the pci paramter table
444  ************************************************************************************
445  * DESCRIPTION: Zeros the pci parameters
446  ************************************************************************************/
447 void initPciParams (void)
449   memset (&pciFile, 0, sizeof(pciFile_t));
450 } /* initPciParams */
454 /************************************************************************************
455  * FUNCTION PURPOSE: Parse the input arguments.
456  ************************************************************************************
457  * DESCRIPTION: Returns -1 on invalid args
458  ************************************************************************************/
459 int parseIt (int argc, char *argv[])
461   int i;
463   if (argc < 2)  {
464      fprintf (stderr, "usage: %s [-compact] inputfile\n", argv[0]);
465      return (-1);
466   }
468   inputFile = NULL;  
470   for (i = 1; i < argc;  )  {
472     if (!strcmp (argv[i], "-compact"))  {
473       compact = 1;
474       i += 1;
476     } else  {
478       if (inputFile != NULL)  {
479         fprintf (stderr, "usage: %s [-compact] inputfile\n", argv[0]);
480         return (-1);
481       }
483       inputFile = argv[i];
484       i += 1;
485     }
486   }
488   return (0);
494 /************************************************************************************
495  * FUNCTION PURPOSE: main function
496  ************************************************************************************
497  * DESCRIPTION: Performs the processing sequence.
498  ************************************************************************************/
499 int main (int argc, char *argv[])
501   int i;
503   /* Initialize the tables */
504   for (i = 0; i < NUM_BOOT_PARAM_TABLES; i++)
505     initTable(&boot_params[i]);
507   initTable (&current_table);
508   current_file = -1;
510   /* Initialize the program file structure */
511   initProgFile ();
513   /* Initialize the PCI param table */
514   initPciParams ();
517   /* Parse the input parameters */
518   if (parseIt (argc, argv))
519     return (-1);
521   
522   yyin = fopen (inputFile, "r");
523   if (yyin == NULL)  {
524     fprintf (stderr, "%s: could not open file %s\n", argv[0], inputFile);
525     return (-1);
526   }
528   /* Parse the input description file */
529   yyparse();
532   /* Create the output file */
533   createOutput ();
535   return (0);