From eb7c85176b8539545380b0b119b297a8fbb5f45a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 20 Oct 2022 18:23:03 -0600 Subject: [PATCH] uboot-mtk-20220606: image: Add the concept of a phase to FIT We want to be able to mark an image as related to a phase, so we can easily load all the images for SPL or for U-Boot proper. Add this to the FIT specification, along with some access functions. Signed-off-by: Simon Glass --- uboot-mtk-20220606/boot/image.c | 18 +++++ .../doc/uImage.FIT/source_file_format.txt | 3 + uboot-mtk-20220606/include/image.h | 74 ++++++++++++++++++- uboot-mtk-20220606/test/boot/Makefile | 1 + uboot-mtk-20220606/test/boot/image.c | 36 +++++++++ 5 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 uboot-mtk-20220606/test/boot/image.c diff --git a/uboot-mtk-20220606/boot/image.c b/uboot-mtk-20220606/boot/image.c index 5dcb55ba4..6d5f2e341 100644 --- a/uboot-mtk-20220606/boot/image.c +++ b/uboot-mtk-20220606/boot/image.c @@ -193,6 +193,13 @@ static const table_entry_t uimage_comp[] = { { -1, "", "", }, }; +static const table_entry_t uimage_phase[] = { + { IH_PHASE_NONE, "none", "any", }, + { IH_PHASE_U_BOOT, "u-boot", "U-Boot phase", }, + { IH_PHASE_SPL, "spl", "SPL Phase", }, + { -1, "", "", }, +}; + struct table_info { const char *desc; int count; @@ -214,6 +221,7 @@ static const struct table_info table_info[IH_COUNT] = { { "compression", IH_COMP_COUNT, uimage_comp }, { "operating system", IH_OS_COUNT, uimage_os }, { "image type", IH_TYPE_COUNT, uimage_type }, + { "phase", IH_PHASE_COUNT, uimage_phase }, }; /*****************************************************************************/ @@ -655,6 +663,11 @@ const char *genimg_get_comp_name(uint8_t comp) comp)); } +const char *genimg_get_phase_name(enum image_phase_t phase) +{ + return get_table_entry_name(uimage_phase, "Unknown Phase", phase); +} + static const char *genimg_get_short_name(const table_entry_t *table, int val) { table = get_table_entry(table, val); @@ -730,3 +743,8 @@ int genimg_get_comp_id(const char *name) { return (get_table_entry_id(uimage_comp, "Compression", name)); } + +int genimg_get_phase_id(const char *name) +{ + return get_table_entry_id(uimage_phase, "Phase", name); +} diff --git a/uboot-mtk-20220606/doc/uImage.FIT/source_file_format.txt b/uboot-mtk-20220606/doc/uImage.FIT/source_file_format.txt index f93ac6d1c..7082e891f 100644 --- a/uboot-mtk-20220606/doc/uImage.FIT/source_file_format.txt +++ b/uboot-mtk-20220606/doc/uImage.FIT/source_file_format.txt @@ -185,6 +185,9 @@ the '/images' node should have the following layout: - compatible : compatible method for loading image. Mandatory for types: "fpga", and images that do not specify a load address. To use the generic fpga loading routine, use "u-boot,fpga-legacy". + - phase : U-Boot phase for which the image is intended. + "spl" - image is an SPL image + "u-boot" - image is a U-Boot image Optional nodes: - hash-1 : Each hash sub-node represents separate hash or checksum diff --git a/uboot-mtk-20220606/include/image.h b/uboot-mtk-20220606/include/image.h index 4d8fd2fe7..b4c3c2c90 100644 --- a/uboot-mtk-20220606/include/image.h +++ b/uboot-mtk-20220606/include/image.h @@ -58,6 +58,7 @@ enum ih_category { IH_COMP, IH_OS, IH_TYPE, + IH_PHASE, IH_COUNT, }; @@ -184,8 +185,7 @@ enum { * New IDs *MUST* be appended at the end of the list and *NEVER* * inserted for backward compatibility. */ - -enum { +enum image_type_t { IH_TYPE_INVALID = 0, /* Invalid Image */ IH_TYPE_STANDALONE, /* Standalone Program */ IH_TYPE_KERNEL, /* OS Kernel Image */ @@ -252,6 +252,59 @@ enum { IH_COMP_COUNT, }; +/** + * Phases - images intended for particular U-Boot phases (SPL, etc.) + * + * @IH_PHASE_NONE: No phase information, can be loaded by any phase + * @IH_PHASE_U_BOOT: Only for U-Boot proper + * @IH_PHASE_SPL: Only for SPL + */ +enum image_phase_t { + IH_PHASE_NONE = 0, + IH_PHASE_U_BOOT, + IH_PHASE_SPL, + + IH_PHASE_COUNT, +}; + +#define IMAGE_PHASE_SHIFT 8 +#define IMAGE_PHASE_MASK (0xff << IMAGE_PHASE_SHIFT) +#define IMAGE_TYPE_MASK 0xff + +/** + * image_ph() - build a composite value combining and type + * + * @phase: Image phase value + * @type: Image type value + * Returns: Composite value containing both + */ +static inline int image_ph(enum image_phase_t phase, enum image_type_t type) +{ + return type | (phase << IMAGE_PHASE_SHIFT); +} + +/** + * image_ph_phase() - obtain the phase from a composite phase/type value + * + * @image_ph_type: Composite value to convert + * Returns: Phase value taken from the composite value + */ +static inline int image_ph_phase(int image_ph_type) +{ + return (image_ph_type & IMAGE_PHASE_MASK) >> IMAGE_PHASE_SHIFT; +} + +/** + * image_ph_type() - obtain the type from a composite phase/type value + * + * @image_ph_type: Composite value to convert + * Returns: Type value taken from the composite value + */ +static inline int image_ph_type(int image_ph_type) +{ + return image_ph_type & IMAGE_TYPE_MASK; +} + #define LZ4F_MAGIC 0x184D2204 /* LZ4 Magic Number */ #define IH_MAGIC 0x27051956 /* Image Magic Number */ #define IH_NMLEN 32 /* Image Name Length */ @@ -433,6 +486,22 @@ const char *genimg_get_os_short_name(uint8_t comp); const char *genimg_get_arch_name(uint8_t arch); +/** + * genimg_get_phase_name() - Get the friendly name for a phase + * + * @phase: Phase value to look up + * Returns: Friendly name for the phase (e.g. "U-Boot phase") + */ +const char *genimg_get_phase_name(enum image_phase_t phase); + +/** + * genimg_get_phase_id() - Convert a phase name to an ID + * + * @name: Name to convert (e.g. "u-boot") + * Returns: ID for that phase (e.g. IH_PHASE_U_BOOT) + */ +int genimg_get_phase_id(const char *name); + /** * genimg_get_arch_short_name() - get the short name for an architecture * @@ -947,6 +1016,7 @@ int booti_setup(ulong image, ulong *relocated_addr, ulong *size, #define FIT_FPGA_PROP "fpga" #define FIT_FIRMWARE_PROP "firmware" #define FIT_STANDALONE_PROP "standalone" +#define FIT_PHASE_PROP "phase" #define FIT_FW_AR_VER_PROP "fw_ar_ver" #define FIT_MAX_HASH_LEN HASH_MAX_DIGEST_SIZE diff --git a/uboot-mtk-20220606/test/boot/Makefile b/uboot-mtk-20220606/test/boot/Makefile index 1730792b5..7e1a64bdf 100644 --- a/uboot-mtk-20220606/test/boot/Makefile +++ b/uboot-mtk-20220606/test/boot/Makefile @@ -3,3 +3,4 @@ # Copyright 2021 Google LLC obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o +obj-$(CONFIG_FIT) += image.o diff --git a/uboot-mtk-20220606/test/boot/image.c b/uboot-mtk-20220606/test/boot/image.c new file mode 100644 index 000000000..2844b0578 --- /dev/null +++ b/uboot-mtk-20220606/test/boot/image.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for vbe-simple bootmeth. All start with 'vbe_simple' + * + * Copyright 2023 Google LLC + * Written by Simon Glass + */ + +#include +#include +#include +#include +#include "bootstd_common.h" + +/* Test of image phase */ +static int test_image_phase(struct unit_test_state *uts) +{ + int val; + + ut_asserteq_str("U-Boot phase", genimg_get_phase_name(IH_PHASE_U_BOOT)); + ut_asserteq_str("SPL Phase", genimg_get_phase_name(IH_PHASE_SPL)); + ut_asserteq_str("any", genimg_get_phase_name(IH_PHASE_NONE)); + ut_asserteq_str("Unknown Phase", genimg_get_phase_name(-1)); + + ut_asserteq(IH_PHASE_U_BOOT, genimg_get_phase_id("u-boot")); + ut_asserteq(IH_PHASE_SPL, genimg_get_phase_id("spl")); + ut_asserteq(IH_PHASE_NONE, genimg_get_phase_id("none")); + ut_asserteq(-1, genimg_get_phase_id("fred")); + + val = image_ph(IH_PHASE_SPL, IH_TYPE_FIRMWARE); + ut_asserteq(IH_PHASE_SPL, image_ph_phase(val)); + ut_asserteq(IH_TYPE_FIRMWARE, image_ph_type(val)); + + return 0; +} +BOOTSTD_TEST(test_image_phase, 0);