[PATCH v2 0/6] Support for dumping capsule headers and empty capsules

These set of patches are intended for two tasks. The first set of patches are adding support for dumping capsule header information, which is then being used in the binman test framework for testing the capsule generation. This replaces the current hardcoding of offsets used for verifying the capsule contents in the binman tests.
Patch 1 introduces this functionality in the mkeficapsule tool. Patch 4 is using this functionality in the binman tests for capsules.
The other set of patches, 5 and 6 are for adding support for generation of empty capsules in binman. The empty capsules are used for the FWU A/B update functionality.
Changes since V1: * Get rid of the superfluous hdr_size variable in the dump_fmp_payload_header() function * Move the get_binman_test_guid() function outside the Entry_efi_capsule class so that it can be called from outside the module. * Use lowercase characters in the GUID values * Add comments for the _GetCapsuleHeaders() function. * Use a simple dict in _GetCapsuleHeaders() for storing the capsule header values dumped by the mkeficapsule tool. * Use a single boolean value to indicate the generation of either of accept/revert capsule. * Move the parameters added to the list on the same line in a couple of places. * Instead of using two separate boolean values, use a 'capsule-type' property for indicating generation of an accept/revert capsule. * Make corresponding changes in the sanity checks, documentation and tests based on the above change. * Use lower case characters for GUIDs. * Call get_binman_test_guid() from the efi_capsule entry module. * Add the documentation entry for the empty capsules in entries.rst. * Remove the #[address,size]-cells properties from the test dts' for empty capsules.
Sughosh Ganu (6): tools: mkeficapsule: Add support to print capsule headers doc: capsule: Add documentation for the capsule dump feature binman: capsule: Remove superfluous [address,size]-cells properties binman: capsule: Use dumped capsule header contents for verification btool: mkeficapsule: Add support for EFI empty capsule generation binman: capsule: Add support for generating EFI empty capsules
doc/develop/uefi/uefi.rst | 17 ++ tools/binman/btool/mkeficapsule.py | 26 ++ tools/binman/entries.rst | 44 ++++ tools/binman/etype/efi_capsule.py | 24 +- tools/binman/etype/efi_empty_capsule.py | 86 +++++++ tools/binman/ftest.py | 160 +++++++++--- tools/binman/test/311_capsule.dts | 3 - tools/binman/test/312_capsule_signed.dts | 3 - tools/binman/test/313_capsule_version.dts | 3 - tools/binman/test/314_capsule_signed_ver.dts | 3 - tools/binman/test/315_capsule_oemflags.dts | 3 - tools/binman/test/316_capsule_missing_key.dts | 3 - .../binman/test/317_capsule_missing_index.dts | 3 - .../binman/test/318_capsule_missing_guid.dts | 3 - tools/binman/test/319_capsule_accept.dts | 13 + tools/binman/test/320_capsule_revert.dts | 11 + .../test/321_capsule_accept_missing_guid.dts | 11 + .../test/322_empty_capsule_type_missing.dts | 12 + .../323_capsule_accept_revert_missing.dts | 13 + tools/eficapsule.h | 2 + tools/mkeficapsule.c | 227 +++++++++++++++++- 21 files changed, 599 insertions(+), 71 deletions(-) create mode 100644 tools/binman/etype/efi_empty_capsule.py create mode 100644 tools/binman/test/319_capsule_accept.dts create mode 100644 tools/binman/test/320_capsule_revert.dts create mode 100644 tools/binman/test/321_capsule_accept_missing_guid.dts create mode 100644 tools/binman/test/322_empty_capsule_type_missing.dts create mode 100644 tools/binman/test/323_capsule_accept_revert_missing.dts

