Added loading of second stage through SPI
authorMike Line <m-line1@ti.com>
Mon, 3 Jan 2011 23:26:48 +0000 (18:26 -0500)
committerMike Line <m-line1@ti.com>
Mon, 3 Jan 2011 23:26:48 +0000 (18:26 -0500)
27 files changed:
src/cfg/c661x/iblcfg.h
src/device/c6455/tiboot_c6455.h [moved from src/util/romparse/tiboot_c6455.h with 100% similarity]
src/device/c6457/tiboot_c6457.h [moved from src/util/romparse/tiboot_c6457.h with 100% similarity]
src/device/c6472/tiboot_c6472.h [moved from src/util/romparse/tiboot_c6472.h with 100% similarity]
src/device/c6474/tiboot_c6474.h [moved from src/util/romparse/tiboot_c6474.h with 100% similarity]
src/device/c661x/c661x.c
src/device/c661x/c661xinit.c
src/device/c661x/target.h
src/device/c661x/tiboot_c661x.h [moved from src/util/romparse/tiboot_c661x.h with 100% similarity]
src/device/device.h
src/hw/plls/pll014phi/cfgpll.c
src/hw/plls/pll014phi/cfgpll2.c
src/hw/plls/pllapi.h
src/ibl.h
src/iblloc.h
src/main/c64x/make/makefile
src/main/iblStage.h
src/main/iblinit.c
src/main/iblinit.h [new file with mode: 0644]
src/main/ibliniti2c.c [new file with mode: 0644]
src/main/iblinitspinor.c [new file with mode: 0644]
src/make/Makefile
src/make/ibl_c661x/ibl_common.inc
src/make/ibl_c661x/ibl_init_objs_template.inc
src/make/makestg1
src/make/makestg2
src/util/romparse/Makefile

index 1edbe12c5847c7fad255acb4431984c2fd20a629..f77ce5125c8d45d404ec25128b7819a7693a156a 100644 (file)
 #ifndef IBL_CFG_I2C_MAP_TABLE_DATA_ADDR
  #define IBL_CFG_I2C_MAP_TABLE_DATA_ADDR     0x420
 #endif
+
+
+/**
+ * @brief The default location for the spi map information can be overridden during make
+ */
+#ifndef IBL_CFG_SPI_MAP_TABLE_DATA_ADDR
+ #define IBL_CFG_SPI_MAP_TABLE_DATA_ADDR     0x400
+#endif
+
 
 #endif
 
index e908fe70e51f3d6b59a6aac2b19e5bc3e9acd620..dd90497e7b14847a7af4b00b8033f137e16b9c3c 100644 (file)
 
 extern cregister unsigned int DNUM;
 
+/* Excluding NAND exclused both SPI and EMIF nand */
+#ifdef EXCLUDE_NAND
+ #define EXCLUDE_NAND_EMIF
+ #define EXCLUDE_NAND_SPI
+#endif
 
 /**
  *  @brief Determine if an address is local
index 159455b1f3dc475f2551a8ea5f56a3a75f9fc194..5857e9ace1a70b0cc5cfc35fd5a837b3c63ced80 100644 (file)
@@ -6,8 +6,20 @@
  *
  */
 #include "ibl.h"
+#include "iblloc.h"
 #include "device.h"
 #include "pllapi.h"
+#include "spi_api.h"
+#include "tiboot_c661x.h"       
+
+#ifdef EXCLUDE_SPI
+ #define EXCLUDE_NAND_SPI
+ #define EXCLUDE_NOR_SPI
+#elif (defined(EXCLUDE_NAND_SPI) && defined(EXCLUDE_NOR_SPI))
+ #define EXCLUDE_SPI
+#endif
+
+
 
 /**
  * @brief Configure the PLLs
@@ -68,3 +80,117 @@ bool deviceIsLittleEndian (void)
 }
 
 
+/**
+ *  @brief
+ *      Return the device used for the second stage program load.
+ *      For SPI NAND a second stage loader is required and this
+ *      function must be changed to locate that fingerprint.
+ */
+int32 deviceReadBootDevice (void)
+{
+    uint32 v;
+    int32  w;
+
+    BOOT_PARAMS_COMMON_T *params;
+
+#if  (defined(EXCLUDE_NOR_SPI) && defined(EXCLUDE_NAND_SPI) && !defined(EXCLUDE_I2C))
+
+    return (BOOT_DEVICE_I2C);
+
+#elif (defined(EXCLUDE_NOR_SPI) && !defined(EXCLUDE_NAND_SPI) && defined(EXCLUDE_I2C))
+
+    return (BOOT_DEVICE_NAND_SPI);
+
+#elif (!defined(EXCLUDE_NOR_SPI) && defined(EXCLUDE_NAND_SPI) && defined(EXCLUDE_I2C))
+
+    return (BOOT_DEVICE_NOR_SPI);
+
+#endif
+
+    v = *((Uint32 *)DEVICE_JTAG_ID_REG);
+
+    if (v == DEVICE_C6618_JTAG_ID_VAL)
+        params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6618;
+    else
+        params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6616;
+
+
+    switch (params->boot_mode)  {
+
+#ifndef EXCLUDE_I2C
+        case BOOT_MODE_I2C:   w = BOOT_DEVICE_I2C;
+#endif
+
+#ifndef EXCLUDE_NOR_SPI
+        case BOOT_MODE_SPI:   w = BOOT_DEVICE_SPI_NOR;
+#endif
+
+        default:              w = BOOT_DEVICE_INVALID;
+    
+    }
+
+    return (w);
+}
+
+
+#ifndef EXCLUDE_SPI
+/**
+ *  @brief
+ *      Return the default hardware configuration for SPI. If this information
+ *      is available in the boot ROM it is used, otherwise defaults are used.
+ */
+void deviceLoadInitSpiConfig (void *vcfg)
+{
+    uint32 v;
+
+    spiConfig_t *cfg = (spiConfig_t *)vcfg;
+
+    BOOT_PARAMS_COMMON_T *params;
+    BOOT_PARAMS_SPI_T    *spip;
+
+    v = *((Uint32 *)DEVICE_JTAG_ID_REG);
+
+    if (v == DEVICE_C6618_JTAG_ID_VAL)
+        params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6618;
+    else
+        params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6616;
+
+
+    /* SPI_ROM is a constant defined during make which enables the use of the
+     * parameters from the ROM boot loader */
+    if ((SPI_ROM == 1) && (params->boot_mode == BOOT_MODE_SPI))  {
+
+        spip = (BOOT_PARAMS_SPI_T *)params;
+
+        cfg->port      = 0;
+        cfg->mode      = spip->mode;
+        cfg->addrWidth = spip->addrWidth;
+        cfg->npin      = spip->nPins;
+        cfg->csel      = spip->csel;
+        cfg->c2tdelay  = spip->c2tdelay;
+
+        v = (UINT32)spip->cpuFreqMhz * 1000;  /* CPU frequency in kHz */
+        v = v / (DEVICE_SPI_MOD_DIVIDER * (((UINT32)(spip->busFreqMhz) * 1000) + spip->busFreqKhz));
+
+        if (v > DEVICE_SPI_MAX_DIVIDER)
+            v = DEVICE_SPI_MAX_DIVIDER;
+
+        cfg->clkdiv = v;
+
+    }  else  {
+
+        cfg->port      = 0;
+        cfg->mode      = SPI_MODE;
+        cfg->addrWidth = SPI_ADDR_WIDTH;
+        cfg->npin      = SPI_NPIN;
+        cfg->csel      = SPI_CSEL;
+        cfg->c2tdelay  = SPI_C2TDEL;
+        cfg->clkdiv    = SPI_CLKDIV;
+
+    }
+
+}
+
+
+
+#endif
index ea10352cab42a7fdc97c24a538b0a51e2120a805..027f29ac028945af940a87a18b4106303fae0cec 100644 (file)
  */
 #define DEVICE_SPI_BASE(x)          0x20bf0000u
 #define DEVICE_SPI_MOD_DIVIDER      6
