08e02d789c19196ff2c4255d72c0dac4d1e1546e
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;
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 *)§ionSize, 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 *)§ionSize, 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;
308 }