1 /*****************************************************************************************
2 * FILE PURPOSE: Perform the top level boot
3 *****************************************************************************************
4 * FILE NAME: iblmain.c
5 *
6 * DESCRIPTION: The top level boot examines the boot configuration and performs boot
7 * based on this configuration
8 *
9 * @file iblmain.c
10 *
11 * @brief
12 * This file is used to launch a boot based on the boot configuration structure
13 *
14 *****************************************************************************************/
15 #include "ibl.h"
16 #include "iblloc.h"
17 #include "iblcfg.h"
18 #include "device.h"
19 #include "ethboot.h"
20 #include "bis.h"
21 #include "coffwrap.h"
22 #include "iblbtbl.h"
23 #include "iblblob.h"
24 #include "timer.h"
25 #include "i2c.h"
26 #include "ibl_elf.h"
27 #include <string.h>
29 /**
30 * @brief
31 * Data structures shared between the 1st and 2nd stage IBL load
32 * are declared in a single header file, included in both stages
33 */
34 #include "iblStage.h"
38 /* Eat printfs */
39 void mprintf(char *x, ...) { }
41 /**
42 * @b Description
43 * @n
44 *
45 * Returns TRUE if the input priority is valid and enabled
46 */
47 BOOL iblPriorityIsValid (uint32 priority)
48 {
49 if ( (priority >= ibl_HIGHEST_PRIORITY) &&
50 (priority <= ibl_LOWEST_PRIORITY) )
52 return (TRUE);
55 return (FALSE);
57 }
59 /**
60 * @b Description
61 * @n
62 *
63 * Returns TRUE if the mac address is 0
64 */
65 BOOL iblMacAddrIsZero (uint8 *maddr)
66 {
67 int32 i;
69 for (i = 0; i < 6; i++)
70 if (maddr[i] != 0)
71 return (FALSE);
73 return (TRUE);
75 }
78 /**
79 * @b Description
80 * @n
81 *
82 * The main function kicks off the boot. If it does not find the magic value in the
83 * configuration array then default values are loaded. This default load
84 * is done only once at the start of boot.
85 *
86 * @retval
87 * None
88 */
89 void main (void)
90 {
91 int32 i, j;
93 /* Initialize the status structure */
94 iblMemset (&iblStatus, 0, sizeof(iblStatus_t));
95 iblStatus.iblMagic = ibl_MAGIC_VALUE;
98 /* Power up the timer */
99 devicePowerPeriph (TARGET_PWR_TIMER_0);
101 /* Initialize the system timer (software tracking of the hardware timer state) */
102 timer_init ();
104 /* Load default mac addresses for ethernet boot if requested */
105 for (i = 0; i < ibl_N_ETH_PORTS; i++) {
107 if ( (iblPriorityIsValid (ibl.ethConfig[i].ethPriority) ) &&
108 (iblMacAddrIsZero (ibl.ethConfig[i].ethInfo.hwAddress) ) )
110 deviceLoadDefaultEthAddress (ibl.ethConfig[i].ethInfo.hwAddress);
112 }
115 /* DDR configuration is device specific */
116 deviceDdrConfig ();
118 /* Try booting forever */
119 for (;;) {
121 /* Start looping through the boot modes to find the one with the lowest priority
122 * value, and try to boot it. If a boot mode is not supported the function
123 * statement is simply defined to be a void statement */
124 for (i = ibl_HIGHEST_PRIORITY; i < ibl_LOWEST_PRIORITY; i++) {
126 #ifndef EXCLUDE_ETH
127 for (j = 0; j < ibl_N_ETH_PORTS; j++) {
128 if (ibl.ethConfig[j].ethPriority == i) {
129 iblStatus.activePeriph = ibl_ACTIVE_PERIPH_ETH;
130 memcpy (&iblStatus.ethParams, &ibl.ethConfig[j].ethInfo, sizeof (iblEthBootInfo_t));
131 iblEthBoot (j);
132 }
133 }
134 #endif
136 #ifndef EXCLUDE_NAND
137 if (ibl.nandConfig.nandPriority == i) {
138 iblStatus.activePeriph = ibl_ACTIVE_PERIPH_NAND;
139 iblNandBoot ();
140 }
141 #endif
143 iblStatus.heartBeat += 1;
144 }
146 }
149 } /* main */
153 /**
154 * @b Description
155 * @n
156 *
157 * The ibl boot function links a device to a data format. The data format
158 * parser pulls data from the boot device
159 *
160 * @param[in] bootFxn The structure containing the boot device functions
161 *
162 * @retval
163 * None
164 */
165 Uint32 iblBoot (BOOT_MODULE_FXN_TABLE *bootFxn, Int32 dataFormat, void *formatParams)
166 {
167 Uint32 entry = 0;
168 Uint32 value32;
169 Uint8 dataBuf[4];
170 Uint16 value16;
172 /* Determine the data format if required */
173 if (dataFormat == ibl_BOOT_FORMAT_AUTO) {
175 (*bootFxn->peek)(dataBuf, sizeof(dataBuf));
176 value32 = (dataBuf[0] << 24) | (dataBuf[1] << 16) | (dataBuf[2] << 8) | (dataBuf[3] << 0);
177 value16 = (dataBuf[0] << 8) | (dataBuf[1] << 0);
179 /* BIS */
180 #ifndef EXCLUDE_BIS
181 if (value32 == BIS_MAGIC_NUMBER)
182 dataFormat = ibl_BOOT_FORMAT_BIS;
183 #endif
185 #ifndef EXCLUDE_COFF
186 if (iblIsCoff (value16))
187 dataFormat = ibl_BOOT_FORMAT_COFF;
188 #endif
190 #ifndef EXCLUDE_ELF
191 if (iblIsElf (dataBuf))
192 dataFormat = ibl_BOOT_FORMAT_ELF;
193 #endif
195 if (dataFormat == ibl_BOOT_FORMAT_AUTO) {
196 iblStatus.autoDetectFailCnt += 1;
197 return (0);
198 }
199 }
202 iblStatus.activeFormat = dataFormat;
205 /* Invoke the parser */
206 switch (dataFormat) {
208 #ifndef EXCLUDE_BIS
209 case ibl_BOOT_FORMAT_BIS:
210 iblBootBis (bootFxn, &entry);
211 break;
212 #endif
214 #ifndef EXCLUDE_COFF
215 case ibl_BOOT_FORMAT_COFF:
216 iblBootCoff (bootFxn, &entry);
217 break;
218 #endif
220 case ibl_BOOT_FORMAT_BTBL:
221 iblBootBtbl (bootFxn, &entry);
222 break;
224 #ifndef EXCLUDE_BLOB
225 case ibl_BOOT_FORMAT_BBLOB:
226 iblBootBlob (bootFxn, &entry, formatParams);
227 break;
228 #endif
230 #ifndef EXCLUDE_ELF
231 case ibl_BOOT_FORMAT_ELF:
232 iblBootElf (bootFxn, &entry);
233 break;
234 #endif
236 default:
237 iblStatus.invalidDataFormatSpec += 1;
238 break;
240 }
243 return (entry);
245 }