+#define DEVICE_SPI_MAX_DIVIDER      0xff     
 
 /**
  * @brief
@@ -314,4 +315,17 @@ Int32 targetMacRcv (void *ptr_device, UINT8 *buffer);
 #define DEVICE_REG_XMPAX_L(x) *((volatile unsigned int *)(0x08000000 + (8*(x))))
 #define DEVICE_REG_XMPAX_H(x) *((volatile unsigned int *)(0x08000004 + (8*(x))))
 
+
+/**
+ *  @brief
+ *      ROM boot loader boot modes and table locations
+ */
+#define BOOT_MODE_I2C               40
+#define BOOT_MODE_SPI               50
+
+
+#define ROM_BOOT_PARAMS_ADDR_C6618   0x873680
+#define ROM_BOOT_PARAMS_ADDR_C6616   0x8f3680
+
+
 #endif /* _TARGET_H */
index 12a075bc37b8fa9cde6577746734c9055adeb954..32d0d78464a4559914514a4ea992b12b4be7d52e 100644 (file)
@@ -180,5 +180,16 @@ typedef struct nandCtbl_s  {
 nandCtbl_t *deviceGetNandCtbl (int32 interface);
 
 
+/**
+ *  @brief
+ *      Return the boot device for the second part of the loader
+ */
+Int32 deviceReadBootDevice(void);
+
+/**
+ *  @brief
+ *      Return the default SPI device configuration
+ */
+void deviceLoadInitSpiConfig (void *cfg);
 
 #endif
index 36af36ff4d85b2332868723573036c7fdf837502..772784ec488850adc23fe8686f81bff076704808 100644 (file)
@@ -25,7 +25,7 @@
  * DESCRIPTION: The PLL is configured. If the existing configuration matches the requested one no
  *              register write is made.
  *********************************************************************************************************/
-SINT16 hwPllSetCfgPll (UINT32 base, UINT16 prediv, UINT16 mult, UINT16 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz)
+SINT16 hwPllSetCfgPll (UINT32 base, UINT32 prediv, UINT32 mult, UINT32 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz)
 {
     UINT32 reg;
     UINT32 regb;
index c4dfebd5c172d70c8fa518539408dfcba598f94e..8c44c1ec4d2d5b62da530593bf2c12692360c5f9 100644 (file)
@@ -28,7 +28,7 @@
  * DESCRIPTION: The PLL is configured. If the existing configuration matches the requested one no
  *              register write is made.
  *********************************************************************************************************/
-SINT16 hwPllSetCfg2Pll (UINT32 base, UINT16 prediv, UINT16 mult, UINT16 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz)
+SINT16 hwPllSetCfg2Pll (UINT32 base, UINT32 prediv, UINT32 mult, UINT32 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz)
 {
     UINT32 reg;
     UINT32 regb;
index a37340dacd7114ec7e9da8e4195b454d75ce8c56..5b91bacdefead4a7329f4fad767802e22831772c 100644 (file)
@@ -58,8 +58,8 @@ int16 hwPllSetPll (uint32 pllNum, uint32 prediv, uint32 mult, uint32 postdiv);
 int16 hwPllDisable (uint32 pllNum);
 int16 hwPllEnable (uint32 pllNum);
 
-SINT16 hwPllSetCfgPll  (UINT32 base, UINT16 prediv, UINT16 mult, UINT16 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz);
-SINT16 hwPllSetCfg2Pll (UINT32 base, UINT16 prediv, UINT16 mult, UINT16 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz);
+SINT16 hwPllSetCfgPll  (UINT32 base, UINT32 prediv, UINT32 mult, UINT32 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz);
+SINT16 hwPllSetCfg2Pll (UINT32 base, UINT32 prediv, UINT32 mult, UINT32 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz);
 
 /**
  * @def pll_POR_RESET
index d09fbfabf0f3e89e3a9b22b510281eedeb907d71..2bd35cc348d3fab67e8d875394a5aec060cb2225 100644 (file)
--- a/src/ibl.h
+++ b/src/ibl.h
@@ -292,8 +292,8 @@ typedef struct iblEmif4p0_s
 /** @def ibl_EMIF4_ENABLE_rdWrtExcThresh */
 #define  ibl_EMIF4_ENABLE_rdWrtExcThresh              (1 << 22)
 
-/** @def BOOT_EMIF4_ENABLE_ALL */
-#define  BOOT_EMIF4_ENABLE_ALL                         0x007fffff
+/** @def ibl_BOOT_EMIF4_ENABLE_ALL */
+#define  ibl_BOOT_EMIF4_ENABLE_ALL                    0x007fffff
     
 /* @} */  
     
@@ -671,6 +671,15 @@ extern ibl_t ibl;
  */
 #define ibl_FAIL_CODE_SPI_PARAMS            703     /**< Invalid SPI configuration found */
 
+/**
+ *  @def ibl_FAIL_CODE_INVALID_INIT_DEVICE
+ */
+#define ibl_FAIL_CODE_INVALID_INIT_DEVICE   704     /**< Second stage boot device specified is invalid */
+
+/**
+ *  @def ibl_FAIL_CODE_INVALID_SPI_ADDRESS
+ */
+#define ibl_FAIL_CODE_INVALID_SPI_ADDRESS   705     /**< Invalid data address specified on SPI */
  
  /* @} */
 
@@ -692,11 +701,15 @@ typedef struct iblStatus_s
     uint32 iblFail;         /**<  If non-zero the IBL has encountered a fatal error */
     
     uint32 i2cRetries;      /**<  Count of I2C read retries */
-    uint32 magicRetries;    /**<  Count of I2C re-reads because the magic number was incorrect */ 
-    uint32 mapSizeFail;     /**<  Number of times an invalid map table size was read from the i2c */
-    uint32 mapRetries;      /**<  Number of times the checksum failed on the read of the i2c map */
     uint32 i2cDataRetries;  /**<  Number of retries while reading block data from the i2c */
     
+    uint32 spiRetries;      /**<  Count of SPI read retries */
+    uint32 spiDataRetries;  /**<  Number of retries while reading block data from the spi */
+    
+    uint32 magicRetries;    /**<  Count of I2C/SPI re-reads because the magic number was incorrect */ 
+    uint32 mapSizeFail;     /**<  Number of times an invalid map table size was read from the i2c/spi */
+    uint32 mapRetries;      /**<  Number of times the checksum failed on the read of the i2c/spi map */
+    
     int32  heartBeat;       /**<  An increasing value as long as the boot code is running */
     
     int32  activePeriph;    /**<  Describes the active boot peripheral @ref iblActivePeriph */
@@ -718,13 +731,13 @@ extern iblStatus_t iblStatus;
 
 /** 
  *  @brief
- *      The i2c map structure
+ *      The ibl boot map structure
  *
  *  @details 
- *      The i2c eeprom contains a structure which identifies the location of the big and little
- *      endian ibl images on the eeprom.
+ *      The ibl boot device contains a structure which identifies the location of the big and little
+ *      endian ibl images on the external device.
  */
-typedef struct iblI2cMap_s 
+typedef struct iblBootMap_s 
 {
     uint16  length;         /**<  Size of the structure in bytes */
     uint16  chkSum;         /**<  Value which makes the ones complement checksum over the block equal to 0 or -0 */
@@ -735,7 +748,7 @@ typedef struct iblI2cMap_s
     uint32  addrBe;         /**<  Base address of the boot tables for the big endian image */
     uint32  configBe;       /**<  Base address of the ibl structure for use with the big endian image */
 
-} iblI2cMap_t;
+} iblBootMap_t;
 
 
 
index 6b3ec291c9a64b951102f12d933ba29a1973c460..cd7a7adc7aa0177c3b996de094f977a47e84d72a 100644 (file)
@@ -119,4 +119,15 @@ void *iblMemcpy (void *s1, const void *s2, Uint32 n);
 /* squash printfs */
 void mprintf(char *x, ...);
 
+
+/* Initial Boot Devices */
+#define BOOT_DEVICE_INVALID    -1
+#define BOOT_DEVICE_I2C         0
+#define BOOT_DEVICE_SPI_NOR     1
+#define BOOT_DEVICE_SPI_NAND    2
+
+BOOT_MODULE_FXN_TABLE *iblInitI2c     (void);
+BOOT_MODULE_FXN_TABLE *iblInitSpiNor  (void);
+BOOT_MODULE_FXN_TABLE *iblInitSpiNand (void);
+
 #endif /* _IBLLOC_H */
index 4af0b1578ee17747ab2ac8428e3cb128aed6a421..e92a7d03a2d4fc8c2b685d3646aa56dc27d2a938 100644 (file)
@@ -49,7 +49,7 @@ endif
 ECODIR= $(IBL_ROOT)/main
 
 
-CSRC= iblmain.c iblinit.c
+CSRC= iblmain.c iblinit.c ibliniti2c.c iblinitspinor.c
 
 
 .PHONY: main
@@ -73,15 +73,10 @@ C6X_C_DIR+= ;$(IBL_ROOT)/ethboot
 C6X_C_DIR+= ;$(IBL_ROOT)/nandboot
 C6X_C_DIR+= ;$(IBL_ROOT)/driver/timer
 C6X_C_DIR+= ;$(IBL_ROOT)/hw/i2c
+C6X_C_DIR+= ;$(IBL_ROOT)/hw/spi
 C6X_C_DIR+= ;$(IBL_ROOT)/cfg/$(TARGET)
 C6X_C_DIR+= ;$(STDINC)
 
-# Paths to the kicker intermediate boot loader for devices which require them
-#ifeq ($(TARGET),c6455)
-# C6X_C_DIR+= ;$(IBL_ROOT)/make/ibl_c6455
-# C6X_C_DIR+= ;$(IBL_ROOT)/util/romparse
-#endif
-
 
 
 export C6X_C_DIR
index 2ac3fdbc56cdf15e4d3b5ca73b7777659ad54390..164f1c45b45fbfc76cd07341ee7aeb7f8b64feb5 100644 (file)
@@ -1,3 +1,38 @@
+/*
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
+ * 
+ * 
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met:
+ *
+ *    Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *    Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the   
+ *    distribution.
+ *
+ *    Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
 #ifndef _IBL_STAGE_H
 #define _IBL_STAGE_H
 /**
index c39999962a4b3a140fb67e7ed42c06734569b5a9..75ef3ade5e028f26699064240406a5b52e8549f0 100644 (file)
@@ -1,3 +1,38 @@
+/*
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
+ * 
+ * 
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met:
+ *
+ *    Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *    Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the   
+ *    distribution.
+ *
+ *    Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
 /**
  *  @file iblinit.c
  *
@@ -30,7 +65,7 @@
 #include "iblcfg.h"
 #include "device.h"
 #include "iblbtbl.h"
-#include "i2c.h"
+#include "iblinit.h"
 #include <string.h>
 
 
  */
 #include "iblStage.h"
 
-/**
- *  @brief
- *      byte swapping of i2c data must be done when in little endian mode
- */
-bool littleEndian;
-
 /**
  *  @brief
  *      The boot table processing status is declared in the boot table wrapper,
@@ -269,30 +298,39 @@ void iblSwap (void)
 
 /**
  *  @brief
- *      The i2c load context consists of the address of the next block 
- *      to read, and a simple fifo holding any existing data.
+ *      The init load context consists of the address of the next block 
+ *      to read, and a simple fifo-ish structure holding any existing data.
+ *
+ *      A full fifo is not defined here. The individual init load blocks
+ *      (I2C, SPI NOR, SPI NAND) will poke the structure values directly
+ *      to minimize the compiled code size. Most notably is the absence
+ *      of the write function. This fifo will always be completely emptied
+ *      before any writes are done, so writes are always done from the top.
  */
-#define I2C_MAX_BLOCK_SIZE      0x80
-uint32 i2cReadAddress;
+uint32 iFifoIn  = 0;
+uint32 iFifoOut = 0;
+uint8  iData[I_MAX_BLOCK_SIZE];
 
-uint32 i2cFifoIn  = 0;
-uint32 i2cFifoOut = 0;
-uint8  i2cData[I2C_MAX_BLOCK_SIZE];
-uint16 i2cSum[I2C_MAX_BLOCK_SIZE >> 1];
+/**
+ *  @brief
+ *      Checkum calculation. 16 bit values constructed from received bytes
+ *      always in big endian format, regardless of the endianness of the device 
+ */
+uint16 iSum[I_MAX_BLOCK_SIZE >> 1];
 
 
 /**
  *  @brief
  *      Return the number of elements in the fifo
  */
-Uint32 i2cFifoCount (void)
+Uint32 iFifoCount (void)
 {
     Int32 count;
 
-    if (i2cFifoIn >= i2cFifoOut)
-        count = i2cFifoIn - i2cFifoOut;
+    if (iFifoIn >= iFifoOut)
+        count = iFifoIn - iFifoOut;
     else
-        count = i2cFifoIn + I2C_MAX_BLOCK_SIZE - i2cFifoOut;
+        count = iFifoIn + I_MAX_BLOCK_SIZE - iFifoOut;
 
     return (count);
 
@@ -303,109 +341,24 @@ Uint32 i2cFifoCount (void)
  *  @brief
  *      Read a byte from the fifo
  */
-Uint8 i2cFifoRead(void)
+Uint8 iFifoRead(void)
 {
     Uint8 v;
 
-    v = i2cData[i2cFifoOut];
+    v = iData[iFifoOut];
 
-    i2cFifoOut += 1;
+    iFifoOut += 1;
 
-    if (i2cFifoOut == i2cFifoIn)
-        i2cFifoOut = i2cFifoIn = 0;
+    if (iFifoOut == iFifoIn)
+        iFifoOut = iFifoIn = 0;
 
-    if (i2cFifoOut >= I2C_MAX_BLOCK_SIZE)
-        i2cFifoOut = 0;
+    if (iFifoOut >= I_MAX_BLOCK_SIZE)
+        iFifoOut = 0;
 
     return (v);
 
 }
 
-/**
- *  @brief
- *      Read a block of data from the I2C eeprom and put it in the fifo
- */
-void i2cReadBlock (void)
-{
-    uint16 len;
-    int32  i, j;
-    uint32 v;
-
-    for (;;) {
-        while (hwI2cMasterRead (i2cReadAddress & 0xffff,    /* The address on the eeprom of the table */
-                                4,                          /* The number of bytes to read */
-                                i2cData,                    /* Where to store the bytes */
-                                i2cReadAddress >> 16,       /* The bus address of the eeprom */
-                                IBL_CFG_I2C_ADDR_DELAY)     /* The delay between sending the address and reading data */
-    
-             != I2C_RET_OK)  {
-
-            iblStatus.i2cDataRetries += 1;
-        }
-
-        /* Form the length. The received bytes are always in big endian format */
-        len    = (i2cData[0] << 8) | i2cData[1];
-
-
-        if (len > I2C_MAX_BLOCK_SIZE)
-            continue;
-
-
-        while (hwI2cMasterRead (i2cReadAddress & 0xffff,    /* The address on the eeprom of the table */
-                                len,                        /* The number of bytes to read */
-                                i2cData,                    /* Where to store the bytes */
-                                i2cReadAddress >> 16,       /* The bus address of the eeprom */
-                                IBL_CFG_I2C_ADDR_DELAY)     /* The delay between sending the address and reading data */
-    
-             != I2C_RET_OK)  {
-
-            iblStatus.i2cDataRetries += 1;
-        }
-
-
-        /* Must do endian conversion to verify the checksum */
-        for (i = j = 0; i < len; i += 2, j += 1) 
-            i2cSum[j] = (i2cData[i+0] << 8) | i2cData[i+1];
-
-        v = onesComplementChksum (i2cSum, j);
-        if ((v == 0) || (v == 0xffff))
-            break;
-
-        
-        iblStatus.i2cDataRetries += 1;
-
-    }
-
-
-    i2cReadAddress += len;
-    
-    i2cFifoIn  = len;
-    i2cFifoOut = 4;    /* The i2c header is effectively removed */
-
-}
-
-             
-
-
-/**
- *  @brief
- *      Read data from the I2C to pass to the interpreter
- */
-Int32 iblI2cRead (Uint8 *buf, Uint32 num_bytes)
-{
-    int i;
-
-    for (i = 0; i < num_bytes; i++)  {
-
-        if (i2cFifoCount() == 0)
-            i2cReadBlock ();
-
-        buf[i] = i2cFifoRead();
-    }
-
-    return (0);
-
-}
 
 #define iblBITMASK(x,y)      (   (   (  ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 )   )   <<  ((UINT32)y)   )
 #define iblREAD_BITFIELD(z,x,y)   (((UINT32)z) & iblBITMASK(x,y)) >> (y)
@@ -430,22 +383,6 @@ uint16 readUpper16 (uint32 v)
 }
 
 
-/**
- *  @brief
- *      The module function table used for boot from i2c
- */
-BOOT_MODULE_FXN_TABLE i2cinit_boot_module = 
-{
-    NULL,           /* Open  API */
-    NULL,           /* Close API */
-    iblI2cRead,     /* Read  API */
-    NULL,           /* Write API */
-    NULL,           /* Peek  API */
-    NULL,           /* Seek  API */
-    NULL            /* Query API */
-};
-
-
 
 /**
  *  @brief
@@ -460,139 +397,50 @@ BOOT_MODULE_FXN_TABLE i2cinit_boot_module =
 void main (void)
 {
 
-    uint16       v;
-    uint16       configAddrLsw;
-    uint16       configAddrMsw;
+    int32        bootDevice;
     uint32       entry;
     void         (*exit)();
-    iblI2cMap_t  map;
+
+    BOOT_MODULE_FXN_TABLE *bFxnTbl;
 
     memset (&iblStatus, 0, sizeof(iblStatus_t));
     iblStatus.iblMagic     = ibl_MAGIC_VALUE;
     iblStatus.iblVersion   = ibl_VERSION;
     iblStatus.activePeriph = ibl_ACTIVE_PERIPH_I2C;
 
-    /* Read the endianness setting of the device */
-    littleEndian = deviceIsLittleEndian();
-    
-    /* Load the default configuration table from the i2c. The actual speed of the device
-     * isn't really known here, since it is part of the table, so a compile time
-     * value is used (the pll may have been configured during the initial load) */
-    hwI2Cinit (IBL_CFG_I2C_DEV_FREQ_MHZ,        /* The CPU frequency during I2C data load */
-               DEVICE_I2C_MODULE_DIVISOR,       /* The divide down of CPU that drives the i2c */
-               IBL_CFG_I2C_CLK_FREQ_KHZ,        /* The I2C data rate used during table load */
-               IBL_CFG_I2C_OWN_ADDR);           /* The address used by this device on the i2c bus */
-
-
-    /* Read the I2C mapping information from the eeprom */
-    for (;;)  {
-        if (hwI2cMasterRead (IBL_CFG_I2C_MAP_TABLE_DATA_ADDR,     /* The address on the eeprom of the data mapping */
-                             sizeof(iblI2cMap_t),                 /* The number of bytes to read */
-                             (UINT8 *)&map,                       /* Where to store the bytes */
-                             IBL_CFG_I2C_MAP_TABLE_DATA_BUS_ADDR, /* The bus address of the eeprom */
-                             IBL_CFG_I2C_ADDR_DELAY)              /* The delay between sending the address and reading data */
-
-             == I2C_RET_OK)  {
-
-                /* On the I2C EEPROM the table is always formatted with the most significant
-                 * byte first. So if the device is running little endain the endian must be
-                 * swapped */
-                if (littleEndian == TRUE)  {
-                    map.length   = swap16val (map.length);
-                    map.chkSum   = swap16val (map.chkSum);
-                    map.addrLe   = swap32val (map.addrLe);
-                    map.configLe = swap32val (map.configLe);
-                    map.addrBe   = swap32val (map.addrBe);
-                    map.configBe = swap32val (map.configBe);
-
-                    configAddrLsw = readLower16 (map.configLe);
-                    configAddrMsw = readUpper16 (map.configLe);
-
-                }  else  {
-                    configAddrLsw = readLower16 (map.configBe);
-                    configAddrMsw = readUpper16 (map.configLe);
-
-                }
-
-
-                if (map.length != sizeof(iblI2cMap_t))  {
-                    iblStatus.mapSizeFail += 1;
-                    continue;
-                }
-
-                if (map.chkSum != 0)  {
-                    
-                    v = onesComplementChksum ((UINT16 *)&map, sizeof(iblI2cMap_t));
-                    if ((v != 0) && (v != 0xffff))  {
-                        iblStatus.mapRetries += 1;
-                        continue;
-                    }
-                }
-
-                break;
-        }
-
-        iblStatus.mapRetries += 1;
-
-    }
-
-
-    /* Read the i2c configuration tables until the checksum passes and the magic number
-     * matches. The checksum must be verified before the endian re-ordering is done */
-    for (;;)  {
-
-        if (hwI2cMasterRead (configAddrLsw,                  /* The address on the eeprom of the table */
-                             sizeof(ibl_t),                  /* The number of bytes to read */
-                             (UINT8 *)&ibl,                  /* Where to store the bytes */
-                             configAddrMsw,                  /* The bus address of the eeprom */
-                             IBL_CFG_I2C_ADDR_DELAY)         /* The delay between sending the address and reading data */
-
-             == I2C_RET_OK)  {
 
-                 if (ibl.chkSum != 0)  {
+    /* Determine the boot device to read from */
+    bootDevice = deviceReadBootDevice();
 
-                    v = onesComplementChksum ((UINT16 *)&ibl, sizeof(ibl_t) / sizeof(UINT16));
-                    if ((v != 0) && (v != 0xffff))  {
-                        iblStatus.i2cRetries += 1;
-                        continue;
-                    }
+    switch (bootDevice)  {
 
-                 }  
+#ifndef EXCLUDE_I2C
+    case BOOT_DEVICE_I2C:       bFxnTbl = iblInitI2c ();
+                                break;
+#endif
 
+#ifndef EXCLUDE_NOR_SPI
+    case BOOT_DEVICE_SPI_NOR:   bFxnTbl = iblInitSpiNor ();
+                                break;
+#endif
 
-                if (ibl.iblMagic == ibl_MAGIC_VALUE)
-                    break;
+#ifndef EXCLUDE_NAND_SPI
+    case BOOT_DEVICE_SPI_NAND:  bFxnTbl = iblInitSpiNand ();
+                                break;
+#endif
 
-                if (swap32val (ibl.iblMagic) == ibl_MAGIC_VALUE)  {
-                    iblSwap ();
-                    break;
-                }
+    default:                    iblStatus.iblFail = ibl_FAIL_CODE_INVALID_INIT_DEVICE;
+                                for (;;);
 
-                iblStatus.magicRetries += 1;
-
-            }
-
-            iblStatus.i2cRetries += 1;
     }
+    
 
     /* Pll configuration is device specific */
     devicePllConfig ();
 
 
-    /* The rest of the IBL is in boot table format. Read and process the data */
-    if (littleEndian == TRUE) 
-        i2cReadAddress = map.addrLe;
-    else
-        i2cReadAddress = map.addrBe;
-
-    if (i2cReadAddress == 0xffffffff)  {
-        iblStatus.iblFail = ibl_FAIL_CODE_INVALID_I2C_ADDRESS;
-        for (;;);
-    }
-
-
     /* Pass control to the boot table processor */
-    iblBootBtbl (&i2cinit_boot_module, &entry);
+    iblBootBtbl (bFxnTbl, &entry);
 
     if (btblWrapEcode != 0)  {
         iblStatus.iblFail = ibl_FAIL_CODE_BTBL_FAIL;
diff --git a/src/main/iblinit.h b/src/main/iblinit.h
new file mode 100644 (file)
index 0000000..7b7e97d
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
+ * 
+ * 
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met:
+ *
+ *    Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *    Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the   
+ *    distribution.
+ *
+ *    Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+
+/**
+ *  @file iblinit.c
+ *
+ *  @brief
+ *      Defines the structures and functions used accross the 2nd part of the
+ *      ibl load.
+ */
+ #include "types.h"
+uint16 onesComplementChksum (uint16 * restrict p_data, uint16 len);
+uint32 swap32val (uint32 v);
+uint16 swap16val (uint16 v);
+void iblSwap (void);
+
+uint16 readLower16 (uint32 v);
+uint16 readUpper16 (uint32 v);
+
+
+/* Fifo-ish structure */
+#define I_MAX_BLOCK_SIZE      0x100
+
+extern uint32 iFifoIn;
+extern uint32 iFifoOut;
+extern uint8  iData[];
+extern uint16 iSum[];
+
+Uint32 iFifoCount (void);
+Uint8 iFifoRead(void);
+
diff --git a/src/main/ibliniti2c.c b/src/main/ibliniti2c.c
new file mode 100644 (file)
index 0000000..043c6a3
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
+ * 
+ * 
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met:
+ *
+ *    Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *    Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the   
+ *    distribution.
+ *
+ *    Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+#include "ibl.h"
+#include "iblloc.h"
+#include "iblcfg.h"
+#include "device.h"
+#include "iblbtbl.h"
+#include "i2c.h"
+#include "iblinit.h"
+#include <string.h>
+
+/**
+ *  @brief
+ *      A global value is used to track the read through the i2c during
+ *      the program load.
+ */
+uint32 i2cReadAddress;
+
+/**
+ *  @brief
+ *      Read a block of data from the I2C eeprom and put it in the fifo
+ */
+void i2cReadBlock (void)
+{
+    uint16 len;
+    int32  i, j;
+    uint32 v;
+
+    for (;;) {
+        while (hwI2cMasterRead (i2cReadAddress & 0xffff,    /* The address on the eeprom of the table */
+                                4,                          /* The number of bytes to read */
+                                iData,                      /* Where to store the bytes */
+                                i2cReadAddress >> 16,       /* The bus address of the eeprom */
+                                IBL_CFG_I2C_ADDR_DELAY)     /* The delay between sending the address and reading data */
+    
+             != I2C_RET_OK)  {
+
+            iblStatus.i2cDataRetries += 1;
+        }
+
+        /* Form the length. The received bytes are always in big endian format */
+        len    = (iData[0] << 8) | iData[1];
+
+
+        if (len > I_MAX_BLOCK_SIZE)
+            continue;
+
+
+        while (hwI2cMasterRead (i2cReadAddress & 0xffff,    /* The address on the eeprom of the table */
+                                len,                        /* The number of bytes to read */
+                                iData,                      /* Where to store the bytes */
+                                i2cReadAddress >> 16,       /* The bus address of the eeprom */
+                                IBL_CFG_I2C_ADDR_DELAY)     /* The delay between sending the address and reading data */
+    
+             != I2C_RET_OK)  {
+
+            iblStatus.i2cDataRetries += 1;
+        }
+
+
+        /* Must do endian conversion to verify the checksum */
+        for (i = j = 0; i < len; i += 2, j += 1) 
+            iSum[j] = (iData[i+0] << 8) | iData[i+1];
+
+        v = onesComplementChksum (iSum, j);
+        if ((v == 0) || (v == 0xffff))
+            break;
+
+        
+        iblStatus.i2cDataRetries += 1;
+
+    }
+
+
+    i2cReadAddress += len;
+    
+    iFifoIn  = len;
+    iFifoOut = 4;    /* The i2c header is effectively removed */
+
+}
+
+             
+
+
+/**
+ *  @brief
+ *      Read data from the I2C to pass to the interpreter
+ */
+Int32 iblI2cRead (Uint8 *buf, Uint32 num_bytes)
+{
+    int i;
+
+    for (i = 0; i < num_bytes; i++)  {
+
+        if (iFifoCount() == 0)
+            i2cReadBlock ();
+
+        buf[i] = iFifoRead();
+    }
+
+    return (0);
+
+}
+
+
+/**
+ *  @brief
+ *      The module function table used for boot from i2c
+ */
+BOOT_MODULE_FXN_TABLE i2cinit_boot_module = 
+{
+    NULL,           /* Open  API */
+    NULL,           /* Close API */
+    iblI2cRead,     /* Read  API */
+    NULL,           /* Write API */
+    NULL,           /* Peek  API */
+    NULL,           /* Seek  API */
+    NULL            /* Query API */
+};
+
+
+/**
+ *  @brief
+ *      Configure the I2C, then read the parameters from I2C and pass
+ *      to the second stage boot
+ */
+BOOT_MODULE_FXN_TABLE *iblInitI2c (void)
+{
+    uint16       v;
+    uint16       configAddrLsw;
+    uint16       configAddrMsw;
+    iblBootMap_t map;
+    bool         littleEndian;
+
+    /* Read the endianness setting of the device */
+    littleEndian = deviceIsLittleEndian();
+
+    /* Load the default configuration table from the i2c. The actual speed of the device
+     * isn't really known here, since it is part of the table, so a compile time
+     * value is used (the pll may have been configured during the initial load) */
+    hwI2Cinit (IBL_CFG_I2C_DEV_FREQ_MHZ,        /* The CPU frequency during I2C data load */
+               DEVICE_I2C_MODULE_DIVISOR,       /* The divide down of CPU that drives the i2c */
+               IBL_CFG_I2C_CLK_FREQ_KHZ,        /* The I2C data rate used during table load */
+               IBL_CFG_I2C_OWN_ADDR);           /* The address used by this device on the i2c bus */
+
+
+    /* Read the I2C mapping information from the eeprom */
+    for (;;)  {
+        if (hwI2cMasterRead (IBL_CFG_I2C_MAP_TABLE_DATA_ADDR,     /* The address on the eeprom of the data mapping */
+                             sizeof(iblBootMap_t),                /* The number of bytes to read */
+                             (UINT8 *)&map,                       /* Where to store the bytes */
+                             IBL_CFG_I2C_MAP_TABLE_DATA_BUS_ADDR, /* The bus address of the eeprom */
+                             IBL_CFG_I2C_ADDR_DELAY)              /* The delay between sending the address and reading data */
+
+             == I2C_RET_OK)  {
+
+                /* On the I2C EEPROM the table is always formatted with the most significant
+                 * byte first. So if the device is running little endain the endian must be
+                 * swapped */
+                if (littleEndian == TRUE)  {
+                    map.length   = swap16val (map.length);
+                    map.chkSum   = swap16val (map.chkSum);
+                    map.addrLe   = swap32val (map.addrLe);
+                    map.configLe = swap32val (map.configLe);
+                    map.addrBe   = swap32val (map.addrBe);
+                    map.configBe = swap32val (map.configBe);
+
+                    configAddrLsw  = readLower16 (map.configLe);
+                    configAddrMsw  = readUpper16 (map.configLe);
+                    i2cReadAddress = map.addrLe;
+
+                }  else  {
+                    configAddrLsw = readLower16 (map.configBe);
+                    configAddrMsw = readUpper16 (map.configBe);
+                    i2cReadAddress = map.addrBe;
+
+                }
+
+
+                if (map.length != sizeof(iblBootMap_t))  {
+                    iblStatus.mapSizeFail += 1;
+                    continue;
+                }
+
+                if (map.chkSum != 0)  {
+                    
+                    v = onesComplementChksum ((UINT16 *)&map, sizeof(iblBootMap_t));
+                    if ((v != 0) && (v != 0xffff))  {
+                        iblStatus.mapRetries += 1;
+                        continue;
+                    }
+                }
+
+                break;
+        }
+
+        iblStatus.mapRetries += 1;
+
+    }
+
+
+    /* Read the i2c configuration tables until the checksum passes and the magic number
+     * matches. The checksum must be verified before the endian re-ordering is done */
+    for (;;)  {
+
+        if (hwI2cMasterRead (configAddrLsw,                  /* The address on the eeprom of the table */
+                             sizeof(ibl_t),                  /* The number of bytes to read */
+                             (UINT8 *)&ibl,                  /* Where to store the bytes */
+                             configAddrMsw,                  /* The bus address of the eeprom */
+                             IBL_CFG_I2C_ADDR_DELAY)         /* The delay between sending the address and reading data */
+
+             == I2C_RET_OK)  {
+
+                 if (ibl.chkSum != 0)  {
+
+                    v = onesComplementChksum ((UINT16 *)&ibl, sizeof(ibl_t) / sizeof(UINT16));
+                    if ((v != 0) && (v != 0xffff))  {
+                        iblStatus.i2cRetries += 1;
+                        continue;
+                    }
+
+                 }  
+
+
+                if (ibl.iblMagic == ibl_MAGIC_VALUE)
+                    break;
+
+                if (swap32val (ibl.iblMagic) == ibl_MAGIC_VALUE)  {
+                    iblSwap ();
+                    break;
+                }
+
+                iblStatus.magicRetries += 1;
+
+            }
+
+            iblStatus.i2cRetries += 1;
+    }
+
+    /* The rest of the IBL is in boot table format. Read and process the data */
+    if (i2cReadAddress == 0xffffffff)  {
+        iblStatus.iblFail = ibl_FAIL_CODE_INVALID_I2C_ADDRESS;
+        for (;;);
+    }
+
+    return (&i2cinit_boot_module);
+
+}
+
diff --git a/src/main/iblinitspinor.c b/src/main/iblinitspinor.c
new file mode 100644 (file)
index 0000000..1339c81
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
+ * 
+ * 
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met:
+ *
+ *    Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *    Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the   
+ *    distribution.
+ *
+ *    Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+#include "ibl.h"
+#include "iblloc.h"
+#include "iblcfg.h"
+#include "device.h"
+#include "iblbtbl.h"
+#include "spi_api.h"
+#include "iblinit.h"
+#include <string.h>
+
+
+/**
+ *  @brief
+ *      The next read address on the SPI flash is stored in a global for
+ *      access through the boot call chain.
+ */
+uint32 spiReadAddress;
+
+/**
+ *  @brief
+ *      Read a block of data from the SPI eeprom and put it in the fifo
+ */
+void spiReadBlock (void)
+{
+    uint16 len;
+    int32  i, j;
+    uint32 v;
+
+    for (;;) {
+        while (hwSpiRead  (spiReadAddress,    /* The address on the eeprom of the table */
+                           4,                 /* The number of bytes to read */
+                           iData)             /* Where to store the bytes */
+    
+             != 0)  {
+
+            iblStatus.spiDataRetries += 1;
+        }
+
+        /* Form the length. The received bytes are always in big endian format */
+        len    = (iData[0] << 8) | iData[1];
+
+
+        if (len > I_MAX_BLOCK_SIZE)
+            continue;
+
+
+        while (hwSpiRead (spiReadAddress,    /* The address on the eeprom of the table */
+                          len,               /* The number of bytes to read */
+                          iData)             /* Where to store the bytes */
+    
+             != 0)  {
+
+            iblStatus.spiDataRetries += 1;
+        }
+
+
+        /* Must do endian conversion to verify the checksum */
+        for (i = j = 0; i < len; i += 2, j += 1) 
+            iSum[j] = (iData[i+0] << 8) | iData[i+1];
+
+        v = onesComplementChksum (iSum, j);
+        if ((v == 0) || (v == 0xffff))
+            break;
+
+        
+        iblStatus.spiDataRetries += 1;
+
+    }
+
+
+    spiReadAddress += len;
+    
+    iFifoIn  = len;
+    iFifoOut = 4;    /* The spi header is effectively removed */
+
+}
+
+             
+
+/**
+ *  @brief
+ *      Read data from the SPI to pass to the interpreter
+ */
+Int32 iblSpiRead (Uint8 *buf, Uint32 num_bytes)
+{
+    int i;
+
+    for (i = 0; i < num_bytes; i++)  {
+
+        if (iFifoCount() == 0)
+            spiReadBlock ();
+
+        buf[i] = iFifoRead();
+    }
+
+    return (0);
+
+}
+
+
+/**
+ *  @brief
+ *      The module function table used for boot from spi
+ */
+BOOT_MODULE_FXN_TABLE spiinit_boot_module = 
+{
+    NULL,           /* Open  API */
+    NULL,           /* Close API */
+    iblSpiRead,     /* Read  API */
+    NULL,           /* Write API */
+    NULL,           /* Peek  API */
+    NULL,           /* Seek  API */
+    NULL            /* Query API */
+};
+
+
+
+
+/**
+ *  @brief
+ *      Configure the SPI, then read the parameters from the SPI and
+ *      pass them to the second stage boot
+ */
+BOOT_MODULE_FXN_TABLE *iblInitSpiNor (void)
+{
+    iblBootMap_t  map;
+    spiConfig_t   cfg;
+    uint32        configAddr;
+
+    bool          littleEndian;
+    uint16        v;
+
+    /* Read the endianness of the device */
+    littleEndian = deviceIsLittleEndian();
+
+    /* Load the default configuration table from the SPI. The actual speed of 
+     * the device isn't really known here, since it is part of the table, so a
+     * compile time value is used (the pll may have been configured during the initial load) */
+    deviceLoadInitSpiConfig ((void *)&cfg);
+
+    if (hwSpiConfig (&cfg) != 0)  {
+
+        iblStatus.iblFail = ibl_FAIL_CODE_SPI_PARAMS;
+        for (;;);
+
+    }
+
+
+    /* Read the SPI mapping information from the nor flash */
+    for (;;)  {
+
+        if (hwSpiRead (IBL_CFG_SPI_MAP_TABLE_DATA_ADDR,      /* The address on the flash of the data mapping */
+                       sizeof(iblBootMap_t),                 /* The number of bytes to read */
+                       (UINT8 *)&map)                        /* Where to store the data */
+
+          == 0)  {
+
+            /* On the flash the table is always formatted with the most significant 
+             * byte first. So if the device is running little endian, the endian
+             * must be swapped */
+            if (littleEndian == TRUE)  {
+                map.length   = swap16val (map.length);
+                map.chkSum   = swap16val (map.chkSum);
+                map.addrLe   = swap32val (map.addrLe);
+                map.configLe = swap32val (map.configLe);
+                map.addrBe   = swap32val (map.addrBe);
+                map.configBe = swap32val (map.configBe);
+
+                configAddr     = map.configLe;
+                spiReadAddress = map.addrLe;
+
+            }  else  {
+
+                configAddr     = map.configBe;
+                spiReadAddress = map.addrBe;
+
+            }
+            
+
+            if (map.length != sizeof(iblBootMap_t))  {
+                iblStatus.mapSizeFail += 1;
+                continue;
+            }
+
+            if (map.chkSum != 0)  {
+
+                v = onesComplementChksum ((UINT16 *)&map, sizeof(iblBootMap_t));
+                if ((v != 0) && (v != 0xffff))  {
+                    iblStatus.mapRetries += 1;
+                    continue;
+                }
+            }
+
+            break;
+
+        }
+
+        iblStatus.mapRetries += 1;
+
+    }
+        
+
+    /* Read the SPI configuration tables until the checksum passes and the magic
+     * number matches. The checksum must be verified before the endian re-ordering */
+    for (;;)  {
+
+        if (hwSpiRead (configAddr,          /* The address on the flash of the table */
+                       sizeof(ibl_t),       /* The number of bytes to read */
+                       (UINT8 *)&ibl)       /* Where to store the bytes */
+             == 0)  {
+
+            if (ibl.chkSum != 0)  {
+
+                v = onesComplementChksum ((UINT16 *)&ibl, sizeof(ibl_t) / sizeof(UINT16));
+                if ((v != 0) && (v != 0xffff))  {
+                    iblStatus.spiRetries += 1;
+                    continue;
+                }
+            }
+
+            if (ibl.iblMagic == ibl_MAGIC_VALUE)
+                break;
+
+            if (swap32val (ibl.iblMagic) == ibl_MAGIC_VALUE)  {
+                iblSwap ();
+                break;
+            }
+
+            iblStatus.magicRetries += 1;
+
+        }
+
+        iblStatus.spiRetries += 1;
+
+    }
+
+
+    /* the rest of the IBL is in boot table format. Read and process the data */
+    if (spiReadAddress == 0xffffffff)  {
+        iblStatus.iblFail = ibl_FAIL_CODE_INVALID_SPI_ADDRESS;
+        for (;;);
+    }
+
+    return (&spiinit_boot_module);
+
+}
+
+
+
+
+
index 67c6a38a93528ae2d7beda0296a58d6964c3b7a4..ce981472289dfc085a5cca56d33fe3683e01b95c 100644 (file)
@@ -41,8 +41,8 @@
 #* DESCRIPTION: Builds the Intermediate Boot Loader (IBL)
 #*
 #*  Usage:  make c6455 | c6472 | c6474 | c6457 | c661x [DEBUG=yes] [ETH=no] [NAND=no]  \
-#*          [BIS=no] [COFF=no] [BLOB=no] [ELF=no] [ENDIAN= both | big | little] [I2C_BUS_ADDR= 0x50 | 0x51] \
-#*                     [COMPACT_I2C=yes]
+#*          [BIS=no] [COFF=no] [BLOB=no] [ELF=no] [NAND_SPI=no] [NOR_SPI=no] [ENDIAN= both | big | little] 
+#*          [I2C_BUS_ADDR= 0x50 | 0x51] [COMPACT_I2C=yes]
 #*
 #* or to make a board specific configuraiton
 #*
@@ -86,6 +86,14 @@ endif
 ifeq ($(ELF),no)
  EXCLUDES+= ELF
 endif
+
+ifeq ($(NAND_SPI),no)
+ EXCLUDES+= NAND_SPI
+endif
+
+ifeq ($(NOR_SPI),no)
+ EXCLUDES+= NOR_SPI
+endif
  
 
 
@@ -106,6 +114,46 @@ ifndef I2C_BUS_ADDR
  I2C_BUS_ADDR=0x50
 endif
 
+# The SPI configuration parameters
+ifndef SPI_MODE
+ SPI_MODE=3
+endif
+
+ifndef SPI_ADDR_WIDTH
+ SPI_ADDR_WIDTH=24
+endif
+
+ifndef SPI_NPIN
+ SPI_NPIN=5
+endif
+
+ifndef SPI_CSEL
+ SPI_CSEL=2
+endif
+
+ifndef SPI_C2TDEL
+ SPI_C2TDEL=4
+endif
+
+ifndef SPI_CLKDIV
+ SPI_CLKDIV=8
+endif
+
+ifneq ($(SPI_USE_ROM_PARAMS),0)
+ SPI_ROM=1
+else
+ SPI_ROM=0
+endif
+
+SPI_DEFS=  SPI_MODE=$(SPI_MODE)
+SPI_DEFS+= SPI_ADDR_WIDTH=$(SPI_ADDR_WIDTH) 
+SPI_DEFS+= SPI_NPIN=$(SPI_NPIN) 
+SPI_DEFS+= SPI_CSEL=$(SPI_CSEL) 
+SPI_DEFS+= SPI_C2TDEL=$(SPI_C2TDEL) 
+SPI_DEFS+= SPI_CLKDIV=$(SPI_CLKDIV) 
+SPI_DEFS+= SPI_ROM=$(SPI_ROM)
+
+
 
 
 all:
@@ -120,7 +168,7 @@ export DEBUG
 
 
 $(IBLS_C6X): 
-       make -f makestg1 ARCH=c64x TARGET=$@ I2C_BUS_ADDR=$(I2C_BUS_ADDR) COMPACT_I2C=$(COMPACT_I2C) ENDIAN_MODE=$(ENDIAN_MODE) EXCLUDES='$(EXCLUDES)' $@
+       make -f makestg1 ARCH=c64x TARGET=$@ I2C_BUS_ADDR=$(I2C_BUS_ADDR) COMPACT_I2C=$(COMPACT_I2C) ENDIAN_MODE=$(ENDIAN_MODE) EXCLUDES='$(EXCLUDES)' SPI_DEFS='$(SPI_DEFS)' $@
 
 
 # Configurations for individual evms
@@ -148,7 +196,7 @@ evm_c6457:
 
 # The 6618 EVM
 evm_c6618:
-       make -f makestg1 ARCH=c64x TARGET=c661x I2C_BUS_ADDR=0x50 ENDIAN_MODE=little EXCLUDES= DEBUG=YES c661x
+       make -f makestg1 ARCH=c64x TARGET=c661x I2C_BUS_ADDR=0x50 ENDIAN_MODE=little EXCLUDES= DEBUG=YES SPI_DEFS='$(SPI_DEFS)' c661x
 
 # Test - builds all the targets, with single component exclusion
 test_build:
index f2bea38779f51195656a91778ee329d5cf38645c..dc888360b0d84899804ac8f05427cb95872a09ba 100644 (file)
 
 MEMORY
 {
-       TEXT_INIT :  origin = 0x800000, length = 0x3000
-       TEXT      :  origin = 0x803000, length = 0xd000
+       TEXT_INIT :  origin = 0x800000, length = 0x3a00
+       TEXT      :  origin = 0x803a00, length = 0xc600
        STACK     :  origin = 0x810000, length = 0x0800
        HEAP      :  origin = 0x810800, length = 0x6000
-       DATA_INIT :  origin = 0x816800, length = 0x0200
-       DATA      :  origin = 0x816a00, length = 0x2e00
+       DATA_INIT :  origin = 0x816800, length = 0x0400
+       DATA      :  origin = 0x816c00, length = 0x2c00
        CFG       :  origin = 0x819800, length = 0x0300
        STAT      :  origin = 0x819b00, length = 0x0200
 
index 1351d383f6f68d07f9525afe170000e26bafaa95..e79352ffa56b9b25a5f99e9b34d9125b503b9bcb 100644 (file)
 ../hw/c64x/make/pll.ENDIAN_TAG.oc
 ../hw/c64x/make/cfgpll.ENDIAN_TAG.oc
 ../hw/c64x/make/cfgpll2.ENDIAN_TAG.oc
-../hw/c64x/make/i2c.ENDIAN_TAG.oc
 ../interp/c64x/make/btblwrap.ENDIAN_TAG.oc
 ../interp/c64x/make/btblpr.ENDIAN_TAG.oc
 ../interp/c64x/make/gem.ENDIAN_TAG.oc
 
+#ifndef EXCLUDE_I2C
+../main/c64x/make/ibliniti2c.ENDIAN_TAG.oc
+../hw/c64x/make/i2c.ENDIAN_TAG.oc
+#endif
+
+#ifndef EXCLUDE_SPI_NOR
+../main/c64x/make/iblinitspinor.ENDIAN_TAG.oc
+../hw/c64x/make/spi.ENDIAN_TAG.oc
+#endif
 
 
 
index be8e5ca3b0bf8cab9d64fc73343c821188148a91..9f2c354f07f6705e7f6810dbf8c599c2d828ca5e 100644 (file)
@@ -46,19 +46,19 @@ all:
 
 
 be_target:
-       make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=big    I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) utils
-       make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=big    I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) $(TARGET)
+       make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=big    I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) SPI_DEFS='$(SPI_DEFS)' utils
+       make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=big    I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) SPI_DEFS='$(SPI_DEFS)' $(TARGET)
 
 le_target:
-       make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=little I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) utils
-       make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=little I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) $(TARGET)
+       make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=little I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) SPI_DEFS='$(SPI_DEFS)' utils
+       make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=little I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) SPI_DEFS='$(SPI_DEFS)' $(TARGET)
 
 compare:
        make -f makestg2 ARCH=c64x TARGET=$(TARGET) compare
 
 
 $(IBLS_C6X): $(STAGE1_TARGET)
