Bug fix for automatic file format detection
[keystone-rtos/ibl.git] / src / interp / bis / bis.c
1 /******************************************************************************
2  * FILE PURPOSE: Boot from a BIS formatted input
3  ******************************************************************************
4  * FILE NAME: bis.c
5  *
6  * DESCRIPTION: A BIS formatted data file is parsed and loaded
7  *
8  *  @file bis.c
9  *
10  *  @brief
11  *      This file is used to load a BIS formatted data file
12  *
13  ******************************************************************************/
14 #include "types.h"
15 #include "ibl.h"
16 #include "iblloc.h"
17 #include "bis.h"
18 #include "iblcfg.h"
20 /**********************************************************************
21  ************************** Local Structures **************************
22  **********************************************************************/
24 /**
25  * @brief 
26  *  The structure describes the Function Entry. 
27  *
28  * @details
29  *  The entry stores information about function which can be executed
30  *  while executing the BIS Command State machine. These entries are
31  *  loaded and executed through the BIS Function Load & Execute commands.
32  */
33 typedef struct FN_ENTRY
34 {
35     /**
36      * @brief   This is the function number which is unique for all
37      * functions.
38      */
39     Uint16       fn_num;
40     
41     /**
42      * @brief   This is the number of arguments the function takes.
43      */
44     Uint16       arg_cnt;
46     /**
47      * @brief   This is the address where the function is loaded in
48      * memory via the function load command.
49      */
50     Uint32       fn_address;
51 }FN_ENTRY;
53 /**
54  * @brief   Global database all functions which can be loaded and executed
55  * via the BIS Function Load/Execute commands.
56 */
57 FN_ENTRY     fn_table[MAX_BIS_FUNCTION_SUPPORT];
60 /**
61  *  @b Description
62  *  @n
63  *      The function interfaces with the boot module and reads data as it 
64  *      is received by the boot module and executes the BIS command state
65  *      machine. 
66  *
67  *  @param[out]  entry_point
68  *      This is the entry point to which control is to be transferred on
69  *      success. This is read from the "payload" of TERMINATE command.
70  *
71  *  @retval
72  *      Success -   0
73  *  @retval
74  *      Error   -   <0
75  */
76 Int32 iblBootBis (BOOT_MODULE_FXN_TABLE *bootFxn, Uint32* entry_point)
77 {
78     Uint32      dataWord;
79     Uint32      loadAddress;
80     Uint32      sectionSize;
81     Uint32      commandFlags;
82     Uint16      argCnt;
83     Uint16      fn_num;
84     FN_ENTRY*   ptr_fn_entry;
85     Bool        done = FALSE;
87     /* Read the Magic word */
88     if ((*bootFxn->read)((Uint8 *)&dataWord, sizeof(Uint32)) < 0)    
89         return -1;
91     /* Check if we received the magic number. */
92     if (dataWord != BIS_MAGIC_NUMBER)
93         return -1;
95     /* If magic word was good, let's start parsing commands */
96     while (done == FALSE)
97     {
98         /* Read BIS command */
99         if ((*bootFxn->read)((Uint8 *)&dataWord, sizeof(Uint32)) < 0)
100             return -1;
102         /* Make sure command at least has right prefix */
103         if ((dataWord & BIS_CMD_MASK) != BIS_CMD_PREFIX )
104             return -1;
106         /* Process the command. */
107         switch (dataWord)
108         {
109             case BIS_CMD_SECTION_LOAD:
110             {
111                 /* Read the Section Load Header: Load Address */
112                 if ((*bootFxn->read)((Uint8 *)&loadAddress, sizeof(Uint32)) < 0)
113                     return -1;
115                 /* Read the Section Load Header: Section Size */
116                 if ((*bootFxn->read)((Uint8 *)&sectionSize, sizeof(Uint32)) < 0)
117                     return -1;
119                 /* Read the Section Load Header: Flags */
120                 if ((*bootFxn->read)((Uint8 *)&commandFlags, sizeof(Uint32)) < 0)
121                     return -1;
123 #if 0
124                 /* DEBUG Message: */
125                 mprintf ("*****************************\n");
126                 mprintf ("Section Load Command\n");
127                 mprintf ("    Load Address : 0x%x\n", loadAddress);
128                 mprintf ("    Section Size : %d\n",   sectionSize);
129                 mprintf ("    Command Flags: 0x%x\n", commandFlags);
130                 mprintf ("*****************************\n");
131 #endif
132                 /* Read the data from the Section Load: Payload section. */
133                 if ((*bootFxn->read)((Uint8 *)loadAddress, sectionSize) < 0)
134                     return -1;
136                 /* Section Load command has been processed. */
137                 break;
138             }
139             case BIS_CMD_FUNCTION_LOAD:
140             {
141                 /* Read the Function Load Header: Load Address */
142                 if ((*bootFxn->read)((Uint8 *)&loadAddress, sizeof(Uint32)) < 0)
143                     return -1;
145                 /* Read the Function Load Header: Section Size */
146                 if ((*bootFxn->read)((Uint8 *)&sectionSize, sizeof(Uint32)) < 0)
147                     return -1;
149                 /* Read the Function Load Header: Flags */
150                 if ((*bootFxn->read)((Uint8 *)&commandFlags, sizeof(Uint32)) < 0)
151                     return -1;
153                 /* Read the Function Load Header: Argument Count */
154                 if ((*bootFxn->read)((Uint8 *)&argCnt, sizeof(Uint16)) < 0)
155                     return -1;
157                 /* Read the Function Load Header: Function Number */
158                 if ((*bootFxn->read)((Uint8 *)&fn_num, sizeof(Uint16)) < 0)
159                     return -1;
161 #if 0
162                 /* DEBUG Message: */
163                 mprintf ("*****************************\n");
164                 mprintf ("Function Load Command\n");
165                 mprintf ("    Load Address : 0x%x\n", loadAddress);
166                 mprintf ("    Section Size : %d\n",   sectionSize);
167                 mprintf ("    Command Flags: 0x%x\n", commandFlags);
168                 mprintf ("    Argument Cnt : %d\n",   argCnt);
169                 mprintf ("    Function Num : %d\n",   fn_num);
170                 mprintf ("*****************************\n");
171 #endif
172                 /* Read the data from the Function Load: Payload section. */
173                 if ((*bootFxn->read)((Uint8 *)loadAddress, sectionSize) < 0)
174                     return -1;
176                 /* Validate the arguments: Ensure that the function number is in range */
177                 if (fn_num > MAX_BIS_FUNCTION_SUPPORT)
178                     return -1;
180                 /* Get access to the kernel function entry. */
181                 ptr_fn_entry = (FN_ENTRY *)&fn_table[fn_num];
183                 /* Validate the arguments: Ensure that the argument count is in range */
184                 if (argCnt > MAX_BIS_FUNCTION_SUPPORT)
185                     return -1;
187                 /* Validate the arguments: Make sure there is no function entry already loaded. 
188                  * This is a user error while generating the BIS images. If the function address
189                  * is non zero this implies that there is already a function loaded. */
190                 if (ptr_fn_entry->fn_address != 0)
191                     return -1;
193                 /* Populate the function entry. */
194                 ptr_fn_entry->fn_address = loadAddress;
195                 ptr_fn_entry->arg_cnt    = argCnt;
196                 ptr_fn_entry->fn_num     = fn_num;
197                 break;
198             }
199             case BIS_CMD_FUNCTION_EXEC:
200             {
201                 void   (*fnEntryPoint)(void);
203                 /* Read the Function Execute Header: Load Address */
204                 if ((*bootFxn->read)((Uint8 *)&argCnt, sizeof(Uint16)) < 0)
205                     return -1;
207                 /* Read the Function Execute Header: Function Number */
208                 if ((*bootFxn->read)((Uint8 *)&fn_num, sizeof(Uint16)) < 0)
209                     return -1;
211 #if 0
212                 /* DEBUG Message: */
213                 mprintf ("*****************************\n");
214                 mprintf ("Function Execute Command\n");
215                 mprintf ("    Argument Cnt : %d\n",   argCnt);
216                 mprintf ("    Function Num : %d\n",   fn_num);
217                 mprintf ("*****************************\n");
218 #endif
219                 /* Validate the arguments: Ensure that the function number is in range */
220                 if (fn_num > MAX_BIS_FUNCTION_SUPPORT)
221                     return -1;
223                 /* Get access to the kernel function entry. */
224                 ptr_fn_entry = (FN_ENTRY *)&fn_table[fn_num];
226                 /* Validate the arguments: Make sure that the function entry is already loaded. 
227                  * If not then we have a FATAL Error. */
228                 if (ptr_fn_entry->fn_address == 0)
229                     return -1;
231                 /* Call the kernel function entry. */
232                 fnEntryPoint = (void (*)(void))ptr_fn_entry->fn_address;
233                 fnEntryPoint();
234                 break;
235             }
236             case BIS_CMD_MEMORY_ACCESS:
237             {
238                 Uint16  op_type;
239                 Uint32  mask;
240                 Uint32  sleep_cnt;
242                 /* Read the Memory Access Header: Address */
243                 if ((*bootFxn->read)((Uint8 *)&loadAddress, sizeof(Uint32)) < 0)
244                     return -1;
246                 /* Read the Memory Access Header: Word Count */
247                 if ((*bootFxn->read)((Uint8 *)&argCnt, sizeof(Uint16)) < 0)
248                     return -1;
250                 /* Read the Memory Access Header: Op Type */
251                 if ((*bootFxn->read)((Uint8 *)&op_type, sizeof(Uint16)) < 0)
252                     return -1;
254                 /* Read the Memory Access Header: Mask */
255                 if ((*bootFxn->read)((Uint8 *)&mask, sizeof(Uint32)) < 0)
256                     return -1;
258                 /* Read the Memory Access Header: Sleep Count */
259                 if ((*bootFxn->read)((Uint8 *)&sleep_cnt, sizeof(Uint32)) < 0)
260                     return -1;
262                 /* Read the Memory Access Header: Data Payload */
263                 if ((*bootFxn->read)((Uint8 *)&dataWord, sizeof(Uint32)) < 0)
264                     return -1;
266 #if 0
267                 /* DEBUG Message: */
268                 mprintf ("*****************************\n");
269                 mprintf ("Memory Access Command\n");
270                 mprintf ("    Address      : 0x%x\n", loadAddress);
271                 mprintf ("    Word Count   : %d\n", argCnt);
272                 mprintf ("    Op Type      : %d\n", op_type);
273                 mprintf ("    Mask         : %d\n", mask);
274                 mprintf ("    Sleep Count  : %d\n", sleep_cnt);
275                 mprintf ("    Data Payload : %d\n", dataWord);
276                 mprintf ("*****************************\n");
277 #endif
278                 break;
279             }
280             case BIS_CMD_SECTION_TERMINATE:
281             {
282                 /* Read the Terminate Command Payload  */
283                 if ((*bootFxn->read)((Uint8 *)&dataWord, sizeof(Uint32)) < 0)
284                     return -1;
286                 /* DEBUG Message: */
287                 mprintf ("*****************************\n");
288                 mprintf ("Terminate Command\n");
289                 mprintf ("    Entry Point : 0x%x\n", dataWord);
290                 mprintf ("*****************************\n");
292                 /* We are done with the BIS Image parsing. */
293                 done         = TRUE;
294                 *entry_point = dataWord;
295                 break;
296             }
297             default:
298             {
299                 /* BIS Command is not supported. */
300                 mprintf ("Error: BIS Command 0x%x not supported\n", dataWord);
301                 return -1;
302             }
303         }
304     }
306     /* Control comes here indicates that the parsing was successful. */
307     return 0;