.gitignore: update to ignore all make created files
[keystone-rtos/ibl.git] / src / interp / bis / bis.c
1 /*
2  *
3  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
4  * 
5  * 
6  *  Redistribution and use in source and binary forms, with or without 
7  *  modification, are permitted provided that the following conditions 
8  *  are met:
9  *
10  *    Redistributions of source code must retain the above copyright 
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  *    Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the 
15  *    documentation and/or other materials provided with the   
16  *    distribution.
17  *
18  *    Neither the name of Texas Instruments Incorporated nor the names of
19  *    its contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
23  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
24  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
26  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
27  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34 */
38 /******************************************************************************
39  * FILE PURPOSE: Boot from a BIS formatted input
40  ******************************************************************************
41  * FILE NAME: bis.c
42  *
43  * DESCRIPTION: A BIS formatted data file is parsed and loaded
44  *
45  *  @file bis.c
46  *
47  *  @brief
48  *      This file is used to load a BIS formatted data file
49  *
50  ******************************************************************************/
51 #include "types.h"
52 #include "ibl.h"
53 #include "iblloc.h"
54 #include "bis.h"
55 #include "iblcfg.h"
57 /**********************************************************************
58  ************************** Local Structures **************************
59  **********************************************************************/
61 /**
62  * @brief 
63  *  The structure describes the Function Entry. 
64  *
65  * @details
66  *  The entry stores information about function which can be executed
67  *  while executing the BIS Command State machine. These entries are
68  *  loaded and executed through the BIS Function Load & Execute commands.
69  */
70 typedef struct FN_ENTRY
71 {
72     /**
73      * @brief   This is the function number which is unique for all
74      * functions.
75      */
76     Uint16       fn_num;
77     
78     /**
79      * @brief   This is the number of arguments the function takes.
80      */
81     Uint16       arg_cnt;
83     /**
84      * @brief   This is the address where the function is loaded in
85      * memory via the function load command.
86      */
87     Uint32       fn_address;
88 }FN_ENTRY;
90 /**
91  * @brief   Global database all functions which can be loaded and executed
92  * via the BIS Function Load/Execute commands.
93 */
94 FN_ENTRY     fn_table[MAX_BIS_FUNCTION_SUPPORT];
97 /**
98  *  @b Description
99  *  @n
100  *      The function interfaces with the boot module and reads data as it 
101  *      is received by the boot module and executes the BIS command state
102  *      machine. 
103  *
104  *  @param[out]  entry_point
105  *      This is the entry point to which control is to be transferred on
106  *      success. This is read from the "payload" of TERMINATE command.
107  *
108  *  @retval
109  *      Success -   0
110  *  @retval
111  *      Error   -   <0
112  */
113 Int32 iblBootBis (BOOT_MODULE_FXN_TABLE *bootFxn, Uint32* entry_point)
115     Uint32      dataWord;
116     Uint32      loadAddress;
117     Uint32      sectionSize;
118     Uint32      commandFlags;
119     Uint16      argCnt;
120     Uint16      fn_num;
121     FN_ENTRY*   ptr_fn_entry;
122     Bool        done = FALSE;
124     /* Read the Magic word */
125     if ((*bootFxn->read)((Uint8 *)&dataWord, sizeof(Uint32)) < 0)    
126         return -1;
128     /* Check if we received the magic number. */
129     if (dataWord != BIS_MAGIC_NUMBER)
130         return -1;
132     /* If magic word was good, let's start parsing commands */
133     while (done == FALSE)
134     {
135         /* Read BIS command */
136         if ((*bootFxn->read)((Uint8 *)&dataWord, sizeof(Uint32)) < 0)
137             return -1;
139         /* Make sure command at least has right prefix */
140         if ((dataWord & BIS_CMD_MASK) != BIS_CMD_PREFIX )
141             return -1;
143         /* Process the command. */
144         switch (dataWord)
145         {
146             case BIS_CMD_SECTION_LOAD:
147             {
148                 /* Read the Section Load Header: Load Address */
149                 if ((*bootFxn->read)((Uint8 *)&loadAddress, sizeof(Uint32)) < 0)
150                     return -1;
152                 /* Read the Section Load Header: Section Size */
153                 if ((*bootFxn->read)((Uint8 *)&sectionSize, sizeof(Uint32)) < 0)
154                     return -1;
156                 /* Read the Section Load Header: Flags */
157                 if ((*bootFxn->read)((Uint8 *)&commandFlags, sizeof(Uint32)) < 0)
158                     return -1;
160 #if 0
161                 /* DEBUG Message: */
162                 mprintf ("*****************************\n");
163                 mprintf ("Section Load Command\n");
164                 mprintf ("    Load Address : 0x%x\n", loadAddress);
165                 mprintf ("    Section Size : %d\n",   sectionSize);
166                 mprintf ("    Command Flags: 0x%x\n", commandFlags);
167                 mprintf ("*****************************\n");
168 #endif
169                 /* Read the data from the Section Load: Payload section. */
170                 if ((*bootFxn->read)((Uint8 *)loadAddress, sectionSize) < 0)
171                     return -1;
173                 /* Section Load command has been processed. */
174                 break;
175             }
176             case BIS_CMD_FUNCTION_LOAD:
177             {
178                 /* Read the Function Load Header: Load Address */
179                 if ((*bootFxn->read)((Uint8 *)&loadAddress, sizeof(Uint32)) < 0)
180                     return -1;
182                 /* Read the Function Load Header: Section Size */
183                 if ((*bootFxn->read)((Uint8 *)&sectionSize, sizeof(Uint32)) < 0)
184                     return -1;
186                 /* Read the Function Load Header: Flags */
187                 if ((*bootFxn->read)((Uint8 *)&commandFlags, sizeof(Uint32)) < 0)
188                     return -1;
190                 /* Read the Function Load Header: Argument Count */
191                 if ((*bootFxn->read)((Uint8 *)&argCnt, sizeof(Uint16)) < 0)
192                     return -1;
194                 /* Read the Function Load Header: Function Number */
195                 if ((*bootFxn->read)((Uint8 *)&fn_num, sizeof(Uint16)) < 0)
196                     return -1;
198 #if 0
199                 /* DEBUG Message: */
200                 mprintf ("*****************************\n");
201                 mprintf ("Function Load Command\n");
202                 mprintf ("    Load Address : 0x%x\n", loadAddress);
203                 mprintf ("    Section Size : %d\n",   sectionSize);
204                 mprintf ("    Command Flags: 0x%x\n", commandFlags);
205                 mprintf ("    Argument Cnt : %d\n",   argCnt);
206                 mprintf ("    Function Num : %d\n",   fn_num);
207                 mprintf ("*****************************\n");
208 #endif
209                 /* Read the data from the Function Load: Payload section. */
210                 if ((*bootFxn->read)((Uint8 *)loadAddress, sectionSize) < 0)
211                     return -1;
213                 /* Validate the arguments: Ensure that the function number is in range */
214                 if (fn_num > MAX_BIS_FUNCTION_SUPPORT)
215                     return -1;
217                 /* Get access to the kernel function entry. */
218                 ptr_fn_entry = (FN_ENTRY *)&fn_table[fn_num];
220                 /* Validate the arguments: Ensure that the argument count is in range */
221                 if (argCnt > MAX_BIS_FUNCTION_SUPPORT)
222                     return -1;
224                 /* Validate the arguments: Make sure there is no function entry already loaded. 
225                  * This is a user error while generating the BIS images. If the function address
226                  * is non zero this implies that there is already a function loaded. */
227                 if (ptr_fn_entry->fn_address != 0)
228                     return -1;
230                 /* Populate the function entry. */
231                 ptr_fn_entry->fn_address = loadAddress;
232                 ptr_fn_entry->arg_cnt    = argCnt;
233                 ptr_fn_entry->fn_num     = fn_num;
234                 break;
235             }
236             case BIS_CMD_FUNCTION_EXEC:
237             {
238                 void   (*fnEntryPoint)(void);
240                 /* Read the Function Execute Header: Load Address */
241                 if ((*bootFxn->read)((Uint8 *)&argCnt, sizeof(Uint16)) < 0)
242                     return -1;
244                 /* Read the Function Execute Header: Function Number */
245                 if ((*bootFxn->read)((Uint8 *)&fn_num, sizeof(Uint16)) < 0)
246                     return -1;
248 #if 0
249                 /* DEBUG Message: */
250                 mprintf ("*****************************\n");
251                 mprintf ("Function Execute Command\n");
252                 mprintf ("    Argument Cnt : %d\n",   argCnt);
253                 mprintf ("    Function Num : %d\n",   fn_num);
254                 mprintf ("*****************************\n");
255 #endif
256                 /* Validate the arguments: Ensure that the function number is in range */
257                 if (fn_num > MAX_BIS_FUNCTION_SUPPORT)
258                     return -1;
260                 /* Get access to the kernel function entry. */
261                 ptr_fn_entry = (FN_ENTRY *)&fn_table[fn_num];
263                 /* Validate the arguments: Make sure that the function entry is already loaded. 
264                  * If not then we have a FATAL Error. */
265                 if (ptr_fn_entry->fn_address == 0)
266                     return -1;
268                 /* Call the kernel function entry. */
269                 fnEntryPoint = (void (*)(void))ptr_fn_entry->fn_address;
270                 fnEntryPoint();
271                 break;
272             }
273             case BIS_CMD_MEMORY_ACCESS:
274             {
275                 Uint16  op_type;
276                 Uint32  mask;
277                 Uint32  sleep_cnt;
279                 /* Read the Memory Access Header: Address */
280                 if ((*bootFxn->read)((Uint8 *)&loadAddress, sizeof(Uint32)) < 0)
281                     return -1;
283                 /* Read the Memory Access Header: Word Count */
284                 if ((*bootFxn->read)((Uint8 *)&argCnt, sizeof(Uint16)) < 0)
285                     return -1;
287                 /* Read the Memory Access Header: Op Type */
288                 if ((*bootFxn->read)((Uint8 *)&op_type, sizeof(Uint16)) < 0)
289                     return -1;
291                 /* Read the Memory Access Header: Mask */
292                 if ((*bootFxn->read)((Uint8 *)&mask, sizeof(Uint32)) < 0)
293                     return -1;
295                 /* Read the Memory Access Header: Sleep Count */
296                 if ((*bootFxn->read)((Uint8 *)&sleep_cnt, sizeof(Uint32)) < 0)
297                     return -1;
299                 /* Read the Memory Access Header: Data Payload */
300                 if ((*bootFxn->read)((Uint8 *)&dataWord, sizeof(Uint32)) < 0)
301                     return -1;
303 #if 0
304                 /* DEBUG Message: */
305                 mprintf ("*****************************\n");
306                 mprintf ("Memory Access Command\n");
307                 mprintf ("    Address      : 0x%x\n", loadAddress);
308                 mprintf ("    Word Count   : %d\n", argCnt);
309                 mprintf ("    Op Type      : %d\n", op_type);
310                 mprintf ("    Mask         : %d\n", mask);
311                 mprintf ("    Sleep Count  : %d\n", sleep_cnt);
312                 mprintf ("    Data Payload : %d\n", dataWord);
313                 mprintf ("*****************************\n");
314 #endif
315                 break;
316             }
317             case BIS_CMD_SECTION_TERMINATE:
318             {
319                 /* Read the Terminate Command Payload  */
320                 if ((*bootFxn->read)((Uint8 *)&dataWord, sizeof(Uint32)) < 0)
321                     return -1;
323                 /* DEBUG Message: */
324                 mprintf ("*****************************\n");
325                 mprintf ("Terminate Command\n");
326                 mprintf ("    Entry Point : 0x%x\n", dataWord);
327                 mprintf ("*****************************\n");
329                 /* We are done with the BIS Image parsing. */
330                 done         = TRUE;
331                 *entry_point = dataWord;
332                 break;
333             }
334             default:
335             {
336                 /* BIS Command is not supported. */
337                 mprintf ("Error: BIS Command 0x%x not supported\n", dataWord);
338                 return -1;
339             }
340         }
341     }
343     /* Control comes here indicates that the parsing was successful. */
344     return 0;