-       make -f makestg2 ARCH=c64x TARGET=$@ I2CROM=$(I2CROM) I2C_BUS_ADDR=$(I2C_BUS_ADDR) COMPACT_I2C=$(COMPACT_I2C) i2cRom
+       make -f makestg2 ARCH=c64x TARGET=$@ I2CROM=$(I2CROM) I2C_BUS_ADDR=$(I2C_BUS_ADDR) COMPACT_I2C=$(COMPACT_I2C) SPI_DEFS='$(SPI_DEFS)' i2cRom
 
 
 
index 36d8873fa50aa2f55bb5c453794f141236faecda..616de5492ccfa9d26ef498d3312a60ea5cb1a8ab 100644 (file)
@@ -27,6 +27,9 @@ MAINDEFS=-DIBL_CFG_I2C_MAP_TABLE_DATA_BUS_ADDR=$(I2C_BUS_ADDR)
 # Add build time exclusion definitions
 MAINDEFS+=$(addprefix -DEXCLUDE_,$(EXCLUDES))
 
+# Add SPI definitions
+SPI_CFG= $(addprefix -D,$(SPI_DEFS))
+
 
 # Common symbols are functions which are loaded with the stage load of the IBL, and
 # also referenced from the second stage
@@ -109,7 +112,9 @@ compare:
 # endian independent code is generated. The symbols required for linking
 # the full application are then extracted
 iblInit: $(CFG_MODULES) $(MODULES)
