Re: [PATCH] RockPi4: Add UEFI capsule update support
hi Peter, On Sat, 14 May 2022 at 13:44, Peter Robinson wrote: > > On Fri, May 13, 2022 at 7:50 AM Sughosh Ganu wrote: > > > > Add support for updating the idbloader and u-boot images through the > > UEFI capsule update functionality. Enable the modules required for > > supporting the functionality. > > > > The implementation is for the updatable images placed on a GPT > > partitioned storage device. With the GPT partition devices, the > > partition information can be obtained at runtime, and hence the > > dfu_alt_info variable needed for the updates is being populated at > > runtime. > > > > This requires the partitions containing the idbloader and u-boot > > images to be created with the PartitionTypeGUID values set to the > > corresponding image type GUID values defined in the platform's config > > header(ROCKPI_4{B,C}_IDBLOADER_IMAGE_GUID and > > ROCKPI_4{B,C}_UBOOT_IMAGE_GUID). > > I think it would be useful to break this patch down into more than one > patch. At least the core changes to evb_rk3399/evb-rk3399.c and the > board specific changes. Also given these changes arre likely of > interest to other boards should they go to somewhere more central > than evb_rk3399/evb-rk3399.c to enable less code duplication across > rk3399 or even rockchip devices as a whole? I believe I can move the logic to set dfu_alt_info to some place like arch/arm/mach-rockchip/board.c. The definition of rk_board_late_init() can stay in evb-rk3399.c since it is populating the capsule update structures for the rk3399 family of platforms. Does that sound okay to you? If so, I will make the changes and send a V2, or if you have some other solution in mind, please let me know. Thanks. -sughosh > > Peter > > > Signed-off-by: Sughosh Ganu > > --- > > arch/arm/mach-rockchip/Kconfig | 1 + > > board/rockchip/evb_rk3399/evb-rk3399.c | 190 - > > configs/rock-pi-4-rk3399_defconfig | 4 + > > configs/rock-pi-4c-rk3399_defconfig| 4 + > > include/configs/rk3399_common.h| 16 +++ > > 5 files changed, 214 insertions(+), 1 deletion(-) > > > > diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig > > index 18aff5480b..6d13e7b92e 100644 > > --- a/arch/arm/mach-rockchip/Kconfig > > +++ b/arch/arm/mach-rockchip/Kconfig > > @@ -246,6 +246,7 @@ config ROCKCHIP_RK3399 > > select DM_PMIC > > select DM_REGULATOR_FIXED > > select BOARD_LATE_INIT > > + imply PARTITION_TYPE_GUID > > imply PRE_CONSOLE_BUFFER > > imply ROCKCHIP_COMMON_BOARD > > imply ROCKCHIP_SDRAM_COMMON > > diff --git a/board/rockchip/evb_rk3399/evb-rk3399.c > > b/board/rockchip/evb_rk3399/evb-rk3399.c > > index abb76585cf..cc976d9471 100644 > > --- a/board/rockchip/evb_rk3399/evb-rk3399.c > > +++ b/board/rockchip/evb_rk3399/evb-rk3399.c > > @@ -5,11 +5,27 @@ > > > > #include > > #include > > +#include > > #include > > #include > > +#include > > +#include > > +#include > > #include > > #include > > > > +#define ROCKPI4_UPDATABLE_IMAGES 2 > > + > > +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) > > +struct efi_fw_image fw_images[ROCKPI4_UPDATABLE_IMAGES] = {0}; > > + > > +struct efi_capsule_update_info update_info = { > > + .images = fw_images, > > +}; > > + > > +u8 num_image_type_guids = ARRAY_SIZE(fw_images); > > +#endif > > + > > #ifndef CONFIG_SPL_BUILD > > int board_early_init_f(void) > > { > > @@ -29,4 +45,176 @@ int board_early_init_f(void) > > out: > > return 0; > > } > > -#endif > > + > > +#if defined(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) && > > defined(CONFIG_EFI_PARTITION) > > + > > +#define DFU_ALT_BUF_LEN SZ_1K > > + > > +static bool board_is_rockpi_4b(void) > > +{ > > + return CONFIG_IS_ENABLED(TARGET_EVB_RK3399) && > > + of_machine_is_compatible("radxa,rockpi4b"); > > +} > > + > > +static bool board_is_rockpi_4c(void) > > +{ > > + return CONFIG_IS_ENABLED(TARGET_EVB_RK3399) && > > + of_machine_is_compatible("radxa,rockpi4c"); > > +} > > + > > +static bool updatable_image(struct disk_partition *info) > > +{ > > + int i; > > + bool ret = false; > > + efi_guid_t image_type_guid; > > + > > + uuid_str_to_bin(info->type_guid, image_ty
[PATCH] RockPi4: Add UEFI capsule update support
Add support for updating the idbloader and u-boot images through the UEFI capsule update functionality. Enable the modules required for supporting the functionality. The implementation is for the updatable images placed on a GPT partitioned storage device. With the GPT partition devices, the partition information can be obtained at runtime, and hence the dfu_alt_info variable needed for the updates is being populated at runtime. This requires the partitions containing the idbloader and u-boot images to be created with the PartitionTypeGUID values set to the corresponding image type GUID values defined in the platform's config header(ROCKPI_4{B,C}_IDBLOADER_IMAGE_GUID and ROCKPI_4{B,C}_UBOOT_IMAGE_GUID). Signed-off-by: Sughosh Ganu --- arch/arm/mach-rockchip/Kconfig | 1 + board/rockchip/evb_rk3399/evb-rk3399.c | 190 - configs/rock-pi-4-rk3399_defconfig | 4 + configs/rock-pi-4c-rk3399_defconfig| 4 + include/configs/rk3399_common.h| 16 +++ 5 files changed, 214 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 18aff5480b..6d13e7b92e 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -246,6 +246,7 @@ config ROCKCHIP_RK3399 select DM_PMIC select DM_REGULATOR_FIXED select BOARD_LATE_INIT + imply PARTITION_TYPE_GUID imply PRE_CONSOLE_BUFFER imply ROCKCHIP_COMMON_BOARD imply ROCKCHIP_SDRAM_COMMON diff --git a/board/rockchip/evb_rk3399/evb-rk3399.c b/board/rockchip/evb_rk3399/evb-rk3399.c index abb76585cf..cc976d9471 100644 --- a/board/rockchip/evb_rk3399/evb-rk3399.c +++ b/board/rockchip/evb_rk3399/evb-rk3399.c @@ -5,11 +5,27 @@ #include #include +#include #include #include +#include +#include +#include #include #include +#define ROCKPI4_UPDATABLE_IMAGES 2 + +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_image fw_images[ROCKPI4_UPDATABLE_IMAGES] = {0}; + +struct efi_capsule_update_info update_info = { + .images = fw_images, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif + #ifndef CONFIG_SPL_BUILD int board_early_init_f(void) { @@ -29,4 +45,176 @@ int board_early_init_f(void) out: return 0; } -#endif + +#if defined(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) && defined(CONFIG_EFI_PARTITION) + +#define DFU_ALT_BUF_LEN SZ_1K + +static bool board_is_rockpi_4b(void) +{ + return CONFIG_IS_ENABLED(TARGET_EVB_RK3399) && + of_machine_is_compatible("radxa,rockpi4b"); +} + +static bool board_is_rockpi_4c(void) +{ + return CONFIG_IS_ENABLED(TARGET_EVB_RK3399) && + of_machine_is_compatible("radxa,rockpi4c"); +} + +static bool updatable_image(struct disk_partition *info) +{ + int i; + bool ret = false; + efi_guid_t image_type_guid; + + uuid_str_to_bin(info->type_guid, image_type_guid.b, + UUID_STR_FORMAT_GUID); + + for (i = 0; i < ROCKPI4_UPDATABLE_IMAGES; i++) { + if (!guidcmp(_images[i].image_type_id, _type_guid)) { + ret = true; + break; + } + } + + return ret; +} + +static void set_image_index(struct disk_partition *info, int index) +{ + int i; + efi_guid_t image_type_guid; + + uuid_str_to_bin(info->type_guid, image_type_guid.b, + UUID_STR_FORMAT_GUID); + + for (i = 0; i < ROCKPI4_UPDATABLE_IMAGES; i++) { + if (!guidcmp(_images[i].image_type_id, _type_guid)) { + fw_images[i].image_index = index; + break; + } + } +} + +static int get_mmc_desc(struct blk_desc **desc) +{ + int ret; + struct mmc *mmc; + struct udevice *dev; + + /* +* For now the firmware images are assumed to +* be on the SD card +*/ + ret = uclass_get_device(UCLASS_MMC, 1, ); + if (ret) + return -1; + + mmc = mmc_get_mmc_dev(dev); + if (!mmc) + return -1; + + if (mmc_init(mmc)) + return -1; + + *desc = mmc_get_blk_desc(mmc); + if (!*desc) + return -1; + + return 0; +} + +void set_dfu_alt_info(char *interface, char *devstr) +{ + const char *name; + bool first = true; + int p, len, devnum, ret; + char buf[DFU_ALT_BUF_LEN]; + struct disk_partition info; + struct blk_desc *desc = NULL; + + ret = get_mmc_desc(); + if (ret) + return; + + memset(buf, 0, sizeof(buf)); + name = blk_get_if_type_name(desc->if_type); + devnum = desc->devnum; + len = strlen(buf); + + len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, +"%s %d=", name, devnum); + + for (p = 1; p
[PATCH v8 8/8] doc: uefi: Update the capsule update related documentation
Update the capsule update functionality related documentation to refect the additional definitions that need to be made per platform for supporting the capsule update feature. Signed-off-by: Sughosh Ganu Reviewed-by: Masami Hiramatsu --- Changes since V7: * Add a comment about using update_info variable doc/develop/uefi/uefi.rst | 100 +- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index fe337c88bd..753a4e5e29 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -312,8 +312,8 @@ Run the following command .. code-block:: console $ mkeficapsule \ - --index 1 --instance 0 \ - [--fit | --raw ] \ + --index --instance 0 \ + --guid \ Performing the update @@ -333,8 +333,104 @@ won't be taken over across the reboot. If this is the case, you can skip this feature check with the Kconfig option (CONFIG_EFI_IGNORE_OSINDICATIONS) set. +A few values need to be defined in the board file for performing the +capsule update. These values are defined in the board file by +initialisation of a structure which provides information needed for +capsule updates. The following structures have been defined for +containing the image related information + +.. code-block:: c + + struct efi_fw_image { + efi_guid_t image_type_id; + u16 *fw_name; + u8 image_index; + }; + + struct efi_capsule_update_info { + const char *dfu_string; + struct efi_fw_image *images; + }; + + +A string is defined which is to be used for populating the +dfu_alt_info variable. This string is used by the function +set_dfu_alt_info. Instead of taking the variable from the environment, +the capsule update feature requires that the variable be set through +the function, since that is more robust. Allowing the user to change +the location of the firmware updates is not a very secure +practice. Getting this information from the firmware itself is more +secure, assuming the firmware has been verified by a previous stage +boot loader. + +The firmware images structure defines the GUID values, image index +values and the name of the images that are to be updated through +the capsule update feature. These values are to be defined as part of +an array. These GUID values would be used by the Firmware Management +Protocol(FMP) to populate the image descriptor array and also +displayed as part of the ESRT table. The image index values defined in +the array should be one greater than the dfu alt number that +corresponds to the firmware image. So, if the dfu alt number for an +image is 2, the value of image index in the fw_images array for that +image should be 3. The dfu alt number can be obtained by running the +following command:: + +dfu list + +When using the FMP for FIT images, the image index value needs to be +set to 1. + Finally, the capsule update can be initiated by rebooting the board. +An example of setting the values in the struct efi_fw_image and +struct efi_capsule_update_info is shown below + +.. code-block:: c + + struct efi_fw_image fw_images[] = { + { + .image_type_id = DEVELOPERBOX_UBOOT_IMAGE_GUID, + .fw_name = u"DEVELOPERBOX-UBOOT", + .image_index = 1, + }, + { + .image_type_id = DEVELOPERBOX_FIP_IMAGE_GUID, + .fw_name = u"DEVELOPERBOX-FIP", + .image_index = 2, + }, + { + .image_type_id = DEVELOPERBOX_OPTEE_IMAGE_GUID, + .fw_name = u"DEVELOPERBOX-OPTEE", + .image_index = 3, + }, + }; + + struct efi_capsule_update_info update_info = { + .dfu_string = "mtd nor1=u-boot.bin raw 20 10;" + "fip.bin raw 18 78000;" + "optee.bin raw 50 10", + .images = fw_images, + }; + +Platforms must declare a variable update_info of type struct +efi_capsule_update_info as shown in the example above. The platform +will also define a fw_images array which contains information of all +the firmware images that are to be updated through capsule update +mechanism. The dfu_string is the string that is to be set as +dfu_alt_info. In the example above, the image index to be set for +u-boot.bin binary is 0x1, for fip.bin is 0x2 and for optee.bin is 0x3. + +As an example, for generating the capsule for the optee.bin image, the +following command can be issued + +.. code-block:: bash + +$ ./tools/mkeficapsule \ + --index 0x3 --instance 0 \ + --guid c1b629f1-ce0e-4894-82bf-f0a38387e630 \ +
[PATCH v8 7/8] mkeficapsule: Remove raw and FIT GUID types
While building a capsule, the GUID value of that specific image is to be passed through the --guid command option to the mkeficapsule tool instead of using one of --raw or --fit options, where the GUID value passed through the command line option is the image GUID. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the --raw and --fit command line options as well. Also modify the mkeficapsule man page to reflect this change. Signed-off-by: Sughosh Ganu --- Changes since V7: None doc/mkeficapsule.1 | 12 tools/eficapsule.h | 8 tools/mkeficapsule.c | 26 +- 3 files changed, 1 insertion(+), 45 deletions(-) diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1 index 8babb27ee8..09bdc24295 100644 --- a/doc/mkeficapsule.1 +++ b/doc/mkeficapsule.1 @@ -41,18 +41,6 @@ If you want to use other types than above two, you should explicitly specify a guid for the FMP driver. .SH "OPTIONS" -One of -.BR --fit ", " --raw " or " --guid -option must be specified. - -.TP -.BR -f ", " --fit -Indicate that the blob is a FIT image file - -.TP -.BR -r ", " --raw -Indicate that the blob is a raw image file - .TP .BI "-g\fR,\fB --guid " guid-string Specify guid for image blob type. The format is: diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 69c9c58c2f..d63b831443 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -37,14 +37,6 @@ typedef struct { EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define EFI_CERT_TYPE_PKCS7_GUID \ EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index c118335b93..5f74d23b9e 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -27,17 +27,11 @@ static const char *tool_name = "mkeficapsule"; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; -efi_guid_t efi_guid_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; -efi_guid_t efi_guid_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; +static const char *opts_short = "g:i:I:v:p:c:m:dh"; static struct option options[] = { - {"fit", no_argument, NULL, 'f'}, - {"raw", no_argument, NULL, 'r'}, {"guid", required_argument, NULL, 'g'}, {"index", required_argument, NULL, 'i'}, {"instance", required_argument, NULL, 'I'}, @@ -54,8 +48,6 @@ static void print_usage(void) fprintf(stderr, "Usage: %s [options] \n" "Options:\n" - "\t-f, --fit FIT image type\n" - "\t-r, --raw raw image type\n" "\t-g, --guid guid for image blob type\n" "\t-i, --index update image index\n" "\t-I, --instanceupdate hardware instance\n" @@ -606,22 +598,6 @@ int main(int argc, char **argv) break; switch (c) { - case 'f': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_fit; - break; - case 'r': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_raw; - break; case 'g': if (guid) { fprintf(stderr, -- 2.25.1
[PATCH v8 6/8] FMP: Remove GUIDs for FIT and raw images
The capsule update code has been modified for getting the image GUID values from the platform code. With this, each image now has a unique GUID value. With this change, there is no longer a need for defining GUIDs for FIT and raw images. Remove these GUID values. Signed-off-by: Sughosh Ganu --- Changes since V7: None include/efi_api.h | 8 lib/efi_loader/efi_firmware.c | 4 2 files changed, 12 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 982c200172..c7f7873b5d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1967,14 +1967,6 @@ struct efi_signature_list { EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ 0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE0x0001 #define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 #define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED0x0004 diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 36a62b02b3..27953fe769 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -187,8 +187,6 @@ static efi_status_t efi_fill_image_desc_array( * - versioning of firmware image * - package information */ -const efi_guid_t efi_firmware_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; /** * efi_firmware_fit_get_image_info - return information about the current @@ -295,8 +293,6 @@ const struct efi_firmware_management_protocol efi_fmp_fit = { * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update * method with raw data. */ -const efi_guid_t efi_firmware_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; /** * efi_firmware_raw_get_image_info - return information about the current -- 2.25.1
[PATCH v8 5/8] test: capsule: Modify the capsule tests to use GUID values for sandbox
The current UEFI capsule updation code uses two GUID values, one for FIT images, and one for raw images across platforms. This logic is being changed to have GUID values per image, per platform. Change the tests for the capsule update code to reflect this change. The GUID values now used are the ones specific to the sandbox platform -- one for the u-boot image, and another for the u-boot environment image. Install the FMP instance for raw images on the sandbox variant for testing the capsule update code. Install the FMP instance for the FIT images on the sandbox64 and sandbox_flattree variant for testing capsule update for FIT images. This is being done by splitting the capsule update script for FIT and raw images. Signed-off-by: Sughosh Ganu --- Changes since V7: None configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + test/py/tests/test_efi_capsule/conftest.py| 21 +- .../test_capsule_firmware_fit.py | 191 ++ ...rmware.py => test_capsule_firmware_raw.py} | 167 ++- 6 files changed, 270 insertions(+), 116 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py rename test/py/tests/test_efi_capsule/{test_capsule_firmware.py => test_capsule_firmware_raw.py} (75%) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 88f9ecbb7f..db748bbed3 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -246,7 +246,6 @@ CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y -CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index cb8d590eb6..0dfc2d863d 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -319,7 +319,6 @@ CONFIG_SHA384=y CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 24b272068a..27dd38a0c0 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -28,6 +28,7 @@ CONFIG_CMD_BOOTEFI_HELLO=y CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_ERASEENV=y +CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_NVEDIT_INFO=y CONFIG_CMD_NVEDIT_LOAD=y CONFIG_CMD_NVEDIT_SELECT=y @@ -209,3 +210,7 @@ CONFIG_HEXDUMP=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y +CONFIG_DFU_SF=y diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 9076087a12..d757415c88 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -72,7 +72,7 @@ def efi_capsule_data(request, u_boot_config): # Create capsule files # two regions: one for u-boot.bin and the other for u-boot.env -check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, +check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, shell=True) check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' % (u_boot_config.source_dir, data_dir), @@ -80,21 +80,29 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --fit uboot_bin_env.itb Test01' % +check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test01' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --raw u-boot.bin.new Test02' % +check_call('cd %s; %s/tools/mkeficapsule --index 2 --guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test02' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid E2BB9C06-70E9-4B14-97A3-5A7913176E3F u-boot.bin.new Test03' % +check_call('cd %s; %s/to
[PATCH v8 4/8] efi: Define set_dfu_alt_info() for boards with UEFI capsule update enabled
Currently, there are a bunch of boards which enable the UEFI capsule update feature. The actual update of the firmware images is done through the dfu framework which uses the dfu_alt_info environment variable for getting information on the update, like device, partition number/address etc. The dfu framework allows the variable to be set through the set_dfu_alt_info function defined by the platform, or if the function is not defined, it gets the variable from the environment. Using the value set in the environment is not very robust, since the variable can be modified from the u-boot command line and this can cause an incorrect update. To prevent this from happening, define the set_dfu_alt_info function when the capsule update feature is enabled. A weak function is defined which sets the dfu_alt_info environment variable by getting the string for the variable from the platform. Signed-off-by: Sughosh Ganu Reviewed-by: Masami Hiramatsu --- Changes since V7: None lib/efi_loader/Kconfig| 2 ++ lib/efi_loader/efi_firmware.c | 5 + 2 files changed, 7 insertions(+) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 559b95a599..d50cd2563d 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -181,6 +181,7 @@ config EFI_CAPSULE_FIRMWARE_FIT depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT select UPDATE_FIT select DFU + select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol @@ -192,6 +193,7 @@ config EFI_CAPSULE_FIRMWARE_RAW depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT) select DFU_WRITE_ALT select DFU + select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 56bd113de1..36a62b02b3 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -35,6 +35,11 @@ struct fmp_payload_header { u32 lowest_supported_version; }; +__weak void set_dfu_alt_info(char *interface, char *devstr) +{ + env_set("dfu_alt_info", update_info.dfu_string); +} + /* Place holder; not supported */ static efi_status_t EFIAPI efi_firmware_get_image_unsupported( -- 2.25.1
[PATCH v8 3/8] capsule: Put a check for image index before the update
The current capsule update code compares the image GUID value in the capsule header with the image GUID value obtained from the GetImageInfo function of the Firmware Management Protocol(FMP). This comparison is done to ascertain if the FMP's SetImage function can be called for the update. Make this checking more robust by comparing the image_index value passed through the capsule with that returned by the FMP's GetImageInfo function. This protects against the scenario of the firmware being updated in a wrong partition/location on the storage device if an incorrect value has been passed through the capsule, since the image_index is used to determine the location of the update on the storage device. Signed-off-by: Sughosh Ganu Reviewed-by: Masami Hiramatsu Reviewed-by: Ilias Apalodimas --- Changes since V7: None lib/efi_loader/efi_capsule.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index a107f285dd..c76a5f3570 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -129,6 +129,7 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, /** * efi_fmp_find - search for Firmware Management Protocol drivers * @image_type:Image type guid + * @image_index: Image Index * @instance: Instance number * @handles: Handles of FMP drivers * @no_handles:Number of handles @@ -142,8 +143,8 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, * * NULL - on failure */ static struct efi_firmware_management_protocol * -efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, -efi_uintn_t no_handles) +efi_fmp_find(efi_guid_t *image_type, u8 image_index, u64 instance, +efi_handle_t *handles, efi_uintn_t no_handles) { efi_handle_t *handle; struct efi_firmware_management_protocol *fmp; @@ -204,6 +205,7 @@ efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, log_debug("+++ desc[%d] index: %d, name: %ls\n", j, desc->image_index, desc->image_id_name); if (!guidcmp(>image_type_id, image_type) && + (desc->image_index == image_index) && (!instance || !desc->hardware_instance || desc->hardware_instance == instance)) @@ -450,8 +452,8 @@ static efi_status_t efi_capsule_update_firmware( } /* find a device for update firmware */ - /* TODO: should we pass index as well, or nothing but type? */ fmp = efi_fmp_find(>update_image_type_id, + image->update_image_index, image->update_hardware_instance, handles, no_handles); if (!fmp) { -- 2.25.1
[PATCH v8 2/8] capsule: FMP: Populate the image descriptor array from platform data
Currently, the image descriptor array that has been passed to the GetImageInfo function of the Firmware Management Protocol(FMP) gets populated through the data stored with the dfu framework. The dfu data is not restricted to contain information only of the images updatable through the capsule update mechanism, but it also contains information on other images. The image descriptor array is also parsed by the ESRT generation code, and thus the ESRT table contains entries for other images that are not being handled by the FMP for the capsule updates. Fix this by populating the image descriptor array from the structure initialised in the board file. The other issue fixed is assignment of a separate GUID for all images in the image descriptor array. The UEFI specification mandates that all entries in the ESRT table should have a unique GUID value as part of the FwClass member of the EFI_SYSTEM_RESOURCE_ENTRY. Currently, all images are assigned a single GUID value, either an FIT GUID or a raw image GUID. This is fixed by obtaining the GUID values from the efi_fw_images array defined per platform. Signed-off-by: Sughosh Ganu Reviewed-by: Masami Hiramatsu --- Changes since V7: * Fix a typo in the function description of efi_fill_image_desc_array lib/efi_loader/efi_firmware.c | 98 +++ 1 file changed, 29 insertions(+), 69 deletions(-) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a5ff32f121..56bd113de1 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -97,91 +97,57 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( } /** - * efi_get_dfu_info - return information about the current firmware image - * @this: Protocol instance + * efi_fill_image_desc_array - populate image descriptor array * @image_info_size: Size of @image_info * @image_info:Image information * @descriptor_version:Pointer to version number - * @descriptor_count: Pointer to number of descriptors + * @descriptor_count: Image count * @descriptor_size: Pointer to descriptor size - * package_version:Package version - * package_version_name: Package version's name - * image_type: Image type GUID + * @package_version: Package version + * @package_version_name: Package version's name * - * Return information bout the current firmware image in @image_info. + * Return information about the current firmware image in @image_info. * @image_info will consist of a number of descriptors. - * Each descriptor will be created based on "dfu_alt_info" variable. + * Each descriptor will be created based on efi_fw_image array. * * Return status code */ -static efi_status_t efi_get_dfu_info( +static efi_status_t efi_fill_image_desc_array( efi_uintn_t *image_info_size, struct efi_firmware_image_descriptor *image_info, u32 *descriptor_version, u8 *descriptor_count, efi_uintn_t *descriptor_size, u32 *package_version, - u16 **package_version_name, - const efi_guid_t *image_type) + u16 **package_version_name) { - struct dfu_entity *dfu; - size_t names_len, total_size; - int dfu_num, i; - u16 *name, *next; - int ret; - - ret = dfu_init_env_entities(NULL, NULL); - if (ret) - return EFI_SUCCESS; - - names_len = 0; - dfu_num = 0; - list_for_each_entry(dfu, _list, list) { - names_len += (utf8_utf16_strlen(dfu->name) + 1) * 2; - dfu_num++; - } - if (!dfu_num) { - log_warning("No entities in dfu_alt_info\n"); - *image_info_size = 0; - dfu_free_entities(); + size_t total_size; + struct efi_fw_image *fw_array; + int i; - return EFI_SUCCESS; - } + fw_array = update_info.images; + *descriptor_count = num_image_type_guids; + + total_size = sizeof(*image_info) * num_image_type_guids; - total_size = sizeof(*image_info) * dfu_num + names_len; - /* -* we will assume that sizeof(*image_info) * dfu_name -* is, at least, a multiple of 2. So the start address for -* image_id_name would be aligned with 2 bytes. -*/ if (*image_info_size < total_size) { *image_info_size = total_size; - dfu_free_entities(); return EFI_BUFFER_TOO_SMALL; } *image_info_size = total_size; *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; - *descriptor_count = dfu_num; *descriptor_size = sizeof(*image_info); *package_version = 0x; /* not supported */ *package_version_name = NULL; /* not supported */ - /* DFU alt number should correspond t
[PATCH v8 1/8] capsule: board: Add information needed for capsule updates
Add a structure which defines the information that is needed for executing capsule updates on a platform. Some information in the structure like the dfu string is used for making the update process more robust while some information like the per platform image GUIDs is used for fixing issues. Initialise this structure in the board file, and use the information for the capsule updates. Signed-off-by: Sughosh Ganu --- Changes since V7: None .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 29 +++ .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 28 +++ board/emulation/common/qemu_dfu.c | 3 +- board/emulation/qemu-arm/qemu-arm.c | 28 +++ board/kontron/pitx_imx8m/pitx_imx8m.c | 21 ++- board/kontron/sl-mx8mm/sl-mx8mm.c | 20 +++ board/kontron/sl28/sl28.c | 21 +++ board/sandbox/sandbox.c | 34 ++ board/socionext/developerbox/developerbox.c | 33 + board/xilinx/common/board.c | 28 +++ board/xilinx/zynq/board.c | 3 +- board/xilinx/zynqmp/zynqmp.c | 3 +- include/configs/imx8mm-cl-iot-gate.h | 9 + include/configs/imx8mp_rsb3720.h | 9 + include/configs/kontron-sl-mx8mm.h| 5 +++ include/configs/kontron_pitx_imx8m.h | 5 +++ include/configs/kontron_sl28.h| 5 +++ include/configs/qemu-arm.h| 9 + include/configs/sandbox.h | 13 +++ include/configs/synquacer.h | 13 +++ include/configs/xilinx_versal.h | 5 +++ include/configs/xilinx_zynqmp.h | 9 + include/configs/zynq-common.h | 9 + include/efi_loader.h | 36 +++ 24 files changed, 374 insertions(+), 4 deletions(-) diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c index 16566092bd..782025dc78 100644 --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -44,6 +47,32 @@ static void setup_gpmi_nand(void) } #endif +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_image fw_images[] = { +#if defined(CONFIG_TARGET_IMX8MP_RSB3720A1_4G) + { + .image_type_id = IMX8MP_RSB3720A1_4G_FIT_IMAGE_GUID, + .fw_name = u"IMX8MP-RSB3720-FIT", + .image_index = 1, + }, +#elif defined(CONFIG_TARGET_IMX8MP_RSB3720A1_6G) + { + .image_type_id = IMX8MP_RSB3720A1_6G_FIT_IMAGE_GUID, + .fw_name = u"IMX8MP-RSB3720-FIT", + .image_index = 1, + }, +#endif +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 2=flash-bin raw 0 0x1B00 mmcpart 1", + .images = fw_images, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + + int board_early_init_f(void) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c index 7e2d88f449..312db0e5f4 100644 --- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c +++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include #include @@ -21,11 +23,37 @@ #include #include #include +#include #include "ddr/ddr.h" DECLARE_GLOBAL_DATA_PTR; +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_image fw_images[] = { +#if defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) + { + .image_type_id = IMX8MM_CL_IOT_GATE_FIT_IMAGE_GUID, + .fw_name = u"IMX8MM-CL-IOT-GATE-FIT", + .image_index = 1, + }, +#elif defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) + { + .image_type_id = IMX8MM_CL_IOT_GATE_OPTEE_FIT_IMAGE_GUID, + .fw_name = u"IMX8MM-CL-IOT-GATE-FIT", + .image_index = 1, + }, +#endif +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 2=flash-bin raw 0x42 0x1D00 mmcpart 1", + .images = fw_images, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + int board_phys_sdram_size(phys_size_t *size) { struct lpddr4_tcm_desc *lpddr4_tcm_desc = diff --git a/board/emulation/common/qemu_dfu.c b/board/emulation/common/qemu_dfu.c index 62234a7647..c1aeaf10d9 100644 --- a/boa
[PATCH v8 0/8] efi: capsule: Capsule Update fixes and enhancements
V6: - * Renamed struct efi_fw_images as struct efi_fw_image as suggested by Takahiro * Made corresponding change in all board files based on the rename done * Use renamed struct efi_fw_image instead of struct efi_fw_images * Reword the commit message to highlight the reason for removing --fit and --raw options as suggested by Takahiro * Remove the --fit and --raw description in the mkeficapsule man page * Add example for the struct efi_fw_image array and struct efi_capsule_update_info as suggested by Takahiro Changes since V5: - * Create a separate entry in fw_images array per config for boards with multiple configs as suggested by Heinrich. * Removed CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) check in the board config headers, as suggested by Heinrich. * Add a check in the set_dfu_alt_info functions for the xilinx and qemu platforms to get the board defined value of dfu_alt_info when capsule update feature is enabled. * Simplify the set_dfu_alt_info function definition to set the variable directly from dfu_string, as suggested by Heinrich. * Restart the platform before starting the tests. This is done to clear out any stale state from a previously run test. Changes since V4: - * Define a structure efi_capsule_update_info which includes the string for populating dfu_alt_info * Initialise the string for dfu_alt_info in the board file * Drop the image_count variable as was suggested by Ilias * Drop another unused variable names_len * Define a weak function set_dfu_alt_info for setting the variable in a non board specific file as suggested by Ilias * Drop the definitions of set_dfu_alt_info that were being added in the board files * Change the description of the platform data based on the changes made in earlier patches Changes since V3: - * Do not remove the existing dfu_alt_info definitions made by platforms in the config files, as discussed with Masami. * Squash the selection of the SET_DFU_ALT_INFO config symbol for capsule update feature as part of this patch. * Rephrase the commit message to indicate that the doc changes are not just limited to adding the GUID values, but other info as well. * Elaborate with an example on the relation between the dfu alt number and the image index Changes since V2: - * Add a new member image_index to the struct efi_fw_images to allow the platforms to define the values for images. * Address review comments from Michal Simek for the xilinx boards. * Fix double inclusion of efi_loader.h as was pointed out by Heiko Thiery. * Use the image index values defined in the platform's fw_images array for the image descriptors * Add a description for adding image index value and definition of set_dfu_alt_info function for the capsule updates. Changes since V1: - * Make changes for the xilinx boards as suggested by Michal Simek. * Add a GUID for the sandbox FIT image. * Split the capsule update test cases into two scripts, one for raw images and one for FIT images. * Add the capsule update test case for FIT images on sandbox64 and sandbox_flattree variants. * Add capsule update support on sandbox_flattree variant for enabling FIT capsule update testing as part of the python tests Sughosh Ganu (8): capsule: board: Add information needed for capsule updates capsule: FMP: Populate the image descriptor array from platform data capsule: Put a check for image index before the update efi: Define set_dfu_alt_info() for boards with UEFI capsule update enabled test: capsule: Modify the capsule tests to use GUID values for sandbox FMP: Remove GUIDs for FIT and raw images mkeficapsule: Remove raw and FIT GUID types doc: uefi: Update the capsule update related documentation .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 29 +++ .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 28 +++ board/emulation/common/qemu_dfu.c | 3 +- board/emulation/qemu-arm/qemu-arm.c | 28 +++ board/kontron/pitx_imx8m/pitx_imx8m.c | 21 +- board/kontron/sl-mx8mm/sl-mx8mm.c | 20 ++ board/kontron/sl28/sl28.c | 21 ++ board/sandbox/sandbox.c | 34 board/socionext/developerbox/developerbox.c | 33 +++ board/xilinx/common/board.c | 28 +++ board/xilinx/zynq/board.c | 3 +- board/xilinx/zynqmp/zynqmp.c | 3 +- configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + doc/develop/uefi/uefi.rst | 100 - doc/mkeficapsule.1| 12 -- include/configs/imx8mm-cl-iot-gate.h | 9 + include/configs/imx8mp_rsb3720.h | 9 + include/configs/kontron-sl-mx8mm.h| 5 + include/configs
[PATCH v7 8/8] doc: uefi: Update the capsule update related documentation
Update the capsule update functionality related documentation to refect the additional definitions that need to be made per platform for supporting the capsule update feature. Signed-off-by: Sughosh Ganu --- Changes since V6: * Add example for the struct efi_fw_image array and struct efi_capsule_update_info as suggested by Takahiro doc/develop/uefi/uefi.rst | 98 ++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index fe337c88bd..1aea04a4e8 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -312,8 +312,8 @@ Run the following command .. code-block:: console $ mkeficapsule \ - --index 1 --instance 0 \ - [--fit | --raw ] \ + --index --instance 0 \ + --guid \ Performing the update @@ -333,9 +333,102 @@ won't be taken over across the reboot. If this is the case, you can skip this feature check with the Kconfig option (CONFIG_EFI_IGNORE_OSINDICATIONS) set. +A few values need to be defined in the board file for performing the +capsule update. These values are defined in the board file by +initialisation of a structure which provides information needed for +capsule updates. The following structures have been defined for +containing the image related information + +.. code-block:: c + + struct efi_fw_images { + efi_guid_t image_type_id; + u16 *fw_name; + u8 image_index; + }; + + struct efi_capsule_update_info { + const char *dfu_string; + struct efi_fw_image *images; + }; + + +A string is defined which is to be used for populating the +dfu_alt_info variable. This string is used by the function +set_dfu_alt_info. Instead of taking the variable from the environment, +the capsule update feature requires that the variable be set through +the function, since that is more robust. Allowing the user to change +the location of the firmware updates is not a very secure +practice. Getting this information from the firmware itself is more +secure, assuming the firmware has been verified by a previous stage +boot loader. + +The firmware images structure defines the GUID values, image index +values and the name of the images that are to be updated through +the capsule update feature. These values are to be defined as part of +an array. These GUID values would be used by the Firmware Management +Protocol(FMP) to populate the image descriptor array and also +displayed as part of the ESRT table. The image index values defined in +the array should be one greater than the dfu alt number that +corresponds to the firmware image. So, if the dfu alt number for an +image is 2, the value of image index in the fw_images array for that +image should be 3. The dfu alt number can be obtained by running the +following command:: + +dfu list + +When using the FMP for FIT images, the image index value needs to be +set to 1. + Finally, the capsule update can be initiated by rebooting the board. +An example of setting the values in the struct efi_fw_image and +struct efi_capsule_update_info is shown below + +.. code-block:: c + + struct efi_fw_image fw_images[] = { + { + .image_type_id = DEVELOPERBOX_UBOOT_IMAGE_GUID, + .fw_name = u"DEVELOPERBOX-UBOOT", + .image_index = 1, + }, + { + .image_type_id = DEVELOPERBOX_FIP_IMAGE_GUID, + .fw_name = u"DEVELOPERBOX-FIP", + .image_index = 2, + }, + { + .image_type_id = DEVELOPERBOX_OPTEE_IMAGE_GUID, + .fw_name = u"DEVELOPERBOX-OPTEE", + .image_index = 3, + }, + }; + + struct efi_capsule_update_info update_info = { + .dfu_string = "mtd nor1=u-boot.bin raw 20 10;" + "fip.bin raw 18 78000;" + "optee.bin raw 50 10", + .images = fw_images, + }; + +The platform will define a fw_images array which contains information +of all the firmware images that are to be updated through capsule +update mechanism. The dfu_string is the string that is to be set as +dfu_alt_info. In the example above, the image index to be set for +u-boot.bin binary is 0x1, for fip.bin is 0x2 and for optee.bin is 0x3. + +As an example, for generating the capsule for the optee.bin image, the +following command can be issued + +.. code-block:: bash + +$ ./tools/mkeficapsule \ + --index 0x3 --instance 0 \ + --guid c1b629f1-ce0e-4894-82bf-f0a38387e630 \ + optee.bin optee.capsule + + Enabling Capsule Authentication *** -- 2.25.1
[PATCH v7 7/8] mkeficapsule: Remove raw and FIT GUID types
While building a capsule, the GUID value of that specific image is to be passed through the --guid command option to the mkeficapsule tool instead of using one of --raw or --fit options, where the GUID value passed through the command line option is the image GUID. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the --raw and --fit command line options as well. Also modify the mkeficapsule man page to reflect this change. Signed-off-by: Sughosh Ganu --- Changes since V6: * Reword the commit message to highlight the reason for removing --fit and --raw options as suggested by Takahiro * Remove the --fit and --raw description in the mkeficapsule man page doc/mkeficapsule.1 | 12 tools/eficapsule.h | 8 tools/mkeficapsule.c | 26 +- 3 files changed, 1 insertion(+), 45 deletions(-) diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1 index 8babb27ee8..09bdc24295 100644 --- a/doc/mkeficapsule.1 +++ b/doc/mkeficapsule.1 @@ -41,18 +41,6 @@ If you want to use other types than above two, you should explicitly specify a guid for the FMP driver. .SH "OPTIONS" -One of -.BR --fit ", " --raw " or " --guid -option must be specified. - -.TP -.BR -f ", " --fit -Indicate that the blob is a FIT image file - -.TP -.BR -r ", " --raw -Indicate that the blob is a raw image file - .TP .BI "-g\fR,\fB --guid " guid-string Specify guid for image blob type. The format is: diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 69c9c58c2f..d63b831443 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -37,14 +37,6 @@ typedef struct { EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define EFI_CERT_TYPE_PKCS7_GUID \ EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index c118335b93..5f74d23b9e 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -27,17 +27,11 @@ static const char *tool_name = "mkeficapsule"; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; -efi_guid_t efi_guid_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; -efi_guid_t efi_guid_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; +static const char *opts_short = "g:i:I:v:p:c:m:dh"; static struct option options[] = { - {"fit", no_argument, NULL, 'f'}, - {"raw", no_argument, NULL, 'r'}, {"guid", required_argument, NULL, 'g'}, {"index", required_argument, NULL, 'i'}, {"instance", required_argument, NULL, 'I'}, @@ -54,8 +48,6 @@ static void print_usage(void) fprintf(stderr, "Usage: %s [options] \n" "Options:\n" - "\t-f, --fit FIT image type\n" - "\t-r, --raw raw image type\n" "\t-g, --guid guid for image blob type\n" "\t-i, --index update image index\n" "\t-I, --instanceupdate hardware instance\n" @@ -606,22 +598,6 @@ int main(int argc, char **argv) break; switch (c) { - case 'f': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_fit; - break; - case 'r': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_raw; - break; case 'g': if (guid) { fprintf(stderr, -- 2.25.1
[PATCH v7 5/8] test: capsule: Modify the capsule tests to use GUID values for sandbox
The current UEFI capsule updation code uses two GUID values, one for FIT images, and one for raw images across platforms. This logic is being changed to have GUID values per image, per platform. Change the tests for the capsule update code to reflect this change. The GUID values now used are the ones specific to the sandbox platform -- one for the u-boot image, and another for the u-boot environment image. Install the FMP instance for raw images on the sandbox variant for testing the capsule update code. Install the FMP instance for the FIT images on the sandbox64 and sandbox_flattree variant for testing capsule update for FIT images. This is being done by splitting the capsule update script for FIT and raw images. Signed-off-by: Sughosh Ganu --- Changes since V6: None configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + test/py/tests/test_efi_capsule/conftest.py| 21 +- .../test_capsule_firmware_fit.py | 191 ++ ...rmware.py => test_capsule_firmware_raw.py} | 167 ++- 6 files changed, 270 insertions(+), 116 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py rename test/py/tests/test_efi_capsule/{test_capsule_firmware.py => test_capsule_firmware_raw.py} (75%) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 88f9ecbb7f..db748bbed3 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -246,7 +246,6 @@ CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y -CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index cb8d590eb6..0dfc2d863d 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -319,7 +319,6 @@ CONFIG_SHA384=y CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 24b272068a..27dd38a0c0 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -28,6 +28,7 @@ CONFIG_CMD_BOOTEFI_HELLO=y CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_ERASEENV=y +CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_NVEDIT_INFO=y CONFIG_CMD_NVEDIT_LOAD=y CONFIG_CMD_NVEDIT_SELECT=y @@ -209,3 +210,7 @@ CONFIG_HEXDUMP=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y +CONFIG_DFU_SF=y diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 9076087a12..d757415c88 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -72,7 +72,7 @@ def efi_capsule_data(request, u_boot_config): # Create capsule files # two regions: one for u-boot.bin and the other for u-boot.env -check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, +check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, shell=True) check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' % (u_boot_config.source_dir, data_dir), @@ -80,21 +80,29 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --fit uboot_bin_env.itb Test01' % +check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test01' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --raw u-boot.bin.new Test02' % +check_call('cd %s; %s/tools/mkeficapsule --index 2 --guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test02' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid E2BB9C06-70E9-4B14-97A3-5A7913176E3F u-boot.bin.new Test03' % +check_call('cd %s; %s/to
[PATCH v7 6/8] FMP: Remove GUIDs for FIT and raw images
The capsule update code has been modified for getting the image GUID values from the platform code. With this, each image now has a unique GUID value. With this change, there is no longer a need for defining GUIDs for FIT and raw images. Remove these GUID values. Signed-off-by: Sughosh Ganu --- Changes since V6: None include/efi_api.h | 8 lib/efi_loader/efi_firmware.c | 4 2 files changed, 12 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 982c200172..c7f7873b5d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1967,14 +1967,6 @@ struct efi_signature_list { EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ 0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE0x0001 #define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 #define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED0x0004 diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index aff5519e54..b6ce94334f 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -188,8 +188,6 @@ static efi_status_t efi_fill_image_desc_array( * - versioning of firmware image * - package information */ -const efi_guid_t efi_firmware_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; /** * efi_firmware_fit_get_image_info - return information about the current @@ -296,8 +294,6 @@ const struct efi_firmware_management_protocol efi_fmp_fit = { * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update * method with raw data. */ -const efi_guid_t efi_firmware_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; /** * efi_firmware_raw_get_image_info - return information about the current -- 2.25.1
[PATCH v7 4/8] efi: Define set_dfu_alt_info() for boards with UEFI capsule update enabled
Currently, there are a bunch of boards which enable the UEFI capsule update feature. The actual update of the firmware images is done through the dfu framework which uses the dfu_alt_info environment variable for getting information on the update, like device, partition number/address etc. The dfu framework allows the variable to be set through the set_dfu_alt_info function defined by the platform, or if the function is not defined, it gets the variable from the environment. Using the value set in the environment is not very robust, since the variable can be modified from the u-boot command line and this can cause an incorrect update. To prevent this from happening, define the set_dfu_alt_info function when the capsule update feature is enabled. A weak function is defined which sets the dfu_alt_info environment variable by getting the string for the variable from the platform. Signed-off-by: Sughosh Ganu --- Changes since V6: None lib/efi_loader/Kconfig| 2 ++ lib/efi_loader/efi_firmware.c | 5 + 2 files changed, 7 insertions(+) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 559b95a599..d50cd2563d 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -181,6 +181,7 @@ config EFI_CAPSULE_FIRMWARE_FIT depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT select UPDATE_FIT select DFU + select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol @@ -192,6 +193,7 @@ config EFI_CAPSULE_FIRMWARE_RAW depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT) select DFU_WRITE_ALT select DFU + select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 46aa7a001a..aff5519e54 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -35,6 +35,11 @@ struct fmp_payload_header { u32 lowest_supported_version; }; +__weak void set_dfu_alt_info(char *interface, char *devstr) +{ + env_set("dfu_alt_info", update_info.dfu_string); +} + /* Place holder; not supported */ static efi_status_t EFIAPI efi_firmware_get_image_unsupported( -- 2.25.1
[PATCH v7 3/8] capsule: Put a check for image index before the update
The current capsule update code compares the image GUID value in the capsule header with the image GUID value obtained from the GetImageInfo function of the Firmware Management Protocol(FMP). This comparison is done to ascertain if the FMP's SetImage function can be called for the update. Make this checking more robust by comparing the image_index value passed through the capsule with that returned by the FMP's GetImageInfo function. This protects against the scenario of the firmware being updated in a wrong partition/location on the storage device if an incorrect value has been passed through the capsule, since the image_index is used to determine the location of the update on the storage device. Signed-off-by: Sughosh Ganu Reviewed-by: Masami Hiramatsu Reviewed-by: Ilias Apalodimas --- Changes since V6: None lib/efi_loader/efi_capsule.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index a107f285dd..c76a5f3570 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -129,6 +129,7 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, /** * efi_fmp_find - search for Firmware Management Protocol drivers * @image_type:Image type guid + * @image_index: Image Index * @instance: Instance number * @handles: Handles of FMP drivers * @no_handles:Number of handles @@ -142,8 +143,8 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, * * NULL - on failure */ static struct efi_firmware_management_protocol * -efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, -efi_uintn_t no_handles) +efi_fmp_find(efi_guid_t *image_type, u8 image_index, u64 instance, +efi_handle_t *handles, efi_uintn_t no_handles) { efi_handle_t *handle; struct efi_firmware_management_protocol *fmp; @@ -204,6 +205,7 @@ efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, log_debug("+++ desc[%d] index: %d, name: %ls\n", j, desc->image_index, desc->image_id_name); if (!guidcmp(>image_type_id, image_type) && + (desc->image_index == image_index) && (!instance || !desc->hardware_instance || desc->hardware_instance == instance)) @@ -450,8 +452,8 @@ static efi_status_t efi_capsule_update_firmware( } /* find a device for update firmware */ - /* TODO: should we pass index as well, or nothing but type? */ fmp = efi_fmp_find(>update_image_type_id, + image->update_image_index, image->update_hardware_instance, handles, no_handles); if (!fmp) { -- 2.25.1
[PATCH v7 2/8] capsule: FMP: Populate the image descriptor array from platform data
Currently, the image descriptor array that has been passed to the GetImageInfo function of the Firmware Management Protocol(FMP) gets populated through the data stored with the dfu framework. The dfu data is not restricted to contain information only of the images updatable through the capsule update mechanism, but it also contains information on other images. The image descriptor array is also parsed by the ESRT generation code, and thus the ESRT table contains entries for other images that are not being handled by the FMP for the capsule updates. Fix this by populating the image descriptor array from the structure initialised in the board file. The other issue fixed is assignment of a separate GUID for all images in the image descriptor array. The UEFI specification mandates that all entries in the ESRT table should have a unique GUID value as part of the FwClass member of the EFI_SYSTEM_RESOURCE_ENTRY. Currently, all images are assigned a single GUID value, either an FIT GUID or a raw image GUID. This is fixed by obtaining the GUID values from the efi_fw_images array defined per platform. Signed-off-by: Sughosh Ganu --- Changes since V6: * Use renamed struct efi_fw_image instead of struct efi_fw_images lib/efi_loader/efi_firmware.c | 95 +++ 1 file changed, 28 insertions(+), 67 deletions(-) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a5ff32f121..46aa7a001a 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -97,91 +97,58 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( } /** - * efi_get_dfu_info - return information about the current firmware image + * efi_fill_image_desc_array - populate image descriptor array * @this: Protocol instance * @image_info_size: Size of @image_info * @image_info:Image information * @descriptor_version:Pointer to version number - * @descriptor_count: Pointer to number of descriptors + * @descriptor_count: Image count * @descriptor_size: Pointer to descriptor size - * package_version:Package version - * package_version_name: Package version's name - * image_type: Image type GUID + * @package_version: Package version + * @package_version_name: Package version's name * * Return information bout the current firmware image in @image_info. * @image_info will consist of a number of descriptors. - * Each descriptor will be created based on "dfu_alt_info" variable. + * Each descriptor will be created based on "efi_fw_images" variable. * * Return status code */ -static efi_status_t efi_get_dfu_info( +static efi_status_t efi_fill_image_desc_array( efi_uintn_t *image_info_size, struct efi_firmware_image_descriptor *image_info, u32 *descriptor_version, u8 *descriptor_count, efi_uintn_t *descriptor_size, u32 *package_version, - u16 **package_version_name, - const efi_guid_t *image_type) + u16 **package_version_name) { - struct dfu_entity *dfu; - size_t names_len, total_size; - int dfu_num, i; - u16 *name, *next; - int ret; - - ret = dfu_init_env_entities(NULL, NULL); - if (ret) - return EFI_SUCCESS; - - names_len = 0; - dfu_num = 0; - list_for_each_entry(dfu, _list, list) { - names_len += (utf8_utf16_strlen(dfu->name) + 1) * 2; - dfu_num++; - } - if (!dfu_num) { - log_warning("No entities in dfu_alt_info\n"); - *image_info_size = 0; - dfu_free_entities(); + size_t total_size; + struct efi_fw_image *fw_array; + int i; - return EFI_SUCCESS; - } + fw_array = update_info.images; + *descriptor_count = num_image_type_guids; + + total_size = sizeof(*image_info) * num_image_type_guids; - total_size = sizeof(*image_info) * dfu_num + names_len; - /* -* we will assume that sizeof(*image_info) * dfu_name -* is, at least, a multiple of 2. So the start address for -* image_id_name would be aligned with 2 bytes. -*/ if (*image_info_size < total_size) { *image_info_size = total_size; - dfu_free_entities(); return EFI_BUFFER_TOO_SMALL; } *image_info_size = total_size; *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; - *descriptor_count = dfu_num; *descriptor_size = sizeof(*image_info); *package_version = 0x; /* not supported */ *package_version_name = NULL; /* not supported */ - /* DFU alt number should correspond to image_index */ - i = 0; - /* Name area starts just after descriptors */ -
[PATCH v7 1/8] capsule: board: Add information needed for capsule updates
Add a structure which defines the information that is needed for executing capsule updates on a platform. Some information in the structure like the dfu string is used for making the update process more robust while some information like the per platform image GUIDs is used for fixing issues. Initialise this structure in the board file, and use the information for the capsule updates. Signed-off-by: Sughosh Ganu --- Changes since V6: * Renamed struct efi_fw_images as struct efi_fw_image as suggested by Takahiro * Made corresponding change in all board files based on the rename done .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 29 +++ .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 28 +++ board/emulation/common/qemu_dfu.c | 3 +- board/emulation/qemu-arm/qemu-arm.c | 28 +++ board/kontron/pitx_imx8m/pitx_imx8m.c | 21 ++- board/kontron/sl-mx8mm/sl-mx8mm.c | 20 +++ board/kontron/sl28/sl28.c | 21 +++ board/sandbox/sandbox.c | 34 ++ board/socionext/developerbox/developerbox.c | 33 + board/xilinx/common/board.c | 28 +++ board/xilinx/zynq/board.c | 3 +- board/xilinx/zynqmp/zynqmp.c | 3 +- include/configs/imx8mm-cl-iot-gate.h | 9 + include/configs/imx8mp_rsb3720.h | 9 + include/configs/kontron-sl-mx8mm.h| 5 +++ include/configs/kontron_pitx_imx8m.h | 5 +++ include/configs/kontron_sl28.h| 5 +++ include/configs/qemu-arm.h| 9 + include/configs/sandbox.h | 13 +++ include/configs/synquacer.h | 13 +++ include/configs/xilinx_versal.h | 5 +++ include/configs/xilinx_zynqmp.h | 9 + include/configs/zynq-common.h | 9 + include/efi_loader.h | 36 +++ 24 files changed, 374 insertions(+), 4 deletions(-) diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c index 16566092bd..782025dc78 100644 --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -44,6 +47,32 @@ static void setup_gpmi_nand(void) } #endif +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_image fw_images[] = { +#if defined(CONFIG_TARGET_IMX8MP_RSB3720A1_4G) + { + .image_type_id = IMX8MP_RSB3720A1_4G_FIT_IMAGE_GUID, + .fw_name = u"IMX8MP-RSB3720-FIT", + .image_index = 1, + }, +#elif defined(CONFIG_TARGET_IMX8MP_RSB3720A1_6G) + { + .image_type_id = IMX8MP_RSB3720A1_6G_FIT_IMAGE_GUID, + .fw_name = u"IMX8MP-RSB3720-FIT", + .image_index = 1, + }, +#endif +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 2=flash-bin raw 0 0x1B00 mmcpart 1", + .images = fw_images, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + + int board_early_init_f(void) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c index 7e2d88f449..312db0e5f4 100644 --- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c +++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include #include @@ -21,11 +23,37 @@ #include #include #include +#include #include "ddr/ddr.h" DECLARE_GLOBAL_DATA_PTR; +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_image fw_images[] = { +#if defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) + { + .image_type_id = IMX8MM_CL_IOT_GATE_FIT_IMAGE_GUID, + .fw_name = u"IMX8MM-CL-IOT-GATE-FIT", + .image_index = 1, + }, +#elif defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) + { + .image_type_id = IMX8MM_CL_IOT_GATE_OPTEE_FIT_IMAGE_GUID, + .fw_name = u"IMX8MM-CL-IOT-GATE-FIT", + .image_index = 1, + }, +#endif +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 2=flash-bin raw 0x42 0x1D00 mmcpart 1", + .images = fw_images, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + int board_phys_sdram_size(phys_size_t *size) { struct lpddr4_tcm_des
[PATCH v7 0/8] efi: capsule: Capsule Update fixes and enhancements
on the rename done * Use renamed struct efi_fw_image instead of struct efi_fw_images * Reword the commit message to highlight the reason for removing --fit and --raw options as suggested by Takahiro * Remove the --fit and --raw description in the mkeficapsule man page * Add example for the struct efi_fw_image array and struct efi_capsule_update_info as suggested by Takahiro Changes since V5: - * Create a separate entry in fw_images array per config for boards with multiple configs as suggested by Heinrich. * Removed CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) check in the board config headers, as suggested by Heinrich. * Add a check in the set_dfu_alt_info functions for the xilinx and qemu platforms to get the board defined value of dfu_alt_info when capsule update feature is enabled. * Simplify the set_dfu_alt_info function definition to set the variable directly from dfu_string, as suggested by Heinrich. * Restart the platform before starting the tests. This is done to clear out any stale state from a previously run test. Changes since V4: - * Define a structure efi_capsule_update_info which includes the string for populating dfu_alt_info * Initialise the string for dfu_alt_info in the board file * Drop the image_count variable as was suggested by Ilias * Drop another unused variable names_len * Define a weak function set_dfu_alt_info for setting the variable in a non board specific file as suggested by Ilias * Drop the definitions of set_dfu_alt_info that were being added in the board files * Change the description of the platform data based on the changes made in earlier patches Changes since V3: - * Do not remove the existing dfu_alt_info definitions made by platforms in the config files, as discussed with Masami. * Squash the selection of the SET_DFU_ALT_INFO config symbol for capsule update feature as part of this patch. * Rephrase the commit message to indicate that the doc changes are not just limited to adding the GUID values, but other info as well. * Elaborate with an example on the relation between the dfu alt number and the image index Changes since V2: - * Add a new member image_index to the struct efi_fw_images to allow the platforms to define the values for images. * Address review comments from Michal Simek for the xilinx boards. * Fix double inclusion of efi_loader.h as was pointed out by Heiko Thiery. * Use the image index values defined in the platform's fw_images array for the image descriptors * Add a description for adding image index value and definition of set_dfu_alt_info function for the capsule updates. Changes since V1: - * Make changes for the xilinx boards as suggested by Michal Simek. * Add a GUID for the sandbox FIT image. * Split the capsule update test cases into two scripts, one for raw images and one for FIT images. * Add the capsule update test case for FIT images on sandbox64 and sandbox_flattree variants. * Add capsule update support on sandbox_flattree variant for enabling FIT capsule update testing as part of the python tests Sughosh Ganu (8): capsule: board: Add information needed for capsule updates capsule: FMP: Populate the image descriptor array from platform data capsule: Put a check for image index before the update efi: Define set_dfu_alt_info() for boards with UEFI capsule update enabled test: capsule: Modify the capsule tests to use GUID values for sandbox FMP: Remove GUIDs for FIT and raw images mkeficapsule: Remove raw and FIT GUID types doc: uefi: Update the capsule update related documentation .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 29 +++ .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 28 +++ board/emulation/common/qemu_dfu.c | 3 +- board/emulation/qemu-arm/qemu-arm.c | 28 +++ board/kontron/pitx_imx8m/pitx_imx8m.c | 21 +- board/kontron/sl-mx8mm/sl-mx8mm.c | 20 ++ board/kontron/sl28/sl28.c | 21 ++ board/sandbox/sandbox.c | 34 board/socionext/developerbox/developerbox.c | 33 +++ board/xilinx/common/board.c | 28 +++ board/xilinx/zynq/board.c | 3 +- board/xilinx/zynqmp/zynqmp.c | 3 +- configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + doc/develop/uefi/uefi.rst | 98 - doc/mkeficapsule.1| 12 -- include/configs/imx8mm-cl-iot-gate.h | 9 + include/configs/imx8mp_rsb3720.h | 9 + include/configs/kontron-sl-mx8mm.h| 5 + include/configs/kontron_pitx_imx8m.h | 5 + include/configs/kontron_sl28.h| 5 + include/configs/qemu-arm.h| 9 + include/configs/sandbox.h
Re: [PATCH v6 5/8] test: capsule: Modify the capsule tests to use GUID values for sandbox
On Wed, 13 Apr 2022 at 12:05, AKASHI Takahiro wrote: > > On Tue, Apr 12, 2022 at 06:34:44PM +0530, Sughosh Ganu wrote: > > The current UEFI capsule updation code uses two GUID values, one for > > FIT images, and one for raw images across platforms. This logic is > > being changed to have GUID values per image, per platform. Change the > > tests for the capsule update code to reflect this change. The GUID > > values now used are the ones specific to the sandbox platform -- one > > for the u-boot image, and another for the u-boot environment image. > > > > Install the FMP instance for raw images on the sandbox variant for > > testing the capsule update code. Install the FMP instance for the FIT > > images on the sandbox64 and sandbox_flattree variant for testing > > capsule update for FIT images. This is being done by splitting the > > capsule update script for FIT and raw images. > > Why do we have to have different configs to test FIT and RAW capsules? With the current design, we have an FMP instance per platform. But the struct efi_fw_images can be extended to have a fmp member, so every image would have an FMP instance associated with it. With that, a platform can define multiple FMP instances. Would you prefer that? > > > Signed-off-by: Sughosh Ganu > > --- > > > > Changes since V5: > > * Restart the platform before starting the tests. This is done to > > clear out any stale state from a previously run test. > > > > > > configs/sandbox64_defconfig | 1 - > > configs/sandbox_defconfig | 1 - > > configs/sandbox_flattree_defconfig| 5 + > > test/py/tests/test_efi_capsule/conftest.py| 21 +- > > .../test_capsule_firmware_fit.py | 191 ++ > > ...rmware.py => test_capsule_firmware_raw.py} | 167 ++- > > 6 files changed, 270 insertions(+), 116 deletions(-) > > create mode 100644 > > test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py > > rename test/py/tests/test_efi_capsule/{test_capsule_firmware.py => > > test_capsule_firmware_raw.py} (75%) > > > > diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig > > index 88f9ecbb7f..db748bbed3 100644 > > --- a/configs/sandbox64_defconfig > > +++ b/configs/sandbox64_defconfig > > @@ -246,7 +246,6 @@ CONFIG_ERRNO_STR=y > > CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y > > CONFIG_EFI_CAPSULE_ON_DISK=y > > CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y > > -CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y > > CONFIG_EFI_SECURE_BOOT=y > > CONFIG_TEST_FDTDEC=y > > CONFIG_UNIT_TEST=y > > diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig > > index cb8d590eb6..0dfc2d863d 100644 > > --- a/configs/sandbox_defconfig > > +++ b/configs/sandbox_defconfig > > @@ -319,7 +319,6 @@ CONFIG_SHA384=y > > CONFIG_ERRNO_STR=y > > CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y > > CONFIG_EFI_CAPSULE_ON_DISK=y > > -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y > > CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y > > CONFIG_EFI_SECURE_BOOT=y > > CONFIG_TEST_FDTDEC=y > > diff --git a/configs/sandbox_flattree_defconfig > > b/configs/sandbox_flattree_defconfig > > index 24b272068a..27dd38a0c0 100644 > > --- a/configs/sandbox_flattree_defconfig > > +++ b/configs/sandbox_flattree_defconfig > > @@ -28,6 +28,7 @@ CONFIG_CMD_BOOTEFI_HELLO=y > > CONFIG_CMD_ASKENV=y > > CONFIG_CMD_GREPENV=y > > CONFIG_CMD_ERASEENV=y > > +CONFIG_CMD_NVEDIT_EFI=y > > CONFIG_CMD_NVEDIT_INFO=y > > CONFIG_CMD_NVEDIT_LOAD=y > > CONFIG_CMD_NVEDIT_SELECT=y > > @@ -209,3 +210,7 @@ CONFIG_HEXDUMP=y > > CONFIG_UNIT_TEST=y > > CONFIG_UT_TIME=y > > CONFIG_UT_DM=y > > +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y > > +CONFIG_EFI_CAPSULE_ON_DISK=y > > +CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y > > +CONFIG_DFU_SF=y > > diff --git a/test/py/tests/test_efi_capsule/conftest.py > > b/test/py/tests/test_efi_capsule/conftest.py > > index 9076087a12..d757415c88 100644 > > --- a/test/py/tests/test_efi_capsule/conftest.py > > +++ b/test/py/tests/test_efi_capsule/conftest.py > > @@ -72,7 +72,7 @@ def efi_capsule_data(request, u_boot_config): > > > > # Create capsule files > > # two regions: one for u-boot.bin and the other for u-boot.env > > -check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n > > u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo > > -n u-boot-env:New > u-boot.env.new' % data_dir, > > +check_call('cd %s; ech
Re: [PATCH v6 8/8] doc: uefi: Update the capsule update related documentation
On Wed, 13 Apr 2022 at 11:48, AKASHI Takahiro wrote: > > On Tue, Apr 12, 2022 at 06:34:47PM +0530, Sughosh Ganu wrote: > > Update the capsule update functionality related documentation to > > refect the additional definitions that need to be made per platform > > for supporting the capsule update feature. > > > > Signed-off-by: Sughosh Ganu > > --- > > > > Changes since V5: None > > > > doc/develop/uefi/uefi.rst | 51 +-- > > 1 file changed, 49 insertions(+), 2 deletions(-) > > > > diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst > > index fe337c88bd..b766aecf67 100644 > > --- a/doc/develop/uefi/uefi.rst > > +++ b/doc/develop/uefi/uefi.rst > > @@ -312,8 +312,8 @@ Run the following command > > .. code-block:: console > > > > $ mkeficapsule \ > > - --index 1 --instance 0 \ > > - [--fit | --raw ] \ > > + --index --instance 0 \ > > + --guid \ > > > > > > Performing the update > > @@ -333,6 +333,53 @@ won't be taken over across the reboot. If this is the > > case, you can skip > > this feature check with the Kconfig option > > (CONFIG_EFI_IGNORE_OSINDICATIONS) > > set. > > > > +A few values need to be defined in the board file for performing the > > +capsule update. These values are defined in the board file by > > +initialisation of a structure which provides information needed for > > +capsule updates. The following structures have been defined for > > +containing the image related information > > + > > +.. code-block:: c > > + > > + struct efi_fw_images { > > Why "images" (in the plural)? Hmm, since this is to be an array of firmware images which should be handled by the capsule update code, I used a plural form. Do you prefer efi_fw_image instead? > > > + efi_guid_t image_type_id; > > + u16 *fw_name; > > + u8 image_index; > > + }; > > Why not add "version" and "last_attempt_version" which is expected > to be easily implemented in this structure. It can be added to this structure, yes. But we will also need to add code in the capsule driver to update these fields accordingly. I can take this up as a follow up task once the FWU series upstreaming is done. > > > > + struct efi_capsule_update_info { > > + const char *dfu_string; > > + struct efi_fw_images *images; > > + }; > > + > > + > > +A string is defined which is to be used for populating the > > +dfu_alt_info variable. This string is used by the function > > +set_dfu_alt_info. Instead of taking the variable from the environment, > > +the capsule update feature requires that the variable be set through > > +the function, since that is more robust. Allowing the user to change > > +the location of the firmware updates is not a very secure > > +practice. Getting this information from the firmware itself is more > > +secure, assuming the firmware has been verified by a previous stage > > +boot loader. > > + > > +The firmware images structure defines the GUID values, image index > > +values and the name of the images that are to be updated through > > +the capsule update feature. These values are to be defined as part of > > +an array. These GUID values would be used by the Firmware Management > > +Protocol(FMP) to populate the image descriptor array and also > > +displayed as part of the ESRT table. The image index values defined in > > +the array should be one greater than the dfu alt number that > > +corresponds to the firmware image. So, if the dfu alt number for an > > +image is 2, the value of image index in the fw_images array for that > > +image should be 3. The dfu alt number can be obtained by running the > > +following command:: > > + > > +dfu list > > + > > +When using the FMP for FIT images, the image index value needs to be > > +set to 1. > > The explanation would be correct, but it's not quite easy to understand, > in particular, index in case of raw. > You should add some examples here. I have added an example above for the raw images, as to how the image index corresponds with the dfu alt number. Does it not suffice? -sughosh > > -Takahiro Akashi > > > + > > Finally, the capsule update can be initiated by rebooting the board. > > > > Enabling Capsule Authentication > > -- > > 2.25.1 > >
Re: [PATCH v6 7/8] mkeficapsule: Remove raw and FIT GUID types
On Wed, 13 Apr 2022 at 11:53, AKASHI Takahiro wrote: > > On Wed, Apr 13, 2022 at 11:44:18AM +0530, Sughosh Ganu wrote: > > On Wed, 13 Apr 2022 at 11:35, AKASHI Takahiro > > wrote: > > > > > > On Tue, Apr 12, 2022 at 06:34:46PM +0530, Sughosh Ganu wrote: > > > > While building a capsule, the GUID value of that specific image is to > > > > be passed through the --guid command option to the mkeficapsule > > > > tool. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and > > > > EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the > > > > > > superfluous? I don't think it is the reason for removing guids for > > > FIT/RAW. > > > > The reason for using that word is that these GUID values would not be > > used any longer. Do you prefer some other phrasing of the sentence? > > They are not used not because we have "--guid" option, which I added later > than "--fit" or "--raw" in order to handle extra cases, but because you > changed > the semantics of FIT/RAW drivers. That is what I have mentioned above. With the passing of the GUID value through the --guid option, the raw and FIT GUIDs are no longer needed. -sughosh > > -Takahiro Akashi > > > > > > > > --raw and --fit command line options as well. > > > > > > Please update doc/mkeficapsule.1 as well. > > > > Will do. > > > > -sughosh > > > > > > > > -Takahiro Akashi > > > > > > > Signed-off-by: Sughosh Ganu > > > > Acked-by: Ilias Apalodimas > > > > --- > > > > > > > > Changes since V5: None > > > > > > > > tools/eficapsule.h | 8 > > > > tools/mkeficapsule.c | 26 +- > > > > 2 files changed, 1 insertion(+), 33 deletions(-) > > > > > > > > diff --git a/tools/eficapsule.h b/tools/eficapsule.h > > > > index 69c9c58c2f..d63b831443 100644 > > > > --- a/tools/eficapsule.h > > > > +++ b/tools/eficapsule.h > > > > @@ -37,14 +37,6 @@ typedef struct { > > > > EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ > > > >0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) > > > > > > > > -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ > > > > - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ > > > > - 0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) > > > > - > > > > -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ > > > > - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ > > > > - 0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) > > > > - > > > > #define EFI_CERT_TYPE_PKCS7_GUID \ > > > > EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ > > > >0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) > > > > diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c > > > > index c118335b93..5f74d23b9e 100644 > > > > --- a/tools/mkeficapsule.c > > > > +++ b/tools/mkeficapsule.c > > > > @@ -27,17 +27,11 @@ > > > > static const char *tool_name = "mkeficapsule"; > > > > > > > > efi_guid_t efi_guid_fm_capsule = > > > > EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; > > > > -efi_guid_t efi_guid_image_type_uboot_fit = > > > > - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; > > > > -efi_guid_t efi_guid_image_type_uboot_raw = > > > > - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; > > > > efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; > > > > > > > > -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; > > > > +static const char *opts_short = "g:i:I:v:p:c:m:dh"; > > > > > > > > static struct option options[] = { > > > > - {"fit", no_argument, NULL, 'f'}, > > > > - {"raw", no_argument, NULL, 'r'}, > > > > {"guid", required_argument, NULL, 'g'}, > > > > {"index", required_argument, NULL, 'i'}, > > > > {"instance", required_argument, NULL, 'I'}, > > > > @@ -54,8 +48,6 @@ static void print_usage(void) > > > > fprintf(stderr, "Usage: %s [options] \n" > > > > "Options:\n" > > > > > > > > - "\t-f, --fit FIT image type\n"
Re: [PATCH v6 7/8] mkeficapsule: Remove raw and FIT GUID types
On Wed, 13 Apr 2022 at 11:35, AKASHI Takahiro wrote: > > On Tue, Apr 12, 2022 at 06:34:46PM +0530, Sughosh Ganu wrote: > > While building a capsule, the GUID value of that specific image is to > > be passed through the --guid command option to the mkeficapsule > > tool. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and > > EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the > > superfluous? I don't think it is the reason for removing guids for FIT/RAW. The reason for using that word is that these GUID values would not be used any longer. Do you prefer some other phrasing of the sentence? > > > --raw and --fit command line options as well. > > Please update doc/mkeficapsule.1 as well. Will do. -sughosh > > -Takahiro Akashi > > > Signed-off-by: Sughosh Ganu > > Acked-by: Ilias Apalodimas > > --- > > > > Changes since V5: None > > > > tools/eficapsule.h | 8 > > tools/mkeficapsule.c | 26 +- > > 2 files changed, 1 insertion(+), 33 deletions(-) > > > > diff --git a/tools/eficapsule.h b/tools/eficapsule.h > > index 69c9c58c2f..d63b831443 100644 > > --- a/tools/eficapsule.h > > +++ b/tools/eficapsule.h > > @@ -37,14 +37,6 @@ typedef struct { > > EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ > >0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) > > > > -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ > > - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ > > - 0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) > > - > > -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ > > - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ > > - 0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) > > - > > #define EFI_CERT_TYPE_PKCS7_GUID \ > > EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ > >0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) > > diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c > > index c118335b93..5f74d23b9e 100644 > > --- a/tools/mkeficapsule.c > > +++ b/tools/mkeficapsule.c > > @@ -27,17 +27,11 @@ > > static const char *tool_name = "mkeficapsule"; > > > > efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; > > -efi_guid_t efi_guid_image_type_uboot_fit = > > - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; > > -efi_guid_t efi_guid_image_type_uboot_raw = > > - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; > > efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; > > > > -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; > > +static const char *opts_short = "g:i:I:v:p:c:m:dh"; > > > > static struct option options[] = { > > - {"fit", no_argument, NULL, 'f'}, > > - {"raw", no_argument, NULL, 'r'}, > > {"guid", required_argument, NULL, 'g'}, > > {"index", required_argument, NULL, 'i'}, > > {"instance", required_argument, NULL, 'I'}, > > @@ -54,8 +48,6 @@ static void print_usage(void) > > fprintf(stderr, "Usage: %s [options] \n" > > "Options:\n" > > > > - "\t-f, --fit FIT image type\n" > > - "\t-r, --raw raw image type\n" > > "\t-g, --guid guid for image blob type\n" > > "\t-i, --index update image index\n" > > "\t-I, --instanceupdate hardware instance\n" > > @@ -606,22 +598,6 @@ int main(int argc, char **argv) > > break; > > > > switch (c) { > > - case 'f': > > - if (guid) { > > - fprintf(stderr, > > - "Image type already specified\n"); > > - exit(EXIT_FAILURE); > > - } > > - guid = _guid_image_type_uboot_fit; > > - break; > > - case 'r': > > - if (guid) { > > - fprintf(stderr, > > - "Image type already specified\n"); > > - exit(EXIT_FAILURE); > > - } > > - guid = _guid_image_type_uboot_raw; > > - break; > > case 'g': > > if (guid) { > > fprintf(stderr, > > -- > > 2.25.1 > >
[PATCH v6 8/8] doc: uefi: Update the capsule update related documentation
Update the capsule update functionality related documentation to refect the additional definitions that need to be made per platform for supporting the capsule update feature. Signed-off-by: Sughosh Ganu --- Changes since V5: None doc/develop/uefi/uefi.rst | 51 +-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index fe337c88bd..b766aecf67 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -312,8 +312,8 @@ Run the following command .. code-block:: console $ mkeficapsule \ - --index 1 --instance 0 \ - [--fit | --raw ] \ + --index --instance 0 \ + --guid \ Performing the update @@ -333,6 +333,53 @@ won't be taken over across the reboot. If this is the case, you can skip this feature check with the Kconfig option (CONFIG_EFI_IGNORE_OSINDICATIONS) set. +A few values need to be defined in the board file for performing the +capsule update. These values are defined in the board file by +initialisation of a structure which provides information needed for +capsule updates. The following structures have been defined for +containing the image related information + +.. code-block:: c + + struct efi_fw_images { + efi_guid_t image_type_id; + u16 *fw_name; + u8 image_index; + }; + + struct efi_capsule_update_info { + const char *dfu_string; + struct efi_fw_images *images; + }; + + +A string is defined which is to be used for populating the +dfu_alt_info variable. This string is used by the function +set_dfu_alt_info. Instead of taking the variable from the environment, +the capsule update feature requires that the variable be set through +the function, since that is more robust. Allowing the user to change +the location of the firmware updates is not a very secure +practice. Getting this information from the firmware itself is more +secure, assuming the firmware has been verified by a previous stage +boot loader. + +The firmware images structure defines the GUID values, image index +values and the name of the images that are to be updated through +the capsule update feature. These values are to be defined as part of +an array. These GUID values would be used by the Firmware Management +Protocol(FMP) to populate the image descriptor array and also +displayed as part of the ESRT table. The image index values defined in +the array should be one greater than the dfu alt number that +corresponds to the firmware image. So, if the dfu alt number for an +image is 2, the value of image index in the fw_images array for that +image should be 3. The dfu alt number can be obtained by running the +following command:: + +dfu list + +When using the FMP for FIT images, the image index value needs to be +set to 1. + Finally, the capsule update can be initiated by rebooting the board. Enabling Capsule Authentication -- 2.25.1
[PATCH v6 7/8] mkeficapsule: Remove raw and FIT GUID types
While building a capsule, the GUID value of that specific image is to be passed through the --guid command option to the mkeficapsule tool. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the --raw and --fit command line options as well. Signed-off-by: Sughosh Ganu Acked-by: Ilias Apalodimas --- Changes since V5: None tools/eficapsule.h | 8 tools/mkeficapsule.c | 26 +- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 69c9c58c2f..d63b831443 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -37,14 +37,6 @@ typedef struct { EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define EFI_CERT_TYPE_PKCS7_GUID \ EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index c118335b93..5f74d23b9e 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -27,17 +27,11 @@ static const char *tool_name = "mkeficapsule"; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; -efi_guid_t efi_guid_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; -efi_guid_t efi_guid_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; +static const char *opts_short = "g:i:I:v:p:c:m:dh"; static struct option options[] = { - {"fit", no_argument, NULL, 'f'}, - {"raw", no_argument, NULL, 'r'}, {"guid", required_argument, NULL, 'g'}, {"index", required_argument, NULL, 'i'}, {"instance", required_argument, NULL, 'I'}, @@ -54,8 +48,6 @@ static void print_usage(void) fprintf(stderr, "Usage: %s [options] \n" "Options:\n" - "\t-f, --fit FIT image type\n" - "\t-r, --raw raw image type\n" "\t-g, --guid guid for image blob type\n" "\t-i, --index update image index\n" "\t-I, --instanceupdate hardware instance\n" @@ -606,22 +598,6 @@ int main(int argc, char **argv) break; switch (c) { - case 'f': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_fit; - break; - case 'r': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_raw; - break; case 'g': if (guid) { fprintf(stderr, -- 2.25.1
[PATCH v6 6/8] FMP: Remove GUIDs for FIT and raw images
The capsule update code has been modified for getting the image GUID values from the platform code. With this, each image now has a unique GUID value. With this change, there is no longer a need for defining GUIDs for FIT and raw images. Remove these GUID values. Signed-off-by: Sughosh Ganu Reviewed-by: Ilias Apalodimas --- Changes since V5: None include/efi_api.h | 8 lib/efi_loader/efi_firmware.c | 4 2 files changed, 12 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 982c200172..c7f7873b5d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1967,14 +1967,6 @@ struct efi_signature_list { EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ 0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE0x0001 #define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 #define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED0x0004 diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index c2fe660cdd..bd9ed1e524 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -188,8 +188,6 @@ static efi_status_t efi_fill_image_desc_array( * - versioning of firmware image * - package information */ -const efi_guid_t efi_firmware_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; /** * efi_firmware_fit_get_image_info - return information about the current @@ -296,8 +294,6 @@ const struct efi_firmware_management_protocol efi_fmp_fit = { * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update * method with raw data. */ -const efi_guid_t efi_firmware_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; /** * efi_firmware_raw_get_image_info - return information about the current -- 2.25.1
[PATCH v6 5/8] test: capsule: Modify the capsule tests to use GUID values for sandbox
The current UEFI capsule updation code uses two GUID values, one for FIT images, and one for raw images across platforms. This logic is being changed to have GUID values per image, per platform. Change the tests for the capsule update code to reflect this change. The GUID values now used are the ones specific to the sandbox platform -- one for the u-boot image, and another for the u-boot environment image. Install the FMP instance for raw images on the sandbox variant for testing the capsule update code. Install the FMP instance for the FIT images on the sandbox64 and sandbox_flattree variant for testing capsule update for FIT images. This is being done by splitting the capsule update script for FIT and raw images. Signed-off-by: Sughosh Ganu --- Changes since V5: * Restart the platform before starting the tests. This is done to clear out any stale state from a previously run test. configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + test/py/tests/test_efi_capsule/conftest.py| 21 +- .../test_capsule_firmware_fit.py | 191 ++ ...rmware.py => test_capsule_firmware_raw.py} | 167 ++- 6 files changed, 270 insertions(+), 116 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py rename test/py/tests/test_efi_capsule/{test_capsule_firmware.py => test_capsule_firmware_raw.py} (75%) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 88f9ecbb7f..db748bbed3 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -246,7 +246,6 @@ CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y -CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index cb8d590eb6..0dfc2d863d 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -319,7 +319,6 @@ CONFIG_SHA384=y CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 24b272068a..27dd38a0c0 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -28,6 +28,7 @@ CONFIG_CMD_BOOTEFI_HELLO=y CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_ERASEENV=y +CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_NVEDIT_INFO=y CONFIG_CMD_NVEDIT_LOAD=y CONFIG_CMD_NVEDIT_SELECT=y @@ -209,3 +210,7 @@ CONFIG_HEXDUMP=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y +CONFIG_DFU_SF=y diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 9076087a12..d757415c88 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -72,7 +72,7 @@ def efi_capsule_data(request, u_boot_config): # Create capsule files # two regions: one for u-boot.bin and the other for u-boot.env -check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, +check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, shell=True) check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' % (u_boot_config.source_dir, data_dir), @@ -80,21 +80,29 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --fit uboot_bin_env.itb Test01' % +check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test01' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --raw u-boot.bin.new Test02' % +check_call('cd %s; %s/tools/mkeficapsule --index 2 --guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test02' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/m
[PATCH v6 4/8] efi: Define set_dfu_alt_info() for boards with UEFI capsule update enabled
Currently, there are a bunch of boards which enable the UEFI capsule update feature. The actual update of the firmware images is done through the dfu framework which uses the dfu_alt_info environment variable for getting information on the update, like device, partition number/address etc. The dfu framework allows the variable to be set through the set_dfu_alt_info function defined by the platform, or if the function is not defined, it gets the variable from the environment. Using the value set in the environment is not very robust, since the variable can be modified from the u-boot command line and this can cause an incorrect update. To prevent this from happening, define the set_dfu_alt_info function when the capsule update feature is enabled. A weak function is defined which sets the dfu_alt_info environment variable by getting the string for the variable from the platform. Signed-off-by: Sughosh Ganu --- Changes since V5: * Simplify the set_dfu_alt_info function definition to set the variable directly from dfu_string, as suggested by Heinrich. lib/efi_loader/Kconfig| 2 ++ lib/efi_loader/efi_firmware.c | 5 + 2 files changed, 7 insertions(+) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 559b95a599..d50cd2563d 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -181,6 +181,7 @@ config EFI_CAPSULE_FIRMWARE_FIT depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT select UPDATE_FIT select DFU + select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol @@ -192,6 +193,7 @@ config EFI_CAPSULE_FIRMWARE_RAW depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT) select DFU_WRITE_ALT select DFU + select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index e9fc4b9c1e..c2fe660cdd 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -35,6 +35,11 @@ struct fmp_payload_header { u32 lowest_supported_version; }; +__weak void set_dfu_alt_info(char *interface, char *devstr) +{ + env_set("dfu_alt_info", update_info.dfu_string); +} + /* Place holder; not supported */ static efi_status_t EFIAPI efi_firmware_get_image_unsupported( -- 2.25.1
[PATCH v6 3/8] capsule: Put a check for image index before the update
The current capsule update code compares the image GUID value in the capsule header with the image GUID value obtained from the GetImageInfo function of the Firmware Management Protocol(FMP). This comparison is done to ascertain if the FMP's SetImage function can be called for the update. Make this checking more robust by comparing the image_index value passed through the capsule with that returned by the FMP's GetImageInfo function. This protects against the scenario of the firmware being updated in a wrong partition/location on the storage device if an incorrect value has been passed through the capsule, since the image_index is used to determine the location of the update on the storage device. Signed-off-by: Sughosh Ganu Reviewed-by: Masami Hiramatsu Reviewed-by: Ilias Apalodimas --- Changes since V5: None lib/efi_loader/efi_capsule.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index a107f285dd..c76a5f3570 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -129,6 +129,7 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, /** * efi_fmp_find - search for Firmware Management Protocol drivers * @image_type:Image type guid + * @image_index: Image Index * @instance: Instance number * @handles: Handles of FMP drivers * @no_handles:Number of handles @@ -142,8 +143,8 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, * * NULL - on failure */ static struct efi_firmware_management_protocol * -efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, -efi_uintn_t no_handles) +efi_fmp_find(efi_guid_t *image_type, u8 image_index, u64 instance, +efi_handle_t *handles, efi_uintn_t no_handles) { efi_handle_t *handle; struct efi_firmware_management_protocol *fmp; @@ -204,6 +205,7 @@ efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, log_debug("+++ desc[%d] index: %d, name: %ls\n", j, desc->image_index, desc->image_id_name); if (!guidcmp(>image_type_id, image_type) && + (desc->image_index == image_index) && (!instance || !desc->hardware_instance || desc->hardware_instance == instance)) @@ -450,8 +452,8 @@ static efi_status_t efi_capsule_update_firmware( } /* find a device for update firmware */ - /* TODO: should we pass index as well, or nothing but type? */ fmp = efi_fmp_find(>update_image_type_id, + image->update_image_index, image->update_hardware_instance, handles, no_handles); if (!fmp) { -- 2.25.1
[PATCH v6 2/8] capsule: FMP: Populate the image descriptor array from platform data
Currently, the image descriptor array that has been passed to the GetImageInfo function of the Firmware Management Protocol(FMP) gets populated through the data stored with the dfu framework. The dfu data is not restricted to contain information only of the images updatable through the capsule update mechanism, but it also contains information on other images. The image descriptor array is also parsed by the ESRT generation code, and thus the ESRT table contains entries for other images that are not being handled by the FMP for the capsule updates. Fix this by populating the image descriptor array from the structure initialised in the board file. The other issue fixed is assignment of a separate GUID for all images in the image descriptor array. The UEFI specification mandates that all entries in the ESRT table should have a unique GUID value as part of the FwClass member of the EFI_SYSTEM_RESOURCE_ENTRY. Currently, all images are assigned a single GUID value, either an FIT GUID or a raw image GUID. This is fixed by obtaining the GUID values from the efi_fw_images array defined per platform. Signed-off-by: Sughosh Ganu --- Changes since V5: None lib/efi_loader/efi_firmware.c | 95 +++ 1 file changed, 28 insertions(+), 67 deletions(-) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a5ff32f121..e9fc4b9c1e 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -97,91 +97,58 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( } /** - * efi_get_dfu_info - return information about the current firmware image + * efi_fill_image_desc_array - populate image descriptor array * @this: Protocol instance * @image_info_size: Size of @image_info * @image_info:Image information * @descriptor_version:Pointer to version number - * @descriptor_count: Pointer to number of descriptors + * @descriptor_count: Image count * @descriptor_size: Pointer to descriptor size - * package_version:Package version - * package_version_name: Package version's name - * image_type: Image type GUID + * @package_version: Package version + * @package_version_name: Package version's name * * Return information bout the current firmware image in @image_info. * @image_info will consist of a number of descriptors. - * Each descriptor will be created based on "dfu_alt_info" variable. + * Each descriptor will be created based on "efi_fw_images" variable. * * Return status code */ -static efi_status_t efi_get_dfu_info( +static efi_status_t efi_fill_image_desc_array( efi_uintn_t *image_info_size, struct efi_firmware_image_descriptor *image_info, u32 *descriptor_version, u8 *descriptor_count, efi_uintn_t *descriptor_size, u32 *package_version, - u16 **package_version_name, - const efi_guid_t *image_type) + u16 **package_version_name) { - struct dfu_entity *dfu; - size_t names_len, total_size; - int dfu_num, i; - u16 *name, *next; - int ret; - - ret = dfu_init_env_entities(NULL, NULL); - if (ret) - return EFI_SUCCESS; - - names_len = 0; - dfu_num = 0; - list_for_each_entry(dfu, _list, list) { - names_len += (utf8_utf16_strlen(dfu->name) + 1) * 2; - dfu_num++; - } - if (!dfu_num) { - log_warning("No entities in dfu_alt_info\n"); - *image_info_size = 0; - dfu_free_entities(); + size_t total_size; + struct efi_fw_images *fw_array; + int i; - return EFI_SUCCESS; - } + fw_array = update_info.images; + *descriptor_count = num_image_type_guids; + + total_size = sizeof(*image_info) * num_image_type_guids; - total_size = sizeof(*image_info) * dfu_num + names_len; - /* -* we will assume that sizeof(*image_info) * dfu_name -* is, at least, a multiple of 2. So the start address for -* image_id_name would be aligned with 2 bytes. -*/ if (*image_info_size < total_size) { *image_info_size = total_size; - dfu_free_entities(); return EFI_BUFFER_TOO_SMALL; } *image_info_size = total_size; *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; - *descriptor_count = dfu_num; *descriptor_size = sizeof(*image_info); *package_version = 0x; /* not supported */ *package_version_name = NULL; /* not supported */ - /* DFU alt number should correspond to image_index */ - i = 0; - /* Name area starts just after descriptors */ - name = (u16 *)((u8 *)image_info + sizeof(*image_i
[PATCH v6 1/8] capsule: board: Add information needed for capsule updates
Add a structure which defines the information that is needed for executing capsule updates on a platform. Some information in the structure like the dfu string is used for making the update process more robust while some information like the per platform image GUIDs is used for fixing issues. Initialise this structure in the board file, and use the information for the capsule updates. Signed-off-by: Sughosh Ganu --- Changes since V5: * Create a separate entry in fw_images array per config for boards with multiple configs as suggested by Heinrich. * Removed CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) check in the board config headers, as suggested by Heinrich. * Add a check in the set_dfu_alt_info functions for the xilinx and qemu platforms to get the board defined value of dfu_alt_info when capsule update feature is enabled. .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 29 +++ .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 28 +++ board/emulation/common/qemu_dfu.c | 3 +- board/emulation/qemu-arm/qemu-arm.c | 28 +++ board/kontron/pitx_imx8m/pitx_imx8m.c | 21 ++- board/kontron/sl-mx8mm/sl-mx8mm.c | 20 +++ board/kontron/sl28/sl28.c | 21 +++ board/sandbox/sandbox.c | 34 ++ board/socionext/developerbox/developerbox.c | 33 + board/xilinx/common/board.c | 28 +++ board/xilinx/zynq/board.c | 3 +- board/xilinx/zynqmp/zynqmp.c | 3 +- include/configs/imx8mm-cl-iot-gate.h | 9 + include/configs/imx8mp_rsb3720.h | 9 + include/configs/kontron-sl-mx8mm.h| 5 +++ include/configs/kontron_pitx_imx8m.h | 5 +++ include/configs/kontron_sl28.h| 5 +++ include/configs/qemu-arm.h| 9 + include/configs/sandbox.h | 13 +++ include/configs/synquacer.h | 13 +++ include/configs/xilinx_versal.h | 5 +++ include/configs/xilinx_zynqmp.h | 9 + include/configs/zynq-common.h | 9 + include/efi_loader.h | 36 +++ 24 files changed, 374 insertions(+), 4 deletions(-) diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c index 16566092bd..c85a99f650 100644 --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -44,6 +47,32 @@ static void setup_gpmi_nand(void) } #endif +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { +#if defined(CONFIG_TARGET_IMX8MP_RSB3720A1_4G) + { + .image_type_id = IMX8MP_RSB3720A1_4G_FIT_IMAGE_GUID, + .fw_name = u"IMX8MP-RSB3720-FIT", + .image_index = 1, + }, +#elif defined(CONFIG_TARGET_IMX8MP_RSB3720A1_6G) + { + .image_type_id = IMX8MP_RSB3720A1_6G_FIT_IMAGE_GUID, + .fw_name = u"IMX8MP-RSB3720-FIT", + .image_index = 1, + }, +#endif +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 2=flash-bin raw 0 0x1B00 mmcpart 1", + .images = fw_images, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + + int board_early_init_f(void) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c index 7e2d88f449..a82a001e2a 100644 --- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c +++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include #include @@ -21,11 +23,37 @@ #include #include #include +#include #include "ddr/ddr.h" DECLARE_GLOBAL_DATA_PTR; +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { +#if defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) + { + .image_type_id = IMX8MM_CL_IOT_GATE_FIT_IMAGE_GUID, + .fw_name = u"IMX8MM-CL-IOT-GATE-FIT", + .image_index = 1, + }, +#elif defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) + { + .image_type_id = IMX8MM_CL_IOT_GATE_OPTEE_FIT_IMAGE_GUID, + .fw_name = u"IMX8MM-CL-IOT-GATE-FIT", + .image_index = 1, + }, +#endif +}; + +struct efi_capsule_update_info update_info = { + .dfu_string =
[PATCH v6 0/8] efi: capsule: Capsule Update fixes and enhancements
CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) check in the board config headers, as suggested by Heinrich. * Add a check in the set_dfu_alt_info functions for the xilinx and qemu platforms to get the board defined value of dfu_alt_info when capsule update feature is enabled. * Simplify the set_dfu_alt_info function definition to set the variable directly from dfu_string, as suggested by Heinrich. * Restart the platform before starting the tests. This is done to clear out any stale state from a previously run test. Changes since V4: - * Define a structure efi_capsule_update_info which includes the string for populating dfu_alt_info * Initialise the string for dfu_alt_info in the board file * Drop the image_count variable as was suggested by Ilias * Drop another unused variable names_len * Define a weak function set_dfu_alt_info for setting the variable in a non board specific file as suggested by Ilias * Drop the definitions of set_dfu_alt_info that were being added in the board files * Change the description of the platform data based on the changes made in earlier patches Changes since V3: - * Do not remove the existing dfu_alt_info definitions made by platforms in the config files, as discussed with Masami. * Squash the selection of the SET_DFU_ALT_INFO config symbol for capsule update feature as part of this patch. * Rephrase the commit message to indicate that the doc changes are not just limited to adding the GUID values, but other info as well. * Elaborate with an example on the relation between the dfu alt number and the image index Changes since V2: - * Add a new member image_index to the struct efi_fw_images to allow the platforms to define the values for images. * Address review comments from Michal Simek for the xilinx boards. * Fix double inclusion of efi_loader.h as was pointed out by Heiko Thiery. * Use the image index values defined in the platform's fw_images array for the image descriptors * Add a description for adding image index value and definition of set_dfu_alt_info function for the capsule updates. Changes since V1: - * Make changes for the xilinx boards as suggested by Michal Simek. * Add a GUID for the sandbox FIT image. * Split the capsule update test cases into two scripts, one for raw images and one for FIT images. * Add the capsule update test case for FIT images on sandbox64 and sandbox_flattree variants. * Add capsule update support on sandbox_flattree variant for enabling FIT capsule update testing as part of the python tests Sughosh Ganu (8): capsule: board: Add information needed for capsule updates capsule: FMP: Populate the image descriptor array from platform data capsule: Put a check for image index before the update efi: Define set_dfu_alt_info() for boards with UEFI capsule update enabled test: capsule: Modify the capsule tests to use GUID values for sandbox FMP: Remove GUIDs for FIT and raw images mkeficapsule: Remove raw and FIT GUID types doc: uefi: Update the capsule update related documentation .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 29 +++ .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 28 +++ board/emulation/common/qemu_dfu.c | 3 +- board/emulation/qemu-arm/qemu-arm.c | 28 +++ board/kontron/pitx_imx8m/pitx_imx8m.c | 21 +- board/kontron/sl-mx8mm/sl-mx8mm.c | 20 ++ board/kontron/sl28/sl28.c | 21 ++ board/sandbox/sandbox.c | 34 board/socionext/developerbox/developerbox.c | 33 +++ board/xilinx/common/board.c | 28 +++ board/xilinx/zynq/board.c | 3 +- board/xilinx/zynqmp/zynqmp.c | 3 +- configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + doc/develop/uefi/uefi.rst | 51 - include/configs/imx8mm-cl-iot-gate.h | 9 + include/configs/imx8mp_rsb3720.h | 9 + include/configs/kontron-sl-mx8mm.h| 5 + include/configs/kontron_pitx_imx8m.h | 5 + include/configs/kontron_sl28.h| 5 + include/configs/qemu-arm.h| 9 + include/configs/sandbox.h | 13 ++ include/configs/synquacer.h | 13 ++ include/configs/xilinx_versal.h | 5 + include/configs/xilinx_zynqmp.h | 9 + include/configs/zynq-common.h | 9 + include/efi_api.h | 8 - include/efi_loader.h | 36 lib/efi_loader/Kconfig| 2 + lib/efi_loader/efi_capsule.c | 8 +- lib/efi_loader/efi_firmware.c | 104 +++--- test/py/tests/test_efi_capsule/conftest.py| 21
Re: [PATCH v5 4/8] efi: Define set_dfu_alt_info() for boards with UEFI capsule update enabled
On Sat, 2 Apr 2022 at 15:00, Heinrich Schuchardt wrote: > > On 4/1/22 21:17, Sughosh Ganu wrote: > > Currently, there are a bunch of boards which enable the UEFI capsule > > update feature. The actual update of the firmware images is done > > through the dfu framework which uses the dfu_alt_info environment > > variable for getting information on the update, like device, partition > > number/address etc. The dfu framework allows the variable to be set > > through the set_dfu_alt_info function defined by the platform, or if > > the function is not defined, it gets the variable from the > > environment. Using the value set in the environment is not very > > robust, since the variable can be modified from the u-boot command > > line and this can cause an incorrect update. > > > > To prevent this from happening, define the set_dfu_alt_info function > > when the capsule update feature is enabled. A weak function is defined > > which sets the dfu_alt_info environment variable by getting the string > > for the variable from the platform. > > > > Signed-off-by: Sughosh Ganu > > --- > > > > Changes since V4: > > * Define a weak function set_dfu_alt_info for setting the variable in > >a non board specific file as suggested by Ilias > > * Drop the definitions of set_dfu_alt_info that were being added in > >the board files > > > > lib/efi_loader/Kconfig| 2 ++ > > lib/efi_loader/efi_firmware.c | 23 +++ > > 2 files changed, 25 insertions(+) > > > > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig > > index e5e35fe51f..09fb8cbe75 100644 > > --- a/lib/efi_loader/Kconfig > > +++ b/lib/efi_loader/Kconfig > > @@ -174,6 +174,7 @@ config EFI_CAPSULE_FIRMWARE_FIT > > depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT > > select UPDATE_FIT > > select DFU > > + select SET_DFU_ALT_INFO > > select EFI_CAPSULE_FIRMWARE > > help > > Select this option if you want to enable firmware management > > protocol > > @@ -185,6 +186,7 @@ config EFI_CAPSULE_FIRMWARE_RAW > > depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT) > > select DFU_WRITE_ALT > > select DFU > > + select SET_DFU_ALT_INFO > > select EFI_CAPSULE_FIRMWARE > > help > > Select this option if you want to enable firmware management > > protocol > > diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c > > index e9fc4b9c1e..cbfa57f64f 100644 > > --- a/lib/efi_loader/efi_firmware.c > > +++ b/lib/efi_loader/efi_firmware.c > > @@ -11,9 +11,11 @@ > > #include > > #include > > #include > > +#include > > #include > > > > #include > > +#include > > > > #define FMP_PAYLOAD_HDR_SIGNATURE SIGNATURE_32('M', 'S', 'S', '1') > > > > @@ -35,6 +37,27 @@ struct fmp_payload_header { > > u32 lowest_supported_version; > > }; > > > > +#define DFU_ALT_BUF_LEN SZ_1K > > + > > +__weak void set_dfu_alt_info(char *interface, char *devstr) > > +{ > > + int n; > > + const char *dfu_alt_info; > > + ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); > > env_set() copies the string and does not require a cache aligned buffer. Okay. WIll check and remove the aligned allocation. This is how it has been defined for all the set_dfu_alt_info functions. If not needed, I will remove it. > > > + > > + if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && > > + env_get("dfu_alt_info")) > > This deserves a comment, e.g. > > For capsule support we always want to use a hard coded value. > For other cases of DFU avoid overwriting a preexisting value. > > But why would you not overwrite a preexisting value if the hardware has > a fixed definition? This can be done away with in this particular definition of the function, since this will be used only for the capsule update use case, where we do need to get the variable as defined by the board through the dfu_string. Will remove this check. > > > + return; > > + > > + dfu_alt_info = update_info.dfu_string; > > + n = strlen(dfu_alt_info); > > + memset(buf, 0, n + 1); > > This will result in a buffer overrun if update_info.dfu_string is longer > than DFU_ALT_BUF_LEN. > > > + > > + strncpy(buf, dfu_alt_info, n); > > Another buffer overrun. > > > + > > + env_set("dfu_alt_info", buf); > > This is all you need: > > env_set("dfu_alt_info", update_info.dfu_string); > > If any DFU driver has a problem with properly handling dfu_alt_info > being longer than DFU_ALT_BUF_LEN, you should fix the problem there. Will clean this up. Thanks. -sughosh > > Best regards > > Heinrich > > > +} > > + > > /* Place holder; not supported */ > > static > > efi_status_t EFIAPI efi_firmware_get_image_unsupported( >
Re: [PATCH v5 1/8] capsule: board: Add information needed for capsule updates
On Sat, 2 Apr 2022 at 14:34, Heinrich Schuchardt wrote: > > On 4/1/22 21:17, Sughosh Ganu wrote: > > Add a structure which defines the information that is needed for > > executing capsule updates on a platform. Some information in the > > structure is used for making the update process more robust while some > > information is used for fixing some issues. Initialise this structure > > in the board file, and use the information for the capsule updates. > > > > Signed-off-by: Sughosh Ganu > > --- > > > > Changes since V1: > > > > * Define a structure efi_capsule_update_info which includes the string > >for populating dfu_alt_info > > * Initialise the string for dfu_alt_info in the board file > > > > > > .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 25 + > > .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 24 + > > board/emulation/qemu-arm/qemu-arm.c | 24 + > > board/kontron/pitx_imx8m/pitx_imx8m.c | 21 ++- > > board/kontron/sl-mx8mm/sl-mx8mm.c | 20 +++ > > board/kontron/sl28/sl28.c | 21 +++ > > board/sandbox/sandbox.c | 34 ++ > > board/socionext/developerbox/developerbox.c | 33 + > > board/xilinx/common/board.c | 28 +++ > > include/configs/imx8mm-cl-iot-gate.h | 10 ++ > > include/configs/imx8mp_rsb3720.h | 10 ++ > > include/configs/kontron-sl-mx8mm.h| 6 > > include/configs/kontron_pitx_imx8m.h | 6 > > include/configs/kontron_sl28.h| 6 > > include/configs/qemu-arm.h| 10 ++ > > include/configs/sandbox.h | 14 > > include/configs/synquacer.h | 14 > > include/configs/xilinx_versal.h | 6 > > include/configs/xilinx_zynqmp.h | 10 ++ > > include/configs/zynq-common.h | 10 ++ > > include/efi_loader.h | 36 +++ > > 21 files changed, 367 insertions(+), 1 deletion(-) > > > > diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > index 16566092bd..aa9cfa8339 100644 > > --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > @@ -6,6 +6,8 @@ > > > > #include > > #include > > +#include > > +#include > > #include > > #include > > #include > > @@ -21,6 +23,7 @@ > > #include > > #include > > #include > > +#include > > #include > > > > DECLARE_GLOBAL_DATA_PTR; > > @@ -44,6 +47,28 @@ static void setup_gpmi_nand(void) > > } > > #endif > > > > +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) > > +struct efi_fw_images fw_images[] = { > > + { > > +#if defined(CONFIG_TARGET_IMX8MP_RSB3720A1_4G) > > + .image_type_id = IMX8MP_RSB3720A1_4G_FIT_IMAGE_GUID, > > +#elif defined(CONFIG_TARGET_IMX8MP_RSB3720A1_6G) > > + .image_type_id = IMX8MP_RSB3720A1_6G_FIT_IMAGE_GUID, > > I am missing a handler for all other cases here, e.g. > > #else > #error Capsule update: firmware image GUID not defined > > But why don't you do this like on the sandbox? Just create one entry per > known config item. I created a separate entry per config since the number of images were different per config. But I can create separate entries per config. Will do so. > > Then the image array will simply be empty for all other boards. > > > +#endif > > + .fw_name = u"IMX8MP-RSB3720-FIT", > > + .image_index = 1, > > + }, > > +}; > > + > > +struct efi_capsule_update_info update_info = { > > + .dfu_string = "mmc 2=flash-bin raw 0 0x1B00 mmcpart 1", > > + .images = fw_images, > > +}; > > + > > +u8 num_image_type_guids = ARRAY_SIZE(fw_images); > > +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ > > + > > + > > int board_early_init_f(void) > > { > > struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; > > diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c > > b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c > > index 7e2d88f449..f2f5eb10f1 100644 > > --- a/board/compulab/imx8mm-cl-iot
[PATCH v5 6/8] FMP: Remove GUIDs for FIT and raw images
The capsule update code has been modified for getting the image GUID values from the platform code. With this, each image now has a unique GUID value. With this change, there is no longer a need for defining GUIDs for FIT and raw images. Remove these GUID values. Signed-off-by: Sughosh Ganu Reviewed-by: Ilias Apalodimas --- Changes since V4: None include/efi_api.h | 8 lib/efi_loader/efi_firmware.c | 4 2 files changed, 12 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 982c200172..c7f7873b5d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1967,14 +1967,6 @@ struct efi_signature_list { EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ 0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE0x0001 #define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 #define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED0x0004 diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index cbfa57f64f..38a0e43b6a 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -206,8 +206,6 @@ static efi_status_t efi_fill_image_desc_array( * - versioning of firmware image * - package information */ -const efi_guid_t efi_firmware_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; /** * efi_firmware_fit_get_image_info - return information about the current @@ -314,8 +312,6 @@ const struct efi_firmware_management_protocol efi_fmp_fit = { * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update * method with raw data. */ -const efi_guid_t efi_firmware_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; /** * efi_firmware_raw_get_image_info - return information about the current -- 2.25.1
[PATCH v5 8/8] doc: uefi: Update the capsule update related documentation
Update the capsule update functionality related documentation to refect the additional definitions that need to be made per platform for supporting the capsule update feature. Signed-off-by: Sughosh Ganu --- Changes since V4: * Change the description of the platform data based on the changes made in earlier patches doc/develop/uefi/uefi.rst | 51 +-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index fe337c88bd..b766aecf67 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -312,8 +312,8 @@ Run the following command .. code-block:: console $ mkeficapsule \ - --index 1 --instance 0 \ - [--fit | --raw ] \ + --index --instance 0 \ + --guid \ Performing the update @@ -333,6 +333,53 @@ won't be taken over across the reboot. If this is the case, you can skip this feature check with the Kconfig option (CONFIG_EFI_IGNORE_OSINDICATIONS) set. +A few values need to be defined in the board file for performing the +capsule update. These values are defined in the board file by +initialisation of a structure which provides information needed for +capsule updates. The following structures have been defined for +containing the image related information + +.. code-block:: c + + struct efi_fw_images { + efi_guid_t image_type_id; + u16 *fw_name; + u8 image_index; + }; + + struct efi_capsule_update_info { + const char *dfu_string; + struct efi_fw_images *images; + }; + + +A string is defined which is to be used for populating the +dfu_alt_info variable. This string is used by the function +set_dfu_alt_info. Instead of taking the variable from the environment, +the capsule update feature requires that the variable be set through +the function, since that is more robust. Allowing the user to change +the location of the firmware updates is not a very secure +practice. Getting this information from the firmware itself is more +secure, assuming the firmware has been verified by a previous stage +boot loader. + +The firmware images structure defines the GUID values, image index +values and the name of the images that are to be updated through +the capsule update feature. These values are to be defined as part of +an array. These GUID values would be used by the Firmware Management +Protocol(FMP) to populate the image descriptor array and also +displayed as part of the ESRT table. The image index values defined in +the array should be one greater than the dfu alt number that +corresponds to the firmware image. So, if the dfu alt number for an +image is 2, the value of image index in the fw_images array for that +image should be 3. The dfu alt number can be obtained by running the +following command:: + +dfu list + +When using the FMP for FIT images, the image index value needs to be +set to 1. + Finally, the capsule update can be initiated by rebooting the board. Enabling Capsule Authentication -- 2.25.1
[PATCH v5 7/8] mkeficapsule: Remove raw and FIT GUID types
While building a capsule, the GUID value of that specific image is to be passed through the --guid command option to the mkeficapsule tool. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the --raw and --fit command line options as well. Signed-off-by: Sughosh Ganu Acked-by: Ilias Apalodimas --- Changes since V4: None tools/eficapsule.h | 8 tools/mkeficapsule.c | 26 +- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 69c9c58c2f..d63b831443 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -37,14 +37,6 @@ typedef struct { EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define EFI_CERT_TYPE_PKCS7_GUID \ EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index c118335b93..5f74d23b9e 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -27,17 +27,11 @@ static const char *tool_name = "mkeficapsule"; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; -efi_guid_t efi_guid_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; -efi_guid_t efi_guid_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; +static const char *opts_short = "g:i:I:v:p:c:m:dh"; static struct option options[] = { - {"fit", no_argument, NULL, 'f'}, - {"raw", no_argument, NULL, 'r'}, {"guid", required_argument, NULL, 'g'}, {"index", required_argument, NULL, 'i'}, {"instance", required_argument, NULL, 'I'}, @@ -54,8 +48,6 @@ static void print_usage(void) fprintf(stderr, "Usage: %s [options] \n" "Options:\n" - "\t-f, --fit FIT image type\n" - "\t-r, --raw raw image type\n" "\t-g, --guid guid for image blob type\n" "\t-i, --index update image index\n" "\t-I, --instanceupdate hardware instance\n" @@ -606,22 +598,6 @@ int main(int argc, char **argv) break; switch (c) { - case 'f': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_fit; - break; - case 'r': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_raw; - break; case 'g': if (guid) { fprintf(stderr, -- 2.25.1
[PATCH v5 5/8] test: capsule: Modify the capsule tests to use GUID values for sandbox
The current UEFI capsule updation code uses two GUID values, one for FIT images, and one for raw images across platforms. This logic is being changed to have GUID values per image, per platform. Change the tests for the capsule update code to reflect this change. The GUID values now used are the ones specific to the sandbox platform -- one for the u-boot image, and another for the u-boot environment image. The UEFI specification does not allow installation of multiple Firmware Management Protocols(FMP) at the same time. Install the FMP instance for raw images on the sandbox variant for testing the capsule update code. Install the FMP instance for the FIT images on the sandbox64 and sandbox_flattree variant for testing capsule update for FIT images. This is being done by splitting the capsule update script for FIT and raw images. Signed-off-by: Sughosh Ganu --- Changes since V4: None configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + test/py/tests/test_efi_capsule/conftest.py| 21 +- .../test_capsule_firmware_fit.py | 186 ++ ...rmware.py => test_capsule_firmware_raw.py} | 159 +-- 6 files changed, 258 insertions(+), 115 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py rename test/py/tests/test_efi_capsule/{test_capsule_firmware.py => test_capsule_firmware_raw.py} (75%) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 7c157a23d0..1a0142795a 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -247,7 +247,6 @@ CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y -CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index ab0e2defee..de2526df09 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -318,7 +318,6 @@ CONFIG_LZ4=y CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 217b0647bb..bbcf435ac6 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -29,6 +29,7 @@ CONFIG_CMD_BOOTEFI_HELLO=y CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_ERASEENV=y +CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_NVEDIT_INFO=y CONFIG_CMD_NVEDIT_LOAD=y CONFIG_CMD_NVEDIT_SELECT=y @@ -210,3 +211,7 @@ CONFIG_HEXDUMP=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y +CONFIG_DFU_SF=y diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 9076087a12..d757415c88 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -72,7 +72,7 @@ def efi_capsule_data(request, u_boot_config): # Create capsule files # two regions: one for u-boot.bin and the other for u-boot.env -check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, +check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, shell=True) check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' % (u_boot_config.source_dir, data_dir), @@ -80,21 +80,29 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --fit uboot_bin_env.itb Test01' % +check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test01' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --raw u-boot.bin.new Test02' % +check_call('cd %s; %s/tools/mkeficapsule --index 2 --guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test02' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --i
[PATCH v5 3/8] capsule: Put a check for image index before the update
The current capsule update code compares the image GUID value in the capsule header with the image GUID value obtained from the GetImageInfo function of the Firmware Management Protocol(FMP). This comparison is done to ascertain if the FMP's SetImage function can be called for the update. Make this checking more robust by comparing the image_index value passed through the capsule with that returned by the FMP's GetImageInfo function. This protects against the scenario of the firmware being updated in a wrong partition/location on the storage device if an incorrect value has been passed through the capsule, since the image_index is used to determine the location of the update on the storage device. Signed-off-by: Sughosh Ganu Reviewed-by: Masami Hiramatsu Reviewed-by: Ilias Apalodimas --- Changes since V4: None lib/efi_loader/efi_capsule.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index f00440163d..f03f4c9044 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -128,6 +128,7 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, /** * efi_fmp_find - search for Firmware Management Protocol drivers * @image_type:Image type guid + * @image_index: Image Index * @instance: Instance number * @handles: Handles of FMP drivers * @no_handles:Number of handles @@ -141,8 +142,8 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, * * NULL - on failure */ static struct efi_firmware_management_protocol * -efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, -efi_uintn_t no_handles) +efi_fmp_find(efi_guid_t *image_type, u8 image_index, u64 instance, +efi_handle_t *handles, efi_uintn_t no_handles) { efi_handle_t *handle; struct efi_firmware_management_protocol *fmp; @@ -203,6 +204,7 @@ efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, log_debug("+++ desc[%d] index: %d, name: %ls\n", j, desc->image_index, desc->image_id_name); if (!guidcmp(>image_type_id, image_type) && + (desc->image_index == image_index) && (!instance || !desc->hardware_instance || desc->hardware_instance == instance)) @@ -449,8 +451,8 @@ static efi_status_t efi_capsule_update_firmware( } /* find a device for update firmware */ - /* TODO: should we pass index as well, or nothing but type? */ fmp = efi_fmp_find(>update_image_type_id, + image->update_image_index, image->update_hardware_instance, handles, no_handles); if (!fmp) { -- 2.25.1
[PATCH v5 4/8] efi: Define set_dfu_alt_info() for boards with UEFI capsule update enabled
Currently, there are a bunch of boards which enable the UEFI capsule update feature. The actual update of the firmware images is done through the dfu framework which uses the dfu_alt_info environment variable for getting information on the update, like device, partition number/address etc. The dfu framework allows the variable to be set through the set_dfu_alt_info function defined by the platform, or if the function is not defined, it gets the variable from the environment. Using the value set in the environment is not very robust, since the variable can be modified from the u-boot command line and this can cause an incorrect update. To prevent this from happening, define the set_dfu_alt_info function when the capsule update feature is enabled. A weak function is defined which sets the dfu_alt_info environment variable by getting the string for the variable from the platform. Signed-off-by: Sughosh Ganu --- Changes since V4: * Define a weak function set_dfu_alt_info for setting the variable in a non board specific file as suggested by Ilias * Drop the definitions of set_dfu_alt_info that were being added in the board files lib/efi_loader/Kconfig| 2 ++ lib/efi_loader/efi_firmware.c | 23 +++ 2 files changed, 25 insertions(+) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index e5e35fe51f..09fb8cbe75 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -174,6 +174,7 @@ config EFI_CAPSULE_FIRMWARE_FIT depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT select UPDATE_FIT select DFU + select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol @@ -185,6 +186,7 @@ config EFI_CAPSULE_FIRMWARE_RAW depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT) select DFU_WRITE_ALT select DFU + select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index e9fc4b9c1e..cbfa57f64f 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -11,9 +11,11 @@ #include #include #include +#include #include #include +#include #define FMP_PAYLOAD_HDR_SIGNATURE SIGNATURE_32('M', 'S', 'S', '1') @@ -35,6 +37,27 @@ struct fmp_payload_header { u32 lowest_supported_version; }; +#define DFU_ALT_BUF_LENSZ_1K + +__weak void set_dfu_alt_info(char *interface, char *devstr) +{ + int n; + const char *dfu_alt_info; + ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); + + if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && + env_get("dfu_alt_info")) + return; + + dfu_alt_info = update_info.dfu_string; + n = strlen(dfu_alt_info); + memset(buf, 0, n + 1); + + strncpy(buf, dfu_alt_info, n); + + env_set("dfu_alt_info", buf); +} + /* Place holder; not supported */ static efi_status_t EFIAPI efi_firmware_get_image_unsupported( -- 2.25.1
[PATCH v5 2/8] capsule: FMP: Populate the image descriptor array from platform data
Currently, the image descriptor array that has been passed to the GetImageInfo function of the Firmware Management Protocol(FMP) gets populated through the data stored with the dfu framework. The dfu data is not restricted to contain information only of the images updatable through the capsule update mechanism, but it also contains information on other images. The image descriptor array is also parsed by the ESRT generation code, and thus the ESRT table contains entries for other images that are not being handled by the FMP for the capsule updates. Fix this by populating the image descriptor array from the structure initialised in the board file. The other issue fixed is assignment of a separate GUID for all images in the image descriptor array. The UEFI specification mandates that all entries in the ESRT table should have a unique GUID value as part of the FwClass member of the EFI_SYSTEM_RESOURCE_ENTRY. Currently, all images are assigned a single GUID value, either an FIT GUID or a raw image GUID. This is fixed by obtaining the GUID values from the efi_fw_images array defined per platform. Signed-off-by: Sughosh Ganu --- Changes since V4: * Drop the image_count variable as was suggested by Ilias * Drop another unused variable names_len lib/efi_loader/efi_firmware.c | 95 +++ 1 file changed, 28 insertions(+), 67 deletions(-) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a5ff32f121..e9fc4b9c1e 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -97,91 +97,58 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( } /** - * efi_get_dfu_info - return information about the current firmware image + * efi_fill_image_desc_array - populate image descriptor array * @this: Protocol instance * @image_info_size: Size of @image_info * @image_info:Image information * @descriptor_version:Pointer to version number - * @descriptor_count: Pointer to number of descriptors + * @descriptor_count: Image count * @descriptor_size: Pointer to descriptor size - * package_version:Package version - * package_version_name: Package version's name - * image_type: Image type GUID + * @package_version: Package version + * @package_version_name: Package version's name * * Return information bout the current firmware image in @image_info. * @image_info will consist of a number of descriptors. - * Each descriptor will be created based on "dfu_alt_info" variable. + * Each descriptor will be created based on "efi_fw_images" variable. * * Return status code */ -static efi_status_t efi_get_dfu_info( +static efi_status_t efi_fill_image_desc_array( efi_uintn_t *image_info_size, struct efi_firmware_image_descriptor *image_info, u32 *descriptor_version, u8 *descriptor_count, efi_uintn_t *descriptor_size, u32 *package_version, - u16 **package_version_name, - const efi_guid_t *image_type) + u16 **package_version_name) { - struct dfu_entity *dfu; - size_t names_len, total_size; - int dfu_num, i; - u16 *name, *next; - int ret; - - ret = dfu_init_env_entities(NULL, NULL); - if (ret) - return EFI_SUCCESS; - - names_len = 0; - dfu_num = 0; - list_for_each_entry(dfu, _list, list) { - names_len += (utf8_utf16_strlen(dfu->name) + 1) * 2; - dfu_num++; - } - if (!dfu_num) { - log_warning("No entities in dfu_alt_info\n"); - *image_info_size = 0; - dfu_free_entities(); + size_t total_size; + struct efi_fw_images *fw_array; + int i; - return EFI_SUCCESS; - } + fw_array = update_info.images; + *descriptor_count = num_image_type_guids; + + total_size = sizeof(*image_info) * num_image_type_guids; - total_size = sizeof(*image_info) * dfu_num + names_len; - /* -* we will assume that sizeof(*image_info) * dfu_name -* is, at least, a multiple of 2. So the start address for -* image_id_name would be aligned with 2 bytes. -*/ if (*image_info_size < total_size) { *image_info_size = total_size; - dfu_free_entities(); return EFI_BUFFER_TOO_SMALL; } *image_info_size = total_size; *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; - *descriptor_count = dfu_num; *descriptor_size = sizeof(*image_info); *package_version = 0x; /* not supported */ *package_version_name = NULL; /* not supported */ - /* DFU alt number should correspond to image_index */ - i = 0; - /* Nam
[PATCH v5 1/8] capsule: board: Add information needed for capsule updates
Add a structure which defines the information that is needed for executing capsule updates on a platform. Some information in the structure is used for making the update process more robust while some information is used for fixing some issues. Initialise this structure in the board file, and use the information for the capsule updates. Signed-off-by: Sughosh Ganu --- Changes since V1: * Define a structure efi_capsule_update_info which includes the string for populating dfu_alt_info * Initialise the string for dfu_alt_info in the board file .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 25 + .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 24 + board/emulation/qemu-arm/qemu-arm.c | 24 + board/kontron/pitx_imx8m/pitx_imx8m.c | 21 ++- board/kontron/sl-mx8mm/sl-mx8mm.c | 20 +++ board/kontron/sl28/sl28.c | 21 +++ board/sandbox/sandbox.c | 34 ++ board/socionext/developerbox/developerbox.c | 33 + board/xilinx/common/board.c | 28 +++ include/configs/imx8mm-cl-iot-gate.h | 10 ++ include/configs/imx8mp_rsb3720.h | 10 ++ include/configs/kontron-sl-mx8mm.h| 6 include/configs/kontron_pitx_imx8m.h | 6 include/configs/kontron_sl28.h| 6 include/configs/qemu-arm.h| 10 ++ include/configs/sandbox.h | 14 include/configs/synquacer.h | 14 include/configs/xilinx_versal.h | 6 include/configs/xilinx_zynqmp.h | 10 ++ include/configs/zynq-common.h | 10 ++ include/efi_loader.h | 36 +++ 21 files changed, 367 insertions(+), 1 deletion(-) diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c index 16566092bd..aa9cfa8339 100644 --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -44,6 +47,28 @@ static void setup_gpmi_nand(void) } #endif +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { + { +#if defined(CONFIG_TARGET_IMX8MP_RSB3720A1_4G) + .image_type_id = IMX8MP_RSB3720A1_4G_FIT_IMAGE_GUID, +#elif defined(CONFIG_TARGET_IMX8MP_RSB3720A1_6G) + .image_type_id = IMX8MP_RSB3720A1_6G_FIT_IMAGE_GUID, +#endif + .fw_name = u"IMX8MP-RSB3720-FIT", + .image_index = 1, + }, +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 2=flash-bin raw 0 0x1B00 mmcpart 1", + .images = fw_images, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + + int board_early_init_f(void) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c index 7e2d88f449..f2f5eb10f1 100644 --- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c +++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include #include @@ -21,11 +23,33 @@ #include #include #include +#include #include "ddr/ddr.h" DECLARE_GLOBAL_DATA_PTR; +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { + { +#if defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) + .image_type_id = IMX8MM_CL_IOT_GATE_FIT_IMAGE_GUID, +#elif defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) + .image_type_id = IMX8MM_CL_IOT_GATE_OPTEE_FIT_IMAGE_GUID, +#endif + .fw_name = u"IMX8MM-CL-IOT-GATE-FIT", + .image_index = 1, + }, +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 2=flash-bin raw 0x42 0x1D00 mmcpart 1", + .images = fw_images, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + int board_phys_sdram_size(phys_size_t *size) { struct lpddr4_tcm_desc *lpddr4_tcm_desc = diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c index 16d5a97167..f36709ea27 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -6,15 +6,39 @@ #include #include #include +#include +#include #include #include #include #include #include +#include + #ifdef CONFIG_ARM64 #include +#if CONFIG_IS_ENABLED(EFI_HAV
[PATCH v5 0/8] efi: capsule: Capsule Update fixes and enhancements
for dfu_alt_info in the board file * Drop the image_count variable as was suggested by Ilias * Drop another unused variable names_len * Define a weak function set_dfu_alt_info for setting the variable in a non board specific file as suggested by Ilias * Drop the definitions of set_dfu_alt_info that were being added in the board files * Change the description of the platform data based on the changes made in earlier patches Changes since V3: - * Do not remove the existing dfu_alt_info definitions made by platforms in the config files, as discussed with Masami. * Squash the selection of the SET_DFU_ALT_INFO config symbol for capsule update feature as part of this patch. * Rephrase the commit message to indicate that the doc changes are not just limited to adding the GUID values, but other info as well. * Elaborate with an example on the relation between the dfu alt number and the image index Changes since V2: - * Add a new member image_index to the struct efi_fw_images to allow the platforms to define the values for images. * Address review comments from Michal Simek for the xilinx boards. * Fix double inclusion of efi_loader.h as was pointed out by Heiko Thiery. * Use the image index values defined in the platform's fw_images array for the image descriptors * Add a description for adding image index value and definition of set_dfu_alt_info function for the capsule updates. Changes since V1: - * Make changes for the xilinx boards as suggested by Michal Simek. * Add a GUID for the sandbox FIT image. * Split the capsule update test cases into two scripts, one for raw images and one for FIT images. * Add the capsule update test case for FIT images on sandbox64 and sandbox_flattree variants. * Add capsule update support on sandbox_flattree variant for enabling FIT capsule update testing as part of the python tests Sughosh Ganu (8): capsule: board: Add information needed for capsule updates capsule: FMP: Populate the image descriptor array from platform data capsule: Put a check for image index before the update efi: Define set_dfu_alt_info() for boards with UEFI capsule update enabled test: capsule: Modify the capsule tests to use GUID values for sandbox FMP: Remove GUIDs for FIT and raw images mkeficapsule: Remove raw and FIT GUID types doc: uefi: Update the capsule update related documentation .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 25 +++ .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 24 +++ board/emulation/qemu-arm/qemu-arm.c | 24 +++ board/kontron/pitx_imx8m/pitx_imx8m.c | 21 +- board/kontron/sl-mx8mm/sl-mx8mm.c | 20 ++ board/kontron/sl28/sl28.c | 21 ++ board/sandbox/sandbox.c | 34 board/socionext/developerbox/developerbox.c | 33 board/xilinx/common/board.c | 28 +++ configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + doc/develop/uefi/uefi.rst | 51 - include/configs/imx8mm-cl-iot-gate.h | 10 + include/configs/imx8mp_rsb3720.h | 10 + include/configs/kontron-sl-mx8mm.h| 6 + include/configs/kontron_pitx_imx8m.h | 6 + include/configs/kontron_sl28.h| 6 + include/configs/qemu-arm.h| 10 + include/configs/sandbox.h | 14 ++ include/configs/synquacer.h | 14 ++ include/configs/xilinx_versal.h | 6 + include/configs/xilinx_zynqmp.h | 10 + include/configs/zynq-common.h | 10 + include/efi_api.h | 8 - include/efi_loader.h | 36 lib/efi_loader/Kconfig| 2 + lib/efi_loader/efi_capsule.c | 8 +- lib/efi_loader/efi_firmware.c | 122 +--- test/py/tests/test_efi_capsule/conftest.py| 21 +- .../test_capsule_firmware_fit.py | 186 ++ ...rmware.py => test_capsule_firmware_raw.py} | 159 +-- tools/eficapsule.h| 8 - tools/mkeficapsule.c | 26 +-- 34 files changed, 733 insertions(+), 233 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py rename test/py/tests/test_efi_capsule/{test_capsule_firmware.py => test_capsule_firmware_raw.py} (75%) -- 2.25.1
Re: [PATCH v4 4/8] board: Define set_dfu_alt_info() for boards with UEFI capsule update enabled
hi Ilias, On Fri, 1 Apr 2022 at 01:05, Ilias Apalodimas wrote: > > Hi Sughosh, > > Some nots below > > On Thu, Mar 31, 2022 at 06:57:46PM +0530, Sughosh Ganu wrote: > > Currently, there are a bunch of boards which enable the UEFI capsule > > update feature. The actual update of the firmware images is done > > through the dfu framework which uses the dfu_alt_info environment > > variable for getting information on the update, like device, partition > > number/address etc. Currently, these boards define the dfu_alt_info > > variable in the board config header, as an environment variable. With > > this, the variable can be modified from the u-boot command line and > > this can cause an incorrect update. > > > > To prevent this from happening, define the set_dfu_alt_info function > > in the board file, and select SET_DFU_ALT_INFO for all platforms which > > enable the capsule update feature. With the function defined, the dfu > > framework populates the dfu_alt_info variable through the board file, > > instead of fetching the variable from the environment, thus making the > > update more robust. > > > > Signed-off-by: Sughosh Ganu > > --- > > > > Changes since V3: > > * Do not remove the existing dfu_alt_info definitions made by > > platforms in the config files, as discussed with Masami. > > * Squash the selection of the SET_DFU_ALT_INFO config symbol for > > capsule update feature as part of this patch. > > > > > > .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 24 + > > .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 24 + > > board/emulation/common/qemu_dfu.c | 6 ++--- > > board/kontron/pitx_imx8m/pitx_imx8m.c | 24 + > > board/kontron/sl-mx8mm/sl-mx8mm.c | 24 + > > board/kontron/sl28/sl28.c | 25 ++ > > board/sandbox/sandbox.c | 26 +++ > > board/socionext/developerbox/developerbox.c | 26 +++ > > board/xilinx/zynq/board.c | 5 ++-- > > board/xilinx/zynqmp/zynqmp.c | 5 ++-- > > lib/efi_loader/Kconfig| 2 ++ > > 11 files changed, 184 insertions(+), 7 deletions(-) > > > > diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > index 1c953ba195..41154ca9f3 100644 > > --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > @@ -5,10 +5,12 @@ > > */ > > > > #include > > +#include > > #include > > #include > > #include > > #include > > +#include > > #include > > #include > > #include > > @@ -24,6 +26,7 @@ > > #include > > #include > > #include > > +#include > > #include > > > > DECLARE_GLOBAL_DATA_PTR; > > @@ -231,3 +234,24 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc > > *mmc) > > } > > } > > #endif /* CONFIG_SPL_MMC_SUPPORT */ > > + > > +#if defined(CONFIG_SET_DFU_ALT_INFO) > > + > > +#define DFU_ALT_BUF_LEN SZ_1K > > + > > +void set_dfu_alt_info(char *interface, char *devstr) > > +{ > > + ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); > > + > > + if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && > > + env_get("dfu_alt_info")) > > + return; > > Just add a helper function with this since we need to repeat it for every > board. Something like 'bool needs_runtime_dfu_alt_info() ' Okay > > + > > + memset(buf, 0, DFU_ALT_BUF_LEN); > > I'd prefer sizeof(buf) instead of explicitly calling the length. So the current boards are using this wrong. The ALLOC_CACHE_ALIGN_BUFFER actually defines an array named __buf, and a char *buf which points to the array. So the existing code in some boards was zeroing out only the sizeof(char *) number of bytes. The sandbox clang build throws up this warning, which is how I found it. -sughosh > > Otherwise LGTM, but I'd prefer if board maintainer had a look as well > > Thanks > /Ilias > > > + > > + snprintf(buf, DFU_ALT_BUF_LEN, > > + "mmc 2=flash-bin raw 0 0x1B00 mmcpart 1"); > > + > > + env_set("dfu_alt_info", buf); > > +} > > +#endif /* CONFIG_SET_DFU_ALT_INFO */ > > [...]
Re: [PATCH v4 2/8] capsule: FMP: Populate the image descriptor array from platform data
hi Ilias, On Thu, 31 Mar 2022 at 20:38, Ilias Apalodimas wrote: > > Hi Sughosh, > > On Thu, Mar 31, 2022 at 06:57:44PM +0530, Sughosh Ganu wrote: > > Currently, the image descriptor array that has been passed to the > > GetImageInfo function of the Firmware Management Protocol(FMP) gets > > populated through the data stored with the dfu framework. The > > dfu data is not restricted to contain information only of the images > > updatable through the capsule update mechanism, but it also contains > > information on other images. > > > > The image descriptor array is also parsed by the ESRT generation code, > > and thus the ESRT table contains entries for other images that are not > > being handled by the FMP for the capsule updates. > > > > The other issue fixed is assignment of a separate GUID for all images > > in the image descriptor array. The UEFI specification mandates that > > all entries in the ESRT table should have a unique GUID value as part > > of the FwClass member of the EFI_SYSTEM_RESOURCE_ENTRY. Currently, all > > images are assigned a single GUID value, either an FIT GUID or a raw > > image GUID. This is fixed by obtaining the GUID values from the > > efi_fw_images array defined per platform. > > > > Signed-off-by: Sughosh Ganu > > Reviewed-by: Masami Hiramatsu > > --- > > > > Changes since V3: None > > > > include/efi_loader.h | 3 ++ > > lib/efi_loader/efi_firmware.c | 91 +++ > > 2 files changed, 30 insertions(+), 64 deletions(-) > > > > diff --git a/include/efi_loader.h b/include/efi_loader.h > > index 284d64547b..9704397bd7 100644 > > --- a/include/efi_loader.h > > +++ b/include/efi_loader.h > > @@ -997,6 +997,9 @@ struct efi_fw_images { > > u8 image_index; > > }; > > > > +extern struct efi_fw_images fw_images[]; > > +extern u8 num_image_type_guids; > > + > > /** > > * Install the ESRT system table. > > * > > diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c > > index a5ff32f121..169f3a29bb 100644 > > --- a/lib/efi_loader/efi_firmware.c > > +++ b/lib/efi_loader/efi_firmware.c > > @@ -97,91 +97,60 @@ efi_status_t EFIAPI > > efi_firmware_set_package_info_unsupported( > > } > > > > /** > > - * efi_get_dfu_info - return information about the current firmware image > > + * efi_fill_image_desc_array - populate image descriptor array > > * @this:Protocol instance > > * @image_info_size: Size of @image_info > > * @image_info: Image information > > * @descriptor_version: Pointer to version number > > - * @descriptor_count:Pointer to number of descriptors > > + * @descriptor_count:Image count > > * @descriptor_size: Pointer to descriptor size > > - * package_version: Package version > > - * package_version_name: Package version's name > > - * image_type: Image type GUID > > + * @package_version: Package version > > + * @package_version_name:Package version's name > > * > > * Return information bout the current firmware image in @image_info. > > * @image_info will consist of a number of descriptors. > > - * Each descriptor will be created based on "dfu_alt_info" variable. > > + * Each descriptor will be created based on "efi_fw_images" variable. > > * > > * Returnstatus code > > */ > > -static efi_status_t efi_get_dfu_info( > > +static efi_status_t efi_fill_image_desc_array( > > efi_uintn_t *image_info_size, > > struct efi_firmware_image_descriptor *image_info, > > u32 *descriptor_version, > > u8 *descriptor_count, > > efi_uintn_t *descriptor_size, > > u32 *package_version, > > - u16 **package_version_name, > > - const efi_guid_t *image_type) > > + u16 **package_version_name) > > { > > - struct dfu_entity *dfu; > > size_t names_len, total_size; > > - int dfu_num, i; > > - u16 *name, *next; > > - int ret; > > - > > - ret = dfu_init_env_entities(NULL, NULL); > > - if (ret) > > - return EFI_SUCCESS; > > + struct efi_fw_images *fw_array; > > + u8 image_count; > > + int i; > > > > + fw_array = _images[0]; > > nit, but fw_array = fw_images looks better Okay. Will change. > > > + *de
[PATCH v4 8/8] doc: uefi: Update the capsule update related documentation
Update the capsule update functionality related documentation to refect the additional definitions that need to be made per platform for supporting the capsule update feature. Signed-off-by: Sughosh Ganu --- Changes since V3: * Rephrase the commit message to indicate that the doc changes are not just limited to adding the GUID values, but other info as well. * Elaborate with an example on the relation between the dfu alt number and the image index doc/develop/uefi/uefi.rst | 24 ++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index fe337c88bd..d886635cc3 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -312,8 +312,8 @@ Run the following command .. code-block:: console $ mkeficapsule \ - --index 1 --instance 0 \ - [--fit | --raw ] \ + --index --instance 0 \ + --guid \ Performing the update @@ -333,6 +333,26 @@ won't be taken over across the reboot. If this is the case, you can skip this feature check with the Kconfig option (CONFIG_EFI_IGNORE_OSINDICATIONS) set. +A few things need to be defined in the board file for performing the +capsule upadte. The first is defining the function set_dfu_alt_info in +the board file. This function sets the environment variable +dfu_alt_info. Instead of taking the variable from the environment, the +capsule update feature requires that the variable be set through the +board function, since that is more robust. Secondly, define GUID +values and image index of the images that are to be updated through +the capsule update feature in the board file. Both the values are to +be defined as part of the fw_images array. These GUID values would be +used by the Firmware Management Protocol(FMP) to populate the image +descriptor array and also displayed as part of the ESRT table. The +image index values defined in the array should be one greater than the +dfu alt number that corresponds to the firmware image. So, if the dfu +alt number for an image is 2, the value of image index in the +fw_images array for that image should be 3. The dfu alt number can be +obtained by running the following command:: + +dfu list + + Finally, the capsule update can be initiated by rebooting the board. Enabling Capsule Authentication -- 2.25.1
[PATCH v4 5/8] test: capsule: Modify the capsule tests to use GUID values for sandbox
The current UEFI capsule updation code uses two GUID values, one for FIT images, and one for raw images across platforms. This logic is being changed to have GUID values per image, per platform. Change the tests for the capsule update code to reflect this change. The GUID values now used are the ones specific to the sandbox platform -- one for the u-boot image, and another for the u-boot environment image. The UEFI specification does not allow installation of multiple Firmware Management Protocols(FMP) at the same time. Install the FMP instance for raw images on the sandbox variant for testing the capsule update code. Install the FMP instance for the FIT images on the sandbox64 and sandbox_flattree variant for testing capsule update for FIT images. This is being done by splitting the capsule update script for FIT and raw images. Signed-off-by: Sughosh Ganu --- Changes since V3: None configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + test/py/tests/test_efi_capsule/conftest.py| 21 +- .../test_capsule_firmware_fit.py | 186 ++ ...rmware.py => test_capsule_firmware_raw.py} | 159 +-- 6 files changed, 258 insertions(+), 115 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py rename test/py/tests/test_efi_capsule/{test_capsule_firmware.py => test_capsule_firmware_raw.py} (75%) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 7c157a23d0..1a0142795a 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -247,7 +247,6 @@ CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y -CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index ab0e2defee..de2526df09 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -318,7 +318,6 @@ CONFIG_LZ4=y CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 217b0647bb..bbcf435ac6 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -29,6 +29,7 @@ CONFIG_CMD_BOOTEFI_HELLO=y CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_ERASEENV=y +CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_NVEDIT_INFO=y CONFIG_CMD_NVEDIT_LOAD=y CONFIG_CMD_NVEDIT_SELECT=y @@ -210,3 +211,7 @@ CONFIG_HEXDUMP=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y +CONFIG_DFU_SF=y diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 9076087a12..d757415c88 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -72,7 +72,7 @@ def efi_capsule_data(request, u_boot_config): # Create capsule files # two regions: one for u-boot.bin and the other for u-boot.env -check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, +check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, shell=True) check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' % (u_boot_config.source_dir, data_dir), @@ -80,21 +80,29 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --fit uboot_bin_env.itb Test01' % +check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test01' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --raw u-boot.bin.new Test02' % +check_call('cd %s; %s/tools/mkeficapsule --index 2 --guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test02' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --i
[PATCH v4 7/8] mkeficapsule: Remove raw and FIT GUID types
While building a capsule, the GUID value of that specific image is to be passed through the --guid command option to the mkeficapsule tool. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the --raw and --fit command line options as well. Signed-off-by: Sughosh Ganu --- Changes since V3: None tools/eficapsule.h | 8 tools/mkeficapsule.c | 26 +- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 69c9c58c2f..d63b831443 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -37,14 +37,6 @@ typedef struct { EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define EFI_CERT_TYPE_PKCS7_GUID \ EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index c118335b93..5f74d23b9e 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -27,17 +27,11 @@ static const char *tool_name = "mkeficapsule"; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; -efi_guid_t efi_guid_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; -efi_guid_t efi_guid_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; +static const char *opts_short = "g:i:I:v:p:c:m:dh"; static struct option options[] = { - {"fit", no_argument, NULL, 'f'}, - {"raw", no_argument, NULL, 'r'}, {"guid", required_argument, NULL, 'g'}, {"index", required_argument, NULL, 'i'}, {"instance", required_argument, NULL, 'I'}, @@ -54,8 +48,6 @@ static void print_usage(void) fprintf(stderr, "Usage: %s [options] \n" "Options:\n" - "\t-f, --fit FIT image type\n" - "\t-r, --raw raw image type\n" "\t-g, --guid guid for image blob type\n" "\t-i, --index update image index\n" "\t-I, --instanceupdate hardware instance\n" @@ -606,22 +598,6 @@ int main(int argc, char **argv) break; switch (c) { - case 'f': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_fit; - break; - case 'r': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_raw; - break; case 'g': if (guid) { fprintf(stderr, -- 2.25.1
[PATCH v4 4/8] board: Define set_dfu_alt_info() for boards with UEFI capsule update enabled
Currently, there are a bunch of boards which enable the UEFI capsule update feature. The actual update of the firmware images is done through the dfu framework which uses the dfu_alt_info environment variable for getting information on the update, like device, partition number/address etc. Currently, these boards define the dfu_alt_info variable in the board config header, as an environment variable. With this, the variable can be modified from the u-boot command line and this can cause an incorrect update. To prevent this from happening, define the set_dfu_alt_info function in the board file, and select SET_DFU_ALT_INFO for all platforms which enable the capsule update feature. With the function defined, the dfu framework populates the dfu_alt_info variable through the board file, instead of fetching the variable from the environment, thus making the update more robust. Signed-off-by: Sughosh Ganu --- Changes since V3: * Do not remove the existing dfu_alt_info definitions made by platforms in the config files, as discussed with Masami. * Squash the selection of the SET_DFU_ALT_INFO config symbol for capsule update feature as part of this patch. .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 24 + .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 24 + board/emulation/common/qemu_dfu.c | 6 ++--- board/kontron/pitx_imx8m/pitx_imx8m.c | 24 + board/kontron/sl-mx8mm/sl-mx8mm.c | 24 + board/kontron/sl28/sl28.c | 25 ++ board/sandbox/sandbox.c | 26 +++ board/socionext/developerbox/developerbox.c | 26 +++ board/xilinx/zynq/board.c | 5 ++-- board/xilinx/zynqmp/zynqmp.c | 5 ++-- lib/efi_loader/Kconfig| 2 ++ 11 files changed, 184 insertions(+), 7 deletions(-) diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c index 1c953ba195..41154ca9f3 100644 --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c @@ -5,10 +5,12 @@ */ #include +#include #include #include #include #include +#include #include #include #include @@ -24,6 +26,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -231,3 +234,24 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc) } } #endif /* CONFIG_SPL_MMC_SUPPORT */ + +#if defined(CONFIG_SET_DFU_ALT_INFO) + +#define DFU_ALT_BUF_LENSZ_1K + +void set_dfu_alt_info(char *interface, char *devstr) +{ + ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); + + if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && + env_get("dfu_alt_info")) + return; + + memset(buf, 0, DFU_ALT_BUF_LEN); + + snprintf(buf, DFU_ALT_BUF_LEN, +"mmc 2=flash-bin raw 0 0x1B00 mmcpart 1"); + + env_set("dfu_alt_info", buf); +} +#endif /* CONFIG_SET_DFU_ALT_INFO */ diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c index f5b89a5ddc..1880dd9c55 100644 --- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c +++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include #include @@ -24,6 +26,7 @@ #include #include #include +#include #include "ddr/ddr.h" @@ -446,3 +449,24 @@ int board_late_init(void) return 0; } + +#if defined(CONFIG_SET_DFU_ALT_INFO) + +#define DFU_ALT_BUF_LENSZ_1K + +void set_dfu_alt_info(char *interface, char *devstr) +{ + ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); + + if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && + env_get("dfu_alt_info")) + return; + + memset(buf, 0, DFU_ALT_BUF_LEN); + + snprintf(buf, DFU_ALT_BUF_LEN, +"mmc 2=flash-bin raw 0x42 0x1D00 mmcpart 1"); + + env_set("dfu_alt_info", buf); +} +#endif /* CONFIG_SET_DFU_ALT_INFO */ diff --git a/board/emulation/common/qemu_dfu.c b/board/emulation/common/qemu_dfu.c index 62234a7647..85dff4373b 100644 --- a/board/emulation/common/qemu_dfu.c +++ b/board/emulation/common/qemu_dfu.c @@ -44,10 +44,11 @@ void set_dfu_alt_info(char *interface, char *devstr) ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); - if (env_get("dfu_alt_info")) + if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && + env_get("dfu_alt_info")) return; - memset(buf, 0, sizeof(buf)); + memset(buf, 0, D
[PATCH v4 6/8] FMP: Remove GUIDs for FIT and raw images
The capsule update code has been modified for getting the image GUID values from the platform code. With this, each image now has a unique GUID value. With this change, there is no longer a need for defining GUIDs for FIT and raw images. Remove these GUID values. Signed-off-by: Sughosh Ganu --- Changes since V3: None include/efi_api.h | 8 lib/efi_loader/efi_firmware.c | 4 2 files changed, 12 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 982c200172..c7f7873b5d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1967,14 +1967,6 @@ struct efi_signature_list { EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ 0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE0x0001 #define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 #define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED0x0004 diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 169f3a29bb..7734d9f353 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -185,8 +185,6 @@ static efi_status_t efi_fill_image_desc_array( * - versioning of firmware image * - package information */ -const efi_guid_t efi_firmware_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; /** * efi_firmware_fit_get_image_info - return information about the current @@ -293,8 +291,6 @@ const struct efi_firmware_management_protocol efi_fmp_fit = { * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update * method with raw data. */ -const efi_guid_t efi_firmware_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; /** * efi_firmware_raw_get_image_info - return information about the current -- 2.25.1
[PATCH v4 1/8] capsule: Add Image GUIDs and image index for platforms using capsule updates
Currently, all platforms that enable capsule updates do so using either EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID or EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID. This is based on the Firmware Management Protocol(FMP) instance used on the platform. However, this means that all platforms that enable a particular FMP instance have the same GUID value for all the updatable images, either the FIT image GUID or the raw image GUID, and that an image for some platform can be updated on any other platform which uses the same FMP instance. Another issue with this implementation is that the ESRT table shows the same GUID value for all images on the platform and also across platforms, which is not in compliance with the UEFI specification. Fix this by defining image GUID values and firmware names for individual images per platform. The GetImageInfo FMP hook would then populate these values in the image descriptor array. Also add the image index value associated with a particular image. This is the value that should match with the image_index value that is part of the capsule header. The capsule update code will check if the two values match, and the update will only proceed on a match. Signed-off-by: Sughosh Ganu Reviewed-by: Masami Hiramatsu Acked-by: Michal Simek --- Changes since V3: None .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 20 + .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 19 + board/emulation/qemu-arm/qemu-arm.c | 20 + board/kontron/pitx_imx8m/pitx_imx8m.c | 16 ++- board/kontron/sl-mx8mm/sl-mx8mm.c | 15 ++ board/kontron/sl28/sl28.c | 15 ++ board/sandbox/sandbox.c | 28 +++ board/socionext/developerbox/developerbox.c | 26 + board/xilinx/common/board.c | 24 include/configs/imx8mm-cl-iot-gate.h | 10 +++ include/configs/imx8mp_rsb3720.h | 10 +++ include/configs/kontron-sl-mx8mm.h| 6 include/configs/kontron_pitx_imx8m.h | 6 include/configs/kontron_sl28.h| 6 include/configs/qemu-arm.h| 10 +++ include/configs/sandbox.h | 14 ++ include/configs/synquacer.h | 14 ++ include/configs/xilinx_versal.h | 6 include/configs/xilinx_zynqmp.h | 10 +++ include/configs/zynq-common.h | 10 +++ include/efi_loader.h | 18 21 files changed, 302 insertions(+), 1 deletion(-) diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c index 16566092bd..1c953ba195 100644 --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -44,6 +47,23 @@ static void setup_gpmi_nand(void) } #endif +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { + { +#if defined(CONFIG_TARGET_IMX8MP_RSB3720A1_4G) + .image_type_id = IMX8MP_RSB3720A1_4G_FIT_IMAGE_GUID, +#elif defined(CONFIG_TARGET_IMX8MP_RSB3720A1_6G) + .image_type_id = IMX8MP_RSB3720A1_6G_FIT_IMAGE_GUID, +#endif + .fw_name = u"IMX8MP-RSB3720-FIT", + .image_index = 1 + }, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + + int board_early_init_f(void) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c index 7e2d88f449..f5b89a5ddc 100644 --- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c +++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include #include @@ -21,11 +23,28 @@ #include #include #include +#include #include "ddr/ddr.h" DECLARE_GLOBAL_DATA_PTR; +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { + { +#if defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) + .image_type_id = IMX8MM_CL_IOT_GATE_FIT_IMAGE_GUID, +#elif defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) + .image_type_id = IMX8MM_CL_IOT_GATE_OPTEE_FIT_IMAGE_GUID, +#endif + .fw_name = u"IMX8MM-CL-IOT-GATE-FIT", + .image_index = 1 + }, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + int board_phys_sdram_size(phys_size_t *size) { struct lpddr4_tcm_desc *lpddr4
[PATCH v4 2/8] capsule: FMP: Populate the image descriptor array from platform data
Currently, the image descriptor array that has been passed to the GetImageInfo function of the Firmware Management Protocol(FMP) gets populated through the data stored with the dfu framework. The dfu data is not restricted to contain information only of the images updatable through the capsule update mechanism, but it also contains information on other images. The image descriptor array is also parsed by the ESRT generation code, and thus the ESRT table contains entries for other images that are not being handled by the FMP for the capsule updates. The other issue fixed is assignment of a separate GUID for all images in the image descriptor array. The UEFI specification mandates that all entries in the ESRT table should have a unique GUID value as part of the FwClass member of the EFI_SYSTEM_RESOURCE_ENTRY. Currently, all images are assigned a single GUID value, either an FIT GUID or a raw image GUID. This is fixed by obtaining the GUID values from the efi_fw_images array defined per platform. Signed-off-by: Sughosh Ganu Reviewed-by: Masami Hiramatsu --- Changes since V3: None include/efi_loader.h | 3 ++ lib/efi_loader/efi_firmware.c | 91 +++ 2 files changed, 30 insertions(+), 64 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 284d64547b..9704397bd7 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -997,6 +997,9 @@ struct efi_fw_images { u8 image_index; }; +extern struct efi_fw_images fw_images[]; +extern u8 num_image_type_guids; + /** * Install the ESRT system table. * diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a5ff32f121..169f3a29bb 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -97,91 +97,60 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( } /** - * efi_get_dfu_info - return information about the current firmware image + * efi_fill_image_desc_array - populate image descriptor array * @this: Protocol instance * @image_info_size: Size of @image_info * @image_info:Image information * @descriptor_version:Pointer to version number - * @descriptor_count: Pointer to number of descriptors + * @descriptor_count: Image count * @descriptor_size: Pointer to descriptor size - * package_version:Package version - * package_version_name: Package version's name - * image_type: Image type GUID + * @package_version: Package version + * @package_version_name: Package version's name * * Return information bout the current firmware image in @image_info. * @image_info will consist of a number of descriptors. - * Each descriptor will be created based on "dfu_alt_info" variable. + * Each descriptor will be created based on "efi_fw_images" variable. * * Return status code */ -static efi_status_t efi_get_dfu_info( +static efi_status_t efi_fill_image_desc_array( efi_uintn_t *image_info_size, struct efi_firmware_image_descriptor *image_info, u32 *descriptor_version, u8 *descriptor_count, efi_uintn_t *descriptor_size, u32 *package_version, - u16 **package_version_name, - const efi_guid_t *image_type) + u16 **package_version_name) { - struct dfu_entity *dfu; size_t names_len, total_size; - int dfu_num, i; - u16 *name, *next; - int ret; - - ret = dfu_init_env_entities(NULL, NULL); - if (ret) - return EFI_SUCCESS; + struct efi_fw_images *fw_array; + u8 image_count; + int i; + fw_array = _images[0]; + *descriptor_count = image_count = num_image_type_guids; names_len = 0; - dfu_num = 0; - list_for_each_entry(dfu, _list, list) { - names_len += (utf8_utf16_strlen(dfu->name) + 1) * 2; - dfu_num++; - } - if (!dfu_num) { - log_warning("No entities in dfu_alt_info\n"); - *image_info_size = 0; - dfu_free_entities(); - return EFI_SUCCESS; - } + total_size = sizeof(*image_info) * image_count; - total_size = sizeof(*image_info) * dfu_num + names_len; - /* -* we will assume that sizeof(*image_info) * dfu_name -* is, at least, a multiple of 2. So the start address for -* image_id_name would be aligned with 2 bytes. -*/ if (*image_info_size < total_size) { *image_info_size = total_size; - dfu_free_entities(); return EFI_BUFFER_TOO_SMALL; } *image_info_size = total_size; *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; - *descriptor_count = dfu_num; *descriptor_size = sizeof(*image_info);
[PATCH v4 3/8] capsule: Put a check for image index before the update
The current capsule update code compares the image GUID value in the capsule header with the image GUID value obtained from the GetImageInfo function of the Firmware Management Protocol(FMP). This comparison is done to ascertain if the FMP's SetImage function can be called for the update. Make this checking more robust by comparing the image_index value passed through the capsule with that returned by the FMP's GetImageInfo function. This protects against the scenario of the firmware being updated in a wrong partition/location on the storage device if an incorrect value has been passed through the capsule, since the image_index is used to determine the location of the update on the storage device. Signed-off-by: Sughosh Ganu Reviewed-by: Masami Hiramatsu --- Changes since V3: None lib/efi_loader/efi_capsule.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index f00440163d..f03f4c9044 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -128,6 +128,7 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, /** * efi_fmp_find - search for Firmware Management Protocol drivers * @image_type:Image type guid + * @image_index: Image Index * @instance: Instance number * @handles: Handles of FMP drivers * @no_handles:Number of handles @@ -141,8 +142,8 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, * * NULL - on failure */ static struct efi_firmware_management_protocol * -efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, -efi_uintn_t no_handles) +efi_fmp_find(efi_guid_t *image_type, u8 image_index, u64 instance, +efi_handle_t *handles, efi_uintn_t no_handles) { efi_handle_t *handle; struct efi_firmware_management_protocol *fmp; @@ -203,6 +204,7 @@ efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, log_debug("+++ desc[%d] index: %d, name: %ls\n", j, desc->image_index, desc->image_id_name); if (!guidcmp(>image_type_id, image_type) && + (desc->image_index == image_index) && (!instance || !desc->hardware_instance || desc->hardware_instance == instance)) @@ -449,8 +451,8 @@ static efi_status_t efi_capsule_update_firmware( } /* find a device for update firmware */ - /* TODO: should we pass index as well, or nothing but type? */ fmp = efi_fmp_find(>update_image_type_id, + image->update_image_index, image->update_hardware_instance, handles, no_handles); if (!fmp) { -- 2.25.1
[PATCH v4 0/8] efi: capsule: Capsule Update fixes and enhancements
with Masami. * Squash the selection of the SET_DFU_ALT_INFO config symbol for capsule update feature as part of this patch. * Rephrase the commit message to indicate that the doc changes are not just limited to adding the GUID values, but other info as well. * Elaborate with an example on the relation between the dfu alt number and the image index Changes since V2: - * Add a new member image_index to the struct efi_fw_images to allow the platforms to define the values for images. * Address review comments from Michal Simek for the xilinx boards. * Fix double inclusion of efi_loader.h as was pointed out by Heiko Thiery. * Use the image index values defined in the platform's fw_images array for the image descriptors * Add a description for adding image index value and definition of set_dfu_alt_info function for the capsule updates. Changes since V1: - * Make changes for the xilinx boards as suggested by Michal Simek. * Add a GUID for the sandbox FIT image. * Split the capsule update test cases into two scripts, one for raw images and one for FIT images. * Add the capsule update test case for FIT images on sandbox64 and sandbox_flattree variants. * Add capsule update support on sandbox_flattree variant for enabling FIT capsule update testing as part of the python tests Sughosh Ganu (8): capsule: Add Image GUIDs and image index for platforms using capsule updates capsule: FMP: Populate the image descriptor array from platform data capsule: Put a check for image index before the update board: Define set_dfu_alt_info() for boards with UEFI capsule update enabled test: capsule: Modify the capsule tests to use GUID values for sandbox FMP: Remove GUIDs for FIT and raw images mkeficapsule: Remove raw and FIT GUID types doc: uefi: Update the capsule update related documentation .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 44 + .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 43 board/emulation/common/qemu_dfu.c | 6 +- board/emulation/qemu-arm/qemu-arm.c | 20 ++ board/kontron/pitx_imx8m/pitx_imx8m.c | 40 +++- board/kontron/sl-mx8mm/sl-mx8mm.c | 39 board/kontron/sl28/sl28.c | 40 board/sandbox/sandbox.c | 54 + board/socionext/developerbox/developerbox.c | 52 + board/xilinx/common/board.c | 24 +++ board/xilinx/zynq/board.c | 5 +- board/xilinx/zynqmp/zynqmp.c | 5 +- configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + doc/develop/uefi/uefi.rst | 24 ++- include/configs/imx8mm-cl-iot-gate.h | 10 + include/configs/imx8mp_rsb3720.h | 10 + include/configs/kontron-sl-mx8mm.h| 6 + include/configs/kontron_pitx_imx8m.h | 6 + include/configs/kontron_sl28.h| 6 + include/configs/qemu-arm.h| 10 + include/configs/sandbox.h | 14 ++ include/configs/synquacer.h | 14 ++ include/configs/xilinx_versal.h | 6 + include/configs/xilinx_zynqmp.h | 10 + include/configs/zynq-common.h | 10 + include/efi_api.h | 8 - include/efi_loader.h | 21 ++ lib/efi_loader/Kconfig| 2 + lib/efi_loader/efi_capsule.c | 8 +- lib/efi_loader/efi_firmware.c | 95 +++-- test/py/tests/test_efi_capsule/conftest.py| 21 +- .../test_capsule_firmware_fit.py | 186 ++ ...rmware.py => test_capsule_firmware_raw.py} | 159 +-- tools/eficapsule.h| 8 - tools/mkeficapsule.c | 26 +-- 37 files changed, 802 insertions(+), 237 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py rename test/py/tests/test_efi_capsule/{test_capsule_firmware.py => test_capsule_firmware_raw.py} (75%) -- 2.25.1
Re: [PATCH v3 5/9] capsule: kconfig: Select SET_DFU_ALT_INFO config symbol for capsule update
hi Masami, On Thu, 31 Mar 2022 at 13:11, Sughosh Ganu wrote: > > hi Masami, > > On Thu, 31 Mar 2022 at 08:18, Masami Hiramatsu > wrote: > > > > Hi, > > > > Even with this patch, if the platform configuration doesn't select > > EFI_CAPSULE_FIRMWARE_* (or user will disable it when use it), the > > platform will lose raw DFU availability. > > I will have to rely on feedback from board maintainers for that. Like > I commented in another email, I think that these platforms are setting > dfu_alt_info primarily for capsule updates. But if some board > maintainer asks, I will enable CONFIG_SET_DFU_ALT_INFO the board's > defconfig. Thanks. Another alternative is that we keep the dfu_alt_info settings in the board config headers. With the capsule update, the CONFIG_SET_DFU_ALT_INFO will be set, and the variable will be populated from the board file. For the non capsule update scenario, the platform can then use the variable set in the board headers. Will that be fine with you. Let me know. Thanks. -sughosh > > -sughosh > > > > > Thank you, > > > > 2022年3月30日(水) 23:51 Sughosh Ganu : > > > > > > The capsule update code uses the dfu_alt_info variable for the actual > > > update of the firmware component. The dfu_alt_info variable gives > > > information needed to perform the update, like the device on which the > > > update is to be made, the partition, type of partition etc. Since the > > > dfu_alt_info is a environmental variable, it can be modified from the > > > u-boot command line. An incorrect update of the variable will result > > > in the update being done incorrectly. > > > > > > Prevent this scenario by forcing an update of the dfu_alt_info > > > variable from the information obtained through the board file when > > > UEFI capsule update functionality is enabled. > > > > > > Signed-off-by: Sughosh Ganu > > > --- > > > > > > Changes since V2: New Patch > > > > > > lib/efi_loader/Kconfig | 2 ++ > > > 1 file changed, 2 insertions(+) > > > > > > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig > > > index e5e35fe51f..09fb8cbe75 100644 > > > --- a/lib/efi_loader/Kconfig > > > +++ b/lib/efi_loader/Kconfig > > > @@ -174,6 +174,7 @@ config EFI_CAPSULE_FIRMWARE_FIT > > > depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT > > > select UPDATE_FIT > > > select DFU > > > + select SET_DFU_ALT_INFO > > > select EFI_CAPSULE_FIRMWARE > > > help > > > Select this option if you want to enable firmware management > > > protocol > > > @@ -185,6 +186,7 @@ config EFI_CAPSULE_FIRMWARE_RAW > > > depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT) > > > select DFU_WRITE_ALT > > > select DFU > > > + select SET_DFU_ALT_INFO > > > select EFI_CAPSULE_FIRMWARE > > > help > > > Select this option if you want to enable firmware management > > > protocol > > > -- > > > 2.25.1 > > > > > > > > > -- > > Masami Hiramatsu
Re: [PATCH v3 5/9] capsule: kconfig: Select SET_DFU_ALT_INFO config symbol for capsule update
hi Masami, On Thu, 31 Mar 2022 at 08:18, Masami Hiramatsu wrote: > > Hi, > > Even with this patch, if the platform configuration doesn't select > EFI_CAPSULE_FIRMWARE_* (or user will disable it when use it), the > platform will lose raw DFU availability. I will have to rely on feedback from board maintainers for that. Like I commented in another email, I think that these platforms are setting dfu_alt_info primarily for capsule updates. But if some board maintainer asks, I will enable CONFIG_SET_DFU_ALT_INFO the board's defconfig. Thanks. -sughosh > > Thank you, > > 2022年3月30日(水) 23:51 Sughosh Ganu : > > > > The capsule update code uses the dfu_alt_info variable for the actual > > update of the firmware component. The dfu_alt_info variable gives > > information needed to perform the update, like the device on which the > > update is to be made, the partition, type of partition etc. Since the > > dfu_alt_info is a environmental variable, it can be modified from the > > u-boot command line. An incorrect update of the variable will result > > in the update being done incorrectly. > > > > Prevent this scenario by forcing an update of the dfu_alt_info > > variable from the information obtained through the board file when > > UEFI capsule update functionality is enabled. > > > > Signed-off-by: Sughosh Ganu > > --- > > > > Changes since V2: New Patch > > > > lib/efi_loader/Kconfig | 2 ++ > > 1 file changed, 2 insertions(+) > > > > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig > > index e5e35fe51f..09fb8cbe75 100644 > > --- a/lib/efi_loader/Kconfig > > +++ b/lib/efi_loader/Kconfig > > @@ -174,6 +174,7 @@ config EFI_CAPSULE_FIRMWARE_FIT > > depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT > > select UPDATE_FIT > > select DFU > > + select SET_DFU_ALT_INFO > > select EFI_CAPSULE_FIRMWARE > > help > > Select this option if you want to enable firmware management > > protocol > > @@ -185,6 +186,7 @@ config EFI_CAPSULE_FIRMWARE_RAW > > depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT) > > select DFU_WRITE_ALT > > select DFU > > + select SET_DFU_ALT_INFO > > select EFI_CAPSULE_FIRMWARE > > help > > Select this option if you want to enable firmware management > > protocol > > -- > > 2.25.1 > > > > > -- > Masami Hiramatsu
Re: [PATCH v3 4/9] board: Define set_dfu_alt_info() for boards with UEFI capsule update enabled
hi Masami, On Thu, 31 Mar 2022 at 08:15, Masami Hiramatsu wrote: > > Hi Sughosh, > > If you remove the DEFAULT_DFU_ALT_INFO definition but introduce > set_dfu_alt_info(), this also must the CONFIG_SET_DFU_ALT_INFO for > each platform configuration too. > Unless that, some platform will not lose the dfu_alt_info until next > patch ([5/9]) is applied. I believe all the platforms are setting dfu_alt_info in the environment primarily for the capsule update. So I will squash this patch with patch 5/9. If you or any other board maintainer gives feedback for adding CONFIG_SET_DFU_ALT_INFO in the board's defconfig file, I will make that change in my next version. Thanks. -sughosh > > Thank you, > > 2022年3月30日(水) 23:51 Sughosh Ganu : > > > > Currently, there are a bunch of boards which enable the UEFI capsule > > update feature. The actual update of the firmware images is done > > through the dfu framework which uses the dfu_alt_info environment > > variable for getting information on the update, like device, partition > > number/address etc. Currently, these boards define the dfu_alt_info > > variable in the board config header, as an environment variable. With > > this, the variable can be modified from the u-boot command line and > > this can cause an incorrect update. > > > > To prevent this from happening, define the set_dfu_alt_info function > > in the board file, and use the function for populating the > > variable. With the function defined, the dfu framework populates the > > dfu_alt_info variable through the board file, instead of fetching the > > variable from the environment, thus making the update more robust. > > > > Signed-off-by: Sughosh Ganu > > --- > > > > Changes since V2: New Patch > > > > > > .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 24 + > > .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 24 + > > board/emulation/common/qemu_dfu.c | 6 ++--- > > board/kontron/pitx_imx8m/pitx_imx8m.c | 24 + > > board/kontron/sl-mx8mm/sl-mx8mm.c | 24 + > > board/kontron/sl28/sl28.c | 25 ++ > > board/sandbox/sandbox.c | 26 +++ > > board/socionext/developerbox/developerbox.c | 26 +++ > > board/xilinx/zynq/board.c | 5 ++-- > > board/xilinx/zynqmp/zynqmp.c | 5 ++-- > > include/configs/imx8mm-cl-iot-gate.h | 1 - > > include/configs/imx8mp_rsb3720.h | 1 - > > include/configs/kontron-sl-mx8mm.h| 1 - > > include/configs/kontron_pitx_imx8m.h | 1 - > > include/configs/kontron_sl28.h| 2 -- > > include/configs/synquacer.h | 6 - > > 16 files changed, 182 insertions(+), 19 deletions(-) > > > > diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > index 1c953ba195..41154ca9f3 100644 > > --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > @@ -5,10 +5,12 @@ > > */ > > > > #include > > +#include > > #include > > #include > > #include > > #include > > +#include > > #include > > #include > > #include > > @@ -24,6 +26,7 @@ > > #include > > #include > > #include > > +#include > > #include > > > > DECLARE_GLOBAL_DATA_PTR; > > @@ -231,3 +234,24 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc > > *mmc) > > } > > } > > #endif /* CONFIG_SPL_MMC_SUPPORT */ > > + > > +#if defined(CONFIG_SET_DFU_ALT_INFO) > > + > > +#define DFU_ALT_BUF_LENSZ_1K > > + > > +void set_dfu_alt_info(char *interface, char *devstr) > > +{ > > + ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); > > + > > + if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && > > + env_get("dfu_alt_info")) > > + return; > > + > > + memset(buf, 0, DFU_ALT_BUF_LEN); > > + > > + snprintf(buf, DFU_ALT_BUF_LEN, > > +"mmc 2=flash-bin raw 0 0x1B00 mmcpart 1"); > > + > > + env_set("dfu_alt_info", buf); > > +} > > +#endif /* CONFIG_SET_DFU_ALT_INFO */ > > diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c > > b/bo
[PATCH v3 9/9] doc: uefi: Update the capsule update related documentation
Update the capsule update functionality related documentation to refect the fact that a unique image GUID is to be used per image that forms part of the capsule file. Signed-off-by: Sughosh Ganu --- Changes since V2: * Add a description for adding image index value and definition of set_dfu_alt_info function for the capsule updates. doc/develop/uefi/uefi.rst | 22 -- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index fe337c88bd..403885d0f2 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -312,8 +312,8 @@ Run the following command .. code-block:: console $ mkeficapsule \ - --index 1 --instance 0 \ - [--fit | --raw ] \ + --index --instance 0 \ + --guid \ Performing the update @@ -333,6 +333,24 @@ won't be taken over across the reboot. If this is the case, you can skip this feature check with the Kconfig option (CONFIG_EFI_IGNORE_OSINDICATIONS) set. +A few things need to be defined in the board file for performing the +capsule upadte. The first is defining the function set_dfu_alt_info in +the board file. This function sets the environment variable +dfu_alt_info. Instead of taking the variable from the environment, the +capsule update feature requires that the variable be set through the +board function, since that is more robust. Secondly, define GUID +values and image index of the images that are to be updated through +the capsule update feature in the board file. Both the values are to +be defined as part of the fw_images array. These GUID values would be +used by the Firmware Management Protocol(FMP) to populate the image +descriptor array and also displayed as part of the ESRT table. The +image index values defined in the array should match the dfu alt +number that corresponds to the firmware image. The dfu alt number can +be obtained by running the following command:: + +dfu list + + Finally, the capsule update can be initiated by rebooting the board. Enabling Capsule Authentication -- 2.25.1
[PATCH v3 8/9] mkeficapsule: Remove raw and FIT GUID types
While building a capsule, the GUID value of that specific image is to be passed through the --guid command option to the mkeficapsule tool. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the --raw and --fit command line options as well. Signed-off-by: Sughosh Ganu --- Changes since V2: None tools/eficapsule.h | 8 tools/mkeficapsule.c | 26 +- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 69c9c58c2f..d63b831443 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -37,14 +37,6 @@ typedef struct { EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define EFI_CERT_TYPE_PKCS7_GUID \ EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index c118335b93..5f74d23b9e 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -27,17 +27,11 @@ static const char *tool_name = "mkeficapsule"; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; -efi_guid_t efi_guid_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; -efi_guid_t efi_guid_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; +static const char *opts_short = "g:i:I:v:p:c:m:dh"; static struct option options[] = { - {"fit", no_argument, NULL, 'f'}, - {"raw", no_argument, NULL, 'r'}, {"guid", required_argument, NULL, 'g'}, {"index", required_argument, NULL, 'i'}, {"instance", required_argument, NULL, 'I'}, @@ -54,8 +48,6 @@ static void print_usage(void) fprintf(stderr, "Usage: %s [options] \n" "Options:\n" - "\t-f, --fit FIT image type\n" - "\t-r, --raw raw image type\n" "\t-g, --guid guid for image blob type\n" "\t-i, --index update image index\n" "\t-I, --instanceupdate hardware instance\n" @@ -606,22 +598,6 @@ int main(int argc, char **argv) break; switch (c) { - case 'f': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_fit; - break; - case 'r': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_raw; - break; case 'g': if (guid) { fprintf(stderr, -- 2.25.1
[PATCH v3 6/9] test: capsule: Modify the capsule tests to use GUID values for sandbox
The current UEFI capsule updation code uses two GUID values, one for FIT images, and one for raw images across platforms. This logic is being changed to have GUID values per image, per platform. Change the tests for the capsule update code to reflect this change. The GUID values now used are the ones specific to the sandbox platform -- one for the u-boot image, and another for the u-boot environment image. The UEFI specification does not allow installation of multiple Firmware Management Protocols(FMP) at the same time. Install the FMP instance for raw images on the sandbox variant for testing the capsule update code. Install the FMP instance for the FIT images on the sandbox64 and sandbox_flattree variant for testing capsule update for FIT images. This is being done by splitting the capsule update script for FIT and raw images. Signed-off-by: Sughosh Ganu --- Changes since V2: None configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + test/py/tests/test_efi_capsule/conftest.py| 21 +- .../test_capsule_firmware_fit.py | 186 ++ ...rmware.py => test_capsule_firmware_raw.py} | 159 +-- 6 files changed, 258 insertions(+), 115 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py rename test/py/tests/test_efi_capsule/{test_capsule_firmware.py => test_capsule_firmware_raw.py} (75%) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 7c157a23d0..1a0142795a 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -247,7 +247,6 @@ CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y -CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index ab0e2defee..de2526df09 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -318,7 +318,6 @@ CONFIG_LZ4=y CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 217b0647bb..bbcf435ac6 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -29,6 +29,7 @@ CONFIG_CMD_BOOTEFI_HELLO=y CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_ERASEENV=y +CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_NVEDIT_INFO=y CONFIG_CMD_NVEDIT_LOAD=y CONFIG_CMD_NVEDIT_SELECT=y @@ -210,3 +211,7 @@ CONFIG_HEXDUMP=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y +CONFIG_DFU_SF=y diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 9076087a12..d757415c88 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -72,7 +72,7 @@ def efi_capsule_data(request, u_boot_config): # Create capsule files # two regions: one for u-boot.bin and the other for u-boot.env -check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, +check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, shell=True) check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' % (u_boot_config.source_dir, data_dir), @@ -80,21 +80,29 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --fit uboot_bin_env.itb Test01' % +check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test01' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --raw u-boot.bin.new Test02' % +check_call('cd %s; %s/tools/mkeficapsule --index 2 --guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test02' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --i
[PATCH v3 7/9] FMP: Remove GUIDs for FIT and raw images
The capsule update code has been modified for getting the image GUID values from the platform code. With this, each image now has a unique GUID value. With this change, there is no longer a need for defining GUIDs for FIT and raw images. Remove these GUID values. Signed-off-by: Sughosh Ganu --- Changes since V2: None include/efi_api.h | 8 lib/efi_loader/efi_firmware.c | 4 2 files changed, 12 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 982c200172..c7f7873b5d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1967,14 +1967,6 @@ struct efi_signature_list { EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ 0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE0x0001 #define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 #define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED0x0004 diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 169f3a29bb..7734d9f353 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -185,8 +185,6 @@ static efi_status_t efi_fill_image_desc_array( * - versioning of firmware image * - package information */ -const efi_guid_t efi_firmware_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; /** * efi_firmware_fit_get_image_info - return information about the current @@ -293,8 +291,6 @@ const struct efi_firmware_management_protocol efi_fmp_fit = { * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update * method with raw data. */ -const efi_guid_t efi_firmware_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; /** * efi_firmware_raw_get_image_info - return information about the current -- 2.25.1
[PATCH v3 4/9] board: Define set_dfu_alt_info() for boards with UEFI capsule update enabled
Currently, there are a bunch of boards which enable the UEFI capsule update feature. The actual update of the firmware images is done through the dfu framework which uses the dfu_alt_info environment variable for getting information on the update, like device, partition number/address etc. Currently, these boards define the dfu_alt_info variable in the board config header, as an environment variable. With this, the variable can be modified from the u-boot command line and this can cause an incorrect update. To prevent this from happening, define the set_dfu_alt_info function in the board file, and use the function for populating the variable. With the function defined, the dfu framework populates the dfu_alt_info variable through the board file, instead of fetching the variable from the environment, thus making the update more robust. Signed-off-by: Sughosh Ganu --- Changes since V2: New Patch .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 24 + .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 24 + board/emulation/common/qemu_dfu.c | 6 ++--- board/kontron/pitx_imx8m/pitx_imx8m.c | 24 + board/kontron/sl-mx8mm/sl-mx8mm.c | 24 + board/kontron/sl28/sl28.c | 25 ++ board/sandbox/sandbox.c | 26 +++ board/socionext/developerbox/developerbox.c | 26 +++ board/xilinx/zynq/board.c | 5 ++-- board/xilinx/zynqmp/zynqmp.c | 5 ++-- include/configs/imx8mm-cl-iot-gate.h | 1 - include/configs/imx8mp_rsb3720.h | 1 - include/configs/kontron-sl-mx8mm.h| 1 - include/configs/kontron_pitx_imx8m.h | 1 - include/configs/kontron_sl28.h| 2 -- include/configs/synquacer.h | 6 - 16 files changed, 182 insertions(+), 19 deletions(-) diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c index 1c953ba195..41154ca9f3 100644 --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c @@ -5,10 +5,12 @@ */ #include +#include #include #include #include #include +#include #include #include #include @@ -24,6 +26,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -231,3 +234,24 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc) } } #endif /* CONFIG_SPL_MMC_SUPPORT */ + +#if defined(CONFIG_SET_DFU_ALT_INFO) + +#define DFU_ALT_BUF_LENSZ_1K + +void set_dfu_alt_info(char *interface, char *devstr) +{ + ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); + + if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && + env_get("dfu_alt_info")) + return; + + memset(buf, 0, DFU_ALT_BUF_LEN); + + snprintf(buf, DFU_ALT_BUF_LEN, +"mmc 2=flash-bin raw 0 0x1B00 mmcpart 1"); + + env_set("dfu_alt_info", buf); +} +#endif /* CONFIG_SET_DFU_ALT_INFO */ diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c index f5b89a5ddc..1880dd9c55 100644 --- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c +++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include #include @@ -24,6 +26,7 @@ #include #include #include +#include #include "ddr/ddr.h" @@ -446,3 +449,24 @@ int board_late_init(void) return 0; } + +#if defined(CONFIG_SET_DFU_ALT_INFO) + +#define DFU_ALT_BUF_LENSZ_1K + +void set_dfu_alt_info(char *interface, char *devstr) +{ + ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); + + if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && + env_get("dfu_alt_info")) + return; + + memset(buf, 0, DFU_ALT_BUF_LEN); + + snprintf(buf, DFU_ALT_BUF_LEN, +"mmc 2=flash-bin raw 0x42 0x1D00 mmcpart 1"); + + env_set("dfu_alt_info", buf); +} +#endif /* CONFIG_SET_DFU_ALT_INFO */ diff --git a/board/emulation/common/qemu_dfu.c b/board/emulation/common/qemu_dfu.c index 62234a7647..85dff4373b 100644 --- a/board/emulation/common/qemu_dfu.c +++ b/board/emulation/common/qemu_dfu.c @@ -44,10 +44,11 @@ void set_dfu_alt_info(char *interface, char *devstr) ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); - if (env_get("dfu_alt_info")) + if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && + env_get("dfu_alt_info")) return; - memset(buf, 0, sizeof(buf)); + memset(b
[PATCH v3 5/9] capsule: kconfig: Select SET_DFU_ALT_INFO config symbol for capsule update
The capsule update code uses the dfu_alt_info variable for the actual update of the firmware component. The dfu_alt_info variable gives information needed to perform the update, like the device on which the update is to be made, the partition, type of partition etc. Since the dfu_alt_info is a environmental variable, it can be modified from the u-boot command line. An incorrect update of the variable will result in the update being done incorrectly. Prevent this scenario by forcing an update of the dfu_alt_info variable from the information obtained through the board file when UEFI capsule update functionality is enabled. Signed-off-by: Sughosh Ganu --- Changes since V2: New Patch lib/efi_loader/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index e5e35fe51f..09fb8cbe75 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -174,6 +174,7 @@ config EFI_CAPSULE_FIRMWARE_FIT depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT select UPDATE_FIT select DFU + select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol @@ -185,6 +186,7 @@ config EFI_CAPSULE_FIRMWARE_RAW depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT) select DFU_WRITE_ALT select DFU + select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol -- 2.25.1
[PATCH v3 3/9] capsule: Put a check for image index before the update
The current capsule update code compares the image GUID value in the capsule header with the image GUID value obtained from the GetImageInfo function of the Firmware Management Protocol(FMP). This comparison is done to ascertain if the FMP's SetImage function can be called for the update. Make this checking more robust by comparing the image_index value passed through the capsule with that returned by the FMP's GetImageInfo function. This protects against the scenario of the firmware being updated in a wrong partition/location on the storage device if an incorrect value has been passed through the capsule, since the image_index is used to determine the location of the update on the storage device. Signed-off-by: Sughosh Ganu --- Changes since V2: New patch lib/efi_loader/efi_capsule.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index f00440163d..f03f4c9044 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -128,6 +128,7 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, /** * efi_fmp_find - search for Firmware Management Protocol drivers * @image_type:Image type guid + * @image_index: Image Index * @instance: Instance number * @handles: Handles of FMP drivers * @no_handles:Number of handles @@ -141,8 +142,8 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, * * NULL - on failure */ static struct efi_firmware_management_protocol * -efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, -efi_uintn_t no_handles) +efi_fmp_find(efi_guid_t *image_type, u8 image_index, u64 instance, +efi_handle_t *handles, efi_uintn_t no_handles) { efi_handle_t *handle; struct efi_firmware_management_protocol *fmp; @@ -203,6 +204,7 @@ efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, log_debug("+++ desc[%d] index: %d, name: %ls\n", j, desc->image_index, desc->image_id_name); if (!guidcmp(>image_type_id, image_type) && + (desc->image_index == image_index) && (!instance || !desc->hardware_instance || desc->hardware_instance == instance)) @@ -449,8 +451,8 @@ static efi_status_t efi_capsule_update_firmware( } /* find a device for update firmware */ - /* TODO: should we pass index as well, or nothing but type? */ fmp = efi_fmp_find(>update_image_type_id, + image->update_image_index, image->update_hardware_instance, handles, no_handles); if (!fmp) { -- 2.25.1
[PATCH v3 1/9] capsule: Add Image GUIDs and image index for platforms using capsule updates
Currently, all platforms that enable capsule updates do so using either EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID or EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID. This is based on the Firmware Management Protocol(FMP) instance used on the platform. However, this means that all platforms that enable a particular FMP instance have the same GUID value for all the updatable images, either the FIT image GUID or the raw image GUID, and that an image for some platform can be updated on any other platform which uses the same FMP instance. Another issue with this implementation is that the ESRT table shows the same GUID value for all images on the platform and also across platforms, which is not in compliance with the UEFI specification. Fix this by defining image GUID values and firmware names for individual images per platform. The GetImageInfo FMP hook would then populate these values in the image descriptor array. Also add the image index value associated with a particular image. This is the value that should match with the image_index value that is part of the capsule header. The capsule update code will check if the two values match, and the update will only proceed on a match. Signed-off-by: Sughosh Ganu --- Changes since V2: * Add a new member image_index to the struct efi_fw_images to allow the platforms to define the values for images. * Address review comments from Michal Simek for the xilinx boards. * Fix double inclusion of efi_loader.h as was pointed out by Heiko Thiery. .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 20 + .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 19 + board/emulation/qemu-arm/qemu-arm.c | 20 + board/kontron/pitx_imx8m/pitx_imx8m.c | 16 ++- board/kontron/sl-mx8mm/sl-mx8mm.c | 15 ++ board/kontron/sl28/sl28.c | 15 ++ board/sandbox/sandbox.c | 28 +++ board/socionext/developerbox/developerbox.c | 26 + board/xilinx/common/board.c | 24 include/configs/imx8mm-cl-iot-gate.h | 10 +++ include/configs/imx8mp_rsb3720.h | 10 +++ include/configs/kontron-sl-mx8mm.h| 6 include/configs/kontron_pitx_imx8m.h | 6 include/configs/kontron_sl28.h| 6 include/configs/qemu-arm.h| 10 +++ include/configs/sandbox.h | 14 ++ include/configs/synquacer.h | 14 ++ include/configs/xilinx_versal.h | 6 include/configs/xilinx_zynqmp.h | 10 +++ include/configs/zynq-common.h | 10 +++ include/efi_loader.h | 18 21 files changed, 302 insertions(+), 1 deletion(-) diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c index 16566092bd..1c953ba195 100644 --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -44,6 +47,23 @@ static void setup_gpmi_nand(void) } #endif +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { + { +#if defined(CONFIG_TARGET_IMX8MP_RSB3720A1_4G) + .image_type_id = IMX8MP_RSB3720A1_4G_FIT_IMAGE_GUID, +#elif defined(CONFIG_TARGET_IMX8MP_RSB3720A1_6G) + .image_type_id = IMX8MP_RSB3720A1_6G_FIT_IMAGE_GUID, +#endif + .fw_name = u"IMX8MP-RSB3720-FIT", + .image_index = 1 + }, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + + int board_early_init_f(void) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c index 7e2d88f449..f5b89a5ddc 100644 --- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c +++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include #include @@ -21,11 +23,28 @@ #include #include #include +#include #include "ddr/ddr.h" DECLARE_GLOBAL_DATA_PTR; +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { + { +#if defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) + .image_type_id = IMX8MM_CL_IOT_GATE_FIT_IMAGE_GUID, +#elif defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) + .image_type_id = IMX8MM_CL_IOT_GATE_OPTEE_FIT_IMAGE_GUID, +#endif + .fw_name = u"IMX8MM-CL-IOT-GATE-FIT", + .image_
[PATCH v3 2/9] capsule: FMP: Populate the image descriptor array from platform data
Currently, the image descriptor array that has been passed to the GetImageInfo function of the Firmware Management Protocol(FMP) gets populated through the data stored with the dfu framework. The dfu data is not restricted to contain information only of the images updatable through the capsule update mechanism, but it also contains information on other images. The image descriptor array is also parsed by the ESRT generation code, and thus the ESRT table contains entries for other images that are not being handled by the FMP for the capsule updates. The other issue fixed is assignment of a separate GUID for all images in the image descriptor array. The UEFI specification mandates that all entries in the ESRT table should have a unique GUID value as part of the FwClass member of the EFI_SYSTEM_RESOURCE_ENTRY. Currently, all images are assigned a single GUID value, either an FIT GUID or a raw image GUID. This is fixed by obtaining the GUID values from the efi_fw_images array defined per platform. Signed-off-by: Sughosh Ganu --- Changes since V2: * Use the image index values defined in the platform's fw_images array for the image descriptors include/efi_loader.h | 3 ++ lib/efi_loader/efi_firmware.c | 91 +++ 2 files changed, 30 insertions(+), 64 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 284d64547b..9704397bd7 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -997,6 +997,9 @@ struct efi_fw_images { u8 image_index; }; +extern struct efi_fw_images fw_images[]; +extern u8 num_image_type_guids; + /** * Install the ESRT system table. * diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a5ff32f121..169f3a29bb 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -97,91 +97,60 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( } /** - * efi_get_dfu_info - return information about the current firmware image + * efi_fill_image_desc_array - populate image descriptor array * @this: Protocol instance * @image_info_size: Size of @image_info * @image_info:Image information * @descriptor_version:Pointer to version number - * @descriptor_count: Pointer to number of descriptors + * @descriptor_count: Image count * @descriptor_size: Pointer to descriptor size - * package_version:Package version - * package_version_name: Package version's name - * image_type: Image type GUID + * @package_version: Package version + * @package_version_name: Package version's name * * Return information bout the current firmware image in @image_info. * @image_info will consist of a number of descriptors. - * Each descriptor will be created based on "dfu_alt_info" variable. + * Each descriptor will be created based on "efi_fw_images" variable. * * Return status code */ -static efi_status_t efi_get_dfu_info( +static efi_status_t efi_fill_image_desc_array( efi_uintn_t *image_info_size, struct efi_firmware_image_descriptor *image_info, u32 *descriptor_version, u8 *descriptor_count, efi_uintn_t *descriptor_size, u32 *package_version, - u16 **package_version_name, - const efi_guid_t *image_type) + u16 **package_version_name) { - struct dfu_entity *dfu; size_t names_len, total_size; - int dfu_num, i; - u16 *name, *next; - int ret; - - ret = dfu_init_env_entities(NULL, NULL); - if (ret) - return EFI_SUCCESS; + struct efi_fw_images *fw_array; + u8 image_count; + int i; + fw_array = _images[0]; + *descriptor_count = image_count = num_image_type_guids; names_len = 0; - dfu_num = 0; - list_for_each_entry(dfu, _list, list) { - names_len += (utf8_utf16_strlen(dfu->name) + 1) * 2; - dfu_num++; - } - if (!dfu_num) { - log_warning("No entities in dfu_alt_info\n"); - *image_info_size = 0; - dfu_free_entities(); - return EFI_SUCCESS; - } + total_size = sizeof(*image_info) * image_count; - total_size = sizeof(*image_info) * dfu_num + names_len; - /* -* we will assume that sizeof(*image_info) * dfu_name -* is, at least, a multiple of 2. So the start address for -* image_id_name would be aligned with 2 bytes. -*/ if (*image_info_size < total_size) { *image_info_size = total_size; - dfu_free_entities(); return EFI_BUFFER_TOO_SMALL; } *image_info_size = total_size; *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; - *descriptor_count
[PATCH v3 0/9] efi: capsule: Capsule Update fixes and enhancements
images. The test for FIT images is being enabled on the sandbox_flattree variant. The seventh patch removes the now unused FIT and raw image GUID values from the FMP module. The eighth patch removes the --raw and --fit command line parameters in the mkeficapsule utility. The ninth patch makes corresponding changes in the capsule update related documentation. Sughosh Ganu (9): capsule: Add Image GUIDs and image index for platforms using capsule updates capsule: FMP: Populate the image descriptor array from platform data capsule: Put a check for image index before the update board: Define set_dfu_alt_info() for boards with UEFI capsule update enabled capsule: kconfig: Select SET_DFU_ALT_INFO config symbol for capsule update test: capsule: Modify the capsule tests to use GUID values for sandbox FMP: Remove GUIDs for FIT and raw images mkeficapsule: Remove raw and FIT GUID types doc: uefi: Update the capsule update related documentation .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 44 + .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 43 board/emulation/common/qemu_dfu.c | 6 +- board/emulation/qemu-arm/qemu-arm.c | 20 ++ board/kontron/pitx_imx8m/pitx_imx8m.c | 40 +++- board/kontron/sl-mx8mm/sl-mx8mm.c | 39 board/kontron/sl28/sl28.c | 40 board/sandbox/sandbox.c | 54 + board/socionext/developerbox/developerbox.c | 52 + board/xilinx/common/board.c | 24 +++ board/xilinx/zynq/board.c | 5 +- board/xilinx/zynqmp/zynqmp.c | 5 +- configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + doc/develop/uefi/uefi.rst | 22 ++- include/configs/imx8mm-cl-iot-gate.h | 11 +- include/configs/imx8mp_rsb3720.h | 11 +- include/configs/kontron-sl-mx8mm.h| 7 +- include/configs/kontron_pitx_imx8m.h | 7 +- include/configs/kontron_sl28.h| 8 +- include/configs/qemu-arm.h| 10 + include/configs/sandbox.h | 14 ++ include/configs/synquacer.h | 18 +- include/configs/xilinx_versal.h | 6 + include/configs/xilinx_zynqmp.h | 10 + include/configs/zynq-common.h | 10 + include/efi_api.h | 8 - include/efi_loader.h | 21 ++ lib/efi_loader/Kconfig| 2 + lib/efi_loader/efi_capsule.c | 8 +- lib/efi_loader/efi_firmware.c | 95 +++-- test/py/tests/test_efi_capsule/conftest.py| 21 +- .../test_capsule_firmware_fit.py | 186 ++ ...rmware.py => test_capsule_firmware_raw.py} | 159 +-- tools/eficapsule.h| 8 - tools/mkeficapsule.c | 26 +-- 37 files changed, 799 insertions(+), 248 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py rename test/py/tests/test_efi_capsule/{test_capsule_firmware.py => test_capsule_firmware_raw.py} (75%) -- 2.25.1
Re: [RFC PATCH 1/6] capsule: Add Image GUIDs for platforms using capsule updates
hi Masami, On Sat, 26 Mar 2022 at 16:17, Masami Hiramatsu wrote: > > Hi Sughosh, > > 2022年3月25日(金) 18:59 Sughosh Ganu : > > > > hi Masami, > > > > On Fri, 25 Mar 2022 at 10:58, Masami Hiramatsu > > wrote: > > > > > > Hi Sughosh, > > > > > > OK I understand that if the platform uses the FIT capsule, the > > > fw_images[] must have 1 entry and it is completely non relationship > > > with dfu_alt_info... We may need a document for this case too. > > > > Actually, what you are stating above applies to both raw images as > > well as FIT images. I have added a paragraph in the capsule update > > related section in the uefi.rst. Can you check my patch 4 of this > > series. Thanks. > > I've checked that you didn't change the FMP::set_image(), but updated > FMP::get_image_info() to use the per-platform GUID list. > Thus, the efi_fmp_find() ensures that the image type GUID in the > capsule image is *included* in the platform GUID list (fw_images[] > array). > > OK, at this point, it filters out the firmware image which is not > supported on the platform. > > However, since you didn't update the FMP::set_image() and > efi_capsule_update_firmware(), it directly uses the *index* number in > the capsule image for updating the firmware. Is that correct? Yes, your observation is correct. The aim of this series is to fix the issue of using a common GUID value across images and platforms for a given FMP instance. > > If so, if the platform supports several image types, the problem happens. > Suppose that if the platform has TF-A and U-Boot, the DFU entity index > are 1 and 2. > And user missed to make a capsule file with index 1 for U-Boot image > with U-Boot image type GUID of that platform. > This capsule file passed the check in the efi_fmp_find(), because the > GUID is included in the platform supported GUID list. However, > FMP::set_image() will overwrite the TF-A with given U-Boot image > without any error. > > I think we need one more patch to check the given image-index in the > capsule image is correctly matched to the image-type GUID for safety. Yes, this is very much in the pipeline. I will be working on extending the struct efi_fw_images to have information on the image index as part of the structure. But please note that what you mention above is just making the process of capsule update more robust -- the current implementation that we have in the capsule update module where the image_index value is taken from the capsule is very much in compliance with the UEFI specification. The current patch series is fixing an issue which was not compliant with the spec. But what you are suggesting above is on my Todo list, just that it is a separate task, and not a fix as such. -sughosh > > Thank you, > > > -sughosh > > > > > > > > Thanks, > > > > > > 2022年3月25日(金) 10:09 Masami Hiramatsu : > > > > > > > > Hi Sughosh, > > > > > > > > 2022年3月24日(木) 23:40 Sughosh Ganu : > > > > > > > > > > hi Masami, > > > > > > > > > > On Thu, 24 Mar 2022 at 19:14, Masami Hiramatsu > > > > > wrote: > > > > > > > > > > > > Hi Sughosh, > > > > > > > > > > > > 2022年3月24日(木) 21:39 Sughosh Ganu : > > > > > > > > > > > > > > Currently, all platforms that enable capsule updates do so using > > > > > > > either EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID or > > > > > > > EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID. This is based on the > > > > > > > Firmware > > > > > > > Management Protocol(FMP) instance used on the platform. However, > > > > > > > this > > > > > > > means that all platforms that enable a particular FMP instance > > > > > > > have > > > > > > > the same GUID value for all the updatable images, either the FIT > > > > > > > image > > > > > > > GUID or the raw image GUID, and that an image for some platform > > > > > > > can be > > > > > > > updated on any other platform which uses the same FMP instance. > > > > > > > Another > > > > > > > issue with this implementation is that the ESRT table shows the > > > > > > > same > > > > > > > GUID value for all images on the platform and also across > > > > > > > platforms, > > > > > > > which is not in compliance wi
Re: [PATCH v2 1/6] capsule: Add Image GUIDs for platforms using capsule updates
hi Heiko, On Sat, 26 Mar 2022 at 12:36, Heiko Thiery wrote: > > Hi > > Sughosh Ganu schrieb am Sa., 26. März 2022, 07:00: >> >> Currently, all platforms that enable capsule updates do so using >> either EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID or >> EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID. This is based on the Firmware >> Management Protocol(FMP) instance used on the platform. However, this >> means that all platforms that enable a particular FMP instance have >> the same GUID value for all the updatable images, either the FIT image >> GUID or the raw image GUID, and that an image for some platform can be >> updated on any other platform which uses the same FMP instance. Another >> issue with this implementation is that the ESRT table shows the same >> GUID value for all images on the platform and also across platforms, >> which is not in compliance with the UEFI specification. >> >> Fix this by defining image GUID values and firmware names for >> individual images per platform. The GetImageInfo FMP hook would then >> populate these values in the image descriptor array. >> >> Signed-off-by: Sughosh Ganu >> --- >> >> Changes since V1: >> * Make changes for the xilinx boards as suggested by Michal Simek. >> * Add a GUID for the sandbox FIT image >> >> .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 19 ++ >> .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 18 + >> board/emulation/qemu-arm/qemu-arm.c | 20 +++ >> board/kontron/pitx_imx8m/pitx_imx8m.c | 15 ++- >> board/kontron/sl-mx8mm/sl-mx8mm.c | 14 +++ >> board/kontron/sl28/sl28.c | 14 +++ >> board/sandbox/sandbox.c | 25 +++ >> board/socionext/developerbox/developerbox.c | 23 + >> board/xilinx/common/board.c | 18 + >> include/configs/imx8mm-cl-iot-gate.h | 10 >> include/configs/imx8mp_rsb3720.h | 10 >> include/configs/kontron-sl-mx8mm.h| 6 + >> include/configs/kontron_pitx_imx8m.h | 6 + >> include/configs/kontron_sl28.h| 6 + >> include/configs/qemu-arm.h| 10 >> include/configs/sandbox.h | 14 +++ >> include/configs/synquacer.h | 14 +++ >> include/configs/xilinx_versal.h | 10 >> include/configs/xilinx_zynqmp.h | 10 >> include/configs/zynq-common.h | 10 >> include/efi_loader.h | 15 +++ >> 21 files changed, 286 insertions(+), 1 deletion(-) >> >> diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c >> b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c >> index 16566092bd..6b534660fe 100644 >> --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c >> +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c >> @@ -6,6 +6,8 @@ >> >> #include >> #include >> +#include >> +#include >> #include >> #include >> #include >> @@ -21,6 +23,7 @@ >> #include >> #include >> #include >> +#include >> #include >> >> DECLARE_GLOBAL_DATA_PTR; >> @@ -44,6 +47,22 @@ static void setup_gpmi_nand(void) >> } >> #endif >> >> +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) >> +struct efi_fw_images fw_images[] = { >> + { >> +#if defined(CONFIG_TARGET_IMX8MP_RSB3720A1_4G) >> + .image_type_id = IMX8MP_RSB3720A1_4G_FIT_IMAGE_GUID, >> +#elif defined(CONFIG_TARGET_IMX8MP_RSB3720A1_6G) >> + .image_type_id = IMX8MP_RSB3720A1_6G_FIT_IMAGE_GUID, >> +#endif >> + .fw_name = u"IMX8MP-RSB3720-FIT" >> + }, >> +}; >> + >> +u8 num_image_type_guids = ARRAY_SIZE(fw_images); >> +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ >> + >> + >> int board_early_init_f(void) >> { >> struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; >> diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c >> b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c >> index 7e2d88f449..ec73d75db3 100644 >> --- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c >> +++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c >> @@ -5,6 +5,8 @@ >> */ >> >> #include >> +#
[PATCH v2 6/6] mkeficapsule: Remove raw and FIT GUID types
While building a capsule, the GUID value of that specific image is to be passed through the --guid command option to the mkeficapsule tool. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the --raw and --fit command line options as well. Signed-off-by: Sughosh Ganu --- Changes since V1: None tools/eficapsule.h | 8 tools/mkeficapsule.c | 26 +- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 69c9c58c2f..d63b831443 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -37,14 +37,6 @@ typedef struct { EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define EFI_CERT_TYPE_PKCS7_GUID \ EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index c118335b93..5f74d23b9e 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -27,17 +27,11 @@ static const char *tool_name = "mkeficapsule"; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; -efi_guid_t efi_guid_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; -efi_guid_t efi_guid_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; +static const char *opts_short = "g:i:I:v:p:c:m:dh"; static struct option options[] = { - {"fit", no_argument, NULL, 'f'}, - {"raw", no_argument, NULL, 'r'}, {"guid", required_argument, NULL, 'g'}, {"index", required_argument, NULL, 'i'}, {"instance", required_argument, NULL, 'I'}, @@ -54,8 +48,6 @@ static void print_usage(void) fprintf(stderr, "Usage: %s [options] \n" "Options:\n" - "\t-f, --fit FIT image type\n" - "\t-r, --raw raw image type\n" "\t-g, --guid guid for image blob type\n" "\t-i, --index update image index\n" "\t-I, --instanceupdate hardware instance\n" @@ -606,22 +598,6 @@ int main(int argc, char **argv) break; switch (c) { - case 'f': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_fit; - break; - case 'r': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_raw; - break; case 'g': if (guid) { fprintf(stderr, -- 2.25.1
[PATCH v2 5/6] FMP: Remove GUIDs for FIT and raw images
The capsule update code has been modified for getting the image GUID values from the platform code. With this, each image now has a unique GUID value. With this change, there is no longer a need for defining GUIDs for FIT and raw images. Remove these GUID values. Signed-off-by: Sughosh Ganu --- Changes since V1: None include/efi_api.h | 8 lib/efi_loader/efi_firmware.c | 4 2 files changed, 12 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 982c200172..c7f7873b5d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1967,14 +1967,6 @@ struct efi_signature_list { EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ 0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE0x0001 #define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 #define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED0x0004 diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 13cb492092..9fbedaf023 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -185,8 +185,6 @@ static efi_status_t efi_fill_image_desc_array( * - versioning of firmware image * - package information */ -const efi_guid_t efi_firmware_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; /** * efi_firmware_fit_get_image_info - return information about the current @@ -293,8 +291,6 @@ const struct efi_firmware_management_protocol efi_fmp_fit = { * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update * method with raw data. */ -const efi_guid_t efi_firmware_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; /** * efi_firmware_raw_get_image_info - return information about the current -- 2.25.1
[PATCH v2 3/6] test: capsule: Modify the capsule tests to use GUID values for sandbox
The current UEFI capsule updation code uses two GUID values, one for FIT images, and one for raw images across platforms. This logic is being changed to have GUID values per image, per platform. Change the tests for the capsule update code to reflect this change. The GUID values now used are the ones specific to the sandbox platform -- one for the u-boot image, and another for the u-boot environment image. The UEFI specification does not allow installation of multiple Firmware Management Protocols(FMP) at the same time. Install the FMP instance for raw images on the sandbox variant for testing the capsule update code. Install the FMP instance for the FIT images on the sandbox64 and sandbox_flattree variant for testing capsule update for FIT images. This is being done by splitting the capsule update script for FIT and raw images. Signed-off-by: Sughosh Ganu --- Changes since V1: * Split the capsule update test cases into two scripts, one for raw images and one for FIT images. * Add the capsule update test case for FIT images on sandbox64 and sandbox_flattree variants. * Add capsule update support on sandbox_flattree variant for enabling FIT capsule update testing as part of the python tests configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + test/py/tests/test_efi_capsule/conftest.py| 21 +- .../test_capsule_firmware_fit.py | 186 ++ ...rmware.py => test_capsule_firmware_raw.py} | 169 ++-- 6 files changed, 264 insertions(+), 119 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py rename test/py/tests/test_efi_capsule/{test_capsule_firmware.py => test_capsule_firmware_raw.py} (76%) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 7c157a23d0..1a0142795a 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -247,7 +247,6 @@ CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y -CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 7ebeb89264..0a601361b6 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -318,7 +318,6 @@ CONFIG_LZ4=y CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 217b0647bb..bbcf435ac6 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -29,6 +29,7 @@ CONFIG_CMD_BOOTEFI_HELLO=y CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_ERASEENV=y +CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_NVEDIT_INFO=y CONFIG_CMD_NVEDIT_LOAD=y CONFIG_CMD_NVEDIT_SELECT=y @@ -210,3 +211,7 @@ CONFIG_HEXDUMP=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y +CONFIG_DFU_SF=y diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 9076087a12..d757415c88 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -72,7 +72,7 @@ def efi_capsule_data(request, u_boot_config): # Create capsule files # two regions: one for u-boot.bin and the other for u-boot.env -check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, +check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, shell=True) check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' % (u_boot_config.source_dir, data_dir), @@ -80,21 +80,29 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --fit uboot_bin_env.itb Test01' % +check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test01' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tool
[PATCH v2 4/6] doc: uefi: Update the capsule update related documentation
Update the capsule update functionality related documentation to refect the fact that a unique image GUID is to be used per image that forms part of the capsule file. Signed-off-by: Sughosh Ganu --- Changes since V1: None doc/develop/uefi/uefi.rst | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index fe337c88bd..0d2825ce88 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -312,8 +312,8 @@ Run the following command .. code-block:: console $ mkeficapsule \ - --index 1 --instance 0 \ - [--fit | --raw ] \ + --index --instance 0 \ + --guid \ Performing the update @@ -333,6 +333,12 @@ won't be taken over across the reboot. If this is the case, you can skip this feature check with the Kconfig option (CONFIG_EFI_IGNORE_OSINDICATIONS) set. +Define GUID values of the images that are to be updated through the +capsule update feature in the platform file. The GUID values are to be +defined as part of the fw_images array. These GUID values would be +used by the Firmware Management Protocol(FMP) to populate the image +descriptor array and also displayed as part of the ESRT table. + Finally, the capsule update can be initiated by rebooting the board. Enabling Capsule Authentication -- 2.25.1
[PATCH v2 2/6] capsule: FMP: Populate the image descriptor array from platform data
Currently, the image descriptor array that has been passed to the GetImageInfo function of the Firmware Management Protocol(FMP) gets populated through the data stored with the dfu framework. The dfu data is not restricted to contain information only of the images updatable through the capsule update mechanism, but it also contains information on other images. The image descriptor array is also parsed by the ESRT generation code, and thus the ESRT table contains entries for other images that are not being handled by the FMP for the capsule updates. The other issue fixed is assignment of a separate GUID for all images in the image descriptor array. The UEFI specification mandates that all entries in the ESRT table should have a unique GUID value as part of the FwClass member of the EFI_SYSTEM_RESOURCE_ENTRY. Currently, all images are assigned a single GUID value, either an FIT GUID or a raw image GUID. This is fixed by obtaining the GUID values from the efi_fw_images array defined per platform. Signed-off-by: Sughosh Ganu --- Changes since V1: None include/efi_loader.h | 3 ++ lib/efi_loader/efi_firmware.c | 91 +++ 2 files changed, 30 insertions(+), 64 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 1965b5a28f..e8f7234230 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -994,6 +994,9 @@ struct efi_fw_images { const u16 *fw_name; }; +extern struct efi_fw_images fw_images[]; +extern u8 num_image_type_guids; + /** * Install the ESRT system table. * diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a5ff32f121..13cb492092 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -97,91 +97,60 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( } /** - * efi_get_dfu_info - return information about the current firmware image + * efi_fill_image_desc_array - populate image descriptor array * @this: Protocol instance * @image_info_size: Size of @image_info * @image_info:Image information * @descriptor_version:Pointer to version number - * @descriptor_count: Pointer to number of descriptors + * @descriptor_count: Image count * @descriptor_size: Pointer to descriptor size - * package_version:Package version - * package_version_name: Package version's name - * image_type: Image type GUID + * @package_version: Package version + * @package_version_name: Package version's name * * Return information bout the current firmware image in @image_info. * @image_info will consist of a number of descriptors. - * Each descriptor will be created based on "dfu_alt_info" variable. + * Each descriptor will be created based on "efi_fw_images" variable. * * Return status code */ -static efi_status_t efi_get_dfu_info( +static efi_status_t efi_fill_image_desc_array( efi_uintn_t *image_info_size, struct efi_firmware_image_descriptor *image_info, u32 *descriptor_version, u8 *descriptor_count, efi_uintn_t *descriptor_size, u32 *package_version, - u16 **package_version_name, - const efi_guid_t *image_type) + u16 **package_version_name) { - struct dfu_entity *dfu; size_t names_len, total_size; - int dfu_num, i; - u16 *name, *next; - int ret; - - ret = dfu_init_env_entities(NULL, NULL); - if (ret) - return EFI_SUCCESS; + struct efi_fw_images *fw_array; + u8 image_count; + int i; + fw_array = _images[0]; + *descriptor_count = image_count = num_image_type_guids; names_len = 0; - dfu_num = 0; - list_for_each_entry(dfu, _list, list) { - names_len += (utf8_utf16_strlen(dfu->name) + 1) * 2; - dfu_num++; - } - if (!dfu_num) { - log_warning("No entities in dfu_alt_info\n"); - *image_info_size = 0; - dfu_free_entities(); - return EFI_SUCCESS; - } + total_size = sizeof(*image_info) * image_count; - total_size = sizeof(*image_info) * dfu_num + names_len; - /* -* we will assume that sizeof(*image_info) * dfu_name -* is, at least, a multiple of 2. So the start address for -* image_id_name would be aligned with 2 bytes. -*/ if (*image_info_size < total_size) { *image_info_size = total_size; - dfu_free_entities(); return EFI_BUFFER_TOO_SMALL; } *image_info_size = total_size; *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; - *descriptor_count = dfu_num; *descriptor_size = sizeof(*image_info); *package_ve
[PATCH v2 1/6] capsule: Add Image GUIDs for platforms using capsule updates
Currently, all platforms that enable capsule updates do so using either EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID or EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID. This is based on the Firmware Management Protocol(FMP) instance used on the platform. However, this means that all platforms that enable a particular FMP instance have the same GUID value for all the updatable images, either the FIT image GUID or the raw image GUID, and that an image for some platform can be updated on any other platform which uses the same FMP instance. Another issue with this implementation is that the ESRT table shows the same GUID value for all images on the platform and also across platforms, which is not in compliance with the UEFI specification. Fix this by defining image GUID values and firmware names for individual images per platform. The GetImageInfo FMP hook would then populate these values in the image descriptor array. Signed-off-by: Sughosh Ganu --- Changes since V1: * Make changes for the xilinx boards as suggested by Michal Simek. * Add a GUID for the sandbox FIT image .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 19 ++ .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 18 + board/emulation/qemu-arm/qemu-arm.c | 20 +++ board/kontron/pitx_imx8m/pitx_imx8m.c | 15 ++- board/kontron/sl-mx8mm/sl-mx8mm.c | 14 +++ board/kontron/sl28/sl28.c | 14 +++ board/sandbox/sandbox.c | 25 +++ board/socionext/developerbox/developerbox.c | 23 + board/xilinx/common/board.c | 18 + include/configs/imx8mm-cl-iot-gate.h | 10 include/configs/imx8mp_rsb3720.h | 10 include/configs/kontron-sl-mx8mm.h| 6 + include/configs/kontron_pitx_imx8m.h | 6 + include/configs/kontron_sl28.h| 6 + include/configs/qemu-arm.h| 10 include/configs/sandbox.h | 14 +++ include/configs/synquacer.h | 14 +++ include/configs/xilinx_versal.h | 10 include/configs/xilinx_zynqmp.h | 10 include/configs/zynq-common.h | 10 include/efi_loader.h | 15 +++ 21 files changed, 286 insertions(+), 1 deletion(-) diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c index 16566092bd..6b534660fe 100644 --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -44,6 +47,22 @@ static void setup_gpmi_nand(void) } #endif +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { + { +#if defined(CONFIG_TARGET_IMX8MP_RSB3720A1_4G) + .image_type_id = IMX8MP_RSB3720A1_4G_FIT_IMAGE_GUID, +#elif defined(CONFIG_TARGET_IMX8MP_RSB3720A1_6G) + .image_type_id = IMX8MP_RSB3720A1_6G_FIT_IMAGE_GUID, +#endif + .fw_name = u"IMX8MP-RSB3720-FIT" + }, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + + int board_early_init_f(void) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c index 7e2d88f449..ec73d75db3 100644 --- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c +++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include #include @@ -21,11 +23,27 @@ #include #include #include +#include #include "ddr/ddr.h" DECLARE_GLOBAL_DATA_PTR; +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { + { +#if defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) + .image_type_id = IMX8MM_CL_IOT_GATE_FIT_IMAGE_GUID, +#elif defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) + .image_type_id = IMX8MM_CL_IOT_GATE_OPTEE_FIT_IMAGE_GUID, +#endif + .fw_name = u"IMX8MM-CL-IOT-GATE-FIT", + }, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + int board_phys_sdram_size(phys_size_t *size) { struct lpddr4_tcm_desc *lpddr4_tcm_desc = diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c index 16d5a97167..99872ce0b8 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -6,15 +6,35 @@ #include #include #include +
[PATCH v2 0/6] efi: capsule: Image GUID usage cleanup
This series is cleaning up the usage of the image GUIDs that are used in capsule update and the EFI System Resource Table(ESRT). Currently, there are two instances of the Firmware Management Protocol(FMP), one defined for updating the FIT images, and the other for updating raw images. The FMP code defines two GUID values, one for all FIT images, and one for raw images. Depending on the FMP instance used on a platform, the platform needs to use the corresponding image GUID value for all images on the platform, and also across platforms. A few issues are being fixed through the patch series. One, that an image for a different platform can be flashed on another platform if both the platforms are using the same FMP instance. So, for e.g. a capsule generated for the Socionext DeveloperBox platform can be flashed on the ZynqMP platform, since both the platforms use the CONFIG_EFI_CAPSULE_FIRMWARE_RAW instance of the FMP. This can be corrected if each firmware image that can be updated through the capsule update mechanism has it's own unique image GUID. The second issue that this patch series fixes is the value of FwClass in the ESRT. With the current logic, all firmware image entries in the ESRT display the same GUID value -- either the FIT GUID or the raw GUID. This is not in compliance with the UEFI specification, as the specification requires all entries to have unique GUID values. The third issue being fixed is the population of the EFI_FIRMWARE_IMAGE_DESCRIPTOR array. The current code uses the dfu framework for populating the image descriptor array. However, there might be other images that are not to be updated through the capsule update mechanism also registered with the dfu framework. As a result of this, the ESRT will show up entries of images that are not to be targeted by the capsule update mechanism. These issues are being fixed by defining a structure, efi_fw_images. A platform can then define image related information like the image GUID and image name. Every platform that uses capsule update mechanism needs to define fw_images array. This array will then be used to populate the image descriptor array, and also in determining if a particular capsule's payload can be used for updating an image on the platform. Changes since V1: * Make changes for the xilinx boards as suggested by Michal Simek. * Add a GUID for the sandbox FIT image. * Split the capsule update test cases into two scripts, one for raw images and one for FIT images. * Add the capsule update test case for FIT images on sandbox64 and sandbox_flattree variants. * Add capsule update support on sandbox_flattree variant for enabling FIT capsule update testing as part of the python tests The first patch of this series adds the fw_images array in all platforms which are using UEFI capsule updates The second patch of the series changes the logic for populating the image descriptor array, using the information from the fw_images array defined by the platform. The third patch of the series removes the test cases using the --raw and --fit parameters, removes test case for FIT images, and refactors the test scripts, one for raw images, and one for FIT images. The FIT test case is enabled on sandbox_flattree variant. The fourth patch of the series makes corresponding changes in the capsule update related documentation. The fifth patch of the series removes the now unused FIT and raw image GUID values from the FMP module. The sixth patch of the series removes the --raw and --fit command line parameters in the mkeficapsule utility. Sughosh Ganu (6): capsule: Add Image GUIDs for platforms using capsule updates capsule: FMP: Populate the image descriptor array from platform data test: capsule: Modify the capsule tests to use GUID values for sandbox doc: uefi: Update the capsule update related documentation FMP: Remove GUIDs for FIT and raw images mkeficapsule: Remove raw and FIT GUID types .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 19 ++ .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 18 ++ board/emulation/qemu-arm/qemu-arm.c | 20 ++ board/kontron/pitx_imx8m/pitx_imx8m.c | 15 +- board/kontron/sl-mx8mm/sl-mx8mm.c | 14 ++ board/kontron/sl28/sl28.c | 14 ++ board/sandbox/sandbox.c | 25 +++ board/socionext/developerbox/developerbox.c | 23 +++ board/xilinx/common/board.c | 18 ++ configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig| 5 + doc/develop/uefi/uefi.rst | 10 +- include/configs/imx8mm-cl-iot-gate.h | 10 + include/configs/imx8mp_rsb3720.h | 10 + include/configs/kontron-sl-mx8mm.h| 6 + include/configs/kontron_pitx_imx8m.h | 6 + include/configs/kontron_sl28.h| 6 + include/configs/qemu-arm.h
Re: [RFC PATCH 1/6] capsule: Add Image GUIDs for platforms using capsule updates
hi Masami, On Fri, 25 Mar 2022 at 10:58, Masami Hiramatsu wrote: > > Hi Sughosh, > > OK I understand that if the platform uses the FIT capsule, the > fw_images[] must have 1 entry and it is completely non relationship > with dfu_alt_info... We may need a document for this case too. Actually, what you are stating above applies to both raw images as well as FIT images. I have added a paragraph in the capsule update related section in the uefi.rst. Can you check my patch 4 of this series. Thanks. -sughosh > > Thanks, > > 2022年3月25日(金) 10:09 Masami Hiramatsu : > > > > Hi Sughosh, > > > > 2022年3月24日(木) 23:40 Sughosh Ganu : > > > > > > hi Masami, > > > > > > On Thu, 24 Mar 2022 at 19:14, Masami Hiramatsu > > > wrote: > > > > > > > > Hi Sughosh, > > > > > > > > 2022年3月24日(木) 21:39 Sughosh Ganu : > > > > > > > > > > Currently, all platforms that enable capsule updates do so using > > > > > either EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID or > > > > > EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID. This is based on the Firmware > > > > > Management Protocol(FMP) instance used on the platform. However, this > > > > > means that all platforms that enable a particular FMP instance have > > > > > the same GUID value for all the updatable images, either the FIT image > > > > > GUID or the raw image GUID, and that an image for some platform can be > > > > > updated on any other platform which uses the same FMP instance. > > > > > Another > > > > > issue with this implementation is that the ESRT table shows the same > > > > > GUID value for all images on the platform and also across platforms, > > > > > which is not in compliance with the UEFI specification. > > > > > > > > > > Fix this by defining image GUID values and firmware names for > > > > > individual images per platform. The GetImageInfo FMP hook would then > > > > > populate these values in the image descriptor array. > > > > > > > > OK, so you have generated GUIDs for each "dfu_alt_info" entry on the > > > > platforms, correct? > > > > > > No, I have generated the fw_images array based on the information that > > > I found in the dfu_alt_info variable for the platform. But this is not > > > correlated to the dfu_alt_info variable. If you think that the array > > > should have more/different entries for your platform, please let me > > > know, and I will change it. > > > > At least for the DeveloperBox, it looks good to me. > > (Hopefully, if you comment the string formatted GUID in the code for > > mkeficapsule, that is perfect. :) ) > > > > > > I think you should explain that those GUIDs (fw_images[] entries) must > > > > be corresponding to the dfu_alt_info entries, in the same order. > > > > > > The dfu_alt_info can have more entries than the firmware images that > > > are updatable through capsule update. One example is the ST platforms > > > which have additional entries in the dfu_alt_info. The image > > > descriptor array should only contain entries of images which are > > > updatable through capsule update, since the same information is also > > > used for generating the ESRT. Which is why I have changed the logic to > > > populate the image descriptors through the fw_images array rather than > > > the dfu_alt_info. > > > > I meant, the order of the fw_images array needs to be same as > > dfu_alt_info entries and the firmware entries for dfu_alt_info must be > > the first, because finally we will use the index of the fw_images > > array, which matched to given image type GUID, for specifying > > dfu_alt_info entry. > > Or, without dfu_alt_info, your new fw_images can update the firmware? > > I would like to see such *relationship* at least in the patch > > description and the documentation. > > > > Thank you, > > > > > > > > > > -sughosh > > > > > > > Without that, it is hard to understand why the next patch ([2/6]) works > > > > :-) > > > > > > > > Thank you, > > > > > > > > > > > > > > Signed-off-by: Sughosh Ganu > > > > > --- > > > > > .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 19 +++ > > > > > .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 18 +++ > >
Re: [RFC PATCH 0/6] efi: capsule: Image GUID usage cleanup
hi Takahiro, On Fri, 25 Mar 2022 at 10:23, AKASHI Takahiro wrote: > > Sughosh, > > On Thu, Mar 24, 2022 at 06:08:55PM +0530, Sughosh Ganu wrote: > > > > This series is cleaning up the usage of the image GUIDs that are used > > in capsule update and the EFI System Resource Table(ESRT). > > > > Currently, there are two instances of the Firmware Management > > Protocol(FMP), one defined for updating the FIT images, and the other > > for updating raw images. The FMP code defines two GUID values, one for > > all FIT images, and one for raw images. Depending on the FMP instance > > used on a platform, the platform needs to use the corresponding image > > GUID value for all images on the platform, and also across platforms. > > > > A few issues are being fixed through the patch series. One, that an > > image for a different platform can be flashed on another platform if > > both the platforms are using the same FMP instance. So, for e.g. a > > capsule generated for the Socionext DeveloperBox platform can be > > flashed on the ZynqMP platform, since both the platforms use the > > CONFIG_EFI_CAPSULE_FIRMWARE_RAW instance of the FMP. This can be > > corrected if each firmware image that can be updated through the > > capsule update mechanism has it's own unique image GUID. > > Ok although the specification doesn't explicitly require the uniqueness > "across platforms". Yes, but unless we have a single image running on multiple platforms, we do need different GUID values across platforms. > > > The second issue that this patch series fixes is the value of FwClass > > in the ESRT. With the current logic, all firmware image entries in the > > ESRT display the same GUID value -- either the FIT GUID or the raw > > GUID. This is not in compliance with the UEFI specification, as the > > specification requires all entries to have unique GUID values. > > Well, this is *not* a problem of fit FMP driver, but a matter of how > ESRT is populated. Table 23-16 "ESRT and FMP Fields" says, > The ImageTypeId GUID from the Firmware > Management Protocol instance for a device is > used as the Firmware Class GUID in the ESRT. > Where there are multiple identical devices in > the system, system firmware must create a > mapping to ensure that the ESRT FwClass > GUIDs are unique and consistent. > The second sentence suggests that UEFI implementation, i.e. > efi_esrt_populate(), may and should allow some *mapping*. > > That said, I basically accept the requirement that you mention above. > > > The third issue being fixed is the population of the > > EFI_FIRMWARE_IMAGE_DESCRIPTOR array. The current code uses the dfu > > framework for populating the image descriptor array. However, there > > might be other images that are not to be updated through the capsule > > update mechanism also registered with the dfu framework. As a result > > of this, the ESRT will show up entries of images that are not to be > > targeted by the capsule update mechanism. > > > > These issues are being fixed by defining a structure, efi_fw_images. A > > platform can then define image related information like the image GUID > > and image name. Every platform that uses capsule update mechanism > > needs to define fw_images array. This array will then be used to > > populate the image descriptor array, and also in determining if a > > particular capsule's payload can be used for updating an image on the > > platform. > > When ESRT support patch was posted, I proposed that we should have > a kind of configuration table that defines all the firmware on the system > for ESRT, but this proposal was rejected. > Your efi_fw_images[] looks quite similar as what I had in mind. > Why not define efi_fw_images[] as ESRT itself. > (Of course, some fields in an entry can still be populated through > GetImageInfo API.) Currently, with this patch series, that is what is happening. The efi_fw_images array gets read by the GetImageInfo function, and that information gets used for populating the ESRT. Btw, I also want to extend this structure as part of a separate task, where we have information related to the dfu framework as part of the structure. Then the capsule related dfu information can be populated from this structure, instead of the dfu_alt_info env variable. This is what Ilias has suggested. But I will take this up as a separate exercise. > > > The first patch of this series adds the fw_images array in all > > platforms which are using UEFI capsule updates > > > > The second patch of the series changes the logic for populating the > > image d
Re: [PATCH v5 5/9] qemu: arm: Remove platform specific function to get RNG device
hi Heinrich, On Sun, 13 Mar 2022 at 20:18, Sughosh Ganu wrote: > > The Qemu platform has a function defined to get the random number > generator(RNG) device. However, the RNG device can be obtained simply > by searching for a device belonging to the RNG uclass. Remove the > superfluous platform function defined for the Qemu platform for > getting the RNG device. > > Signed-off-by: Sughosh Ganu > Tested-by: Heinrich Schuchardt > Reviewed-by: Ilias Apalodimas > Reviewed-by: Simon Glass > --- > > Changes since V4: None > > board/emulation/qemu-arm/qemu-arm.c | 42 - > 1 file changed, 42 deletions(-) Can you please pick this up, as this has been reviewed, and is not related to the TPM RNG discussion. Thanks. -sughosh > > diff --git a/board/emulation/qemu-arm/qemu-arm.c > b/board/emulation/qemu-arm/qemu-arm.c > index 16d5a97167..c9e886e44a 100644 > --- a/board/emulation/qemu-arm/qemu-arm.c > +++ b/board/emulation/qemu-arm/qemu-arm.c > @@ -107,48 +107,6 @@ void enable_caches(void) > dcache_enable(); > } > > -#if defined(CONFIG_EFI_RNG_PROTOCOL) > -#include > -#include > - > -#include > - > -efi_status_t platform_get_rng_device(struct udevice **dev) > -{ > - int ret; > - efi_status_t status = EFI_DEVICE_ERROR; > - struct udevice *bus, *devp; > - > - for (uclass_first_device(UCLASS_VIRTIO, ); bus; > -uclass_next_device()) { > - for (device_find_first_child(bus, ); devp; > -device_find_next_child()) { > - if (device_get_uclass_id(devp) == UCLASS_RNG) { > - *dev = devp; > - status = EFI_SUCCESS; > - break; > - } > - } > - } > - > - if (status != EFI_SUCCESS) { > - debug("No rng device found\n"); > - return EFI_DEVICE_ERROR; > - } > - > - if (*dev) { > - ret = device_probe(*dev); > - if (ret) > - return EFI_DEVICE_ERROR; > - } else { > - debug("Couldn't get child device\n"); > - return EFI_DEVICE_ERROR; > - } > - > - return EFI_SUCCESS; > -} > -#endif /* CONFIG_EFI_RNG_PROTOCOL */ > - > #ifdef CONFIG_ARM64 > #define __W"w" > #else > -- > 2.25.1 >
Re: [PATCH v3 8/8] test: rng: Add a UT testcase for the rng command
hi Heinrich, On Fri, 4 Mar 2022 at 19:05, Sughosh Ganu wrote: > > The 'rng' command dumps a number of random bytes on the console. Add a > set of tests for the 'rng' command. The test function performs basic > sanity testing of the command. > > Since a unit test is being added for the command, enable it by default > in the sandbox platforms. > > Signed-off-by: Sughosh Ganu > --- > > Changes since V2: None > > cmd/Kconfig | 1 + > test/dm/rng.c | 29 + > 2 files changed, 30 insertions(+) Can you please pick this up, as this is unrelated to the TPM RNG changes which are still under discussion. Thanks. -sughosh > > diff --git a/cmd/Kconfig b/cmd/Kconfig > index 5e25e45fd2..47f1e23ef0 100644 > --- a/cmd/Kconfig > +++ b/cmd/Kconfig > @@ -1810,6 +1810,7 @@ config CMD_GETTIME > config CMD_RNG > bool "rng command" > depends on DM_RNG > + default y if SANDBOX > select HEXDUMP > help > Print bytes from the hardware random number generator. > diff --git a/test/dm/rng.c b/test/dm/rng.c > index 5b34c93ed6..6d1f68848d 100644 > --- a/test/dm/rng.c > +++ b/test/dm/rng.c > @@ -25,3 +25,32 @@ static int dm_test_rng_read(struct unit_test_state *uts) > return 0; > } > DM_TEST(dm_test_rng_read, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); > + > +/* Test the rng command */ > +static int dm_test_rng_cmd(struct unit_test_state *uts) > +{ > + struct udevice *dev; > + > + ut_assertok(uclass_get_device(UCLASS_RNG, 0, )); > + ut_assertnonnull(dev); > + > + ut_assertok(console_record_reset_enable()); > + > + run_command("rng", 0); > + ut_assert_nextlinen(":"); > + ut_assert_nextlinen("0010:"); > + ut_assert_nextlinen("0020:"); > + ut_assert_nextlinen("0030:"); > + ut_assert_console_end(); > + > + run_command("rng 0 10", 0); > + ut_assert_nextlinen(":"); > + ut_assert_console_end(); > + > + run_command("rng 20", 0); > + ut_assert_nextlinen("No RNG device"); > + ut_assert_console_end(); > + > + return 0; > +} > +DM_TEST(dm_test_rng_cmd, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | > UT_TESTF_CONSOLE_REC); > -- > 2.25.1 >
Re: [PATCH v5 9/9] test: rng: Add a UT testcase for the rng command
hi Heinrich, On Sun, 13 Mar 2022 at 20:19, Sughosh Ganu wrote: > > The 'rng' command dumps a number of random bytes on the console. Add a > set of tests for the 'rng' command. The test function performs basic > sanity testing of the command. > > Since a unit test is being added for the command, enable it by default > in the sandbox platforms. > > Signed-off-by: Sughosh Ganu > Reviewed-by: Simon Glass > --- > > Changes since V4: None > > cmd/Kconfig | 1 + > test/dm/rng.c | 29 + > 2 files changed, 30 insertions(+) Can you please pick this up as this is unrelated to the TPM RNG changes under discussion. Thanks. -sughosh > > diff --git a/cmd/Kconfig b/cmd/Kconfig > index 5e25e45fd2..47f1e23ef0 100644 > --- a/cmd/Kconfig > +++ b/cmd/Kconfig > @@ -1810,6 +1810,7 @@ config CMD_GETTIME > config CMD_RNG > bool "rng command" > depends on DM_RNG > + default y if SANDBOX > select HEXDUMP > help > Print bytes from the hardware random number generator. > diff --git a/test/dm/rng.c b/test/dm/rng.c > index 5b34c93ed6..6d1f68848d 100644 > --- a/test/dm/rng.c > +++ b/test/dm/rng.c > @@ -25,3 +25,32 @@ static int dm_test_rng_read(struct unit_test_state *uts) > return 0; > } > DM_TEST(dm_test_rng_read, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); > + > +/* Test the rng command */ > +static int dm_test_rng_cmd(struct unit_test_state *uts) > +{ > + struct udevice *dev; > + > + ut_assertok(uclass_get_device(UCLASS_RNG, 0, )); > + ut_assertnonnull(dev); > + > + ut_assertok(console_record_reset_enable()); > + > + run_command("rng", 0); > + ut_assert_nextlinen(":"); > + ut_assert_nextlinen("0010:"); > + ut_assert_nextlinen("0020:"); > + ut_assert_nextlinen("0030:"); > + ut_assert_console_end(); > + > + run_command("rng 0 10", 0); > + ut_assert_nextlinen(":"); > + ut_assert_console_end(); > + > + run_command("rng 20", 0); > + ut_assert_nextlinen("No RNG device"); > + ut_assert_console_end(); > + > + return 0; > +} > +DM_TEST(dm_test_rng_cmd, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | > UT_TESTF_CONSOLE_REC); > -- > 2.25.1 >
Re: [PATCH v5 8/9] doc: rng: Add documentation for the rng command
hi Heinrich, On Sun, 13 Mar 2022 at 20:19, Sughosh Ganu wrote: > > Add a usage document for the 'rng' u-boot command. > > Signed-off-by: Sughosh Ganu > Reviewed-by: Ilias Apalodimas > Reviewed-by: Simon Glass > --- > > Changes since V4: > > * Reflect the fact that a maximum of 64 bytes can be read on each > invocation of the 'rng' command > > doc/usage/index.rst | 1 + > doc/usage/rng.rst | 26 ++ > 2 files changed, 27 insertions(+) > create mode 100644 doc/usage/rng.rst Can you please pick this up, as this has been reviewed and is not related to the TPM RNG changes which are still under discussion. Thanks. -sughosh > > diff --git a/doc/usage/index.rst b/doc/usage/index.rst > index 0aacf531b2..5712a924ae 100644 > --- a/doc/usage/index.rst > +++ b/doc/usage/index.rst > @@ -45,6 +45,7 @@ Shell commands > pstore > qfw > reset > + rng > sbi > sf > scp03 > diff --git a/doc/usage/rng.rst b/doc/usage/rng.rst > new file mode 100644 > index 00..1a352da41a > --- /dev/null > +++ b/doc/usage/rng.rst > @@ -0,0 +1,26 @@ > +.. SPDX-License-Identifier: GPL-2.0+ > + > +rng command > +=== > + > +Synopsis > + > + > +:: > + > +rng [devnum [n]] > + > +Description > +--- > + > +The *rng* command reads the random number generator(RNG) device and > +prints the random bytes read on the console. A maximum of 64 bytes can > +be read in one invocation of the command. > + > +devnum > +The RNG device from which the random bytes are to be > +read. Defaults to 0. > + > +n > +Number of random bytes to be read and displayed on the > +console. Default value is 0x40. Max value is 0x40. > -- > 2.25.1 >
Re: [PATCH v5 7/9] cmd: rng: Use a statically allocated array for random bytes
hi Heinrich, On Sun, 13 Mar 2022 at 20:19, Sughosh Ganu wrote: > > Use a statically allocated buffer on stack instead of using malloc for > reading the random bytes. Using a local array is faster than > allocating heap memory on every initiation of the command. > > Signed-off-by: Sughosh Ganu > --- > > Changes since V4: > > * New patch based on review comments from Simon to not use the malloc > call > > cmd/rng.c | 17 +++-- > 1 file changed, 7 insertions(+), 10 deletions(-) Can you please pick this up, as this has been reviewed and is not related to the TPM RNG changes which are still under discussion. Thanks. -sughosh > > diff --git a/cmd/rng.c b/cmd/rng.c > index 2ddf27545f..81a23964b8 100644 > --- a/cmd/rng.c > +++ b/cmd/rng.c > @@ -14,9 +14,9 @@ > static int do_rng(struct cmd_tbl *cmdtp, int flag, int argc, char *const > argv[]) > { > size_t n; > - struct udevice *dev; > - void *buf; > + u8 buf[64]; > int devnum; > + struct udevice *dev; > int ret = CMD_RET_SUCCESS; > > switch (argc) { > @@ -41,11 +41,10 @@ static int do_rng(struct cmd_tbl *cmdtp, int flag, int > argc, char *const argv[]) > return CMD_RET_FAILURE; > } > > - buf = malloc(n); > - if (!buf) { > - printf("Out of memory\n"); > - return CMD_RET_FAILURE; > - } > + if (!n) > + return 0; > + > + n = min(n, sizeof(buf)); > > if (dm_rng_read(dev, buf, n)) { > printf("Reading RNG failed\n"); > @@ -54,15 +53,13 @@ static int do_rng(struct cmd_tbl *cmdtp, int flag, int > argc, char *const argv[]) > print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, n); > } > > - free(buf); > - > return ret; > } > > #ifdef CONFIG_SYS_LONGHELP > static char rng_help_text[] = > "[dev [n]]\n" > - " - print n random bytes read from dev\n"; > + " - print n random bytes(max 64) read from dev\n"; > #endif > > U_BOOT_CMD( > -- > 2.25.1 >
Re: [PATCH v5 6/9] cmd: rng: Add support for selecting RNG device
hi Heinrich, On Mon, 14 Mar 2022 at 03:53, Simon Glass wrote: > > Hi Sughosh, > > On Sun, 13 Mar 2022 at 08:49, Sughosh Ganu wrote: > > > > The 'rng' u-boot command is used for printing a select number of > > random bytes on the console. Currently, the RNG device from which the > > random bytes are read is fixed. However, a platform can have multiple > > RNG devices, one example being qemu, which has a virtio RNG device and > > the RNG pseudo device through the TPM chip. > > > > Extend the 'rng' command so that the user can provide the RNG device > > number from which the random bytes are to be read. This will be the > > device index under the RNG uclass. > > > > Signed-off-by: Sughosh Ganu > > Tested-by: Heinrich Schuchardt > > Reviewed-by: Ilias Apalodimas > > --- > > > > Changes since V4: > > > > * Use uclass_get_device_by_seq API to get the RNG device as suggested > > by Simon > > > > cmd/rng.c | 31 +++ > > 1 file changed, 23 insertions(+), 8 deletions(-) Can you please pick this up, as this has been reviewed and is not related to the TPM RNG changes which are still under discussion. Thanks. -sughosh > > Reviewed-by: Simon Glass > > with the nit below fixed > > > > > diff --git a/cmd/rng.c b/cmd/rng.c > > index 1ad5a096c0..2ddf27545f 100644 > > --- a/cmd/rng.c > > +++ b/cmd/rng.c > > @@ -13,19 +13,34 @@ > > > > static int do_rng(struct cmd_tbl *cmdtp, int flag, int argc, char *const > > argv[]) > > { > > - size_t n = 0x40; > > + size_t n; > > struct udevice *dev; > > void *buf; > > + int devnum; > > int ret = CMD_RET_SUCCESS; > > > > - if (uclass_get_device(UCLASS_RNG, 0, ) || !dev) { > > + switch (argc) { > > + case 1: > > + devnum = 0; > > + n = 0x40; > > + break; > > + case 2: > > + devnum = hextoul(argv[1], NULL); > > + n = 0x40; > > + break; > > + case 3: > > + devnum = hextoul(argv[1], NULL); > > + n = hextoul(argv[2], NULL); > > + break; > > + default: > > + return CMD_RET_USAGE; > > + } > > + > > + if (uclass_get_device_by_seq(UCLASS_RNG, devnum, ) || !dev) { > > Please check the function comments: you can drop the '|| !dev' bit > since it returns an error if no device is found. > > > > printf("No RNG device\n"); > > return CMD_RET_FAILURE; > > } > > > > - if (argc >= 2) > > - n = hextoul(argv[1], NULL); > > - > > buf = malloc(n); > > if (!buf) { > > printf("Out of memory\n"); > > @@ -46,12 +61,12 @@ static int do_rng(struct cmd_tbl *cmdtp, int flag, int > > argc, char *const argv[]) > > > > #ifdef CONFIG_SYS_LONGHELP > > static char rng_help_text[] = > > - "[n]\n" > > - " - print n random bytes\n"; > > + "[dev [n]]\n" > > + " - print n random bytes read from dev\n"; > > #endif > > > > U_BOOT_CMD( > > - rng, 2, 0, do_rng, > > + rng, 3, 0, do_rng, > > "print bytes from the hardware random number generator", > > rng_help_text > > ); > > -- > > 2.25.1 > > > > Regards, > SImon
Re: [RFC PATCH 6/6] mkeficapsule: Remove raw and FIT GUID types
On Thu, 24 Mar 2022 at 20:40, Michal Simek wrote: > > > > On 3/24/22 15:51, Sughosh Ganu wrote: > > On Thu, 24 Mar 2022 at 19:55, Michal Simek wrote: > >> > >> > >> > >> On 3/24/22 13:39, Sughosh Ganu wrote: > >>> While building a capsule, the GUID value of that specific image is to > >>> be passed through the --guid command option to the mkeficapsule > >>> tool. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and > >>> EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the > >>> --raw and --fit command line options as well. > >>> > >>> Signed-off-by: Sughosh Ganu > >>> --- > >>>tools/eficapsule.h | 8 > >>>tools/mkeficapsule.c | 26 +- > >>>2 files changed, 1 insertion(+), 33 deletions(-) > >>> > >>> diff --git a/tools/eficapsule.h b/tools/eficapsule.h > >>> index 69c9c58c2f..d63b831443 100644 > >>> --- a/tools/eficapsule.h > >>> +++ b/tools/eficapsule.h > >>> @@ -37,14 +37,6 @@ typedef struct { > >>>EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ > >>> 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) > >>> > >>> -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ > >>> - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ > >>> - 0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) > >>> - > >>> -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ > >>> - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ > >>> - 0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) > >>> - > >>>#define EFI_CERT_TYPE_PKCS7_GUID \ > >>>EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ > >>> 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) > >>> diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c > >>> index c118335b93..5f74d23b9e 100644 > >>> --- a/tools/mkeficapsule.c > >>> +++ b/tools/mkeficapsule.c > >>> @@ -27,17 +27,11 @@ > >>>static const char *tool_name = "mkeficapsule"; > >>> > >>>efi_guid_t efi_guid_fm_capsule = > >>> EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; > >>> -efi_guid_t efi_guid_image_type_uboot_fit = > >>> - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; > >>> -efi_guid_t efi_guid_image_type_uboot_raw = > >>> - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; > >>>efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; > >>> > >>> -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; > >>> +static const char *opts_short = "g:i:I:v:p:c:m:dh"; > >>> > >>>static struct option options[] = { > >>> - {"fit", no_argument, NULL, 'f'}, > >>> - {"raw", no_argument, NULL, 'r'}, > >>>{"guid", required_argument, NULL, 'g'}, > >>>{"index", required_argument, NULL, 'i'}, > >>>{"instance", required_argument, NULL, 'I'}, > >>> @@ -54,8 +48,6 @@ static void print_usage(void) > >>>fprintf(stderr, "Usage: %s [options] \n" > >>>"Options:\n" > >>> > >>> - "\t-f, --fit FIT image type\n" > >>> - "\t-r, --raw raw image type\n" > >>>"\t-g, --guid guid for image blob type\n" > >>>"\t-i, --index update image index\n" > >>>"\t-I, --instanceupdate hardware instance\n" > >>> @@ -606,22 +598,6 @@ int main(int argc, char **argv) > >>>break; > >>> > >>>switch (c) { > >>> - case 'f': > >>> - if (guid) { > >>> - fprintf(stderr, > >>> - "Image type already specified\n"); > >>> - exit(EXIT_FAILURE); > >>> - } > >>> - guid = _guid_image_type_uboot_fit; > >>> - break; > >>> - case 'r': > >>> - if (guid) { > >>> - f
Re: [RFC PATCH 1/6] capsule: Add Image GUIDs for platforms using capsule updates
On Thu, 24 Mar 2022 at 20:21, Michal Simek wrote: > > > > On 3/24/22 15:44, Sughosh Ganu wrote: > > On Thu, 24 Mar 2022 at 19:55, Michal Simek wrote: > >> > >> > >> > >> On 3/24/22 13:38, Sughosh Ganu wrote: > >>> Currently, all platforms that enable capsule updates do so using > >>> either EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID or > >>> EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID. This is based on the Firmware > >>> Management Protocol(FMP) instance used on the platform. However, this > >>> means that all platforms that enable a particular FMP instance have > >>> the same GUID value for all the updatable images, either the FIT image > >>> GUID or the raw image GUID, and that an image for some platform can be > >>> updated on any other platform which uses the same FMP instance. Another > >>> issue with this implementation is that the ESRT table shows the same > >>> GUID value for all images on the platform and also across platforms, > >>> which is not in compliance with the UEFI specification. > >>> > >>> Fix this by defining image GUID values and firmware names for > >>> individual images per platform. The GetImageInfo FMP hook would then > >>> populate these values in the image descriptor array. > >>> > >>> Signed-off-by: Sughosh Ganu > >>> --- > >>>.../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 19 +++ > >>>.../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 18 +++ > >>>board/emulation/qemu-arm/qemu-arm.c | 20 > >>>board/kontron/pitx_imx8m/pitx_imx8m.c | 15 +++- > >>>board/kontron/sl-mx8mm/sl-mx8mm.c | 14 +++ > >>>board/kontron/sl28/sl28.c | 14 +++ > >>>board/sandbox/sandbox.c | 17 ++ > >>>board/socionext/developerbox/developerbox.c | 23 +++ > >>>board/xilinx/common/board.h | 18 +++ > >>>board/xilinx/zynq/board.c | 18 +++ > >>>board/xilinx/zynqmp/zynqmp.c | 18 +++ > >>>include/configs/imx8mm-cl-iot-gate.h | 10 > >>>include/configs/imx8mp_rsb3720.h | 10 > >>>include/configs/kontron-sl-mx8mm.h| 6 + > >>>include/configs/kontron_pitx_imx8m.h | 6 + > >>>include/configs/kontron_sl28.h| 6 + > >>>include/configs/qemu-arm.h| 10 > >>>include/configs/sandbox.h | 10 > >>>include/configs/synquacer.h | 14 +++ > >>>include/efi_loader.h | 15 > >>>20 files changed, 280 insertions(+), 1 deletion(-) > > > > > > > >>> diff --git a/board/xilinx/common/board.h b/board/xilinx/common/board.h > >>> index 69e642429b..9bcac14946 100644 > >>> --- a/board/xilinx/common/board.h > >>> +++ b/board/xilinx/common/board.h > >>> @@ -7,6 +7,24 @@ > >>>#ifndef _BOARD_XILINX_COMMON_BOARD_H > >>>#define _BOARD_XILINX_COMMON_BOARD_H > >>> > >>> +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) > >>> +#define ZYNQ_BOOT_IMAGE_GUID \ > >>> + EFI_GUID(0x1ba29a15, 0x9969, 0x40aa, 0xb4, 0x24, \ > >>> + 0xe8, 0x61, 0x21, 0x61, 0x86, 0x64) > >>> + > >>> +#define ZYNQ_UBOOT_IMAGE_GUID \ > >>> + EFI_GUID(0x1a5178f0, 0x87d3, 0x4f36, 0xac, 0x63, \ > >>> + 0x3b, 0x31, 0xa2, 0x3b, 0xe3, 0x05) > >>> + > >>> +#define ZYNQMP_BOOT_IMAGE_GUID \ > >>> + EFI_GUID(0xde6066e8, 0x0256, 0x4fad, 0x82, 0x38, \ > >>> + 0xe4, 0x06, 0xe2, 0x74, 0xc4, 0xcf) > >>> + > >>> +#define ZYNQMP_UBOOT_IMAGE_GUID \ > >>> + EFI_GUID(0xcf9ecfd4, 0x938b, 0x41c5, 0x85, 0x51, \ > >>> + 0x1f, 0x88, 0x3a, 0xb7, 0xdc, 0x18) > >>> +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ > >> > >> I can't see any benefit to have it defined here for all. > >> Directly in board or in include/configs/* seems to be better option. > > > > I had initially put these definitions in > > include/configs/zynq-common.h, but that br
Re: [RFC PATCH 6/6] mkeficapsule: Remove raw and FIT GUID types
On Thu, 24 Mar 2022 at 19:55, Michal Simek wrote: > > > > On 3/24/22 13:39, Sughosh Ganu wrote: > > While building a capsule, the GUID value of that specific image is to > > be passed through the --guid command option to the mkeficapsule > > tool. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and > > EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the > > --raw and --fit command line options as well. > > > > Signed-off-by: Sughosh Ganu > > --- > > tools/eficapsule.h | 8 > > tools/mkeficapsule.c | 26 +- > > 2 files changed, 1 insertion(+), 33 deletions(-) > > > > diff --git a/tools/eficapsule.h b/tools/eficapsule.h > > index 69c9c58c2f..d63b831443 100644 > > --- a/tools/eficapsule.h > > +++ b/tools/eficapsule.h > > @@ -37,14 +37,6 @@ typedef struct { > > EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ > >0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) > > > > -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ > > - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ > > - 0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) > > - > > -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ > > - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ > > - 0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) > > - > > #define EFI_CERT_TYPE_PKCS7_GUID \ > > EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ > >0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) > > diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c > > index c118335b93..5f74d23b9e 100644 > > --- a/tools/mkeficapsule.c > > +++ b/tools/mkeficapsule.c > > @@ -27,17 +27,11 @@ > > static const char *tool_name = "mkeficapsule"; > > > > efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; > > -efi_guid_t efi_guid_image_type_uboot_fit = > > - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; > > -efi_guid_t efi_guid_image_type_uboot_raw = > > - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; > > efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; > > > > -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; > > +static const char *opts_short = "g:i:I:v:p:c:m:dh"; > > > > static struct option options[] = { > > - {"fit", no_argument, NULL, 'f'}, > > - {"raw", no_argument, NULL, 'r'}, > > {"guid", required_argument, NULL, 'g'}, > > {"index", required_argument, NULL, 'i'}, > > {"instance", required_argument, NULL, 'I'}, > > @@ -54,8 +48,6 @@ static void print_usage(void) > > fprintf(stderr, "Usage: %s [options] \n" > > "Options:\n" > > > > - "\t-f, --fit FIT image type\n" > > - "\t-r, --raw raw image type\n" > > "\t-g, --guid guid for image blob type\n" > > "\t-i, --index update image index\n" > > "\t-I, --instanceupdate hardware instance\n" > > @@ -606,22 +598,6 @@ int main(int argc, char **argv) > > break; > > > > switch (c) { > > - case 'f': > > - if (guid) { > > - fprintf(stderr, > > - "Image type already specified\n"); > > - exit(EXIT_FAILURE); > > - } > > - guid = _guid_image_type_uboot_fit; > > - break; > > - case 'r': > > - if (guid) { > > - fprintf(stderr, > > - "Image type already specified\n"); > > - exit(EXIT_FAILURE); > > - } > > - guid = _guid_image_type_uboot_raw; > > - break; > > case 'g': > > if (guid) { > > fprintf(stderr, > > Can you please find a way how to export guid based on what you build? > I think the best would be when capsules are enable to generated them directly > as > the part of build process with proper guids. I don't know how that can be done in a generic way. A platform might have more than one updatable image. So for doing what you are suggesting, we will need to a) pass the board for which the capsule is generated, and b) for which image in that board is the capsule generated. Currently, the mkeficapsule command parameters are on pretty much similar lines to what we have in the EDK2 GenerateCapsule tool. Can you not have a script for the xilinx boards which does what you are suggesting. That script can populate the GUID and image index values and then call the mkeficapsule tool. -sughosh
Re: [RFC PATCH 1/6] capsule: Add Image GUIDs for platforms using capsule updates
On Thu, 24 Mar 2022 at 19:55, Michal Simek wrote: > > > > On 3/24/22 13:38, Sughosh Ganu wrote: > > Currently, all platforms that enable capsule updates do so using > > either EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID or > > EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID. This is based on the Firmware > > Management Protocol(FMP) instance used on the platform. However, this > > means that all platforms that enable a particular FMP instance have > > the same GUID value for all the updatable images, either the FIT image > > GUID or the raw image GUID, and that an image for some platform can be > > updated on any other platform which uses the same FMP instance. Another > > issue with this implementation is that the ESRT table shows the same > > GUID value for all images on the platform and also across platforms, > > which is not in compliance with the UEFI specification. > > > > Fix this by defining image GUID values and firmware names for > > individual images per platform. The GetImageInfo FMP hook would then > > populate these values in the image descriptor array. > > > > Signed-off-by: Sughosh Ganu > > --- > > .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 19 +++ > > .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 18 +++ > > board/emulation/qemu-arm/qemu-arm.c | 20 > > board/kontron/pitx_imx8m/pitx_imx8m.c | 15 +++- > > board/kontron/sl-mx8mm/sl-mx8mm.c | 14 +++ > > board/kontron/sl28/sl28.c | 14 +++ > > board/sandbox/sandbox.c | 17 ++ > > board/socionext/developerbox/developerbox.c | 23 +++ > > board/xilinx/common/board.h | 18 +++ > > board/xilinx/zynq/board.c | 18 +++ > > board/xilinx/zynqmp/zynqmp.c | 18 +++ > > include/configs/imx8mm-cl-iot-gate.h | 10 > > include/configs/imx8mp_rsb3720.h | 10 > > include/configs/kontron-sl-mx8mm.h| 6 + > > include/configs/kontron_pitx_imx8m.h | 6 + > > include/configs/kontron_sl28.h| 6 + > > include/configs/qemu-arm.h| 10 > > include/configs/sandbox.h | 10 > > include/configs/synquacer.h | 14 +++ > > include/efi_loader.h | 15 > > 20 files changed, 280 insertions(+), 1 deletion(-) > > diff --git a/board/xilinx/common/board.h b/board/xilinx/common/board.h > > index 69e642429b..9bcac14946 100644 > > --- a/board/xilinx/common/board.h > > +++ b/board/xilinx/common/board.h > > @@ -7,6 +7,24 @@ > > #ifndef _BOARD_XILINX_COMMON_BOARD_H > > #define _BOARD_XILINX_COMMON_BOARD_H > > > > +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) > > +#define ZYNQ_BOOT_IMAGE_GUID \ > > + EFI_GUID(0x1ba29a15, 0x9969, 0x40aa, 0xb4, 0x24, \ > > + 0xe8, 0x61, 0x21, 0x61, 0x86, 0x64) > > + > > +#define ZYNQ_UBOOT_IMAGE_GUID \ > > + EFI_GUID(0x1a5178f0, 0x87d3, 0x4f36, 0xac, 0x63, \ > > + 0x3b, 0x31, 0xa2, 0x3b, 0xe3, 0x05) > > + > > +#define ZYNQMP_BOOT_IMAGE_GUID \ > > + EFI_GUID(0xde6066e8, 0x0256, 0x4fad, 0x82, 0x38, \ > > + 0xe4, 0x06, 0xe2, 0x74, 0xc4, 0xcf) > > + > > +#define ZYNQMP_UBOOT_IMAGE_GUID \ > > + EFI_GUID(0xcf9ecfd4, 0x938b, 0x41c5, 0x85, 0x51, \ > > + 0x1f, 0x88, 0x3a, 0xb7, 0xdc, 0x18) > > +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ > > I can't see any benefit to have it defined here for all. > Directly in board or in include/configs/* seems to be better option. I had initially put these definitions in include/configs/zynq-common.h, but that breaks the build for both zynq_virt and zynqmp_virt, since this file does not get included in the corresponding board file. Which is why I put these under board/xilinx/common/board.h, as this gets included in both the board files. I don't see any other zynq* file under include/configs/. Can you suggest one for both the platforms. -sughosh
Re: [RFC PATCH 1/6] capsule: Add Image GUIDs for platforms using capsule updates
hi Masami, On Thu, 24 Mar 2022 at 19:14, Masami Hiramatsu wrote: > > Hi Sughosh, > > 2022年3月24日(木) 21:39 Sughosh Ganu : > > > > Currently, all platforms that enable capsule updates do so using > > either EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID or > > EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID. This is based on the Firmware > > Management Protocol(FMP) instance used on the platform. However, this > > means that all platforms that enable a particular FMP instance have > > the same GUID value for all the updatable images, either the FIT image > > GUID or the raw image GUID, and that an image for some platform can be > > updated on any other platform which uses the same FMP instance. Another > > issue with this implementation is that the ESRT table shows the same > > GUID value for all images on the platform and also across platforms, > > which is not in compliance with the UEFI specification. > > > > Fix this by defining image GUID values and firmware names for > > individual images per platform. The GetImageInfo FMP hook would then > > populate these values in the image descriptor array. > > OK, so you have generated GUIDs for each "dfu_alt_info" entry on the > platforms, correct? No, I have generated the fw_images array based on the information that I found in the dfu_alt_info variable for the platform. But this is not correlated to the dfu_alt_info variable. If you think that the array should have more/different entries for your platform, please let me know, and I will change it. > I think you should explain that those GUIDs (fw_images[] entries) must > be corresponding to the dfu_alt_info entries, in the same order. The dfu_alt_info can have more entries than the firmware images that are updatable through capsule update. One example is the ST platforms which have additional entries in the dfu_alt_info. The image descriptor array should only contain entries of images which are updatable through capsule update, since the same information is also used for generating the ESRT. Which is why I have changed the logic to populate the image descriptors through the fw_images array rather than the dfu_alt_info. -sughosh > Without that, it is hard to understand why the next patch ([2/6]) works :-) > > Thank you, > > > > > Signed-off-by: Sughosh Ganu > > --- > > .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 19 +++ > > .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 18 +++ > > board/emulation/qemu-arm/qemu-arm.c | 20 > > board/kontron/pitx_imx8m/pitx_imx8m.c | 15 +++- > > board/kontron/sl-mx8mm/sl-mx8mm.c | 14 +++ > > board/kontron/sl28/sl28.c | 14 +++ > > board/sandbox/sandbox.c | 17 ++ > > board/socionext/developerbox/developerbox.c | 23 +++ > > board/xilinx/common/board.h | 18 +++ > > board/xilinx/zynq/board.c | 18 +++ > > board/xilinx/zynqmp/zynqmp.c | 18 +++ > > include/configs/imx8mm-cl-iot-gate.h | 10 > > include/configs/imx8mp_rsb3720.h | 10 > > include/configs/kontron-sl-mx8mm.h| 6 + > > include/configs/kontron_pitx_imx8m.h | 6 + > > include/configs/kontron_sl28.h| 6 + > > include/configs/qemu-arm.h| 10 > > include/configs/sandbox.h | 10 > > include/configs/synquacer.h | 14 +++ > > include/efi_loader.h | 15 > > 20 files changed, 280 insertions(+), 1 deletion(-) > > > > diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > index 16566092bd..6b534660fe 100644 > > --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c > > @@ -6,6 +6,8 @@ > > > > #include > > #include > > +#include > > +#include > > #include > > #include > > #include > > @@ -21,6 +23,7 @@ > > #include > > #include > > #include > > +#include > > #include > > > > DECLARE_GLOBAL_DATA_PTR; > > @@ -44,6 +47,22 @@ static void setup_gpmi_nand(void) > > } > > #endif > > > > +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) > > +struct efi_fw_images fw_images[] = { > > + { > > +#if defined(CONFIG_TARGET_IMX8MP_RSB3720A1_4G) >
[RFC PATCH 6/6] mkeficapsule: Remove raw and FIT GUID types
While building a capsule, the GUID value of that specific image is to be passed through the --guid command option to the mkeficapsule tool. This renders the EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID and EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID values superfluous. Remove the --raw and --fit command line options as well. Signed-off-by: Sughosh Ganu --- tools/eficapsule.h | 8 tools/mkeficapsule.c | 26 +- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 69c9c58c2f..d63b831443 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -37,14 +37,6 @@ typedef struct { EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define EFI_CERT_TYPE_PKCS7_GUID \ EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index c118335b93..5f74d23b9e 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -27,17 +27,11 @@ static const char *tool_name = "mkeficapsule"; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; -efi_guid_t efi_guid_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; -efi_guid_t efi_guid_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; +static const char *opts_short = "g:i:I:v:p:c:m:dh"; static struct option options[] = { - {"fit", no_argument, NULL, 'f'}, - {"raw", no_argument, NULL, 'r'}, {"guid", required_argument, NULL, 'g'}, {"index", required_argument, NULL, 'i'}, {"instance", required_argument, NULL, 'I'}, @@ -54,8 +48,6 @@ static void print_usage(void) fprintf(stderr, "Usage: %s [options] \n" "Options:\n" - "\t-f, --fit FIT image type\n" - "\t-r, --raw raw image type\n" "\t-g, --guid guid for image blob type\n" "\t-i, --index update image index\n" "\t-I, --instanceupdate hardware instance\n" @@ -606,22 +598,6 @@ int main(int argc, char **argv) break; switch (c) { - case 'f': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_fit; - break; - case 'r': - if (guid) { - fprintf(stderr, - "Image type already specified\n"); - exit(EXIT_FAILURE); - } - guid = _guid_image_type_uboot_raw; - break; case 'g': if (guid) { fprintf(stderr, -- 2.25.1
[RFC PATCH 5/6] FMP: Remove GUIDs for FIT and raw images
The capsule update code has been modified for getting the image GUID values from the platform code. With this, each image now has a unique GUID value. With this change, there is no longer a need for defining GUIDs for FIT and raw images. Remove these GUID values. Signed-off-by: Sughosh Ganu --- include/efi_api.h | 8 lib/efi_loader/efi_firmware.c | 4 2 files changed, 12 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 982c200172..c7f7873b5d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1967,14 +1967,6 @@ struct efi_signature_list { EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ 0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ - EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ -0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) - -#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ - EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ -0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) - #define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE0x0001 #define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0002 #define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED0x0004 diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 13cb492092..9fbedaf023 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -185,8 +185,6 @@ static efi_status_t efi_fill_image_desc_array( * - versioning of firmware image * - package information */ -const efi_guid_t efi_firmware_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; /** * efi_firmware_fit_get_image_info - return information about the current @@ -293,8 +291,6 @@ const struct efi_firmware_management_protocol efi_fmp_fit = { * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update * method with raw data. */ -const efi_guid_t efi_firmware_image_type_uboot_raw = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; /** * efi_firmware_raw_get_image_info - return information about the current -- 2.25.1
[RFC PATCH 4/6] doc: uefi: Update the capsule update related documentation
Update the capsule update functionality related documentation to refect the fact that a unique image GUID is to be used per image that forms part of the capsule file. Signed-off-by: Sughosh Ganu --- doc/develop/uefi/uefi.rst | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index fe337c88bd..0d2825ce88 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -312,8 +312,8 @@ Run the following command .. code-block:: console $ mkeficapsule \ - --index 1 --instance 0 \ - [--fit | --raw ] \ + --index --instance 0 \ + --guid \ Performing the update @@ -333,6 +333,12 @@ won't be taken over across the reboot. If this is the case, you can skip this feature check with the Kconfig option (CONFIG_EFI_IGNORE_OSINDICATIONS) set. +Define GUID values of the images that are to be updated through the +capsule update feature in the platform file. The GUID values are to be +defined as part of the fw_images array. These GUID values would be +used by the Firmware Management Protocol(FMP) to populate the image +descriptor array and also displayed as part of the ESRT table. + Finally, the capsule update can be initiated by rebooting the board. Enabling Capsule Authentication -- 2.25.1
[RFC PATCH 3/6] test: capsule: Modify the capsule tests to use GUID values for sandbox
The current UEFI capsule updation code uses two GUID values, one for FIT images, and one for raw images across platforms. This logic is being changed to have GUID values per image, per platform. Change the tests for the capsule update code to reflect this change. The GUID values now used are the ones specific to the sandbox platform -- one for the u-boot image, and another for the u-boot environment image. The UEFI specification does not allow installation of multiple Firmware Management Protocols(FMP) at the same time. Install only the FMP instance for raw images for testing the capsule update code. Signed-off-by: Sughosh Ganu --- configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - test/py/tests/test_efi_capsule/conftest.py| 20 +-- .../test_efi_capsule/test_capsule_firmware.py | 167 ++ 4 files changed, 65 insertions(+), 124 deletions(-) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 7c157a23d0..f93040 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -246,7 +246,6 @@ CONFIG_LZ4=y CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 7ebeb89264..0a601361b6 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -318,7 +318,6 @@ CONFIG_LZ4=y CONFIG_ERRNO_STR=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 9076087a12..5d9f680d14 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -72,21 +72,15 @@ def efi_capsule_data(request, u_boot_config): # Create capsule files # two regions: one for u-boot.bin and the other for u-boot.env -check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, +check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, shell=True) -check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' % - (u_boot_config.source_dir, data_dir), - shell=True) -check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' % - (data_dir, u_boot_config.build_dir), - shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --fit uboot_bin_env.itb Test01' % +check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test01' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --raw u-boot.bin.new Test02' % +check_call('cd %s; %s/tools/mkeficapsule --index 2 --guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test02' % (data_dir, u_boot_config.build_dir), shell=True) -check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid E2BB9C06-70E9-4B14-97A3-5A7913176E3F u-boot.bin.new Test03' % +check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 058B7D83-50D5-4C47-A195-60D86AD341C4 u-boot.bin.new Test03' % (data_dir, u_boot_config.build_dir), shell=True) if capsule_auth_enabled: @@ -94,7 +88,8 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; ' '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' '--private-key SIGNER.key --certificate SIGNER.crt ' -'--raw u-boot.bin.new Test11' +'--guid 09D7DF52-0720-4710-91D1-08469B7FE9C8 ' +'u-boot.bin.new Test11' % (data_dir, u_boot_config.build_dir), shell=True) # firmware signed with *mal* key @@ -102,7 +97,8 @@ def efi_capsule_data(request, u_boot_config): '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' '--private-key SIGNER2.key ' '--certificate SIGNER2.crt ' -'--raw u-boot.bin.new Test12
[RFC PATCH 2/6] capsule: FMP: Populate the image descriptor array from platform data
Currently, the image descriptor array that has been passed to the GetImageInfo function of the Firmware Management Protocol(FMP) gets populated through the data stored with the dfu framework. The dfu data is not restricted to contain information only of the images updatable through the capsule update mechanism, but it also contains information on other images. The image descriptor array is also parsed by the ESRT generation code, and thus the ESRT table contains entries for other images that are not being handled by the FMP for the capsule updates. The other issue fixed is assignment of a separate GUID for all images in the image descriptor array. The UEFI specification mandates that all entries in the ESRT table should have a unique GUID value as part of the FwClass member of the EFI_SYSTEM_RESOURCE_ENTRY. Currently, all images are assigned a single GUID value, either an FIT GUID or a raw image GUID. This is fixed by obtaining the GUID values from the efi_fw_images array defined per platform. Signed-off-by: Sughosh Ganu --- include/efi_loader.h | 3 ++ lib/efi_loader/efi_firmware.c | 91 +++ 2 files changed, 30 insertions(+), 64 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 1965b5a28f..e8f7234230 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -994,6 +994,9 @@ struct efi_fw_images { const u16 *fw_name; }; +extern struct efi_fw_images fw_images[]; +extern u8 num_image_type_guids; + /** * Install the ESRT system table. * diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index a5ff32f121..13cb492092 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -97,91 +97,60 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( } /** - * efi_get_dfu_info - return information about the current firmware image + * efi_fill_image_desc_array - populate image descriptor array * @this: Protocol instance * @image_info_size: Size of @image_info * @image_info:Image information * @descriptor_version:Pointer to version number - * @descriptor_count: Pointer to number of descriptors + * @descriptor_count: Image count * @descriptor_size: Pointer to descriptor size - * package_version:Package version - * package_version_name: Package version's name - * image_type: Image type GUID + * @package_version: Package version + * @package_version_name: Package version's name * * Return information bout the current firmware image in @image_info. * @image_info will consist of a number of descriptors. - * Each descriptor will be created based on "dfu_alt_info" variable. + * Each descriptor will be created based on "efi_fw_images" variable. * * Return status code */ -static efi_status_t efi_get_dfu_info( +static efi_status_t efi_fill_image_desc_array( efi_uintn_t *image_info_size, struct efi_firmware_image_descriptor *image_info, u32 *descriptor_version, u8 *descriptor_count, efi_uintn_t *descriptor_size, u32 *package_version, - u16 **package_version_name, - const efi_guid_t *image_type) + u16 **package_version_name) { - struct dfu_entity *dfu; size_t names_len, total_size; - int dfu_num, i; - u16 *name, *next; - int ret; - - ret = dfu_init_env_entities(NULL, NULL); - if (ret) - return EFI_SUCCESS; + struct efi_fw_images *fw_array; + u8 image_count; + int i; + fw_array = _images[0]; + *descriptor_count = image_count = num_image_type_guids; names_len = 0; - dfu_num = 0; - list_for_each_entry(dfu, _list, list) { - names_len += (utf8_utf16_strlen(dfu->name) + 1) * 2; - dfu_num++; - } - if (!dfu_num) { - log_warning("No entities in dfu_alt_info\n"); - *image_info_size = 0; - dfu_free_entities(); - return EFI_SUCCESS; - } + total_size = sizeof(*image_info) * image_count; - total_size = sizeof(*image_info) * dfu_num + names_len; - /* -* we will assume that sizeof(*image_info) * dfu_name -* is, at least, a multiple of 2. So the start address for -* image_id_name would be aligned with 2 bytes. -*/ if (*image_info_size < total_size) { *image_info_size = total_size; - dfu_free_entities(); return EFI_BUFFER_TOO_SMALL; } *image_info_size = total_size; *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; - *descriptor_count = dfu_num; *descriptor_size = sizeof(*image_info); *package_version = 0x; /* not supported */
[RFC PATCH 1/6] capsule: Add Image GUIDs for platforms using capsule updates
Currently, all platforms that enable capsule updates do so using either EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID or EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID. This is based on the Firmware Management Protocol(FMP) instance used on the platform. However, this means that all platforms that enable a particular FMP instance have the same GUID value for all the updatable images, either the FIT image GUID or the raw image GUID, and that an image for some platform can be updated on any other platform which uses the same FMP instance. Another issue with this implementation is that the ESRT table shows the same GUID value for all images on the platform and also across platforms, which is not in compliance with the UEFI specification. Fix this by defining image GUID values and firmware names for individual images per platform. The GetImageInfo FMP hook would then populate these values in the image descriptor array. Signed-off-by: Sughosh Ganu --- .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 19 +++ .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 18 +++ board/emulation/qemu-arm/qemu-arm.c | 20 board/kontron/pitx_imx8m/pitx_imx8m.c | 15 +++- board/kontron/sl-mx8mm/sl-mx8mm.c | 14 +++ board/kontron/sl28/sl28.c | 14 +++ board/sandbox/sandbox.c | 17 ++ board/socionext/developerbox/developerbox.c | 23 +++ board/xilinx/common/board.h | 18 +++ board/xilinx/zynq/board.c | 18 +++ board/xilinx/zynqmp/zynqmp.c | 18 +++ include/configs/imx8mm-cl-iot-gate.h | 10 include/configs/imx8mp_rsb3720.h | 10 include/configs/kontron-sl-mx8mm.h| 6 + include/configs/kontron_pitx_imx8m.h | 6 + include/configs/kontron_sl28.h| 6 + include/configs/qemu-arm.h| 10 include/configs/sandbox.h | 10 include/configs/synquacer.h | 14 +++ include/efi_loader.h | 15 20 files changed, 280 insertions(+), 1 deletion(-) diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c index 16566092bd..6b534660fe 100644 --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -44,6 +47,22 @@ static void setup_gpmi_nand(void) } #endif +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { + { +#if defined(CONFIG_TARGET_IMX8MP_RSB3720A1_4G) + .image_type_id = IMX8MP_RSB3720A1_4G_FIT_IMAGE_GUID, +#elif defined(CONFIG_TARGET_IMX8MP_RSB3720A1_6G) + .image_type_id = IMX8MP_RSB3720A1_6G_FIT_IMAGE_GUID, +#endif + .fw_name = u"IMX8MP-RSB3720-FIT" + }, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + + int board_early_init_f(void) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c index 7e2d88f449..ec73d75db3 100644 --- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c +++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include #include @@ -21,11 +23,27 @@ #include #include #include +#include #include "ddr/ddr.h" DECLARE_GLOBAL_DATA_PTR; +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +struct efi_fw_images fw_images[] = { + { +#if defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) + .image_type_id = IMX8MM_CL_IOT_GATE_FIT_IMAGE_GUID, +#elif defined(CONFIG_TARGET_IMX8MM_CL_IOT_GATE_OPTEE) + .image_type_id = IMX8MM_CL_IOT_GATE_OPTEE_FIT_IMAGE_GUID, +#endif + .fw_name = u"IMX8MM-CL-IOT-GATE-FIT", + }, +}; + +u8 num_image_type_guids = ARRAY_SIZE(fw_images); +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + int board_phys_sdram_size(phys_size_t *size) { struct lpddr4_tcm_desc *lpddr4_tcm_desc = diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c index 16d5a97167..99872ce0b8 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -6,15 +6,35 @@ #include #include #include +#include +#include +#include #include #include #include #include #include +#include + #ifdef CONFIG_ARM64 #include +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_
[RFC PATCH 0/6] efi: capsule: Image GUID usage cleanup
This series is cleaning up the usage of the image GUIDs that are used in capsule update and the EFI System Resource Table(ESRT). Currently, there are two instances of the Firmware Management Protocol(FMP), one defined for updating the FIT images, and the other for updating raw images. The FMP code defines two GUID values, one for all FIT images, and one for raw images. Depending on the FMP instance used on a platform, the platform needs to use the corresponding image GUID value for all images on the platform, and also across platforms. A few issues are being fixed through the patch series. One, that an image for a different platform can be flashed on another platform if both the platforms are using the same FMP instance. So, for e.g. a capsule generated for the Socionext DeveloperBox platform can be flashed on the ZynqMP platform, since both the platforms use the CONFIG_EFI_CAPSULE_FIRMWARE_RAW instance of the FMP. This can be corrected if each firmware image that can be updated through the capsule update mechanism has it's own unique image GUID. The second issue that this patch series fixes is the value of FwClass in the ESRT. With the current logic, all firmware image entries in the ESRT display the same GUID value -- either the FIT GUID or the raw GUID. This is not in compliance with the UEFI specification, as the specification requires all entries to have unique GUID values. The third issue being fixed is the population of the EFI_FIRMWARE_IMAGE_DESCRIPTOR array. The current code uses the dfu framework for populating the image descriptor array. However, there might be other images that are not to be updated through the capsule update mechanism also registered with the dfu framework. As a result of this, the ESRT will show up entries of images that are not to be targeted by the capsule update mechanism. These issues are being fixed by defining a structure, efi_fw_images. A platform can then define image related information like the image GUID and image name. Every platform that uses capsule update mechanism needs to define fw_images array. This array will then be used to populate the image descriptor array, and also in determining if a particular capsule's payload can be used for updating an image on the platform. The first patch of this series adds the fw_images array in all platforms which are using UEFI capsule updates The second patch of the series changes the logic for populating the image descriptor array, using the information from the fw_images array defined by the platform. The third patch of the series removes the test cases using the --raw and --fit parameters, removes test case for FIT images, and adds a test case for checking that the update happens only with the correct image GUID value in the capsule. The fourth patch of the series makes corresponding changes in the capsule update related documentation. The fifth patch of the series removes the now unused FIT and raw image GUID values from the FMP module. The sixth patch of the series removes the --raw and --fit command line parameters in the mkeficapsule utility. Sughosh Ganu (6): capsule: Add Image GUIDs for platforms using capsule updates capsule: FMP: Populate the image descriptor array from platform data test: capsule: Modify the capsule tests to use GUID values for sandbox doc: uefi: Update the capsule update related documentation FMP: Remove GUIDs for FIT and raw images mkeficapsule: Remove raw and FIT GUID types .../imx8mp_rsb3720a1/imx8mp_rsb3720a1.c | 19 ++ .../imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c | 18 ++ board/emulation/qemu-arm/qemu-arm.c | 20 +++ board/kontron/pitx_imx8m/pitx_imx8m.c | 15 +- board/kontron/sl-mx8mm/sl-mx8mm.c | 14 ++ board/kontron/sl28/sl28.c | 14 ++ board/sandbox/sandbox.c | 17 ++ board/socionext/developerbox/developerbox.c | 23 +++ board/xilinx/common/board.h | 18 ++ board/xilinx/zynq/board.c | 18 ++ board/xilinx/zynqmp/zynqmp.c | 18 ++ configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - doc/develop/uefi/uefi.rst | 10 +- include/configs/imx8mm-cl-iot-gate.h | 10 ++ include/configs/imx8mp_rsb3720.h | 10 ++ include/configs/kontron-sl-mx8mm.h| 6 + include/configs/kontron_pitx_imx8m.h | 6 + include/configs/kontron_sl28.h| 6 + include/configs/qemu-arm.h| 10 ++ include/configs/sandbox.h | 10 ++ include/configs/synquacer.h | 14 ++ include/efi_api.h | 8 - include/efi_loader.h | 18 ++ lib/efi_loader/efi_firmware.c | 95 +++--- test/py/tests/test_efi_capsule/conftest.py| 20 +-- .../test_efi_capsule/test_capsule_firmware.py | 167
Re: [PATCH v5 4/9] tpm: Add the RNG child device
hi Simon, On Wed, 16 Mar 2022 at 02:45, Simon Glass wrote: > > Hi Ilias, > > On Tue, 15 Mar 2022 at 00:34, Ilias Apalodimas > wrote: > > > > Hi Simon, > > > > On Mon, 14 Mar 2022 at 20:24, Simon Glass wrote: > > > > > > > [...] > > > > > > > > + } > > > > > > > > > > This really should be in the device tree so what you are doing here is > > > > > quite strange. > > > > > > > > Like I had mentioned in my earlier emails, the TPM device has a > > > > builtin RNG functionality, which is non-optional. So I don't > > > > understand why we need to use a device tree subnode here. Whether the > > > > device is being bound to the parent is being controlled by the TPM_RNG > > > > config that you asked me to put in my previous version, which I am > > > > doing. > > > > > > See how PMICs work, for example. We have GPIOs, regulators and > > > suchlike in the PMIC and we add subnodes for them in the DT. It is > > > just how it is done. > > > > > > Driver model is designed to automatically bind devices based on the > > > device tree. There are cases where it is necessary to manually bind > > > things, but we mustn't prevent people from doing it 'properly'. > > > > There's a small difference here though. The RNG is not a device. The > > TPM is the device and an encoded command to that device returns a > > random number. There's no binding initiating etc. > > A device is just something with a struct udevice, so I don't see the > random number generator as anything different from another device. We > might have a white-noise generator which produces random numbers. Just > because the feature is packaged inside a single chip doesn't make it > any less a device. Just like the PMIC. > > > > > > > > > Finally, I know you keep saying that random numbers are only needed in > > > U-Boot proper, but if I want a random number in SPL, it may not work, > > > since device_bind() is often not available, for code-size reasons. > > > > And the entire tpm framework will fit? > > Yes. For verified boot it has to, since you cannot init RAM until you > have selected your A/B/recovery image. > > > > > > > > > So that is why I say that what you are doing is quite strange. Perhaps > > > you are coming from a different project, which does things > > > differently. > > > > I don't personally find it strange. The device is already described > > in the DTS and I don't see a strong reason to deviate for the upstream > > version again. > > Linux tends to rely a lot more on manually adding devices. It can have > a pretty dramatic bloating effect on code size in U-Boot. > > Anyway, so long as we can detect an existing device, as I explained > below, it is fine to manually add it when it is missing. Just so that I understand what you are saying, do you want support for both approaches. Meaning, using device tree when the rng node is described in the device tree, and otherwise using the manual device binding when the device tree node is absent. Do I understand this right? -sughosh > > > > > > Regards > > /Ilias > > > > > > > > > > > If you want to manually bind it, please call > > > > > device_find_first_child_by_uclass() first to make sure it isn't > > > > > already there. > > > > > > > > Okay > > > > > > > > > > > > > > Also you should bind it in the bind() method, not in probe(). > > > > > > > > Okay > > > > > > > > > > > > > > This is the code used for the same thing in the bootstd series: > > > > > > > > > > struct udevice *bdev; > > > > > int ret; > > > > > > > > > > ret = device_find_first_child_by_uclass(parent, UCLASS_BOOTDEV, > > > > > ); > > > > > if (ret) { > > > > >if (ret != -ENODEV) { > > > > >log_debug("Cannot access bootdev device\n"); > > > > >return ret; > > > > >} > > > > > > > > > >ret = bootdev_bind(parent, drv_name, "bootdev", ); > > > > >if (ret) { > > > > > log_debug("Cannot create bootdev device\n"); > > > > > return ret; > > > > >} > > > > > } > > > > > > > > > > > > > > > > + > > > > > > + return 0; > > > > > > +} > > > > > > + > > > > > > UCLASS_DRIVER(tpm) = { > > > > > > - .id = UCLASS_TPM, > > > > > > - .name = "tpm", > > > > > > - .flags = DM_UC_FLAG_SEQ_ALIAS, > > > > > > + .id = UCLASS_TPM, > > > > > > + .name = "tpm", > > > > > > + .flags = DM_UC_FLAG_SEQ_ALIAS, > > > > > > #if CONFIG_IS_ENABLED(OF_REAL) > > > > > > - .post_bind = dm_scan_fdt_dev, > > > > > > + .post_bind = dm_scan_fdt_dev, > > > > > > #endif > > > > > > + .post_probe = tpm_uclass_post_probe, > > > > > > > > > > Should be post_bind. > > > > > > > > Okay > > > > > > [..] > > Regards, > Simon
Re: [PATCH v5 3/9] tpm: rng: Add driver model interface for TPM RNG device
hi Simon, On Mon, 14 Mar 2022 at 23:55, Simon Glass wrote: > > Hi Sughosh, > > On Mon, 14 Mar 2022 at 05:39, Sughosh Ganu wrote: > > > > hi Simon, > > > > On Mon, 14 Mar 2022 at 03:53, Simon Glass wrote: > > > > > > Hi Sughosh, > > > > > > On Sun, 13 Mar 2022 at 08:48, Sughosh Ganu > > > wrote: > > > > > > > > The TPM device has a builtin random number generator(RNG) > > > > functionality. Expose the RNG functions of the TPM device to the > > > > driver model so that they can be used by the EFI_RNG_PROTOCOL if the > > > > protocol is installed. > > > > > > > > Also change the function arguments and return type of the random > > > > number functions to comply with the driver model api. > > > > > > Please don't do that > > > > > > > > > > > Signed-off-by: Sughosh Ganu > > > > --- > > > > > > > > Changes since V4: > > > > > > > > * Call the existing tpm_get_random API function from the TPM RNG > > > > driver, instead of the tpm{1,2}_get_random API's > > > > * Introduce a new Kconfig symbol TPM_RNG and build the corresponding > > > > driver if the symbol is enabled > > > > * Change the last parameter of the tpm_get_random API to have a data > > > > type of size_t instead of u32 to comply with the RNG driver model > > > > API > > > > > > > > drivers/rng/Kconfig | 7 +++ > > > > drivers/rng/Makefile | 1 + > > > > drivers/rng/tpm_rng.c | 23 +++ > > > > include/tpm-v1.h | 4 ++-- > > > > include/tpm-v2.h | 4 ++-- > > > > include/tpm_api.h | 2 +- > > > > lib/Kconfig | 1 + > > > > lib/tpm-v1.c | 16 +--- > > > > lib/tpm-v2.c | 9 + > > > > lib/tpm_api.c | 16 +++- > > > > 10 files changed, 62 insertions(+), 21 deletions(-) > > > > create mode 100644 drivers/rng/tpm_rng.c > > > > > > > > diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig > > > > index b1c5ab93d1..a89fa99ffa 100644 > > > > --- a/drivers/rng/Kconfig > > > > +++ b/drivers/rng/Kconfig > > > > @@ -49,4 +49,11 @@ config RNG_IPROC200 > > > > depends on DM_RNG > > > > help > > > > Enable random number generator for RPI4. > > > > + > > > > +config TPM_RNG > > > > + bool "Enable random number generator on TPM device" > > > > + depends on TPM > > > > + default y > > > > + help > > > > + Enable random number generator on TPM devices > > > > > > Needs 3 lines of text so please add more detail > > > > Okay > > > > > > > > > endif > > > > diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile > > > > index 39f7ee3f03..a21f3353ea 100644 > > > > --- a/drivers/rng/Makefile > > > > +++ b/drivers/rng/Makefile > > > > @@ -10,3 +10,4 @@ obj-$(CONFIG_RNG_MSM) += msm_rng.o > > > > obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o > > > > obj-$(CONFIG_RNG_ROCKCHIP) += rockchip_rng.o > > > > obj-$(CONFIG_RNG_IPROC200) += iproc_rng200.o > > > > +obj-$(CONFIG_TPM_RNG) += tpm_rng.o > > > > diff --git a/drivers/rng/tpm_rng.c b/drivers/rng/tpm_rng.c > > > > new file mode 100644 > > > > index 00..69b41dbbf5 > > > > --- /dev/null > > > > +++ b/drivers/rng/tpm_rng.c > > > > @@ -0,0 +1,23 @@ > > > > +// SPDX-License-Identifier: GPL-2.0-or-later > > > > +/* > > > > + * Copyright (c) 2022, Linaro Limited > > > > + */ > > > > + > > > > +#include > > > > +#include > > > > +#include > > > > + > > > > +static int rng_tpm_random_read(struct udevice *dev, void *data, size_t > > > > count) > > > > +{ > > > > + return tpm_get_random(dev->parent, data, count); > > > > > > dev_get_parent(dev) > > > > > > Here you should check the return value and decide whether to return an > > > error, such as -EIO > > > > > > > +} > > > > + > > > > +static const struct dm_rng_ops tpm_rng_ops = { &g
Re: [PATCH v5 4/9] tpm: Add the RNG child device
hi Simon, On Mon, 14 Mar 2022 at 23:54, Simon Glass wrote: > > Hi Sughosh, > > On Mon, 14 Mar 2022 at 05:43, Sughosh Ganu wrote: > > > > hi Simon, > > > > On Mon, 14 Mar 2022 at 03:53, Simon Glass wrote: > > > > > > Hi Sughosh, > > > > > > On Sun, 13 Mar 2022 at 08:48, Sughosh Ganu > > > wrote: > > > > > > > > The TPM device comes with the random number generator(RNG) > > > > functionality which is built into the TPM device. Add logic to add the > > > > RNG child device in the TPM uclass post probe callback. > > > > > > > > The RNG device can then be used to pass a set of random bytes to the > > > > linux kernel, need for address space randomisation through the > > > > EFI_RNG_PROTOCOL interface. > > > > > > > > Signed-off-by: Sughosh Ganu > > > > --- > > > > > > > > Changes since V4: > > > > > > > > * Put a check for CONFIG_TPM_RNG for binding the RNG device with it's > > > > driver in the post_probe callback instead of putting > > > > CONFIG_{SPL,TPL}_BUILD guards > > > > > > > > drivers/tpm/tpm-uclass.c | 29 + > > > > 1 file changed, 25 insertions(+), 4 deletions(-) > > > > > > > > > > This looks a lot better, please see below. > > > > > > > diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c > > > > index f67fe1019b..e1c61d26f0 100644 > > > > --- a/drivers/tpm/tpm-uclass.c > > > > +++ b/drivers/tpm/tpm-uclass.c > > > > @@ -11,10 +11,15 @@ > > > > #include > > > > #include > > > > #include > > > > +#include > > > > #include > > > > #include > > > > #include "tpm_internal.h" > > > > > > > > +#include > > > > + > > > > +#define TPM_RNG_DRV_NAME "tpm-rng" > > > > + > > > > int tpm_open(struct udevice *dev) > > > > { > > > > struct tpm_ops *ops = tpm_get_ops(dev); > > > > @@ -136,12 +141,28 @@ int tpm_xfer(struct udevice *dev, const uint8_t > > > > *sendbuf, size_t send_size, > > > > return 0; > > > > } > > > > > > > > +static int tpm_uclass_post_probe(struct udevice *dev) > > > > +{ > > > > + int ret; > > > > + const char *drv = TPM_RNG_DRV_NAME; > > > > + struct udevice *child; > > > > + > > > > + if (CONFIG_IS_ENABLED(TPM_RNG)) { > > > > + ret = device_bind_driver(dev, drv, "tpm-rng0", ); > > > > + if (ret) > > > > + return log_msg_ret("bind", ret); > > > > + } > > > > > > This really should be in the device tree so what you are doing here is > > > quite strange. > > > > Like I had mentioned in my earlier emails, the TPM device has a > > builtin RNG functionality, which is non-optional. So I don't > > understand why we need to use a device tree subnode here. Whether the > > device is being bound to the parent is being controlled by the TPM_RNG > > config that you asked me to put in my previous version, which I am > > doing. > > See how PMICs work, for example. We have GPIOs, regulators and > suchlike in the PMIC and we add subnodes for them in the DT. It is > just how it is done. > > Driver model is designed to automatically bind devices based on the > device tree. There are cases where it is necessary to manually bind > things, but we mustn't prevent people from doing it 'properly'. > > Finally, I know you keep saying that random numbers are only needed in > U-Boot proper, but if I want a random number in SPL, it may not work, > since device_bind() is often not available, for code-size reasons. > > So that is why I say that what you are doing is quite strange. Perhaps > you are coming from a different project, which does things > differently. Well, FWIW I actually found usage of this kind of device binding in this very project. There are quite a few drivers which are using the API in the same way that is being done in this patch. And I have already mentioned the reason that I am using this method as against a device tree. Thanks. -sughosh > > > > > If you want to manually bind it, please call > > > device_find_first_child_by_uclass() first to make sure it isn't