Two stage load of ibl from I2C
authorMike Line <m-line1@ti.com>
Mon, 1 Nov 2010 17:42:30 +0000 (13:42 -0400)
committerMike Line <m-line1@ti.com>
Mon, 1 Nov 2010 17:42:30 +0000 (13:42 -0400)
A two stage load of the ibl is done. The first stage loaded is an
endian independent program which then loads the rest of the ibl
(endian dependent). The PLL is also setup in the first stage
which will increase the load time for the c6455

12 files changed:
src/cfg/c6472/iblcfg.h
src/device/c6472/c6472.c
src/device/c64x/make/makefile
src/device/device.h
src/hw/plls/pllapi.h
src/hw/plls/pllxx1p8/pll.c
src/ibl.h
src/main/c64x/make/makefile
src/main/iblmain.c
src/make/Makefile
src/make/ibl_c6472/ibl.cmd
src/make/makestg2

index 6fd37b40d152856f15339fa7a85d4040c98bed39..df1a3bfb47d8643a8b85e14a08075c7c469f181a 100644 (file)
 #define IBL_I2C_OWN_ADDR                10
 #define IBL_I2C_CFG_ADDR_DELAY          0x100       /* Delay between sending the address and reading data */
 
-#ifndef IBL_I2C_CFG_EEPROM_BUS_ADDR
- #define IBL_I2C_CFG_EEPROM_BUS_ADDR    0x50
-#endif
+#define IBL_I2C_CFG_EEPROM_BUS_ADDR    0x50
 
 #define IBL_I2C_CFG_TABLE_DATA_ADDR     (0x10000 - 0x300)
+#define IBL_I2C_MAP_TABLE_DATA_ADDR     0x180
  
 
 
index 2b44a7ea0baac239d29cc0f109a6c2c1714aedae..26bdc0e821c5a0bb56c663d562de813dbd15d7bc 100644 (file)
 extern cregister unsigned int DNUM;
 
 
