Initial bug fixes for Nyquist IBL
[keystone-rtos/ibl.git] / src / main / iblmain.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: Perform the top level boot
40  *****************************************************************************************
41  * FILE NAME: iblmain.c
42  *
43  * DESCRIPTION: The top level boot examines the boot configuration and performs boot
44  *                              based on this configuration
45  *
46  * @file iblmain.c
47  *
48  * @brief
49  *   This file is used to launch a boot based on the boot configuration structure
50  *
51  *****************************************************************************************/
52 #include "ibl.h"
53 #include "iblloc.h"
54 #include "iblcfg.h"
55 #include "device.h"
56 #include "ethboot.h"
57 #include "nandboot.h"
58 #include "bis.h"
59 #include "coffwrap.h"
60 #include "iblbtbl.h"
61 #include "iblblob.h"
62 #include "timer.h"
63 #include "i2c.h"
64 #include "ibl_elf.h"
65 #include <string.h>
67 /**
68  *  @brief
69  *      Data structures shared between the 1st and 2nd stage IBL load
70  *      are declared in a single header file, included in both stages
71  */
72 #include "iblStage.h"
76 /* Eat printfs */
77 void mprintf(char *x, ...) { }
79 /**
80  * @b Description
81  * @n
82  *
83  *  Returns TRUE if the input priority is valid and enabled
84  */
85 BOOL iblPriorityIsValid (uint32 priority)
86 {
87     if ( (priority >= ibl_HIGHEST_PRIORITY)  &&
88          (priority <= ibl_LOWEST_PRIORITY)   )
90         return (TRUE);
93     return (FALSE);
95 }
97 /**
98  * @b Description
99  * @n
100  *
101  *  Returns TRUE if the mac address is 0
102  */
103 BOOL iblMacAddrIsZero (uint8 *maddr)
105     int32 i;
107     for (i = 0; i < 6; i++)
108         if (maddr[i] != 0)
109             return (FALSE);
111     return (TRUE);
116 /**
117  * @b Description
118  * @n
119  *
120  * The main function kicks off the boot. If it does not find the magic value in the
121  *     configuration array then default values are loaded. This default load
122  *     is done only once at the start of boot. 
123  *
124  * @retval
125  *  None
126  */
127 void main (void)
129     int32 i, j;
131     /* Initialize the status structure */
132     iblMemset (&iblStatus, 0, sizeof(iblStatus_t));
133     iblStatus.iblMagic   = ibl_MAGIC_VALUE;
134     iblStatus.iblVersion = ibl_VERSION;
137     /* Power up the timer */
138     devicePowerPeriph (TARGET_PWR_TIMER_0);
140     /* Initialize the system timer (software tracking of the hardware timer state) */
141     timer_init ();
143     /* Load default mac addresses for ethernet boot if requested */
144     for (i = 0; i < ibl_N_ETH_PORTS; i++)  {
146         if ( (iblPriorityIsValid (ibl.ethConfig[i].ethPriority)       )   &&
147              (iblMacAddrIsZero   (ibl.ethConfig[i].ethInfo.hwAddress) )   )
149             deviceLoadDefaultEthAddress (ibl.ethConfig[i].ethInfo.hwAddress);
151     }
154     /* DDR configuration is device specific */
155     deviceDdrConfig ();
157     /* Try booting forever */
158     for (;;)  {
160         /* Start looping through the boot modes to find the one with the lowest priority
161          * value, and try to boot it. If a boot mode is not supported the function
162          * statement is simply defined to be a void statement */
163         for (i = ibl_HIGHEST_PRIORITY; i < ibl_LOWEST_PRIORITY; i++)  {
165 #ifndef EXCLUDE_ETH
166             for (j = 0; j < ibl_N_ETH_PORTS; j++)  {
167                 if (ibl.ethConfig[j].ethPriority == i)  {
168                     iblStatus.activePeriph = ibl_ACTIVE_PERIPH_ETH;
169                     memcpy (&iblStatus.ethParams, &ibl.ethConfig[j].ethInfo, sizeof (iblEthBootInfo_t));
170                     iblEthBoot (j);
171                 }
172             }
173 #endif
175 #ifndef EXCLUDE_NAND
176             if (ibl.nandConfig.nandPriority == i)  {
177                 iblStatus.activePeriph = ibl_ACTIVE_PERIPH_NAND;
178                 iblNandBoot ();
179             }
180 #endif
182             iblStatus.heartBeat += 1;
183         }
185     }
188 } /* main */
191     
192 /**
193  * @b Description
194  * @n
195  * 
196  * The ibl boot function links a device to a data format. The data format
197  * parser pulls data from the boot device
198  *
199  * @param[in] bootFxn      The structure containing the boot device functions
200  *
201  * @retval
202  *  None
203  */
204 Uint32 iblBoot (BOOT_MODULE_FXN_TABLE *bootFxn, Int32 dataFormat, void *formatParams)
205
206     Uint32  entry = 0;
207     Uint32  value32;
208     Uint8   dataBuf[4];   
209     Uint16  value16;
211     /* Determine the data format if required */
212     if (dataFormat == ibl_BOOT_FORMAT_AUTO)  {
214         (*bootFxn->peek)(dataBuf, sizeof(dataBuf));
215         value32 = (dataBuf[0] << 24) | (dataBuf[1] << 16) | (dataBuf[2] << 8) | (dataBuf[3] << 0);
216         value16 = (dataBuf[0] <<  8) | (dataBuf[1] <<  0);
218         /* BIS */
219 #ifndef EXCLUDE_BIS
220         if (value32 == BIS_MAGIC_NUMBER)
221             dataFormat = ibl_BOOT_FORMAT_BIS;
222 #endif
224 #ifndef EXCLUDE_COFF
225         if (iblIsCoff (value16))
226             dataFormat = ibl_BOOT_FORMAT_COFF;
227 #endif
229 #ifndef EXCLUDE_ELF
230         if (iblIsElf (dataBuf))
231             dataFormat = ibl_BOOT_FORMAT_ELF;
232 #endif
234         if (dataFormat == ibl_BOOT_FORMAT_AUTO)  {
235             iblStatus.autoDetectFailCnt += 1;
236             return (0);
237         }
238     }        
241     iblStatus.activeFormat = dataFormat;
244     /* Invoke the parser */
245     switch (dataFormat)  {
247 #ifndef EXCLUDE_BIS
248         case ibl_BOOT_FORMAT_BIS:
249             iblBootBis (bootFxn, &entry);
250             break;
251 #endif
253 #ifndef EXCLUDE_COFF
254         case ibl_BOOT_FORMAT_COFF:
255             iblBootCoff (bootFxn, &entry);
256             break;
257 #endif
259         case ibl_BOOT_FORMAT_BTBL:
260             iblBootBtbl (bootFxn, &entry);
261             break;
263 #ifndef EXCLUDE_BLOB
264         case ibl_BOOT_FORMAT_BBLOB:
265             iblBootBlob (bootFxn, &entry, formatParams);
266             break;
267 #endif
269 #ifndef EXCLUDE_ELF
270         case ibl_BOOT_FORMAT_ELF:
271             iblBootElf (bootFxn, &entry);
272             break;
273 #endif
275         default:
276             iblStatus.invalidDataFormatSpec += 1;
277             break;
279     }
280     
282     return (entry);