-       cat ibl_$(TARGET)/ibl_init_objs_template.inc | sed -e s/ENDIAN_TAG/$(IEXT)/g > ibl_$(TARGET)/ibl_init_objs.inc
+       cat ibl_$(TARGET)/ibl_init_objs_template.inc | sed -e s/ENDIAN_TAG/$(IEXT)/g > ibl_$(TARGET)/ibl_init_objs.tmp
+       $(CC) -ppo $(MAINDEFS) -DENDIAN_TAG=$(IEXT) ibl_$(TARGET)/ibl_init_objs.tmp
+       $(CP) ibl_$(TARGET)/ibl_init_objs.pp ibl_$(TARGET)/ibl_init_objs.inc
        $(LD) -o ibl_$(TARGET)/ibl_$(TARGET)_init.out -m ibl_$(TARGET)/ibl_$(TARGET)_init.map ibl_$(TARGET)/ibl_init.cmd $(RTLIBS)
        $(CP) ibl_$(TARGET)/ibl_$(TARGET)_init.out ibl_$(TARGET)/ibl_$(TARGET)_init.$(IEXT).out
        $(RM) -f ibl_$(TARGET)/ibl_init_obj.inc
@@ -147,15 +152,15 @@ $(MODULES):
        make -C $(IBL_ROOT)/$@/$(ARCH)/make $@
 
 $(CFG_MODULES):