Add support to dump the contents of capsule headers. This is useful as a debug feature for checking the contents of the capsule headers, and can also be used in capsule verification.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- Changes since V1: * Get rid of the superfluous hdr_size variable in the dump_fmp_payload_header() function
tools/eficapsule.h | 2 + tools/mkeficapsule.c | 227 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 228 insertions(+), 1 deletion(-)
diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 2099a2e9b8..6efd07d2eb 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -22,6 +22,8 @@ #define __aligned(x) __attribute__((__aligned__(x))) #endif
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + typedef struct { uint8_t b[16]; } efi_guid_t __aligned(8); diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index 52be1f122e..b8fc6069b5 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -29,7 +29,7 @@ static const char *tool_name = "mkeficapsule"; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
-static const char *opts_short = "g:i:I:v:p:c:m:o:dhAR"; +static const char *opts_short = "g:i:I:v:p:c:m:o:dhARD";
enum { CAPSULE_NORMAL_BLOB = 0, @@ -49,6 +49,7 @@ static struct option options[] = { {"fw-accept", no_argument, NULL, 'A'}, {"fw-revert", no_argument, NULL, 'R'}, {"capoemflag", required_argument, NULL, 'o'}, + {"dump-capsule", no_argument, NULL, 'D'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}, }; @@ -69,6 +70,7 @@ static void print_usage(void) "\t-A, --fw-accept firmware accept capsule, requires GUID, no image blob\n" "\t-R, --fw-revert firmware revert capsule, takes no GUID, no image blob\n" "\t-o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff\n" + "\t-D, --dump-capsule dump the contents of the capsule headers\n" "\t-h, --help print a help message\n", tool_name); } @@ -647,6 +649,215 @@ err: return ret; }
+static void print_guid(void *ptr) +{ + int i; + efi_guid_t *guid = ptr; + const uint8_t seq[] = { + 3, 2, 1, 0, '-', 5, 4, '-', 7, 6, + '-', 8, 9, '-', 10, 11, 12, 13, 14, 15 }; + + for (i = 0; i < ARRAY_SIZE(seq); i++) { + if (seq[i] == '-') + putchar(seq[i]); + else + printf("%02X", guid->b[seq[i]]); + } + + printf("\n"); +} + +static uint32_t dump_fmp_payload_header( + struct fmp_payload_header *fmp_payload_hdr) +{ + if (fmp_payload_hdr->signature == FMP_PAYLOAD_HDR_SIGNATURE) { + printf("--------\n"); + printf("FMP_PAYLOAD_HDR.SIGNATURE\t\t\t: %08X\n", + FMP_PAYLOAD_HDR_SIGNATURE); + printf("FMP_PAYLOAD_HDR.HEADER_SIZE\t\t\t: %08X\n", + fmp_payload_hdr->header_size); + printf("FMP_PAYLOAD_HDR.FW_VERSION\t\t\t: %08X\n", + fmp_payload_hdr->fw_version); + printf("FMP_PAYLOAD_HDR.LOWEST_SUPPORTED_VERSION\t: %08X\n", + fmp_payload_hdr->lowest_supported_version); + return fmp_payload_hdr->header_size; + } + + return 0; +} + +static void dump_capsule_auth_header( + struct efi_firmware_image_authentication *capsule_auth_hdr) +{ + printf("EFI_FIRMWARE_IMAGE_AUTH.MONOTONIC_COUNT\t\t: %08lX\n", + capsule_auth_hdr->monotonic_count); + printf("EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.HDR.dwLENGTH\t: %08X\n", + capsule_auth_hdr->auth_info.hdr.dwLength); + printf("EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.HDR.wREVISION\t: %08X\n", + capsule_auth_hdr->auth_info.hdr.wRevision); + printf("EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.HDR.wCERTTYPE\t: %08X\n", + capsule_auth_hdr->auth_info.hdr.wCertificateType); + printf("EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.CERT_TYPE\t: "); + print_guid(&capsule_auth_hdr->auth_info.cert_type); +} + +static void dump_fmp_capsule_image_header( + struct efi_firmware_management_capsule_image_header *image_hdr) +{ + void *capsule_auth_hdr; + void *fmp_payload_hdr; + uint64_t signature_size = 0; + uint32_t payload_size = 0; + uint32_t fmp_payload_hdr_size = 0; + struct efi_firmware_image_authentication *auth_hdr; + + printf("--------\n"); + printf("FMP_CAPSULE_IMAGE_HDR.VERSION\t\t\t: %08X\n", + image_hdr->version); + printf("FMP_CAPSULE_IMAGE_HDR.UPDATE_IMAGE_TYPE_ID\t: "); + print_guid(&image_hdr->update_image_type_id); + printf("FMP_CAPSULE_IMAGE_HDR.UPDATE_IMAGE_INDEX\t: %08X\n", + image_hdr->update_image_index); + printf("FMP_CAPSULE_IMAGE_HDR.UPDATE_IMAGE_SIZE\t\t: %08X\n", + image_hdr->update_image_size); + printf("FMP_CAPSULE_IMAGE_HDR.UPDATE_VENDOR_CODE_SIZE\t: %08X\n", + image_hdr->update_vendor_code_size); + printf("FMP_CAPSULE_IMAGE_HDR.UPDATE_HARDWARE_INSTANCE\t: %08lX\n", + image_hdr->update_hardware_instance); + printf("FMP_CAPSULE_IMAGE_HDR.IMAGE_CAPSULE_SUPPORT\t: %08lX\n", + image_hdr->image_capsule_support); + + printf("--------\n"); + if (image_hdr->image_capsule_support & CAPSULE_SUPPORT_AUTHENTICATION) { + capsule_auth_hdr = (char *)image_hdr + sizeof(*image_hdr); + dump_capsule_auth_header(capsule_auth_hdr); + + auth_hdr = capsule_auth_hdr; + signature_size = sizeof(auth_hdr->monotonic_count) + + auth_hdr->auth_info.hdr.dwLength; + fmp_payload_hdr = (char *)capsule_auth_hdr + signature_size; + } else { + printf("Capsule Authentication Not Enabled\n"); + fmp_payload_hdr = (char *)image_hdr + sizeof(*image_hdr); + } + + fmp_payload_hdr_size = dump_fmp_payload_header(fmp_payload_hdr); + + payload_size = image_hdr->update_image_size - signature_size - + fmp_payload_hdr_size; + printf("--------\n"); + printf("Payload Image Size\t\t\t\t: %08X\n", payload_size); +} + +static void dump_fmp_header( + struct efi_firmware_management_capsule_header *fmp_hdr) +{ + int i; + void *capsule_image_hdr; + + printf("EFI_FMP_HDR.VERSION\t\t\t\t: %08X\n", fmp_hdr->version); + printf("EFI_FMP_HDR.EMBEDDED_DRIVER_COUNT\t\t: %08X\n", + fmp_hdr->embedded_driver_count); + printf("EFI_FMP_HDR.PAYLOAD_ITEM_COUNT\t\t\t: %08X\n", + fmp_hdr->payload_item_count); + + /* + * We currently don't support Embedded Drivers. + * Only worry about the payload items. + */ + for (i = 0; i < fmp_hdr->payload_item_count; i++) { + capsule_image_hdr = (char *)fmp_hdr + + fmp_hdr->item_offset_list[i]; + dump_fmp_capsule_image_header(capsule_image_hdr); + } +} + +static void dump_capsule_header(struct efi_capsule_header *capsule_hdr) +{ + printf("EFI_CAPSULE_HDR.CAPSULE_GUID\t\t\t: "); + print_guid((void *)&capsule_hdr->capsule_guid); + printf("EFI_CAPSULE_HDR.HEADER_SIZE\t\t\t: %08X\n", + capsule_hdr->header_size); + printf("EFI_CAPSULE_HDR.FLAGS\t\t\t\t: %08X\n", capsule_hdr->flags); + printf("EFI_CAPSULE_HDR.CAPSULE_IMAGE_SIZE\t\t: %08X\n", + capsule_hdr->capsule_image_size); +} + +static void normal_capsule_dump(void *capsule_buf) +{ + void *fmp_hdr; + struct efi_capsule_header *hdr = capsule_buf; + + dump_capsule_header(hdr); + printf("--------\n"); + + fmp_hdr = (char *)capsule_buf + sizeof(*hdr); + dump_fmp_header(fmp_hdr); +} + +static void empty_capsule_dump(void *capsule_buf) +{ + efi_guid_t *accept_image_guid; + struct efi_capsule_header *hdr = capsule_buf; + efi_guid_t efi_empty_accept_capsule = FW_ACCEPT_OS_GUID; + + dump_capsule_header(hdr); + + if (!memcmp(&efi_empty_accept_capsule, &hdr->capsule_guid, + sizeof(efi_guid_t))) { + accept_image_guid = (void *)(char *)capsule_buf + + sizeof(struct efi_capsule_header); + printf("--------\n"); + printf("ACCEPT_IMAGE_GUID\t\t\t\t: "); + print_guid(accept_image_guid); + } +} + +static void dump_capsule_contents(char *capsule_file) +{ + int fd; + char *ptr; + efi_guid_t efi_fmp_guid = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; + efi_guid_t efi_empty_accept_capsule = FW_ACCEPT_OS_GUID; + efi_guid_t efi_empty_revert_capsule = FW_REVERT_OS_GUID; + struct stat sbuf; + + if (!capsule_file) { + fprintf(stderr, "No capsule file provided\n"); + exit(EXIT_FAILURE); + } + + if ((fd = open(capsule_file, O_RDONLY)) < 0) { + fprintf(stderr, "Error opening capsule file: %s\n", + capsule_file); + exit(EXIT_FAILURE); + } + + if (fstat(fd, &sbuf) < 0) { + fprintf(stderr, "Can't stat capsule file: %s\n", capsule_file); + exit(EXIT_FAILURE); + } + + if ((ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0)) + == MAP_FAILED) { + fprintf(stderr, "Can't mmap capsule file: %s\n", capsule_file); + exit(EXIT_FAILURE); + } + + if (!memcmp(&efi_fmp_guid, ptr, sizeof(efi_guid_t))) { + normal_capsule_dump(ptr); + } else if (!memcmp(&efi_empty_accept_capsule, ptr, + sizeof(efi_guid_t)) || + !memcmp(&efi_empty_revert_capsule, ptr, + sizeof(efi_guid_t))) { + empty_capsule_dump(ptr); + } else { + fprintf(stderr, "Unable to decode the capsule file: %s\n", + capsule_file); + exit(EXIT_FAILURE); + } +} + /** * main - main entry function of mkeficapsule * @argc: Number of arguments @@ -666,6 +877,7 @@ int main(int argc, char **argv) unsigned long index, instance; uint64_t mcount; unsigned long oemflags; + bool capsule_dump; char *privkey_file, *cert_file; int c, idx; struct fmp_payload_header_params fmp_ph_params = { 0 }; @@ -676,6 +888,7 @@ int main(int argc, char **argv) mcount = 0; privkey_file = NULL; cert_file = NULL; + capsule_dump = false; dump_sig = 0; capsule_type = CAPSULE_NORMAL_BLOB; oemflags = 0; @@ -754,12 +967,24 @@ int main(int argc, char **argv) exit(1); } break; + case 'D': + capsule_dump = true; + break; default: print_usage(); exit(EXIT_SUCCESS); } }
+ if (capsule_dump) { + if (argc != optind + 1) { + fprintf(stderr, "Must provide the capsule file to parse\n"); + exit(EXIT_FAILURE); + } + dump_capsule_contents(argv[argc - 1]); + exit(EXIT_SUCCESS); + } + /* check necessary parameters */ if ((capsule_type == CAPSULE_NORMAL_BLOB && ((argc != optind + 2) || !guid ||

Add support to dump the contents of capsule headers. This is useful as a debug feature for checking the contents of the capsule headers, and can also be used in capsule verification.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- Changes since V1: * Get rid of the superfluous hdr_size variable in the dump_fmp_payload_header() function
tools/eficapsule.h | 2 + tools/mkeficapsule.c | 227 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 228 insertions(+), 1 deletion(-)
Applied to u-boot-dm, thanks!

Add documentation to explain the printing of the capsule headers through the mkeficapsule tool.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- Changes since V1: None
doc/develop/uefi/uefi.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index 68f9b332d1..f16580e169 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -385,6 +385,23 @@ capsules. Refer :ref:`etype_efi_capsule` for documentation about the efi-capsule binman entry type, which describes all the properties that can be specified.
+Dumping capsule headers +*********************** + +The mkeficapsule tool also provides a command-line option to dump the +contents of the capsule header. This is a useful functionality when +trying to understand the structure of a capsule and is also used in +capsule verification. This feature is used in testing the capsule +contents in binman's test framework. + +To check the contents of the capsule headers, the mkeficapsule command +can be used. + +.. code-block:: console + + $ mkeficapsule --dump-capsule \ + <capsule_file_name> + Performing the update *********************

Add documentation to explain the printing of the capsule headers through the mkeficapsule tool.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org Reviewed-by: Simon Glass sjg@chromium.org --- Changes since V1: None
doc/develop/uefi/uefi.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
Applied to u-boot-dm, thanks!

The #address-cells and #size-cells are not needed for running the capsule generation binman tests. Remove the superfluous properties.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V1: * New patch based on review comment from Simon.
tools/binman/test/311_capsule.dts | 3 --- tools/binman/test/312_capsule_signed.dts | 3 --- tools/binman/test/313_capsule_version.dts | 3 --- tools/binman/test/314_capsule_signed_ver.dts | 3 --- tools/binman/test/315_capsule_oemflags.dts | 3 --- tools/binman/test/316_capsule_missing_key.dts | 3 --- tools/binman/test/317_capsule_missing_index.dts | 3 --- tools/binman/test/318_capsule_missing_guid.dts | 3 --- 8 files changed, 24 deletions(-)
diff --git a/tools/binman/test/311_capsule.dts b/tools/binman/test/311_capsule.dts index 8eb4250b14..0a62ef81dd 100644 --- a/tools/binman/test/311_capsule.dts +++ b/tools/binman/test/311_capsule.dts @@ -3,9 +3,6 @@ /dts-v1/;
/ { - #address-cells = <1>; - #size-cells = <1>; - binman { efi-capsule { image-index = <0x1>; diff --git a/tools/binman/test/312_capsule_signed.dts b/tools/binman/test/312_capsule_signed.dts index d1c76e269c..4ab838efed 100644 --- a/tools/binman/test/312_capsule_signed.dts +++ b/tools/binman/test/312_capsule_signed.dts @@ -3,9 +3,6 @@ /dts-v1/;
/ { - #address-cells = <1>; - #size-cells = <1>; - binman { efi-capsule { image-index = <0x1>; diff --git a/tools/binman/test/313_capsule_version.dts b/tools/binman/test/313_capsule_version.dts index bafef3609e..19e7e83348 100644 --- a/tools/binman/test/313_capsule_version.dts +++ b/tools/binman/test/313_capsule_version.dts @@ -3,9 +3,6 @@ /dts-v1/;
/ { - #address-cells = <1>; - #size-cells = <1>; - binman { efi-capsule { image-index = <0x1>; diff --git a/tools/binman/test/314_capsule_signed_ver.dts b/tools/binman/test/314_capsule_signed_ver.dts index 85c784bba4..649b8ccb2d 100644 --- a/tools/binman/test/314_capsule_signed_ver.dts +++ b/tools/binman/test/314_capsule_signed_ver.dts @@ -3,9 +3,6 @@ /dts-v1/;
/ { - #address-cells = <1>; - #size-cells = <1>; - binman { efi-capsule { image-index = <0x1>; diff --git a/tools/binman/test/315_capsule_oemflags.dts b/tools/binman/test/315_capsule_oemflags.dts index f736e8758f..45853f69c3 100644 --- a/tools/binman/test/315_capsule_oemflags.dts +++ b/tools/binman/test/315_capsule_oemflags.dts @@ -3,9 +3,6 @@ /dts-v1/;
/ { - #address-cells = <1>; - #size-cells = <1>; - binman { efi-capsule { image-index = <0x1>; diff --git a/tools/binman/test/316_capsule_missing_key.dts b/tools/binman/test/316_capsule_missing_key.dts index 2080b50e3d..a14a74ee77 100644 --- a/tools/binman/test/316_capsule_missing_key.dts +++ b/tools/binman/test/316_capsule_missing_key.dts @@ -3,9 +3,6 @@ /dts-v1/;
/ { - #address-cells = <1>; - #size-cells = <1>; - binman { efi-capsule { image-index = <0x1>; diff --git a/tools/binman/test/317_capsule_missing_index.dts b/tools/binman/test/317_capsule_missing_index.dts index aadb61f647..99a54d55c3 100644 --- a/tools/binman/test/317_capsule_missing_index.dts +++ b/tools/binman/test/317_capsule_missing_index.dts @@ -3,9 +3,6 @@ /dts-v1/;
/ { - #address-cells = <1>; - #size-cells = <1>; - binman { efi-capsule { /* Image GUID for testing capsule update */ diff --git a/tools/binman/test/318_capsule_missing_guid.dts b/tools/binman/test/318_capsule_missing_guid.dts index d76afba853..85d3317ecb 100644 --- a/tools/binman/test/318_capsule_missing_guid.dts +++ b/tools/binman/test/318_capsule_missing_guid.dts @@ -3,9 +3,6 @@ /dts-v1/;
/ { - #address-cells = <1>; - #size-cells = <1>; - binman { efi-capsule { image-index = <0x1>;

On Tue, 10 Oct 2023 at 02:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
The #address-cells and #size-cells are not needed for running the capsule generation binman tests. Remove the superfluous properties.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
Changes since V1:
- New patch based on review comment from Simon.
tools/binman/test/311_capsule.dts | 3 --- tools/binman/test/312_capsule_signed.dts | 3 --- tools/binman/test/313_capsule_version.dts | 3 --- tools/binman/test/314_capsule_signed_ver.dts | 3 --- tools/binman/test/315_capsule_oemflags.dts | 3 --- tools/binman/test/316_capsule_missing_key.dts | 3 --- tools/binman/test/317_capsule_missing_index.dts | 3 --- tools/binman/test/318_capsule_missing_guid.dts | 3 --- 8 files changed, 24 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Tue, 10 Oct 2023 at 02:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
The #address-cells and #size-cells are not needed for running the capsule generation binman tests. Remove the superfluous properties.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
Changes since V1:
- New patch based on review comment from Simon.
tools/binman/test/311_capsule.dts | 3 --- tools/binman/test/312_capsule_signed.dts | 3 --- tools/binman/test/313_capsule_version.dts | 3 --- tools/binman/test/314_capsule_signed_ver.dts | 3 --- tools/binman/test/315_capsule_oemflags.dts | 3 --- tools/binman/test/316_capsule_missing_key.dts | 3 --- tools/binman/test/317_capsule_missing_index.dts | 3 --- tools/binman/test/318_capsule_missing_guid.dts | 3 --- 8 files changed, 24 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm, thanks!

The various fields of a generated capsule are currently verified through hard-coded offsets. Use the dump-capsule feature for dumping the capsule header contents and use those for capsule verification.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V1: * Move the get_binman_test_guid() function outside the Entry_efi_capsule class so that it can be called from outside the module. * Use lowercase characters in the GUID values * Add comments for the _GetCapsuleHeaders() function. * Use a simple dict in _GetCapsuleHeaders() for storing the capsule header values dumped by the mkeficapsule tool.
tools/binman/etype/efi_capsule.py | 24 +++++-- tools/binman/ftest.py | 105 ++++++++++++++++++------------ 2 files changed, 82 insertions(+), 47 deletions(-)
diff --git a/tools/binman/etype/efi_capsule.py b/tools/binman/etype/efi_capsule.py index 006eb630ad..e320371782 100644 --- a/tools/binman/etype/efi_capsule.py +++ b/tools/binman/etype/efi_capsule.py @@ -11,6 +11,24 @@ from binman.etype.section import Entry_section from dtoc import fdt_util from u_boot_pylib import tools
+def get_binman_test_guid(type_str): + """Get the test image GUID for binman + + Based on the string passed to the function, return + the corresponding GUID. + + Args: + type_str: Key value of the type of GUID to look for + + Returns: + The actual GUID value (str) + """ + TYPE_TO_GUID = { + 'binman-test' : '09d7cf52-0720-4710-91d1-08469b7fe9c8' + } + + return TYPE_TO_GUID[type_str] + class Entry_efi_capsule(Entry_section): """Generate EFI capsules
@@ -104,12 +122,6 @@ class Entry_efi_capsule(Entry_section): self.auth = 1
def BuildSectionData(self, required): - def get_binman_test_guid(type_str): - TYPE_TO_GUID = { - 'binman-test' : '09d7cf52-0720-4710-91d1-08469b7fe9c8' - } - return TYPE_TO_GUID[type_str] - private_key = '' public_key_cert = '' if self.auth: diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 8e419645a6..2ea18d2d08 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -121,9 +121,11 @@ COMP_BINTOOLS = ['bzip2', 'gzip', 'lz4', 'lzma_alone', 'lzop', 'xz', 'zstd'] TEE_ADDR = 0x5678
# Firmware Management Protocol(FMP) GUID -FW_MGMT_GUID = 'edd5cb6d2de8444cbda17194199ad92a' +FW_MGMT_GUID = '6dcbd5ed-e82d-4c44-bda1-7194199ad92a' # Image GUID specified in the DTS -CAPSULE_IMAGE_GUID = '52cfd7092007104791d108469b7fe9c8' +CAPSULE_IMAGE_GUID = '09d7cf52-0720-4710-91d1-08469b7fe9c8' +# Windows cert GUID +WIN_CERT_TYPE_EFI_GUID = '4aafd29d-68df-49ee-8aa9-347d375665a7'
class TestFunctional(unittest.TestCase): """Functional tests for binman @@ -7223,52 +7225,73 @@ fdt fdtmap Extract the devicetree blob from the fdtmap self.assertRegex(err, "Image 'image'.*missing bintools.*: bootgen")
+ def _GetCapsuleHeaders(self, data): + """Get the capsule header contents + + Args: + data: Capsule file contents + + Returns: + Dict: + key: Capsule Header name (str) + value: Header field value (str) + """ + capsule_file = os.path.join(self._indir, 'test.capsule') + tools.write_file(capsule_file, data) + + out = tools.run('mkeficapsule', '--dump-capsule', capsule_file) + lines = out.splitlines() + + re_line = re.compile(r'^([^:-\t]*)(?:\t*\s*:\s*(.*))?$') + vals = {} + for line in lines: + mat = re_line.match(line) + if mat: + vals[mat.group(1)] = mat.group(2) + + return vals + def _CheckCapsule(self, data, signed_capsule=False, version_check=False, capoemflags=False): - fmp_signature = "4d535331" # 'M', 'S', 'S', '1' - fmp_size = "10" - fmp_fw_version = "02" - oemflag = "0080" + fmp_signature = "3153534D" # 'M', 'S', 'S', '1' + fmp_size = "00000010" + fmp_fw_version = "00000002" + capsule_image_index = "00000001" + oemflag = "00018000" + auth_hdr_revision = "00000200" + auth_hdr_cert_type = "00000EF1" + + payload_data_len = len(EFI_CAPSULE_DATA)
- payload_data = EFI_CAPSULE_DATA + hdr = self._GetCapsuleHeaders(data)
- # TODO - Currently, these offsets for capsule fields are hardcoded. - # There are plans to add support to the mkeficapsule tool to dump - # the capsule contents which can then be used for capsule - # verification. + self.assertEqual(FW_MGMT_GUID.upper(), hdr['EFI_CAPSULE_HDR.CAPSULE_GUID'])
- # Firmware Management Protocol(FMP) GUID - offset(0 - 32) - self.assertEqual(FW_MGMT_GUID, data.hex()[:32]) - # Image GUID - offset(96 - 128) - self.assertEqual(CAPSULE_IMAGE_GUID, data.hex()[96:128]) + self.assertEqual(CAPSULE_IMAGE_GUID.upper(), + hdr['FMP_CAPSULE_IMAGE_HDR.UPDATE_IMAGE_TYPE_ID']) + self.assertEqual(capsule_image_index, + hdr['FMP_CAPSULE_IMAGE_HDR.UPDATE_IMAGE_INDEX'])
if capoemflags: - # OEM Flags - offset(40 - 44) - self.assertEqual(oemflag, data.hex()[40:44]) - if signed_capsule and version_check: - # FMP header signature - offset(4770 - 4778) - self.assertEqual(fmp_signature, data.hex()[4770:4778]) - # FMP header size - offset(4778 - 4780) - self.assertEqual(fmp_size, data.hex()[4778:4780]) - # firmware version - offset(4786 - 4788) - self.assertEqual(fmp_fw_version, data.hex()[4786:4788]) - # payload offset signed capsule(4802 - 4808) - self.assertEqual(payload_data.hex(), data.hex()[4802:4808]) - elif signed_capsule: - # payload offset signed capsule(4770 - 4776) - self.assertEqual(payload_data.hex(), data.hex()[4770:4776]) - elif version_check: - # FMP header signature - offset(184 - 192) - self.assertEqual(fmp_signature, data.hex()[184:192]) - # FMP header size - offset(192 - 194) - self.assertEqual(fmp_size, data.hex()[192:194]) - # firmware version - offset(200 - 202) - self.assertEqual(fmp_fw_version, data.hex()[200:202]) - # payload offset for non-signed capsule with version header(216 - 222) - self.assertEqual(payload_data.hex(), data.hex()[216:222]) - else: - # payload offset for non-signed capsule with no version header(184 - 190) - self.assertEqual(payload_data.hex(), data.hex()[184:190]) + self.assertEqual(oemflag, hdr['EFI_CAPSULE_HDR.FLAGS']) + + if signed_capsule: + self.assertEqual(auth_hdr_revision, + hdr['EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.HDR.wREVISION']) + self.assertEqual(auth_hdr_cert_type, + hdr['EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.HDR.wCERTTYPE']) + self.assertEqual(WIN_CERT_TYPE_EFI_GUID.upper(), + hdr['EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.CERT_TYPE']) + + if version_check: + self.assertEqual(fmp_signature, + hdr['FMP_PAYLOAD_HDR.SIGNATURE']) + self.assertEqual(fmp_size, + hdr['FMP_PAYLOAD_HDR.HEADER_SIZE']) + self.assertEqual(fmp_fw_version, + hdr['FMP_PAYLOAD_HDR.FW_VERSION']) + + self.assertEqual(payload_data_len, int(hdr['Payload Image Size']))
def testCapsuleGen(self): """Test generation of EFI capsule"""

On Tue, 10 Oct 2023 at 02:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
The various fields of a generated capsule are currently verified through hard-coded offsets. Use the dump-capsule feature for dumping the capsule header contents and use those for capsule verification.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
Changes since V1:
- Move the get_binman_test_guid() function outside the Entry_efi_capsule class so that it can be called from outside the module.
- Use lowercase characters in the GUID values
- Add comments for the _GetCapsuleHeaders() function.
- Use a simple dict in _GetCapsuleHeaders() for storing the capsule header values dumped by the mkeficapsule tool.
tools/binman/etype/efi_capsule.py | 24 +++++-- tools/binman/ftest.py | 105 ++++++++++++++++++------------ 2 files changed, 82 insertions(+), 47 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Tue, 10 Oct 2023 at 02:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
The various fields of a generated capsule are currently verified through hard-coded offsets. Use the dump-capsule feature for dumping the capsule header contents and use those for capsule verification.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
Changes since V1:
- Move the get_binman_test_guid() function outside the Entry_efi_capsule class so that it can be called from outside the module.
- Use lowercase characters in the GUID values
- Add comments for the _GetCapsuleHeaders() function.
- Use a simple dict in _GetCapsuleHeaders() for storing the capsule header values dumped by the mkeficapsule tool.
tools/binman/etype/efi_capsule.py | 24 +++++-- tools/binman/ftest.py | 105 ++++++++++++++++++------------ 2 files changed, 82 insertions(+), 47 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm, thanks!

Add a method to the mkeficapsule bintool to generate empty capsules. These are capsules needed for the FWU A/B update feature.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V1: * Use a single boolean value to indicate the generation of either of accept/revert capsule. * Move the parameters added to the list on the same line in a couple of places.
tools/binman/btool/mkeficapsule.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py index 61179747ff..ef1da638df 100644 --- a/tools/binman/btool/mkeficapsule.py +++ b/tools/binman/btool/mkeficapsule.py @@ -80,6 +80,32 @@ class Bintoolmkeficapsule(bintool.Bintool):
return self.run_cmd(*args)
+ def generate_empty_capsule(self, image_guid, output_fname, + accept=True): + """Generate empty capsules for FWU A/B updates + + Args: + image_guid (str): GUID used for identifying the image + in case of an accept capsule + output_fname (str): Path to the output capsule file + accept (bool): Generate an accept capsule, + else a revert capsule + + Returns: + str: Tool output + """ + if accept: + args = [ + f'--guid={image_guid}', + '--fw-accept' + ] + else: + args = [ '--fw-revert' ] + + args += [ output_fname ] + + return self.run_cmd(*args) + def fetch(self, method): """Fetch handler for mkeficapsule

On Tue, 10 Oct 2023 at 02:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
Add a method to the mkeficapsule bintool to generate empty capsules. These are capsules needed for the FWU A/B update feature.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
Changes since V1:
- Use a single boolean value to indicate the generation of either of accept/revert capsule.
- Move the parameters added to the list on the same line in a couple of places.
tools/binman/btool/mkeficapsule.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

On Tue, 10 Oct 2023 at 02:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
Add a method to the mkeficapsule bintool to generate empty capsules. These are capsules needed for the FWU A/B update feature.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
Changes since V1:
- Use a single boolean value to indicate the generation of either of accept/revert capsule.
- Move the parameters added to the list on the same line in a couple of places.
tools/binman/btool/mkeficapsule.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm, thanks!

Add support in binman for generating EFI empty capsules. These capsules are used in the FWU A/B update feature. Also add test cases in binman for the corresponding code coverage.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V1: * Instead of using two separate boolean values, use a 'capsule-type' property for indicating generation of an accept/revert capsule. * Make corresponding changes in the sanity checks, documentation and tests based on the above change. * Use lower case characters for GUIDs. * Call get_binman_test_guid() from the efi_capsule entry module. * Add the documentation entry for the empty capsules in entries.rst. * Remove the #[address,size]-cells properties from the test dts' for empty capsules.
tools/binman/entries.rst | 44 ++++++++++ tools/binman/etype/efi_empty_capsule.py | 86 +++++++++++++++++++ tools/binman/ftest.py | 57 ++++++++++++ tools/binman/test/319_capsule_accept.dts | 13 +++ tools/binman/test/320_capsule_revert.dts | 11 +++ .../test/321_capsule_accept_missing_guid.dts | 11 +++ .../test/322_empty_capsule_type_missing.dts | 12 +++ .../323_capsule_accept_revert_missing.dts | 13 +++ 8 files changed, 247 insertions(+) create mode 100644 tools/binman/etype/efi_empty_capsule.py create mode 100644 tools/binman/test/319_capsule_accept.dts create mode 100644 tools/binman/test/320_capsule_revert.dts create mode 100644 tools/binman/test/321_capsule_accept_missing_guid.dts create mode 100644 tools/binman/test/322_empty_capsule_type_missing.dts create mode 100644 tools/binman/test/323_capsule_accept_revert_missing.dts
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst index 801bd94674..e7b4e9380e 100644 --- a/tools/binman/entries.rst +++ b/tools/binman/entries.rst @@ -532,6 +532,50 @@ payload using the blob-ext subnode.
+.. _etype_efi_empty_capsule: + +Entry: efi-empty-capsule: Entry for generating EFI Empty Capsule files +---------------------------------------------------------------------- + +The parameters needed for generation of the empty capsules can +be provided as properties in the entry. + +Properties / Entry arguments: + - image-guid: Image GUID which will be used for identifying the + updatable image on the board. Mandatory for accept capsule. + - capsule-type - String to indicate type of capsule to generate. Valid + values are 'accept' and 'revert'. + +For more details on the description of the capsule format, and the capsule +update functionality, refer Section 8.5 and Chapter 23 in the `UEFI +specification`_. For more information on the empty capsule, refer the +sections 2.3.2 and 2.3.3 in the `Dependable Boot specification`_. + +A typical accept empty capsule entry node would then look something +like this:: + + empty-capsule { + type = "efi-empty-capsule"; + /* GUID of the image being accepted */ + image-type-id = SANDBOX_UBOOT_IMAGE_GUID; + capsule-type = "accept"; + }; + +A typical revert empty capsule entry node would then look something +like this:: + + empty-capsule { + type = "efi-empty-capsule"; + capsule-type = "revert"; + }; + +The empty capsules do not have any input payload image. + +.. _`UEFI specification`: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf +.. _`Dependable Boot specification`: https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e... + + + .. _etype_encrypted:
Entry: encrypted: Externally built encrypted binary blob diff --git a/tools/binman/etype/efi_empty_capsule.py b/tools/binman/etype/efi_empty_capsule.py new file mode 100644 index 0000000000..064bf9a77f --- /dev/null +++ b/tools/binman/etype/efi_empty_capsule.py @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2023 Linaro Limited +# +# Entry-type module for producing an empty EFI capsule +# + +import os + +from binman.entry import Entry +from binman.etype.efi_capsule import get_binman_test_guid +from binman.etype.section import Entry_section +from dtoc import fdt_util +from u_boot_pylib import tools + +class Entry_efi_empty_capsule(Entry_section): + """Generate EFI empty capsules + + The parameters needed for generation of the empty capsules can + be provided as properties in the entry. + + Properties / Entry arguments: + - image-guid: Image GUID which will be used for identifying the + updatable image on the board. Mandatory for accept capsule. + - capsule-type - String to indicate type of capsule to generate. Valid + values are 'accept' and 'revert'. + + For more details on the description of the capsule format, and the capsule + update functionality, refer Section 8.5 and Chapter 23 in the `UEFI + specification`_. For more information on the empty capsule, refer the + sections 2.3.2 and 2.3.3 in the `Dependable Boot specification`_. + + A typical accept empty capsule entry node would then look something like this + + empty-capsule { + type = "efi-empty-capsule"; + /* GUID of image being accepted */ + image-type-id = SANDBOX_UBOOT_IMAGE_GUID; + capsule-type = "accept"; + }; + + A typical revert empty capsule entry node would then look something like this + + empty-capsule { + type = "efi-empty-capsule"; + capsule-type = "revert"; + }; + + The empty capsules do not have any input payload image. + + .. _`UEFI specification`: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf + .. _`Dependable Boot specification`: https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e... + """ + def __init__(self, section, etype, node): + super().__init__(section, etype, node) + self.required_props = ['capsule-type'] + self.accept = 0 + self.revert = 0 + + def ReadNode(self): + super().ReadNode() + + self.image_guid = fdt_util.GetString(self._node, 'image-guid') + self.capsule_type = fdt_util.GetString(self._node, 'capsule-type') + + if self.capsule_type != 'accept' and self.capsule_type != 'revert': + self.Raise('capsule-type should be either 'accept' or 'revert'') + + if self.capsule_type == 'accept' and not self.image_guid: + self.Raise('Image GUID needed for generating accept capsule') + + def BuildSectionData(self, required): + uniq = self.GetUniqueName() + outfile = self._filename if self._filename else 'capsule.%s' % uniq + capsule_fname = tools.get_output_filename(outfile) + accept = True if self.capsule_type == 'accept' else False + guid = self.image_guid + if self.image_guid == "binman-test": + guid = get_binman_test_guid('binman-test') + + ret = self.mkeficapsule.generate_empty_capsule(guid, capsule_fname, + accept) + if ret is not None: + return tools.read_file(capsule_fname) + + def AddBintools(self, btools): + self.mkeficapsule = self.AddBintool(btools, 'mkeficapsule') diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 2ea18d2d08..16156b7410 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -126,6 +126,9 @@ FW_MGMT_GUID = '6dcbd5ed-e82d-4c44-bda1-7194199ad92a' CAPSULE_IMAGE_GUID = '09d7cf52-0720-4710-91d1-08469b7fe9c8' # Windows cert GUID WIN_CERT_TYPE_EFI_GUID = '4aafd29d-68df-49ee-8aa9-347d375665a7' +# Empty capsule GUIDs +EMPTY_CAPSULE_ACCEPT_GUID = '0c996046-bcc0-4d04-85ec-e1fcedf1c6f8' +EMPTY_CAPSULE_REVERT_GUID = 'acd58b4b-c0e8-475f-99b5-6b3f7e07aaf0'
class TestFunctional(unittest.TestCase): """Functional tests for binman @@ -7293,6 +7296,27 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self.assertEqual(payload_data_len, int(hdr['Payload Image Size']))
+ def _CheckEmptyCapsule(self, data, accept_capsule=False): + if accept_capsule: + capsule_hdr_guid = EMPTY_CAPSULE_ACCEPT_GUID + else: + capsule_hdr_guid = EMPTY_CAPSULE_REVERT_GUID + + hdr = self._GetCapsuleHeaders(data) + + self.assertEqual(capsule_hdr_guid.upper(), + hdr['EFI_CAPSULE_HDR.CAPSULE_GUID']) + + if accept_capsule: + capsule_size = "0000002C" + else: + capsule_size = "0000001C" + self.assertEqual(capsule_size, + hdr['EFI_CAPSULE_HDR.CAPSULE_IMAGE_SIZE']) + + if accept_capsule: + self.assertEqual(CAPSULE_IMAGE_GUID.upper(), hdr['ACCEPT_IMAGE_GUID']) + def testCapsuleGen(self): """Test generation of EFI capsule""" data = self._DoReadFile('311_capsule.dts') @@ -7357,5 +7381,38 @@ fdt fdtmap Extract the devicetree blob from the fdtmap self.assertIn("entry is missing properties: image-guid", str(e.exception))
+ def testCapsuleGenAcceptCapsule(self): + """Test generationg of accept EFI capsule""" + data = self._DoReadFile('319_capsule_accept.dts') + + self._CheckEmptyCapsule(data, accept_capsule=True) + + def testCapsuleGenRevertCapsule(self): + """Test generationg of revert EFI capsule""" + data = self._DoReadFile('320_capsule_revert.dts') + + self._CheckEmptyCapsule(data) + + def testCapsuleGenAcceptGuidMissing(self): + """Test that binman errors out on missing image GUID for accept capsule""" + with self.assertRaises(ValueError) as e: + self._DoReadFile('321_capsule_accept_missing_guid.dts') + + self.assertIn("Image GUID needed for generating accept capsule", + str(e.exception)) + + def testCapsuleGenEmptyCapsuleTypeMissing(self): + """Test that capsule-type is specified""" + with self.assertRaises(ValueError) as e: + self._DoReadFile('322_empty_capsule_type_missing.dts') + + self.assertIn("entry is missing properties: capsule-type", + str(e.exception)) + + def testCapsuleGenAcceptOrRevertMissing(self): + """Test that both accept and revert capsule are not specified""" + with self.assertRaises(ValueError) as e: + self._DoReadFile('323_capsule_accept_revert_missing.dts') + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/319_capsule_accept.dts b/tools/binman/test/319_capsule_accept.dts new file mode 100644 index 0000000000..d48e59f859 --- /dev/null +++ b/tools/binman/test/319_capsule_accept.dts @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + binman { + efi-empty-capsule { + /* Image GUID for testing capsule update */ + image-guid = "binman-test"; + capsule-type = "accept"; + }; + }; +}; diff --git a/tools/binman/test/320_capsule_revert.dts b/tools/binman/test/320_capsule_revert.dts new file mode 100644 index 0000000000..bd141ef292 --- /dev/null +++ b/tools/binman/test/320_capsule_revert.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + binman { + efi-empty-capsule { + capsule-type = "revert"; + }; + }; +}; diff --git a/tools/binman/test/321_capsule_accept_missing_guid.dts b/tools/binman/test/321_capsule_accept_missing_guid.dts new file mode 100644 index 0000000000..a0088b174c --- /dev/null +++ b/tools/binman/test/321_capsule_accept_missing_guid.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + binman { + efi-empty-capsule { + capsule-type = "accept"; + }; + }; +}; diff --git a/tools/binman/test/322_empty_capsule_type_missing.dts b/tools/binman/test/322_empty_capsule_type_missing.dts new file mode 100644 index 0000000000..d356168e77 --- /dev/null +++ b/tools/binman/test/322_empty_capsule_type_missing.dts @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + binman { + efi-empty-capsule { + /* Image GUID for testing capsule update */ + image-guid = "binman-test"; + }; + }; +}; diff --git a/tools/binman/test/323_capsule_accept_revert_missing.dts b/tools/binman/test/323_capsule_accept_revert_missing.dts new file mode 100644 index 0000000000..31268b20b8 --- /dev/null +++ b/tools/binman/test/323_capsule_accept_revert_missing.dts @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + binman { + efi-empty-capsule { + /* Image GUID for testing capsule update */ + image-guid = "binman-test"; + capsule-type = "foo"; + }; + }; +};

On Tue, 10 Oct 2023 at 02:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
Add support in binman for generating EFI empty capsules. These capsules are used in the FWU A/B update feature. Also add test cases in binman for the corresponding code coverage.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
Changes since V1:
- Instead of using two separate boolean values, use a 'capsule-type' property for indicating generation of an accept/revert capsule.
- Make corresponding changes in the sanity checks, documentation and tests based on the above change.
- Use lower case characters for GUIDs.
- Call get_binman_test_guid() from the efi_capsule entry module.
- Add the documentation entry for the empty capsules in entries.rst.
- Remove the #[address,size]-cells properties from the test dts' for empty capsules.
tools/binman/entries.rst | 44 ++++++++++ tools/binman/etype/efi_empty_capsule.py | 86 +++++++++++++++++++ tools/binman/ftest.py | 57 ++++++++++++ tools/binman/test/319_capsule_accept.dts | 13 +++ tools/binman/test/320_capsule_revert.dts | 11 +++ .../test/321_capsule_accept_missing_guid.dts | 11 +++ .../test/322_empty_capsule_type_missing.dts | 12 +++ .../323_capsule_accept_revert_missing.dts | 13 +++ 8 files changed, 247 insertions(+) create mode 100644 tools/binman/etype/efi_empty_capsule.py create mode 100644 tools/binman/test/319_capsule_accept.dts create mode 100644 tools/binman/test/320_capsule_revert.dts create mode 100644 tools/binman/test/321_capsule_accept_missing_guid.dts create mode 100644 tools/binman/test/322_empty_capsule_type_missing.dts create mode 100644 tools/binman/test/323_capsule_accept_revert_missing.dts
Reviewed-by: Simon Glass sjg@chromium.org

On Tue, 10 Oct 2023 at 02:12, Sughosh Ganu sughosh.ganu@linaro.org wrote:
Add support in binman for generating EFI empty capsules. These capsules are used in the FWU A/B update feature. Also add test cases in binman for the corresponding code coverage.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
Changes since V1:
- Instead of using two separate boolean values, use a 'capsule-type' property for indicating generation of an accept/revert capsule.
- Make corresponding changes in the sanity checks, documentation and tests based on the above change.
- Use lower case characters for GUIDs.
- Call get_binman_test_guid() from the efi_capsule entry module.
- Add the documentation entry for the empty capsules in entries.rst.
- Remove the #[address,size]-cells properties from the test dts' for empty capsules.
tools/binman/entries.rst | 44 ++++++++++ tools/binman/etype/efi_empty_capsule.py | 86 +++++++++++++++++++ tools/binman/ftest.py | 57 ++++++++++++ tools/binman/test/319_capsule_accept.dts | 13 +++ tools/binman/test/320_capsule_revert.dts | 11 +++ .../test/321_capsule_accept_missing_guid.dts | 11 +++ .../test/322_empty_capsule_type_missing.dts | 12 +++ .../323_capsule_accept_revert_missing.dts | 13 +++ 8 files changed, 247 insertions(+) create mode 100644 tools/binman/etype/efi_empty_capsule.py create mode 100644 tools/binman/test/319_capsule_accept.dts create mode 100644 tools/binman/test/320_capsule_revert.dts create mode 100644 tools/binman/test/321_capsule_accept_missing_guid.dts create mode 100644 tools/binman/test/322_empty_capsule_type_missing.dts create mode 100644 tools/binman/test/323_capsule_accept_revert_missing.dts
Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm, thanks!
participants (2)
-
Simon Glass
-
Sughosh Ganu