@@ -56,9 +56,9 @@
extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *
const argv[]);
-#if defined(CONFIG_UPDATE_TFTP)
-void update_tftp (void);
-#endif /* CONFIG_UPDATE_TFTP */
+#if defined(CONFIG_UPDITB)
+void update_itb (void);
+#endif /* CONFIG_UPDITB */
#define MAX_DELAY_STOP_STR 32
@@ -365,9 +365,9 @@
}
#endif /* CONFIG_PREBOOT */
-#if defined(CONFIG_UPDATE_TFTP)
- update_tftp ();
-#endif /* CONFIG_UPDATE_TFTP */
+#if defined(CONFIG_UPDITB)
+ update_itb ();
+#endif /* CONFIG_UPDITB */
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
s = getenv ("bootdelay");
@@ -164,7 +164,7 @@
COBJS-$(CONFIG_LCD) += lcd.o
COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
-COBJS-$(CONFIG_UPDATE_TFTP) += update.o
+COBJS-$(CONFIG_UPDITB) += upditb.o
COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
@@ -1,315 +0,0 @@
-/*
- * (C) Copyright 2008 Semihalf
- *
- * Written by: Rafal Czubak <rcz@semihalf.com>
- * Bartlomiej Sieka <tur@semihalf.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-
-#include <common.h>
-
-#if !(defined(CONFIG_FIT) && defined(CONFIG_OF_LIBFDT))
-#error "CONFIG_FIT and CONFIG_OF_LIBFDT are required for auto-update
feature"
-#endif
-
-#if defined(CONFIG_SYS_NO_FLASH)
-#error "CONFIG_SYS_NO_FLASH defined, but FLASH is required for
auto-update feature"
-#endif
-
-#include <command.h>
-#include <flash.h>
-#include <net.h>
-#include <malloc.h>
-
-/* env variable holding the location of the update file */
-#define UPDATE_FILE_ENV "updatefile"
-
-/* set configuration defaults if needed */
-#ifndef CONFIG_UPDATE_LOAD_ADDR
-#define CONFIG_UPDATE_LOAD_ADDR 0x100000
-#endif
-
-#ifndef CONFIG_UPDATE_TFTP_MSEC_MAX
-#define CONFIG_UPDATE_TFTP_MSEC_MAX 100
-#endif
-
-#ifndef CONFIG_UPDATE_TFTP_CNT_MAX
-#define CONFIG_UPDATE_TFTP_CNT_MAX 0
-#endif
-
-extern ulong TftpRRQTimeoutMSecs;
-extern int TftpRRQTimeoutCountMax;
-extern flash_info_t flash_info[];
-extern ulong load_addr;
-
-static uchar *saved_prot_info;
-
-static int update_load(char *filename, ulong msec_max, int cnt_max,
ulong addr)
-{
- int size, rv;
- ulong saved_timeout_msecs;
- int saved_timeout_count;
- char *saved_netretry, *saved_bootfile;
-
- rv = 0;
- /* save used globals and env variable */
- saved_timeout_msecs = TftpRRQTimeoutMSecs;
- saved_timeout_count = TftpRRQTimeoutCountMax;
- saved_netretry = strdup(getenv("netretry"));
- saved_bootfile = strdup(BootFile);
-
- /* set timeouts for auto-update */
- TftpRRQTimeoutMSecs = msec_max;
- TftpRRQTimeoutCountMax = cnt_max;
-
- /* we don't want to retry the connection if errors occur */
- setenv("netretry", "no");
-
- /* download the update file */
- load_addr = addr;
- copy_filename(BootFile, filename, sizeof(BootFile));
- size = NetLoop(TFTP);
-
- if (size < 0)
- rv = 1;
- else if (size > 0)
- flush_cache(addr, size);
-
- /* restore changed globals and env variable */
- TftpRRQTimeoutMSecs = saved_timeout_msecs;
- TftpRRQTimeoutCountMax = saved_timeout_count;
-
- setenv("netretry", saved_netretry);
- if (saved_netretry != NULL)
- free(saved_netretry);
-
- if (saved_bootfile != NULL) {
- copy_filename(BootFile, saved_bootfile, sizeof(BootFile));
- free(saved_bootfile);
- }
-
- return rv;
-}
-
-static int update_flash_protect(int prot, ulong addr_first, ulong
addr_last)
-{
- uchar *sp_info_ptr;
- ulong s;
- int i, bank, cnt;
- flash_info_t *info;
-
- sp_info_ptr = NULL;
-
- if (prot == 0) {
- saved_prot_info =
- calloc(CONFIG_SYS_MAX_FLASH_BANKS *
CONFIG_SYS_MAX_FLASH_SECT, 1);
- if (!saved_prot_info)
- return 1;
- }
-
- for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
- cnt = 0;
- info = &flash_info[bank];
-
- /* Nothing to do if the bank doesn't exist */
- if (info->sector_count == 0)
- return 0;
-
- /* Point to current bank protection information */
- sp_info_ptr = saved_prot_info + (bank *
CONFIG_SYS_MAX_FLASH_SECT);
-
- /*
- * Adjust addr_first or addr_last if we are on bank
boundary.
- * Address space between banks must be continuous for other
- * flash functions (like flash_sect_erase or flash_write) to
- * succeed. Banks must also be numbered in correct order,
- * according to increasing addresses.
- */
- if (addr_last > info->start[0] + info->size - 1)
- addr_last = info->start[0] + info->size - 1;
- if (addr_first < info->start[0])
- addr_first = info->start[0];
-
- for (i = 0; i < info->sector_count; i++) {
- /* Save current information about protected
sectors */
- if (prot == 0) {
- s = info->start[i];
- if ((s >= addr_first) && (s <= addr_last))
- sp_info_ptr[i] = info->protect[i];
-
- }
-
- /* Protect/unprotect sectors */
- if (sp_info_ptr[i] == 1) {
-#if defined(CONFIG_SYS_FLASH_PROTECTION)
- if (flash_real_protect(info, i, prot))
- return 1;
-#else
- info->protect[i] = prot;
-#endif
- cnt++;
- }
- }
-
- if (cnt) {
- printf("%sProtected %d sectors\n",
- prot ? "": "Un-", cnt);
- }
- }
-
- if((prot == 1) && saved_prot_info)
- free(saved_prot_info);
-
- return 0;
-}
-
-static int update_flash(ulong addr_source, ulong addr_first, ulong size)
-{
- ulong addr_last = addr_first + size - 1;
-
- /* round last address to the sector boundary */
- if (flash_sect_roundb(&addr_last) > 0)
- return 1;
-
- if (addr_first >= addr_last) {
- printf("Error: end address exceeds addressing space\n");
- return 1;
- }
-
- /* remove protection on processed sectors */
- if (update_flash_protect(0, addr_first, addr_last) > 0) {
- printf("Error: could not unprotect flash sectors\n");
- return 1;
- }
-
- printf("Erasing 0x%08lx - 0x%08lx", addr_first, addr_last);
- if (flash_sect_erase(addr_first, addr_last) > 0) {
- printf("Error: could not erase flash\n");
- return 1;
- }
-
- printf("Copying to flash...");
- if (flash_write((char *)addr_source, addr_first, size) > 0) {
- printf("Error: could not copy to flash\n");
- return 1;
- }
- printf("done\n");
-
- /* enable protection on processed sectors */
- if (update_flash_protect(1, addr_first, addr_last) > 0) {
- printf("Error: could not protect flash sectors\n");
- return 1;
- }
-
- return 0;
-}
-
-static int update_fit_getparams(const void *fit, int noffset, ulong *addr,
- ulong *fladdr, ulong *size)
-{
- const void *data;
-
- if (fit_image_get_data(fit, noffset, &data, (size_t *)size))
- return 1;
-
- if (fit_image_get_load(fit, noffset, (ulong *)fladdr))
- return 1;
-
- *addr = (ulong)data;
-
- return 0;
-}
-
-void update_tftp(void)
-{
- char *filename, *env_addr;
- int images_noffset, ndepth, noffset;
- ulong update_addr, update_fladdr, update_size;
- ulong addr;
- void *fit;
-
- printf("Auto-update from TFTP: ");
-
- /* get the file name of the update file */
- filename = getenv(UPDATE_FILE_ENV);
- if (filename == NULL) {
- printf("failed, env. variable '%s' not found\n",
- UPDATE_FILE_ENV);
- return;
- }
-
- printf("trying update file '%s'\n", filename);
-
- /* get load address of downloaded update file */
- if ((env_addr = getenv("loadaddr")) != NULL)
- addr = simple_strtoul(env_addr, NULL, 16);
- else
- addr = CONFIG_UPDATE_LOAD_ADDR;
-
-
- if (update_load(filename, CONFIG_UPDATE_TFTP_MSEC_MAX,
- CONFIG_UPDATE_TFTP_CNT_MAX, addr)) {
- printf("Can't load update file, aborting auto-update\n");
- return;
- }
-
- fit = (void *)addr;
-
- if (!fit_check_format((void *)fit)) {
- printf("Bad FIT format of the update file, aborting "
- "auto-update\n");
- return;
- }
-
- /* process updates */
- images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
-
- ndepth = 0;
- noffset = fdt_next_node(fit, images_noffset, &ndepth);
- while (noffset >= 0 && ndepth > 0) {
- if (ndepth != 1)
- goto next_node;
-
- printf("Processing update '%s' :",
- fit_get_name(fit, noffset, NULL));
-
- if (!fit_image_check_hashes(fit, noffset)) {
- printf("Error: invalid update hash, aborting\n");
- goto next_node;
- }
-
- printf("\n");
- if (update_fit_getparams(fit, noffset, &update_addr,
- &update_fladdr, &update_size)) {
- printf("Error: can't get update parameteres, "
-
"aborting\n");
- goto next_node;
- }
- if (update_flash(update_addr, update_fladdr, update_size)) {
- printf("Error: can't flash update (%ld %ld %ld),
aborting\n", update_addr, update_fladdr, update_size);
- goto next_node;
- }
-next_node:
- noffset = fdt_next_node(fit, noffset, &ndepth);
- }
-
- return;
-}
@@ -0,0 +1,556 @@
+/*
+ * (C) Copyright 2008 Semihalf
+ *
+ * Written by: Rafal Czubak <rcz@semihalf.com>
+ * Bartlomiej Sieka <tur@semihalf.com>
+ *
+ * (C) Copyright 2011 Tibbo Tech.
+ * Code refactoring, Cmd and Nand load/save features:
+ * Dvorkin Dmitry <dvorkin@tibbo.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+
+#if !(defined(CONFIG_FIT) && defined(CONFIG_OF_LIBFDT))
+#error "CONFIG_FIT and CONFIG_OF_LIBFDT are required for auto-update
feature"
+#endif
+
+#include <command.h>
+#if !defined(CONFIG_SYS_NO_FLASH)
+#include <flash.h>
+#endif
+#if defined(CONFIG_CMD_NAND)
+#include <nand.h>
+#endif
+#include <net.h>
+#include <malloc.h>
+
+/* env variable holding the location of the update file */
+#define UPDATE_FILE_ENV "updatefile"
+
+/* set configuration defaults if needed */
+#ifndef CONFIG_UPDITB_LOAD_ADDR
+#define CONFIG_UPDITB_LOAD_ADDR 0x100000
+#endif
+
+#ifndef CONFIG_UPDITB_TFTP_MSEC_MAX
+#define CONFIG_UPDITB_TFTP_MSEC_MAX 100
+#endif
+
+#ifndef CONFIG_UPDITB_TFTP_CNT_MAX
+#define CONFIG_UPDITB_TFTP_CNT_MAX 0
+#endif
+
+extern ulong TftpRRQTimeoutMSecs;
+extern int TftpRRQTimeoutCountMax;
+extern flash_info_t flash_info[];
+extern ulong load_addr;
+
+extern int run_command (const char *cmd, int flag);
+
+static uchar *saved_prot_info;
+
+enum XLAT_ST {
+ XLAT_ST_D, /* default */
+ XLAT_ST_S, /* skip \ */
+ XLAT_ST_B, /* begin attr name */
+ XLAT_ST_A, /* in attr name */
+ XLAT_ST_s, /* skip \} in attr name */
+ XLAT_ST_E, /* end attr name */
+};
+
+enum XLAT_CT {
+ XLAT_CT_DEF,
+ XLAT_CT_BKS,
+ XLAT_CT_BEG,
+ XLAT_CT_END,
+};
+
+enum XLAT_ST xlat_st_tbl[ 6][ 4] = {
+ // def \\ { }
+ { XLAT_ST_D, XLAT_ST_S, XLAT_ST_B, XLAT_ST_D }, // _ST_D
+ { XLAT_ST_D, XLAT_ST_D, XLAT_ST_D, XLAT_ST_D }, // _ST_S
+ { XLAT_ST_A, XLAT_ST_A, XLAT_ST_A, XLAT_ST_E }, // _ST_B
+ { XLAT_ST_A, XLAT_ST_s, XLAT_ST_A, XLAT_ST_E }, // _ST_A
+ { XLAT_ST_A, XLAT_ST_A, XLAT_ST_A, XLAT_ST_A }, // _ST_s
+ { XLAT_ST_D, XLAT_ST_S, XLAT_ST_B, XLAT_ST_D }, // _ST_E
+};
+
+typedef char *( *xlat_cfpt)( void *_data, char *_as, ulong _al, ulong
*_rlen);
+
+static int Xlat_R( const char *_i, ulong _il, char *_o, ulong _ol,
+ xlat_cfpt _cfp, void *_data) {
+ ulong i = -1, oi = 0;
+ ulong rlen, ret = 0;
+ char *tks;
+ ulong tkl;
+ char *repl_av = NULL;
+ unsigned char c;
+ enum XLAT_CT ctype;
+ enum XLAT_ST curst = XLAT_ST_D;
+
+ tks = NULL; tkl = 0;
+ while ( ++i < _il && ( c = _i[ i]) != '\0') {
+//printf( "x:%d\n", i);
+ ctype = XLAT_CT_DEF;
+ if ( c == '\\') ctype = XLAT_CT_BKS;
+ if ( c == '{' ) ctype = XLAT_CT_BEG;
+ if ( c == '}' ) ctype = XLAT_CT_END;
+ curst = xlat_st_tbl[ curst][ ctype];
+ switch ( curst) {
+ case XLAT_ST_s:
+ case XLAT_ST_S: break;
+ case XLAT_ST_D: if ( _o) _o[ oi++] = c; break;
+ case XLAT_ST_B: tks = ( _i + i + 1); tkl = 0; break;
+ case XLAT_ST_A: tkl++; break;
+ case XLAT_ST_E:
+// printf( "AVP:%s\n", tmp_attr);
+ // macro name ended
+ ret++;
+ // if output buffer == NULL - return number of potential subs
+ if ( !_o) break;
+ repl_av = NULL; rlen = 0;
+ if ( _cfp) repl_av = _cfp( _data, tks, tkl, &rlen);
+ // actually replace
+ if ( repl_av != NULL) { memcpy( _o + oi, repl_av, rlen); oi +=
rlen; }
+ // if replace to NULL
+ if ( repl_av == NULL && rlen > 0) break;
+ // if no replace found - copy {text} to output - safe for future
+ if ( repl_av == NULL && rlen < 1) {
+ _o[ oi++] = '{';
+ memcpy( _o + oi, tks, tkl); oi += tkl;
+ _o[ oi++] = '}'; }
+ break;
+ } // end of switch
+ if ( tkl >= _ol) return( ret);
+ }
+ return( ret); }
+
+static int update_load_tftp(char *filename, ulong addr)
+{
+ int size, rv;
+ ulong msec_max = CONFIG_UPDITB_TFTP_MSEC_MAX;
+ int cnt_max = CONFIG_UPDITB_TFTP_CNT_MAX;
+ ulong saved_timeout_msecs;
+ int saved_timeout_count;
+ char *saved_netretry, *saved_bootfile;
+
+ rv = 0;
+ /* save used globals and env variable */
+ saved_timeout_msecs = TftpRRQTimeoutMSecs;
+ saved_timeout_count = TftpRRQTimeoutCountMax;
+ saved_netretry = strdup(getenv("netretry"));
+ saved_bootfile = strdup(BootFile);
+
+ /* set timeouts for auto-update */
+ TftpRRQTimeoutMSecs = msec_max;
+ TftpRRQTimeoutCountMax = cnt_max;
+
+ /* we don't want to retry the connection if errors occur */
+ setenv("netretry", "no");
+
+ /* download the update file */
+ load_addr = addr;
+ copy_filename(BootFile, filename, sizeof(BootFile));
+ size = NetLoop(TFTP);
+
+ if (size < 0)
+ rv = 1;
+ else if (size > 0)
+ flush_cache(addr, size);
+
+ /* restore changed globals and env variable */
+ TftpRRQTimeoutMSecs = saved_timeout_msecs;
+ TftpRRQTimeoutCountMax = saved_timeout_count;
+
+ setenv("netretry", saved_netretry);
+ if (saved_netretry != NULL)
+ free(saved_netretry);
+
+ if (saved_bootfile != NULL) {
+ copy_filename(BootFile, saved_bootfile, sizeof(BootFile));
+ free(saved_bootfile);
+ }
+
+ return rv;
+}
+
+typedef struct Xlate_load_T {
+ char *file;
+ ulong load_to;
+} Xlate_load_t;
+
+char *Xlate_load( void *_data, char *_as, ulong _al, ulong *_rlen) {
+ Xlate_load_t *Xdp = ( Xlate_load_t *)_data;
+ char xs[ 64];
+ memset( xs, 0, 64);
+ if ( _al == 4 && memcmp( _as, "file", 4) == 0) sprintf( xs, "%s",
Xdp->file);
+ if ( _al == 7 && memcmp( _as, "load_to", 7) == 0) sprintf( xs,
"0x%08x", Xdp->load_to);
+ *_rlen = strlen( xs);
+ return( xs); }
+
+static int update_load_cmd( char *_file, ulong _addr) {
+ char *cmd;
+ char cmdx[ 1024];
+ Xlate_load_t Xd = { .file = _file, .load_to = _addr };
+ if ( ( cmd = getenv( "upditb_cmd_load_pre")) != NULL) {
+ memset( cmdx, 0, 1024);
+ Xlat_R( cmd, strlen( cmd), cmdx, 1024, Xlate_load, &Xd);
+ printf( "Preload cmd template:%s\n", cmd);
+ printf( "Xlated to:%s\n", cmdx);
+ /* prepare for loading into RAM, 'usb start' for ex. */
+ if ( run_command( cmdx, 0) == -1) return( 1);
+ }
+ /* load to RAM. 'fatload usb 0:1 <address> <file>' for ex. */
+ if ( ( cmd = getenv( "upditb_cmd_load")) != NULL) {
+ memset( cmdx, 0, 1024);
+ Xlat_R( cmd, strlen( cmd), cmdx, 1024, Xlate_load, &Xd);
+ printf( "Load cmd template:%s\n", cmd);
+ printf( "Xlated to:%s\n", cmdx);
+ /* prepare for loading into RAM, 'usb start' for ex. */
+ if ( run_command( cmdx, 0) == -1) return( 1);
+ }
+ return( 0); }
+
+typedef struct Xlate_flash_T {
+ ulong a_src;
+ ulong a_dst;
+ ulong size;
+} Xlate_flash_t;
+
+char *Xlate_flash( void *_data, char *_as, ulong _al, ulong *_rlen) {
+ Xlate_flash_t *Xdp = ( Xlate_flash_t *)_data;
+ char xs[ 64];
+ memset( xs, 0, 64);
+ if ( _al == 8 && memcmp( _as, "addr_src", 8) == 0) sprintf( xs,
"0x%08x", Xdp->a_src);
+ if ( _al == 8 && memcmp( _as, "addr_dst", 8) == 0) sprintf( xs,
"0x%08x", Xdp->a_dst);
+ if ( _al == 8 && memcmp( _as, "img_size", 8) == 0) sprintf( xs,
"0x%08x", Xdp->size);
+ *_rlen = strlen( xs);
+ return( xs); }
+
+static int update_s_cmd( ulong _addr_source, ulong _addr_first, ulong
_size) {
+ char *cmdc;
+ char cmdcx[ 1024];
+ Xlate_flash_t Xd = { .a_src = _addr_source, .a_dst = _addr_first,
.size = _size };
+ printf( "%s()\n", __FUNCTION__);
+ if ( ( cmdc = getenv( "upditb_cmd_save")) == NULL) return( 1);
+ memset( cmdcx, 0, 1024);
+ Xlat_R( cmdc, strlen( cmdc), cmdcx, 1024, Xlate_flash, &Xd);
+ printf( "Save cmd template:%s\n", cmdc);
+ printf( "Xlated to:%s\n", cmdcx);
+ /* save to target, nand write {addr_src} {addr_dst} {img_size} for ex. */
+ if ( run_command( cmdcx, 0) == -1) return( 1);
+ return( 0); }
+
+#if !defined(CONFIG_SYS_NO_FLASH)
+static int update_flash_protect(int prot, ulong addr_first, ulong
addr_last)
+{
+ uchar *sp_info_ptr;
+ ulong s;
+ int i, bank, cnt;
+ flash_info_t *info;
+
+ sp_info_ptr = NULL;
+
+ if (prot == 0) {
+ saved_prot_info =
+ calloc(CONFIG_SYS_MAX_FLASH_BANKS *
CONFIG_SYS_MAX_FLASH_SECT, 1);
+ if (!saved_prot_info)
+ return 1;
+ }
+
+ for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
+ cnt = 0;
+ info = &flash_info[bank];
+
+ /* Nothing to do if the bank doesn't exist */
+ if (info->sector_count == 0)
+ return 0;
+
+ /* Point to current bank protection information */
+ sp_info_ptr = saved_prot_info + (bank *
CONFIG_SYS_MAX_FLASH_SECT);
+
+ /*
+ * Adjust addr_first or addr_last if we are on bank
boundary.
+ * Address space between banks must be continuous for other
+ * flash functions (like flash_sect_erase or flash_write) to
+ * succeed. Banks must also be numbered in correct order,
+ * according to increasing addresses.
+ */
+ if (addr_last > info->start[0] + info->size - 1)
+ addr_last = info->start[0] + info->size - 1;
+ if (addr_first < info->start[0])
+ addr_first = info->start[0];
+
+ for (i = 0; i < info->sector_count; i++) {
+ /* Save current information about protected
sectors */
+ if (prot == 0) {
+ s = info->start[i];
+ if ((s >= addr_first) && (s <= addr_last))
+ sp_info_ptr[i] = info->protect[i];
+
+ }
+
+ /* Protect/unprotect sectors */
+ if (sp_info_ptr[i] == 1) {
+#if defined(CONFIG_SYS_FLASH_PROTECTION)
+ if (flash_real_protect(info, i, prot))
+ return 1;
+#else
+ info->protect[i] = prot;
+#endif
+ cnt++;
+ }
+ }
+
+ if (cnt) {
+ printf("%sProtected %d sectors\n",
+ prot ? "": "Un-", cnt);
+ }
+ }
+
+ if((prot == 1) && saved_prot_info)
+ free(saved_prot_info);
+
+ return 0;
+}
+
+static int update_s_flash(ulong addr_source, ulong addr_first, ulong size)
+{
+ ulong addr_last = addr_first + size - 1;
+
+ printf( "%s()\n", __FUNCTION__);
+ /* round last address to the sector boundary */
+ if (flash_sect_roundb(&addr_last) > 0)
+ return 1;
+
+ if (addr_first >= addr_last) {
+ printf("Error: end address exceeds addressing space\n");
+ return 1;
+ }
+
+ /* remove protection on processed sectors */
+ if (update_flash_protect(0, addr_first, addr_last) > 0) {
+ printf("Error: could not unprotect flash sectors\n");
+ return 1;
+ }
+
+ printf("Erasing 0x%08lx - 0x%08lx", addr_first, addr_last);
+ if (flash_sect_erase(addr_first, addr_last) > 0) {
+ printf("Error: could not erase flash\n");
+ return 1;
+ }
+
+ printf("Copying to flash...");
+ if (flash_write((char *)addr_source, addr_first, size) > 0) {
+ printf("Error: could not copy to flash\n");
+ return 1;
+ }
+ printf("done\n");
+
+ /* enable protection on processed sectors */
+ if (update_flash_protect(1, addr_first, addr_last) > 0) {
+ printf("Error: could not protect flash sectors\n");
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_NAND)
+static int update_s_nand( ulong _a_src, ulong _a_dst, size_t _size)
+{
+ int err;
+ size_t len = _size;
+ size_t tl;
+ tl = nand_info[ 0].writesize;
+ printf( "%s()\n", __FUNCTION__);
+ if ( ( _size % tl) != 0) {
+ printf( "padding %d with %d bytes\n", _size, ( tl - ( _size % tl)));
+ len = _size += ( tl - ( _size % tl));
+ printf( "new size is %d bytes\n", _size);
+ }
+ err = nand_write_skip_bad( &nand_info[ 0], _a_dst, &len, _a_src);
+ if ( err != 0) return( 1);
+ return( 0); }
+#endif
+
+static int update_fit_getparams(const void *fit, int noffset, ulong *addr,
+ ulong *fladdr, ulong *size)
+{
+ const void *data;
+
+ if (fit_image_get_data(fit, noffset, &data, (size_t *)size))
+ return 1;
+
+ if (fit_image_get_load(fit, noffset, (ulong *)fladdr))
+ return 1;
+
+ *addr = (ulong)data;
+
+ return 0;
+}
+
+void update_itb(void)
+{
+ char *filename, *env_addr;
+ char *method_load, *method_save, *ts;
+ int images_noffset, ndepth, noffset;
+ ulong update_addr, update_fladdr, update_size;
+ ulong addr;
+ void *fit;
+ int err, sl;
+
+ /* update method: tftp or something else */
+ ts = method_load = getenv( "upditb_load_method");
+ if ( method_load == NULL) method_load = "none";
+ printf( "Auto-update ITB load method:%s\n", method_load);
+ if ( ts == NULL) return;
+ method_save = getenv( "upditb_save_method");
+ if ( method_save == NULL) method_save = "flash";
+
+ /* get the file name of the update file */
+ filename = getenv(UPDATE_FILE_ENV);
+ if (filename == NULL) {
+ printf("failed, env. variable '%s' not found\n",
+ UPDATE_FILE_ENV);
+ return;
+ }
+
+ printf("trying update file '%s'\n", filename);
+#ifdef CONFIG_LCD
+ lcd_printf( "Loading auto-update file '%s'...", filename);
+#endif
+
+ /* get load address of downloaded update file */
+ if ((env_addr = getenv("loadaddr")) != NULL)
+ addr = simple_strtoul(env_addr, NULL, 16);
+ else
+ addr = CONFIG_UPDITB_LOAD_ADDR;
+
+ err = -1;
+ sl = strlen( method_load);
+ if ( sl == 4 && strcmp( method_load, "tftp") == 0) err =
update_load_tftp( filename, addr);
+ if ( sl == 3 && strcmp( method_load, "cmd" ) == 0) err =
update_load_cmd( filename, addr);
+ switch ( err) {
+ case -1:
+#ifdef CONFIG_LCD
+ lcd_printf( "ERR-1\n");
+#endif
+ printf( "No such method '%s', aborting auto-update\n",
method_load);
+ return;
+ break;
+ case 0: /* it's OK */
+#ifdef CONFIG_LCD
+ lcd_printf( "OK\n");
+#endif
+ break;
+ default:
+#ifdef CONFIG_LCD
+ lcd_printf( "ERR\n");
+#endif
+ printf( "Can't load update file, aborting auto-update\n");
+ return;
+ break;
+ }
+
+#ifdef CONFIG_LCD
+ lcd_printf( "Auto-update file is loaded, checking...");
+#endif
+ fit = (void *)addr;
+
+ if (!fit_check_format((void *)fit)) {
+ printf("Bad FIT format of the update file, aborting "
+ "auto-update\n");
+#ifdef CONFIG_LCD
+ lcd_printf( "ERR\n");
+#endif
+ return;
+ }
+#ifdef CONFIG_LCD
+ lcd_printf( "OK\n");
+#endif
+
+ /* process updates */
+ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+
+#ifdef CONFIG_LCD
+ err = fit_get_desc( fit, 0, &ts);
+ if ( err) ts = "(no description)";
+ lcd_printf( "Processing %s...\n", ts);
+#endif
+fit_print_contents( (void *)fit);
+ ndepth = 0;
+ noffset = fdt_next_node(fit, images_noffset, &ndepth);
+ while (noffset >= 0 && ndepth > 0) {
+ if (ndepth != 1)
+ goto next_node;
+
+ printf("Processing update '%s' :",
+ fit_get_name(fit, noffset, NULL));
+
+ if (!fit_image_check_hashes(fit, noffset)) {
+ printf("Error: invalid update hash, aborting\n");
+ goto next_node;
+ }
+
+ printf("\n");
+ if (update_fit_getparams(fit, noffset, &update_addr,
+ &update_fladdr, &update_size)) {
+ printf("Error: can't get update parameteres, "
+
"aborting\n");
+ goto next_node;
+ }
+fit_image_print( fit, noffset, "");
+#ifdef CONFIG_LCD
+ err = fit_get_desc( fit, noffset, &ts);
+ if ( err) ts = "(no description)";
+ lcd_printf( "Flashing %s...", ts);
+#endif
+ sl = strlen( method_save);
+ err = -1;
+#if !defined(CONFIG_SYS_NO_FLASH)
+ if ( sl == 5 && strcmp( method_save, "flash") == 0) err
= update_s_flash(update_addr, update_fladdr, update_size);
+#endif
+ if ( sl == 3 && strcmp( method_save, "cmd" ) == 0) err =
update_s_cmd( update_addr, update_fladdr, update_size);
+#if defined(CONFIG_CMD_NAND)
+ if ( sl == 4 && strcmp( method_save, "nand") == 0) err =
update_s_nand(update_addr, update_fladdr, update_size);
+#endif
+ /* fallback if method not found */
+ if ( err == -1) err = update_s_flash(update_addr,
update_fladdr, update_size);
+ if ( err) {
+ printf("Error: can't flash update (%ld %ld %ld),
aborting\n", update_addr, update_fladdr, update_size);
+#ifdef CONFIG_LCD
+ lcd_printf( "ERR\n");
+#endif
+ goto next_node;
+ }
+#ifdef CONFIG_LCD
+ lcd_printf( "OK\n");
+#endif
+next_node:
+ noffset = fdt_next_node(fit, noffset, &ndepth);
+ }
+
+ return;
+}
@@ -2108,10 +2108,11 @@
-150 common/cmd_nand.c Incorrect FIT image format
151 common/cmd_nand.c FIT image format OK
-- Automatic software updates via TFTP server
- CONFIG_UPDATE_TFTP
- CONFIG_UPDATE_TFTP_CNT_MAX
- CONFIG_UPDATE_TFTP_MSEC_MAX
+- Automatic software updates via ITB structure
+ CONFIG_UPDITB
+ CONFIG_UPDITB_TFTP
+ CONFIG_UPDITB_TFTP_CNT_MAX
+ CONFIG_UPDITB_TFTP_MSEC_MAX
These options enable and control the auto-update feature;
for a more detailed description refer to doc/README.update.