-/**
- * @brief The default boot configuration table is filled in
- *
- * @details
- *   A default ibl configuraiton table is provided when one is not found
- *   preloaded.
- */
-void deviceLoadDefaultIblTable (void)
-{
-    uint32 macA, macB;
-
-#if 0  /* This is really the default. Switching to a direct tftp boot until I have a bootp server
-        * on a private lan for test */
-    ibl.ethConfig[0].ethPriority = ibl_LOWEST_PRIORITY;
-    ibl.ethConfig[0].port        = 0;
-    ibl.ethConfig[0].doBootp     = TRUE;
-    ibl.ethConfig[0].bootFormat  = ibl_BOOT_FORMAT_AUTO;
-
-    memset (&ibl.ethConfig[0].ethInfo, 0, sizeof(ibl.ethConfig[0].ethInfo));
-#endif
-
-    /* This is the temporary code */
-    ibl.ethConfig[0].ethPriority      = ibl_LOWEST_PRIORITY;
-    ibl.ethConfig[0].port             = 0;
-    ibl.ethConfig[0].doBootp          = FALSE;
-    ibl.ethConfig[0].useBootpServerIp = FALSE;
-    ibl.ethConfig[0].useBootpFileName = FALSE;
-    ibl.ethConfig[0].bootFormat       = ibl_BOOT_FORMAT_NAME;
-
-    memset (&ibl.ethConfig[0].ethInfo, 0, sizeof(ibl.ethConfig[0].ethInfo));
-
-    ibl.ethConfig[0].ethInfo.ipAddr[0] = 10;
-    ibl.ethConfig[0].ethInfo.ipAddr[1] = 218;
-    ibl.ethConfig[0].ethInfo.ipAddr[2] = 109;
-    ibl.ethConfig[0].ethInfo.ipAddr[3] = 21;
-
-    ibl.ethConfig[0].ethInfo.serverIp[0] = 10;
-    ibl.ethConfig[0].ethInfo.serverIp[1] = 218;
-    ibl.ethConfig[0].ethInfo.serverIp[2] = 109;
-    ibl.ethConfig[0].ethInfo.serverIp[3] = 196;
-
-    ibl.ethConfig[0].ethInfo.gatewayIp[0] = 10;
-    ibl.ethConfig[0].ethInfo.gatewayIp[1] = 218;
-    ibl.ethConfig[0].ethInfo.gatewayIp[2] = 109;
-    ibl.ethConfig[0].ethInfo.gatewayIp[3] = 1;
-
-    /* Leave hw address as 0 */
-
-    strcpy (ibl.ethConfig[0].ethInfo.fileName, "test2_little.out");
-
-    ibl.ethConfig[0].blob.startAddress  = 0x00200000;       /* Base address of SL2 */
-    ibl.ethConfig[0].blob.sizeBytes     = 0x000c0000;       /* All of SL2 */
-    ibl.ethConfig[0].blob.branchAddress = 0x00200000;       /* Base of SL2 */
-
-
-
-    macA = *((uint32 *)0x2a80700);
-    macB = *((uint32 *)0x2a80704);
-
-    ibl.ethConfig[0].ethInfo.hwAddress[0] = (macA >> 24) & 0xff;
-    ibl.ethConfig[0].ethInfo.hwAddress[1] = (macA >> 16) & 0xff;
-    ibl.ethConfig[0].ethInfo.hwAddress[2] = (macA >>  8) & 0xff;
-    ibl.ethConfig[0].ethInfo.hwAddress[3] = (macA >>  0) & 0xff;
-    ibl.ethConfig[0].ethInfo.hwAddress[4] = (macB >> 24) & 0xff;
-    ibl.ethConfig[0].ethInfo.hwAddress[5] = (macB >> 16) & 0xff;
-
-
-    ibl.ethConfig[1].ethPriority = ibl_DEVICE_NOBOOT;
-
-
-    /* MDIO configuration */
-    ibl.mdioConfig.nMdioOps = 8;
-    ibl.mdioConfig.mdioClkDiv = 0x20;
-    ibl.mdioConfig.interDelay = 1400;   /* ~2ms at 700 MHz */
-
-    ibl.mdioConfig.mdio[0] =  (1 << 30) | (27 << 21) | (24 << 16) | 0x848b;
-    ibl.mdioConfig.mdio[1] =  (1 << 30) | (20 << 21) | (24 << 16) | 0x0ce0;
-    ibl.mdioConfig.mdio[2] =  (1 << 30) | (24 << 21) | (24 << 16) | 0x4101;
-    ibl.mdioConfig.mdio[3] =  (1 << 30) | ( 0 << 21) | (24 << 16) | 0x9140;
-
-    ibl.mdioConfig.mdio[4] =  (1 << 30) | (27 << 21) | (25 << 16) | 0x848b;
-    ibl.mdioConfig.mdio[5] =  (1 << 30) | (20 << 21) | (25 << 16) | 0x0ce0;
-    ibl.mdioConfig.mdio[6] =  (1 << 30) | (24 << 21) | (25 << 16) | 0x4101;
-    ibl.mdioConfig.mdio[7] =  (1 << 30) | ( 0 << 21) | (25 << 16) | 0x9140;
-
-
-    /* Main Pll configuration */
-    ibl.pllConfig[ibl_MAIN_PLL].doEnable = TRUE;
-    ibl.pllConfig[ibl_MAIN_PLL].prediv   = 1;
-    ibl.pllConfig[ibl_MAIN_PLL].mult     = 28;
-    ibl.pllConfig[ibl_MAIN_PLL].postdiv  = 1;
-
-    ibl.pllConfig[ibl_MAIN_PLL].pllOutFreqMhz = 500;
-
-    /* The DDR PLL. The multipliers/dividers are fixed, so are really dont cares */
-    ibl.pllConfig[ibl_DDR_PLL].doEnable = TRUE;
-
-    /* The network PLL. The multipliers/dividers are fixed */
-    ibl.pllConfig[ibl_NET_PLL].doEnable = TRUE;
-
-    /* EMIF configuration */
-    ibl.ddrConfig.uEmif.emif3p1.sdcfg  = 0x00538832; /* timing, 32bit wide */
-    ibl.ddrConfig.uEmif.emif3p1.sdrfc  = 0x0000073B; /* Refresh 533Mhz */ 
-    ibl.ddrConfig.uEmif.emif3p1.sdtim1 = 0x47245BD2; /* Timing 1 */
-    ibl.ddrConfig.uEmif.emif3p1.sdtim2 = 0x0125DC44; /* Timing 2 */
-    ibl.ddrConfig.uEmif.emif3p1.dmcctl = 0x50001906; /* PHY read latency for CAS 5 is 5 + 2 - 1 */
-
-
-    /* NAND configuration for the MT29F1G08 flash */
-    ibl.nandConfig.nandPriority = ibl_HIGHEST_PRIORITY;
-    ibl.nandConfig.bootFormat   = ibl_BOOT_FORMAT_COFF;
-
-    ibl.nandConfig.nandInfo.busWidthBits  = 8;
-    ibl.nandConfig.nandInfo.pageSizeBytes = 2048;
-    ibl.nandConfig.nandInfo.pageEccBytes  = 64;
-    ibl.nandConfig.nandInfo.pagesPerBlock = 64;
-    ibl.nandConfig.nandInfo.totalBlocks   = 1024;
-
-    ibl.nandConfig.nandInfo.addressBytes  = 4;
-    ibl.nandConfig.nandInfo.lsbFirst      = TRUE;
-    ibl.nandConfig.nandInfo.blockOffset   = 22;
-    ibl.nandConfig.nandInfo.pageOffset    = 16;
-    ibl.nandConfig.nandInfo.columnOffset  = 0;
-
-    ibl.nandConfig.nandInfo.resetCommand    = 0xff;
-    ibl.nandConfig.nandInfo.readCommandPre  = 0;
-    ibl.nandConfig.nandInfo.readCommandPost = 0x30;
-    ibl.nandConfig.nandInfo.postCommand     = TRUE;
-    
-
-}
-
 /**
  *  @brief Determine if an address is local
  *
@@ -197,30 +65,6 @@ Uint32 deviceLocalAddrToGlobal (Uint32 addr)
 }
         
         
-/**
- * @brief Configure the PLLs
- *
- * @details
- *   The three PLLs are enabled. Only the main PLL has the ability to configure
- *   the multiplier and dividers.
- */
-void devicePllConfig (void)
-{
-    if (ibl.pllConfig[ibl_MAIN_PLL].doEnable == TRUE)
-        hwPllSetPll (MAIN_PLL, 
-                     ibl.pllConfig[ibl_MAIN_PLL].prediv,
-                     ibl.pllConfig[ibl_MAIN_PLL].mult,
-                     ibl.pllConfig[ibl_MAIN_PLL].postdiv);
-
-    if (ibl.pllConfig[ibl_DDR_PLL].doEnable == TRUE)
-        hwPllEnable (DDR_PLL);
-
-    if (ibl.pllConfig[ibl_NET_PLL].doEnable == TRUE)
-        hwPllEnable (NET_PLL);
-
-
-}
-
 /**
  * @brief
  *   Enable the DDR
index 64f4e0aeca1e8ef4ef861bc4106c79f917e9165c..12601a8d74cda2ef47f540dfc5daa6b43c9fd37b 100644 (file)
@@ -15,7 +15,7 @@ ECODIR= $(IBL_ROOT)/device
 
 # For no target set CSRC to all sources for clean
 ifeq ($(TARGET),c6472)
- CSRC= c6472.c
+ CSRC= c6472.c c6472init.c
 else 
  ifeq ($(TARGET),c6455)
   CSRC= c6455.c
index 89a5d78e8167cc2286afcdf755e1a3bff71b96b9..0d54a011812a3f1016185fdbdbb0aa6af45312bf 100644 (file)
@@ -102,6 +102,14 @@ void deviceLoadDefaultEthAddress (uint8 *maddr);
 void deviceSetEthResetState (int32 portNum, BOOL applyReset);
 #endif
  
+ /**
+  *  @brief
+  *     Return the endian status
+  *
+  *  @details
+  *     Returns true if the device is executing in little endian mode
+  */
+bool deviceIsLittleEndian(void);
 
 #endif
 
