]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/ibl.git/blob - src/main/iblmain.c
d687b3825d12ec4dbebf47fb8c97195a031e0549
[keystone-rtos/ibl.git] / src / main / iblmain.c
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)
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 */
193     
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     }
269     
271     return (entry);