-       @echo making $@
-       make -C $(IBL_ROOT)/$@/$(ARCH)/make CDEFS='$(MAINDEFS)' $@
+       @echo making $@ SPI_CFG=$(SPI_CFG)
+       make -C $(IBL_ROOT)/$@/$(ARCH)/make CDEFS='$(MAINDEFS) $(SPI_CFG)' $@
 
 utils:
        make -C $(IBL_ROOT)/util/btoccs
        make -C $(IBL_ROOT)/util/romparse TARGET=$(TARGET)
-       make -C $(IBL_ROOT)/util/i2cRead  TARGET=$(TARGET) $(TARGET)
-       make -C $(IBL_ROOT)/util/i2cWrite TARGET=$(TARGET) I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) MAINDEFS='$(MAINDEFS)' $(TARGET)
-       make -C $(IBL_ROOT)/util/i2cConfig $(TARGET) MAINDEFS='$(MAINDEFS)'
+       make -C $(IBL_ROOT)/util/i2cRead  TARGET=$(TARGET) $(TARGET) 
+       make -C $(IBL_ROOT)/util/i2cWrite TARGET=$(TARGET) I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) MAINDEFS='$(MAINDEFS) -DEXCLUDE_SPI' $(TARGET)
+       make -C $(IBL_ROOT)/util/i2cConfig $(TARGET) MAINDEFS='$(MAINDEFS) -DEXCLUDE_SPI'
        make -C $(IBL_ROOT)/util/bconvert
 
 clean: $(CLEAN_MODULES) hwClean
index 0542f1e4c960e4a038f9ce7dc2c132cbcf6b0029..d5b5720f8c59900e6a72d830201da711a0372063 100644 (file)
@@ -41,7 +41,7 @@ endif
 all: gen_cdefdep romparse
 
 romparse: cdefdep rparse.tab.o lex.yy.o romparse.c
-       gcc -o romparse -g romparse.c rparse.tab.o lex.yy.o -I../.. -I. -D$(TARGET)
+       gcc -o romparse -g romparse.c rparse.tab.o lex.yy.o -I../.. -I. -I../../device/$(TARGET) -D$(TARGET)
 
 
 rparse.tab.o: rparse.y