index ee461b9334319c4c81594a495d1a98223fcc3f0b..1692f04149b02f8ccf45ba6bc2c234b3239d4b80 100644 (file)
 #include "types.h"
 
 /* Prototypes */
-uint16 hwPllResetType (uint16 pllNum);
-int16 hwPllSetPll (uint16 pllNum, uint16 prediv, uint16 mult, uint16 postdiv);
-int16 hwPllDisable (uint16 pllNum);
-int16 hwPllEnable (uint16 pllNum);
+uint16 hwPllResetType (uint32 pllNum);
+int16 hwPllSetPll (uint32 pllNum, uint32 prediv, uint32 mult, uint32 postdiv);
+int16 hwPllDisable (uint32 pllNum);
+int16 hwPllEnable (uint32 pllNum);
 
 
 /**
index 95543b6c8e7503e72cc1daf785c53fd9ddea880e..7ac70b2a2ed7dba34075c8473549ece883ad825a 100644 (file)
@@ -25,7 +25,7 @@
  **************************************************************************************
  * DESCRIPTION: Returns the last boot mode type
  **************************************************************************************/
-uint16 hwPllResetType (uint16 pllNum)
+uint16 hwPllResetType (uint32 pllNum)
 {
   if ( ((DEVICE_REG32_R (DEVICE_PLL_BASE(pllNum) + PLL_REG_RSTYPE)) & PLL_REG_RSTYPE_FIELD_POWER_ON_RESET) != 0 )
     return (pll_POR_RESET);
@@ -56,7 +56,7 @@ void hw_pll_delay (uint32 del)
  **********************************************************************************
  * DESCRIPTION: Sets up the pll
  **********************************************************************************/
-int16 hwPllSetPll (uint16 pllNum, uint16 prediv, uint16 mult, uint16 postdiv)
+int16 hwPllSetPll (uint32 pllNum, uint32 prediv, uint32 mult, uint32 postdiv)
 {
   uint32 ctl;
   uint32 status;
@@ -140,7 +140,7 @@ int16 hwPllSetPll (uint16 pllNum, uint16 prediv, uint16 mult, uint16 postdiv)
  **********************************************************************************
  * DESCRIPTION: The pll is put into bypass. Returns 0 on success. 
  **********************************************************************************/
-int16 hwPllDisable (uint16 pllNum)
+int16 hwPllDisable (uint32 pllNum)
 {
   uint32 ctl;
   uint32 pllBase;
@@ -169,7 +169,7 @@ int16 hwPllDisable (uint16 pllNum)
  ***********************************************************************************
  * DESCRIPTION: The PLL is enabled with no changes to multipliers or dividers
  ***********************************************************************************/
-int16 hwPllEnable (uint16 pllNum)
+int16 hwPllEnable (uint32 pllNum)
 {
   uint32 ctl;
   uint32 pllBase;
index a2b73a2de6deef294580b1e7c50306071725cb88..f8e75d5bb0f2b5648246b842fbacf2250c40a287 100644 (file)
--- a/src/ibl.h
+++ b/src/ibl.h
@@ -384,6 +384,8 @@ typedef struct ibl_s
     
     iblNand_t nandConfig;                    /**< NAND configuration @ref iblNand_t */
     
+    uint16    chkSum;                        /**< Ones complement checksum over the whole config structure */
+    
     
 /*    iblI2c_t  i2cConfig;  */
 /*    iblSpi_t  spiConfig;  */
@@ -423,6 +425,24 @@ extern ibl_t ibl;
 /* @} */
 
 
+/**
+ *  @defgroup iblFailCode
+ *
+ * @ingroup iblFailCode
+ * @{
+ *      @def ibl_FAIL_CODE_INVALID_I2C_ADDRESS
+ */
+#define ibl_FAIL_CODE_INVALID_I2C_ADDRESS  700      /**< Invalid i2c eeprom address encountered */
+/**
+ *  @def ibl_FAIL_CODE_BTBL_FAIL
+ */
+#define ibl_FAIL_CODE_BTBL_FAIL             701     /**< Boot table processing function error */
+
+ /* @} */
+
+
 /**
  * @brief
  *   Provide status on the boot operation
@@ -435,6 +455,14 @@ typedef struct iblStatus_s
 {
     uint32 iblMagic;        /**<  The @ref ibl_MAGIC_VALUE is placed here to indicate the boot has begun */
     
+    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 */
+    
     int32  tableLoadFail;   /**<  If non-zero then the load of the parameter table from i2c failed */
     
     int32  heartBeat;       /**<  An increasing value as long as the boot code is running */
@@ -457,6 +485,23 @@ typedef struct iblStatus_s
 extern iblStatus_t iblStatus;                               
 
 
+/** 
+ *  @brief
+ *      The i2c map structure
+ *
+ *  @details 
+ *      The i2c eeprom contains a structure which identifies the location of the big and little
+ *      endian ibl images on the eeprom.
+ */
+typedef struct iblI2cMap_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 */
+    uint32  addrLe;         /**<  Base address of the boot tables for the little endian image */
+    uint32  addrBe;         /**<  Base address of the boot tables for the big endian image */
+
+} iblI2cMap_t;
+
 
 
 
index 9a73485fec75d9c2827446fe5b946eddbdf7d4b2..4c6f435843da84c6f02486a110ea5a3a4763f483 100644 (file)
@@ -14,7 +14,7 @@ endif
 ECODIR= $(IBL_ROOT)/main
 
 
-CSRC= iblmain.c
+CSRC= iblmain.c iblinit.c
 
 
 CDEFS += -DIBL_I2C_CFG_EEPROM_BUS_ADDR=$(I2C_PARAM_BUS_ADDR)
index 8507b5f2e4297c93040ce0c2770f6c5ce156f089..46e7387665354931f4b56ab2663f0d4d2beda6e6 100644 (file)
 #include "ibl_elf.h"
 #include <string.h>
 
-
 /**
- * @brief The ibl table is declared.
- *
- * @details
- *   The ibl table is declared uninitialized by this ibl program. An external
- *   initialization can be performed if the default operation of the ibl is
- *   not desired.
+ *  @brief
+ *      Data structures shared between the 1st and 2nd stage IBL load
+ *      are declared in a single header file, included in both stages
  */
-#pragma DATA_SECTION(ibl, ".ibl_config_table")
-ibl_t ibl;
-
+#include "iblStage.h"
 
-/**
- * @brief The ibl status table is declared.
- *  
- * @details
- *   The ibl status table is declared. It is initialized at run time
- *   in function main.
- */
-#pragma DATA_SECTION(iblStatus, ".ibl_status_table")
-iblStatus_t iblStatus;
 
 
 /* Eat printfs */
@@ -152,9 +137,6 @@ void main (void)
     }
 
 
-    /* Pll configuration is device specific */
-    devicePllConfig ();
-
     /* DDR configuration is device specific */
     deviceDdrConfig ();
 
index 72cea2c96b7d1c7fb49abdff3be601b73dc9fbb5..bd0137b650a2d2b09f862eb933008aa422c8aa73 100644 (file)
@@ -14,35 +14,17 @@ all:
        @echo must specify a target [ $(IBLS_C6X) ]
 
 
-# Default options that can be overridden on the command line
-ifndef ENDIAN
- ENDIAN=little
-endif
-export ENDIAN
-
 # The debug flag changes compiler options
 ifndef DEBUG
  DEBUG=no
 endif
 export DEBUG
 
-# The value of I2C_PARAM_BUS_ADDR determines the I2C bus address used
-# to read the ibl configuration table from. The default values are
-# 0x50 for little endian and 0x51 for big endian.
-
-ifndef I2C_PARAM_BUS_ADDR
- ifeq ($(ENDIAN),little)
-   I2C_PARAM_BUS_ADDR=0x50
- else
-   I2C_PARAM_BUS_ADDR=0x51
- endif
-endif
-
-export I2C_PARAM_BUS_ADDR
 
 
 $(IBLS_C6X):
-       make -f makestg2 ARCH=c64x TARGET=$@ $@ 
+       make -f makestg2 ARCH=c64x TARGET=$@ ENDIAN=big    $@ 
+       make -f makestg2 ARCH=c64x TARGET=$@ ENDIAN=little $@ 
 
 
 # will need to add a line for each additional ARCH type added
index d94b8de7617cc3f7b3ba6c8dadb2dd39b07a3b4d..24714a02b6daae25c7ad061460f31d7d37fbcc3b 100644 (file)
 ../driver/c64x/make/nand.oc
 ../hw/c64x/make/t64.oc
 ../hw/c64x/make/cpmacdrv.oc
-../hw/c64x/make/pll.oc
 ../hw/c64x/make/psc.oc
 ../hw/c64x/make/emif31.oc
 ../hw/c64x/make/mdio.oc
 ../hw/c64x/make/gpio.oc
 ../hw/c64x/make/nandgpio.oc
-../hw/c64x/make/i2c.oc
 ../interp/c64x/make/bis.oc
 ../interp/c64x/make/cload.oc
 ../interp/c64x/make/osal.oc
-../interp/c64x/make/btblwrap.oc
-../interp/c64x/make/btblpr.oc
-../interp/c64x/make/gem.oc
 ../interp/c64x/make/blob.oc
 
 ../interp/c64x/make/dload.oc
@@ -46,6 +41,9 @@
 
 ../ecc/c64x/make/3byte_ecc.oc
 
+/* Symbols from the 1st portion of the load, generated by the make process */
+#include "ibl_init_symbols.inc"
+
 -c
 -stack 0x800
 -heap  0x6000
index 456628b6bfc703e46f80c22f32302a544ededea6..03f0eb0feefad33d2f2545da0b601e8d2ca662bc 100644 (file)
@@ -16,6 +16,8 @@ CLEAN_MODULES=$(addprefix clean_,$(MODULES))
 
 TARGETS= c6472 c6474 c6474l c6455 c6457
 
+COMMON_SYMBOLS= hwI2Cinit hwI2cMasterRead iblBootBtbl
+
 ifeq ($(ENDIAN),little)
        HEX_OPT= -order L
        IEXT=     le
@@ -35,17 +37,38 @@ include $(IBL_ROOT)/make/$(ARCH)/makedefs.mk
 export ARCH
 export TARGET
 
+$(TARGETS): iblMain
+
+
+# For the init code a raw image is created as well as the i2c code to verify
+# endian independent code is generated. The symbols required for linking
+# the full application are then extracted
+iblInit: $(MODULES) utils
+       $(LD) -o ibl_$(TARGET)/ibl_$(TARGET)_init.out -m ibl_$(TARGET)/ibl_$(TARGET)_init.map ibl_$(TARGET)/ibl_init.cmd $(RTLIBS)
+
+       hex6x $(HEX_OPT) ibl_$(TARGET)/ibl_init_image.rmd ibl_$(TARGET)/ibl_$(TARGET)_init.out
+       $(CP) ibl_le.b ibl_$(TARGET)/ibl.b
+       ../util/btoccs/b2ccs ibl_$(TARGET)/ibl.b ibl_$(TARGET)/ibl_init.$(IEXT).ccs
 
-$(TARGETS): $(MODULES) utils $(RIBL)
-       $(LD) -o ibl_$@/ibl_$@.out -m ibl_$@/ibl_$@.map  ibl_$@/ibl.cmd $(RTLIBS)
-       hex6x $(HEX_OPT) ibl_$@/ibl.rmd ibl_$@/ibl_$@.out
+       hex6x $(HEX_OPT) ibl_$(TARGET)/ibl_init.rmd ibl_$(TARGET)/ibl_$(TARGET)_init.out
+       ../util/bconvert/bconvert64x -$(IEXT) ibl_le.b ibl.b
+       $(CP) ibl.b ibl_$(TARGET)
+       ../util/btoccs/b2i2c ibl_$(TARGET)/ibl.b ibl_$(TARGET)/ibl.i2c.b
+       ../util/btoccs/b2ccs ibl_$(TARGET)/ibl.i2c.b ibl_$(TARGET)/ibl.i2c.$(IEXT).ccs
+
+       bash ../util/symExtract/symExtract ibl_$(TARGET)/ibl_$(TARGET)_init.map ibl_$(TARGET)/ibl_init_symbols.inc $(COMMON_SYMBOLS)
+
+       
+iblMain: iblInit $(MODULES)
+       $(LD) -o ibl_$(TARGET)/ibl_$(TARGET).out -m ibl_$(TARGET)/ibl_$(TARGET).map  ibl_$(TARGET)/ibl.cmd $(RTLIBS)
+       hex6x $(HEX_OPT) ibl_$(TARGET)/ibl.rmd ibl_$(TARGET)/ibl_$(TARGET).out
        ../util/bconvert/bconvert64x -$(IEXT) ibl_le.b ibl.b
-       $(CP) ibl.b ibl_$@
-       ../util/btoccs/b2i2c ibl_$@/ibl.b ibl_$@/ibl.i2c.b
-       ../util/btoccs/b2ccs ibl_$@/ibl.i2c.b ibl_$@/ibl.i2c.$(IEXT).ccs
-       ../util/romparse/romparse $(COMPACT) ibl_$@/i2crom_$(IEXT).map
-       $(CP) i2crom.ccs ibl_$@/i2crom_$(IEXT).ccs
-       $(CP) i2crom.ccs ibl_$@/i2crom_$(IEXT).dat
+       $(CP) ibl.b ibl_$(TARGET)
+       ../util/btoccs/b2i2c ibl_$(TARGET)/ibl.b ibl_$(TARGET)/ibl.i2c.b
+       ../util/btoccs/b2ccs ibl_$(TARGET)/ibl.i2c.b ibl_$(TARGET)/ibl.i2c.$(IEXT).ccs
+       ../util/romparse/romparse $(COMPACT) ibl_$(TARGET)/i2crom_$(IEXT).map
+       $(CP) i2crom.ccs ibl_$(TARGET)/i2crom_$(IEXT).ccs
+       $(CP) i2crom.ccs ibl_$(TARGET)/i2crom_$(IEXT).dat
        $(RM) i2crom.ccs ibl_le.b ibl.b