X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fupdate.c;h=c8dd346a0956951a0683679bdd37d13c07383e60;hb=a595a0e910960ccd4611719d5fb5c279859efaee;hp=938cc068166c41e1a28fcf4bbe83302c2918d2cd;hpb=4bae90904b69ce3deb9f7c334ef12ed74e18a275;p=oweals%2Fu-boot.git diff --git a/common/update.c b/common/update.c index 938cc06816..c8dd346a09 100644 --- a/common/update.c +++ b/common/update.c @@ -1,43 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2008 Semihalf * * Written by: Rafal Czubak * Bartlomiej Sieka - * - * 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 +#include +#include #if !(defined(CONFIG_FIT) && defined(CONFIG_OF_LIBFDT)) #error "CONFIG_FIT and CONFIG_OF_LIBFDT are required for auto-update feature" #endif -#if defined(CFG_NO_FLASH) -#error "CFG_NO_FLASH defined, but FLASH is required for auto-update feature" +#if defined(CONFIG_UPDATE_TFTP) && !defined(CONFIG_MTD_NOR_FLASH) +#error "CONFIG_UPDATE_TFTP and !CONFIG_MTD_NOR_FLASH needed for legacy behaviour" #endif #include +#include #include #include +#include #include +#include +#include +#include /* env variable holding the location of the update file */ #define UPDATE_FILE_ENV "updatefile" @@ -55,13 +44,12 @@ #define CONFIG_UPDATE_TFTP_CNT_MAX 0 #endif -extern ulong TftpRRQTimeoutMSecs; -extern int TftpRRQTimeoutCountMax; +extern ulong tftp_timeout_ms; +extern int tftp_timeout_count_max; +#ifdef CONFIG_MTD_NOR_FLASH extern flash_info_t flash_info[]; -extern ulong load_addr; - static uchar *saved_prot_info; - +#endif static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) { int size, rv; @@ -71,22 +59,22 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) 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); + saved_timeout_msecs = tftp_timeout_ms; + saved_timeout_count = tftp_timeout_count_max; + saved_netretry = strdup(env_get("netretry")); + saved_bootfile = strdup(net_boot_file_name); /* set timeouts for auto-update */ - TftpRRQTimeoutMSecs = msec_max; - TftpRRQTimeoutCountMax = cnt_max; + tftp_timeout_ms = msec_max; + tftp_timeout_count_max = cnt_max; /* we don't want to retry the connection if errors occur */ - setenv("netretry", "no"); + env_set("netretry", "no"); /* download the update file */ - load_addr = addr; - copy_filename(BootFile, filename, sizeof(BootFile)); - size = NetLoop(TFTP); + image_load_addr = addr; + copy_filename(net_boot_file_name, filename, sizeof(net_boot_file_name)); + size = net_loop(TFTPGET); if (size < 0) rv = 1; @@ -94,21 +82,23 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) flush_cache(addr, size); /* restore changed globals and env variable */ - TftpRRQTimeoutMSecs = saved_timeout_msecs; - TftpRRQTimeoutCountMax = saved_timeout_count; + tftp_timeout_ms = saved_timeout_msecs; + tftp_timeout_count_max = saved_timeout_count; - setenv("netretry", saved_netretry); + env_set("netretry", saved_netretry); if (saved_netretry != NULL) free(saved_netretry); if (saved_bootfile != NULL) { - copy_filename(BootFile, saved_bootfile, sizeof(BootFile)); + copy_filename(net_boot_file_name, saved_bootfile, + sizeof(net_boot_file_name)); free(saved_bootfile); } return rv; } +#ifdef CONFIG_MTD_NOR_FLASH static int update_flash_protect(int prot, ulong addr_first, ulong addr_last) { uchar *sp_info_ptr; @@ -120,12 +110,12 @@ static int update_flash_protect(int prot, ulong addr_first, ulong addr_last) if (prot == 0) { saved_prot_info = - calloc(CFG_MAX_FLASH_BANKS * CFG_MAX_FLASH_SECT, 1); + calloc(CONFIG_SYS_MAX_FLASH_BANKS * CONFIG_SYS_MAX_FLASH_SECT, 1); if (!saved_prot_info) return 1; } - for (bank = 0; bank < CFG_MAX_FLASH_BANKS; ++bank) { + for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) { cnt = 0; info = &flash_info[bank]; @@ -134,7 +124,7 @@ static int update_flash_protect(int prot, ulong addr_first, ulong addr_last) return 0; /* Point to current bank protection information */ - sp_info_ptr = saved_prot_info + (bank * CFG_MAX_FLASH_SECT); + sp_info_ptr = saved_prot_info + (bank * CONFIG_SYS_MAX_FLASH_SECT); /* * Adjust addr_first or addr_last if we are on bank boundary. @@ -159,7 +149,7 @@ static int update_flash_protect(int prot, ulong addr_first, ulong addr_last) /* Protect/unprotect sectors */ if (sp_info_ptr[i] == 1) { -#if defined(CFG_FLASH_PROTECTION) +#if defined(CONFIG_SYS_FLASH_PROTECTION) if (flash_real_protect(info, i, prot)) return 1; #else @@ -180,9 +170,11 @@ static int update_flash_protect(int prot, ulong addr_first, ulong addr_last) return 0; } +#endif static int update_flash(ulong addr_source, ulong addr_first, ulong size) { +#ifdef CONFIG_MTD_NOR_FLASH ulong addr_last = addr_first + size - 1; /* round last address to the sector boundary */ @@ -218,7 +210,7 @@ static int update_flash(ulong addr_source, ulong addr_first, ulong size) printf("Error: could not protect flash sectors\n"); return 1; } - +#endif return 0; } @@ -238,28 +230,44 @@ static int update_fit_getparams(const void *fit, int noffset, ulong *addr, return 0; } -void update_tftp(void) +int update_tftp(ulong addr, char *interface, char *devstring) { - char *filename, *env_addr; - int images_noffset, ndepth, noffset; + char *filename, *env_addr, *fit_image_name; ulong update_addr, update_fladdr, update_size; - ulong addr; + int images_noffset, ndepth, noffset; + bool update_tftp_dfu; + int ret = 0; void *fit; + if (interface == NULL && devstring == NULL) { + update_tftp_dfu = false; + } else if (interface && devstring) { + update_tftp_dfu = true; + } else { + pr_err("Interface: %s and devstring: %s not supported!\n", + interface, devstring); + return -EINVAL; + } + + /* use already present image */ + if (addr) + goto got_update_file; + printf("Auto-update from TFTP: "); /* get the file name of the update file */ - filename = getenv(UPDATE_FILE_ENV); + filename = env_get(UPDATE_FILE_ENV); if (filename == NULL) { printf("failed, env. variable '%s' not found\n", UPDATE_FILE_ENV); - return; + return 1; } printf("trying update file '%s'\n", filename); /* get load address of downloaded update file */ - if ((env_addr = getenv("loadaddr")) != NULL) + env_addr = env_get("loadaddr"); + if (env_addr) addr = simple_strtoul(env_addr, NULL, 16); else addr = CONFIG_UPDATE_LOAD_ADDR; @@ -268,15 +276,16 @@ void update_tftp(void) 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; + return 1; } +got_update_file: fit = (void *)addr; if (!fit_check_format((void *)fit)) { printf("Bad FIT format of the update file, aborting " "auto-update\n"); - return; + return 1; } /* process updates */ @@ -288,11 +297,12 @@ void update_tftp(void) if (ndepth != 1) goto next_node; - printf("Processing update '%s' :", - fit_get_name(fit, noffset, NULL)); + fit_image_name = (char *)fit_get_name(fit, noffset, NULL); + printf("Processing update '%s' :", fit_image_name); - if (!fit_image_check_hashes(fit, noffset)) { + if (!fit_image_verify(fit, noffset)) { printf("Error: invalid update hash, aborting\n"); + ret = 1; goto next_node; } @@ -301,15 +311,27 @@ void update_tftp(void) &update_fladdr, &update_size)) { printf("Error: can't get update parameteres, " "aborting\n"); + ret = 1; goto next_node; } - if (update_flash(update_addr, update_fladdr, update_size)) { - printf("Error: can't flash update, aborting\n"); - goto next_node; + + if (!update_tftp_dfu) { + if (update_flash(update_addr, update_fladdr, + update_size)) { + printf("Error: can't flash update, aborting\n"); + ret = 1; + goto next_node; + } + } else if (fit_image_check_type(fit, noffset, + IH_TYPE_FIRMWARE)) { + ret = dfu_tftp_write(fit_image_name, update_addr, + update_size, interface, devstring); + if (ret) + return ret; } next_node: noffset = fdt_next_node(fit, noffset, &ndepth); } - return; + return ret; }