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 iblEthBoot (j);
130 }
131 #endif
133 #ifndef EXCLUDE_NAND
134 if (ibl.nandConfig.nandPriority == i)
135 iblNandBoot ();
136 #endif
138 iblStatus.heartBeat += 1;
139 }
141 }
144 } /* main */
148 /**
149 * @b Description
150 * @n
151 *
152 * The ibl boot function links a device to a data format. The data format
153 * parser pulls data from the boot device
154 *
155 * @param[in] bootFxn The structure containing the boot device functions
156 *
157 * @retval
158 * None
159 */
160 Uint32 iblBoot (BOOT_MODULE_FXN_TABLE *bootFxn, Int32 dataFormat, void *formatParams)
161 {
162 Uint32 entry = 0;
164 union {
166 Uint8 dataBuf[4]; /* Place holder */
167 Uint32 bisValue;
168 Uint16 coffVer;
170 } fid;
173 /* Determine the data format if required */
174 if (dataFormat == ibl_BOOT_FORMAT_AUTO) {
176 (*bootFxn->peek)((Uint8 *)&fid, sizeof(fid));
178 /* BIS */
179 #ifndef EXCLUDE_BIS
180 if (fid.bisValue == BIS_MAGIC_NUMBER)
181 dataFormat = ibl_BOOT_FORMAT_BIS;
182 #endif
184 #ifndef EXCLUDE_COFF
185 if (iblIsCoff (fid.coffVer))
186 dataFormat = ibl_BOOT_FORMAT_COFF;
187 #endif
189 #ifndef EXCLUDE_ELF
190 if (iblIsElf (fid.dataBuf))
191 dataFormat = ibl_BOOT_FORMAT_ELF;
192 #endif
194 else {
195 iblStatus.autoDetectFailCnt += 1;
196 return (0);
197 }
198 }
201 /* Invoke the parser */
202 switch (dataFormat) {
204 #ifndef EXCLUDE_BIS
205 case ibl_BOOT_FORMAT_BIS:
206 iblBootBis (bootFxn, &entry);
207 break;
208 #endif
210 #ifndef EXCLUDE_COFF
211 case ibl_BOOT_FORMAT_COFF:
212 iblBootCoff (bootFxn, &entry);
213 break;
214 #endif
216 case ibl_BOOT_FORMAT_BTBL:
217 iblBootBtbl (bootFxn, &entry);
218 break;
220 #ifndef EXCLUDE_BLOB
221 case ibl_BOOT_FORMAT_BBLOB:
222 iblBootBlob (bootFxn, &entry, formatParams);
223 break;
224 #endif
226 #ifndef EXCLUDE_ELF
227 case ibl_BOOT_FORMAT_ELF:
228 iblBootElf (bootFxn, &entry);
229 break;
230 #endif
232 default:
233 iblStatus.invalidDataFormatSpec += 1;
234 break;
236 }
239 return (entry);
241 }