From 045fd8b13dc7b08a309043c28fc764c8fd2fde14 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Thu, 29 Oct 2020 13:47:41 +0900 Subject: dfu: rename dfu_tftp_write() to dfu_write_by_name() This function is essentially independent from tftp, and will also be utilised in implementing UEFI capsule update in a later commit. So just give it a more generic name. In addition, a new configuration option, CONFIG_DFU_WRITE_ALT, was introduced so that the file will be compiled with different options, particularly one added in a later commit. Signed-off-by: AKASHI Takahiro Reviewed-by: Tom Rini --- common/update.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'common') diff --git a/common/update.c b/common/update.c index 36b6b7523d5..39946776d74 100644 --- a/common/update.c +++ b/common/update.c @@ -324,8 +324,9 @@ got_update_file: } } else if (fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE)) { - ret = dfu_tftp_write(fit_image_name, update_addr, - update_size, interface, devstring); + ret = dfu_write_by_name(fit_image_name, update_addr, + update_size, interface, + devstring); if (ret) return ret; } -- cgit v1.3.1 From 1c2d1293f608a367488b5dea7250dda8bb8f1d02 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Thu, 29 Oct 2020 13:47:42 +0900 Subject: dfu: modify an argument type for an address The range of an addressable pointer can go beyond 'integer'. So change the argument type to a void pointer. Signed-off-by: AKASHI Takahiro Reviewed-by: Heinrich Schuchardt Reviewed-by: Tom Rini --- common/update.c | 3 ++- drivers/dfu/dfu_alt.c | 6 +++--- include/dfu.h | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'common') diff --git a/common/update.c b/common/update.c index 39946776d74..8dd6ee8b7dd 100644 --- a/common/update.c +++ b/common/update.c @@ -324,7 +324,8 @@ got_update_file: } } else if (fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE)) { - ret = dfu_write_by_name(fit_image_name, update_addr, + ret = dfu_write_by_name(fit_image_name, + (void *)update_addr, update_size, interface, devstring); if (ret) diff --git a/drivers/dfu/dfu_alt.c b/drivers/dfu/dfu_alt.c index 8870967f4a6..53e8489b0e5 100644 --- a/drivers/dfu/dfu_alt.c +++ b/drivers/dfu/dfu_alt.c @@ -23,14 +23,14 @@ * * Return: 0 - on success, error code - otherwise */ -int dfu_write_by_name(char *dfu_entity_name, unsigned int addr, +int dfu_write_by_name(char *dfu_entity_name, void *addr, unsigned int len, char *interface, char *devstring) { char *s, *sb; int alt_setting_num, ret; struct dfu_entity *dfu; - debug("%s: name: %s addr: 0x%x len: %d device: %s:%s\n", __func__, + debug("%s: name: %s addr: 0x%p len: %d device: %s:%s\n", __func__, dfu_entity_name, addr, len, interface, devstring); ret = dfu_init_env_entities(interface, devstring); @@ -69,7 +69,7 @@ int dfu_write_by_name(char *dfu_entity_name, unsigned int addr, goto done; } - ret = dfu_write_from_mem_addr(dfu, (void *)(uintptr_t)addr, len); + ret = dfu_write_from_mem_addr(dfu, (void *)addr, len); done: dfu_free_entities(); diff --git a/include/dfu.h b/include/dfu.h index a4cd86c0a6c..d3d7e07b60d 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -507,10 +507,10 @@ static inline int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, * Return: 0 - on success, error code - otherwise */ #if CONFIG_IS_ENABLED(DFU_WRITE_ALT) -int dfu_write_by_name(char *dfu_entity_name, unsigned int addr, +int dfu_write_by_name(char *dfu_entity_name, void *addr, unsigned int len, char *interface, char *devstring); #else -static inline int dfu_write_by_name(char *dfu_entity_name, unsigned int addr, +static inline int dfu_write_by_name(char *dfu_entity_name, void *addr, unsigned int len, char *interface, char *devstring) { -- cgit v1.3.1 From 3149e524fc1e76ec1420cd17588c724d4232a904 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Thu, 29 Oct 2020 13:47:43 +0900 Subject: common: update: add a generic interface for FIT image The main purpose of this patch is to separate a generic interface for updating firmware using DFU drivers from "auto-update" via tftp. This function will also be used in implementing UEFI capsule update in a later commit. Signed-off-by: AKASHI Takahiro Reviewed-by: Tom Rini --- common/Kconfig | 15 +++++++++++ common/Makefile | 3 +-- common/update.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/dfu/Kconfig | 1 + include/image.h | 12 +++++++++ 5 files changed, 100 insertions(+), 2 deletions(-) (limited to 'common') diff --git a/common/Kconfig b/common/Kconfig index 318d372a481..2bce8c9ba1b 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -599,9 +599,15 @@ endmenu menu "Update support" +config UPDATE_COMMON + bool + default n + select DFU_WRITE_ALT + config UPDATE_TFTP bool "Auto-update using fitImage via TFTP" depends on FIT + select UPDATE_COMMON help This option allows performing update of NOR with data in fitImage sent via TFTP boot. @@ -616,6 +622,15 @@ config UPDATE_TFTP_MSEC_MAX default 100 depends on UPDATE_TFTP +config UPDATE_FIT + bool "Firmware update using fitImage" + depends on FIT + depends on DFU + select UPDATE_COMMON + help + This option allows performing update of DFU-capable storage with + data in fitImage. + config ANDROID_AB bool "Android A/B updates" default n diff --git a/common/Makefile b/common/Makefile index 2e7a090588d..bcf352d0165 100644 --- a/common/Makefile +++ b/common/Makefile @@ -53,8 +53,7 @@ obj-$(CONFIG_LCD_ROTATION) += lcd_console_rotation.o obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o obj-$(CONFIG_LYNXKDI) += lynxkdi.o obj-$(CONFIG_MENU) += menu.o -obj-$(CONFIG_UPDATE_TFTP) += update.o -obj-$(CONFIG_DFU_TFTP) += update.o +obj-$(CONFIG_UPDATE_COMMON) += update.o obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o obj-$(CONFIG_CMDLINE) += cli_readline.o cli_simple.o diff --git a/common/update.c b/common/update.c index 8dd6ee8b7dd..808be0880df 100644 --- a/common/update.c +++ b/common/update.c @@ -29,6 +29,7 @@ #include #include +#ifdef CONFIG_DFU_TFTP /* env variable holding the location of the update file */ #define UPDATE_FILE_ENV "updatefile" @@ -98,6 +99,7 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) return rv; } +#endif /* CONFIG_DFU_TFTP */ #ifdef CONFIG_MTD_NOR_FLASH static int update_flash_protect(int prot, ulong addr_first, ulong addr_last) @@ -231,6 +233,7 @@ static int update_fit_getparams(const void *fit, int noffset, ulong *addr, return 0; } +#ifdef CONFIG_DFU_TFTP int update_tftp(ulong addr, char *interface, char *devstring) { char *filename, *env_addr, *fit_image_name; @@ -337,3 +340,71 @@ next_node: return ret; } +#endif /* CONFIG_DFU_UPDATE */ + +#ifdef CONFIG_UPDATE_FIT +/** + * fit_update - update storage with FIT image + * @fit: Pointer to FIT image + * + * Update firmware on storage using FIT image as input. + * The storage area to be update will be identified by the name + * in FIT and matching it to "dfu_alt_info" variable. + * + * Return: 0 - on success, non-zero - otherwise + */ +int fit_update(const void *fit) +{ + char *fit_image_name; + ulong update_addr, update_fladdr, update_size; + int images_noffset, ndepth, noffset; + int ret = 0; + + if (!fit) + return -EINVAL; + + if (!fit_check_format((void *)fit)) { + printf("Bad FIT format of the update file, aborting auto-update\n"); + return -EINVAL; + } + + /* 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; + + fit_image_name = (char *)fit_get_name(fit, noffset, NULL); + printf("Processing update '%s' :", fit_image_name); + + if (!fit_image_verify(fit, noffset)) { + printf("Error: invalid update hash, aborting\n"); + ret = 1; + goto next_node; + } + + printf("\n"); + if (update_fit_getparams(fit, noffset, &update_addr, + &update_fladdr, &update_size)) { + printf("Error: can't get update parameters, aborting\n"); + ret = 1; + goto next_node; + } + + if (fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE)) { + ret = dfu_write_by_name(fit_image_name, + (void *)update_addr, + update_size, NULL, NULL); + if (ret) + return ret; + } +next_node: + noffset = fdt_next_node(fit, noffset, &ndepth); + } + + return ret; +} +#endif /* CONFIG_UPDATE_FIT */ diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig index 10196f390fc..b7427fc4f0d 100644 --- a/drivers/dfu/Kconfig +++ b/drivers/dfu/Kconfig @@ -22,6 +22,7 @@ config DFU_TFTP bool "DFU via TFTP" select DFU_WRITE_ALT select DFU_OVER_TFTP + select UPDATE_COMMON help This option allows performing update of DFU-managed medium with data sent via TFTP boot. diff --git a/include/image.h b/include/image.h index 4094ee588a5..00bc03bebec 100644 --- a/include/image.h +++ b/include/image.h @@ -1602,4 +1602,16 @@ struct fit_loadable_tbl { .handler = _handler, \ } +/** + * fit_update - update storage with FIT image + * @fit: Pointer to FIT image + * + * Update firmware on storage using FIT image as input. + * The storage area to be update will be identified by the name + * in FIT and matching it to "dfu_alt_info" variable. + * + * Return: 0 on success, non-zero otherwise + */ +int fit_update(const void *fit); + #endif /* __IMAGE_H__ */ -- cgit v1.3.1 From c57c9439548a58a0c1f0eb2ec7b5ab5d7b7fd801 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Thu, 29 Oct 2020 13:47:45 +0900 Subject: efi_loader: add option to initialise EFI subsystem early If this option, CONFIG_EFI_SETUP_EARLY, is enabled, the initialisation of UEFI subsystem will be done as part of U-Boot initialisation. Please note that this option won't be enabled explicitly by users, instead, should be enabled implicitly by other configuration options. Specifically, this feature will be utilised in implementing capsule-on-disk feature. Signed-off-by: AKASHI Takahiro Reviewed-by: Heinrich Schuchardt --- common/board_r.c | 6 ++++++ lib/efi_loader/Kconfig | 4 ++++ 2 files changed, 10 insertions(+) (limited to 'common') diff --git a/common/board_r.c b/common/board_r.c index b9217b2e27f..2212d981e5e 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -73,6 +73,9 @@ #if defined(CONFIG_GPIO_HOG) #include #endif +#ifdef CONFIG_EFI_SETUP_EARLY +#include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -889,6 +892,9 @@ static init_fnc_t init_sequence_r[] = { #endif #if defined(CONFIG_PRAM) initr_mem, +#endif +#ifdef CONFIG_EFI_SETUP_EARLY + (init_fnc_t)efi_init_obj_list, #endif run_main_loop, }; diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index ab42f3ba75b..075481428cd 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -27,6 +27,10 @@ config EFI_LOADER if EFI_LOADER +config EFI_SETUP_EARLY + bool + default n + choice prompt "Store for non-volatile UEFI variables" default EFI_VARIABLE_FILE_STORE -- cgit v1.3.1