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>
30 /**
31 * @brief The ibl table is declared.
32 *
33 * @details
34 * The ibl table is declared uninitialized by this ibl program. An external
35 * initialization can be performed if the default operation of the ibl is
36 * not desired.
37 */
38 #pragma DATA_SECTION(ibl, ".ibl_config_table")
39 ibl_t ibl;
42 /**
43 * @brief The ibl status table is declared.
44 *
45 * @details
46 * The ibl status table is declared. It is initialized at run time
47 * in function main.
48 */
49 #pragma DATA_SECTION(iblStatus, ".ibl_status_table")
50 iblStatus_t iblStatus;
53 /* Eat printfs */
54 void mprintf(char *x, ...) { }
56 /**
57 * @b Description
58 * @n
59 *
60 * Returns TRUE if the input priority is valid and enabled
61 */
62 BOOL iblPriorityIsValid (uint32 priority)
63 {
64 if ( (priority >= ibl_HIGHEST_PRIORITY) &&
65 (priority <= ibl_LOWEST_PRIORITY) )
67 return (TRUE);
70 return (FALSE);
72 }
74 /**
75 * @b Description
76 * @n
77 *
78 * Returns TRUE if the mac address is 0
79 */
80 BOOL iblMacAddrIsZero (uint8 *maddr)
81 {
82 int32 i;
84 for (i = 0; i < 6; i++)
85 if (maddr[i] != 0)
86 return (FALSE);
88 return (TRUE);
90 }
93 /**
94 * @b Description
95 * @n
96 *
97 * The main function kicks off the boot. If it does not find the magic value in the
98 * configuration array then default values are loaded. This default load
99 * is done only once at the start of boot.
100 *
101 * @retval
102 * None
103 */
104 void main (void)
105 {
106 int32 i, j;
108 /* Initialize the status structure */
109 memset (&iblStatus, 0, sizeof(iblStatus_t));
110 iblStatus.iblMagic = ibl_MAGIC_VALUE;
112 /* Initialize the system timer (software tracking of the hardware timer state */
113 timer_init ();
115 #if 0
116 /* If there is no magic value in the ibl configuration structure then a default
117 * table is used. */
118 if (ibl.iblMagic != ibl_MAGIC_VALUE) {
119 deviceLoadDefaultIblTable();
120 iblStatus.noMagic = 1;
121 ibl.iblMagic = ibl_MAGIC_VALUE;
122 }
123 #endif
126 #if 0 /* debugging c6472 using ccs download. Remove for i2c config download */
128 /* Load the default configuration table from the i2c. The actual speed of the device
129 * isn't really known here, since it is part of the table, so a compile time
130 * value is used (the pll may have been configured during the initial load) */
131 hwI2Cinit (IBL_I2C_DEV_FREQ_MHZ, /* The CPU frequency during I2C data load */
132 DEVICE_I2C_MODULE_DIVISOR, /* The divide down of CPU that drives the i2c */
133 IBL_I2C_CLK_FREQ_KHZ, /* The I2C data rate used during table load */
134 IBL_I2C_OWN_ADDR); /* The address used by this device on the i2c bus */
136 if (hwI2cMasterRead (IBL_I2C_CFG_TABLE_DATA_ADDR, /* The address on the eeprom of the table */
137 sizeof(ibl_t), /* The number of bytes to read */
138 (UINT8 *)&ibl, /* Where to store the bytes */
139 IBL_I2C_CFG_EEPROM_BUS_ADDR, /* The bus address of the eeprom */
140 IBL_I2C_CFG_ADDR_DELAY) /* The delay between sending the address and reading data */
142 != I2C_RET_OK) {
144 /* There is no recovery if the load of the configuration table failed */
145 iblStatus.tableLoadFail = 0x11111111;
146 for (;;);
148 }
150 #endif
152 /* Load default mac addresses for ethernet boot if requested */
153 for (i = 0; i < ibl_N_ETH_PORTS; i++) {
155 if ( (iblPriorityIsValid (ibl.ethConfig[i].ethPriority) ) &&
156 (iblMacAddrIsZero (ibl.ethConfig[i].ethInfo.hwAddress) ) )
158 deviceLoadDefaultEthAddress (ibl.ethConfig[i].ethInfo.hwAddress);
160 }
163 /* Pll configuration is device specific */
164 devicePllConfig ();
166 /* DDR configuration is device specific */
167 deviceDdrConfig ();
169 /* Try booting forever */
170 for (;;) {
172 /* Start looping through the boot modes to find the one with the lowest priority
173 * value, and try to boot it */
174 for (i = ibl_HIGHEST_PRIORITY; i < ibl_LOWEST_PRIORITY; i++) {
176 for (j = 0; j < ibl_N_ETH_PORTS; j++) {
177 if (ibl.ethConfig[j].ethPriority == i)
178 iblEthBoot (j);
179 }
181 if (ibl.nandConfig.nandPriority == i)
182 iblNandBoot ();
184 iblStatus.heartBeat += 1;
185 }
187 }
190 } /* main */
194 /**
195 * @b Description
196 * @n
197 *
198 * The ibl boot function links a device to a data format. The data format
199 * parser pulls data from the boot device
200 *
201 * @param[in] bootFxn The structure containing the boot device functions
202 *
203 * @retval
204 * None
205 */
206 Uint32 iblBoot (BOOT_MODULE_FXN_TABLE *bootFxn, Int32 dataFormat, void *formatParams)
207 {
208 Uint32 entry = 0;
210 union {
212 Uint8 dataBuf[4]; /* Place holder */
213 Uint32 bisValue;
214 Uint16 coffVer;
216 } fid;
219 /* Determine the data format if required */
220 if (dataFormat == ibl_BOOT_FORMAT_AUTO) {
222 (*bootFxn->peek)((Uint8 *)&fid, sizeof(fid));
224 /* BIS */
225 if (fid.bisValue == BIS_MAGIC_NUMBER)
226 dataFormat = ibl_BOOT_FORMAT_BIS;
228 if (iblIsCoff (fid.coffVer))
229 dataFormat = ibl_BOOT_FORMAT_COFF;
231 if (iblIsElf (fid.dataBuf))
232 dataFormat = ibl_BOOT_FORMAT_ELF;
234 else {
235 iblStatus.autoDetectFailCnt += 1;
236 return (0);
237 }
238 }
241 /* Invoke the parser */
242 switch (dataFormat) {
244 case ibl_BOOT_FORMAT_BIS:
245 iblBootBis (bootFxn, &entry);
246 break;
248 case ibl_BOOT_FORMAT_COFF:
249 iblBootCoff (bootFxn, &entry);
250 break;
252 case ibl_BOOT_FORMAT_BTBL:
253 iblBootBtbl (bootFxn, &entry);
254 break;
256 case ibl_BOOT_FORMAT_BBLOB:
257 iblBootBlob (bootFxn, &entry, formatParams);
258 break;
260 case ibl_BOOT_FORMAT_ELF:
261 iblBootElf (bootFxn, &entry);
262 break;
264 default:
265 iblStatus.invalidDataFormatSpec += 1;
266 break;
268 }
271 return (entry);
273 }