[PATCH v2 00/18] Support Firmware Handoff spec via bloblist

Major changes:
Update bloblist to align to Firmware Handoff spec v0.9 (https://github.com/FirmwareHandoff/firmware_handoff).
Implement Qemu-Arm platform custom functions to retrieve the bloblist (aka. Transfer List) from previous loader via boot arguments when CONFIG_OF_BOARD option is enabled.
If a board provides both custom functions for getting the bloblist and the address of external FDT, the FDT inside the bloblist will be prioritized during FDT setup.
The patch set is tested with previous done TF-A/OP-TEE patches through a complete Firmware Handoff cycle (BL2, BL31, BL32, BL33). TF-A Patches: feat(handoff): introduce firmware handoff library (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/22215) feat(qemu): implement firmware handoff on qemu (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/22178) feat(handoff): enhance transfer list library (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/23776) feat(optee): enable transfer list in opteed (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/23777) feat(qemu): enable transfer list to BL31/32 (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/23778) OP-TEE Patch: Firmware handoff (https://github.com/OP-TEE/optee_os/pull/6308) fixup of transfer list entry overriding (https://github.com/OP-TEE/optee_os/pull/6461)
Raymond Mao (3): bloblist: Align bloblist used_size and total_size to spec qemu-arm: Get bloblist from boot arguments bloblist: Load the bloblist from the previous loader
Simon Glass (15): bloblist: Update the tag numbering bloblist: Adjust API to align in powers of 2 bloblist: Change the magic value bloblist: Set version to 1 bloblist: Access record hdr_size and tag via a function bloblist: Drop the flags value bloblist: Drop the spare values bloblist: Change the checksum algorithm bloblist: Checksum the entire bloblist bloblist: Handle alignment with a void entry bloblist: Reduce blob-header size bloblist: Reduce bloblist header size bloblist: Add alignment to bloblist_new() bloblist: Update documentation and header comment fdt: Allow the devicetree to come from a bloblist
arch/x86/lib/tables.c | 3 +- board/emulation/qemu-arm/Makefile | 1 + board/emulation/qemu-arm/lowlevel_init.S | 19 ++ board/emulation/qemu-arm/qemu-arm.c | 54 ++++++ common/bloblist.c | 225 +++++++++++++---------- configs/qemu_arm64_defconfig | 3 + configs/qemu_arm_defconfig | 3 + doc/develop/bloblist.rst | 4 +- doc/develop/devicetree/control.rst | 8 +- dts/Kconfig | 9 +- include/bloblist.h | 181 ++++++++++-------- include/fdtdec.h | 3 +- lib/fdtdec.c | 52 ++++-- test/bloblist.c | 86 ++++----- 14 files changed, 420 insertions(+), 231 deletions(-) create mode 100644 board/emulation/qemu-arm/lowlevel_init.S

From: Simon Glass sjg@chromium.org
Align bloblist tags with the FW handoff spec v0.9. The most common ones are from 0. TF related ones are from 0x100. All non-standard ones from 0xfff000.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - Align bloblist tags to FW handoff spec v0.9.
common/bloblist.c | 16 +++++++++--- include/bloblist.h | 65 ++++++++++++++++++++++++---------------------- test/bloblist.c | 4 +-- 3 files changed, 48 insertions(+), 37 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index a22f6c12b0..349ceddea5 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -36,16 +36,24 @@ static struct tag_name { enum bloblist_tag_t tag; const char *name; } tag_name[] = { - { BLOBLISTT_NONE, "(none)" }, + { BLOBLISTT_VOID, "(void)" },
/* BLOBLISTT_AREA_FIRMWARE_TOP */ + { BLOBLISTT_CONTROL_FDT, "Control FDT" }, + { BLOBLISTT_HOB_BLOCK, "HOB block" }, + { BLOBLISTT_HOB_LIST, "HOB list" }, + { BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
/* BLOBLISTT_AREA_FIRMWARE */ - { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" }, - { BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" }, { BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" }, - { BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" }, + { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" }, + + /* BLOBLISTT_AREA_ARM */ + { BLOBLISTT_OPTEE_PAGABLE_PART, "OP-TEE pagable part" }, + + /* BLOBLISTT_AREA_OTHER */ + { BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" }, { BLOBLISTT_SMBIOS_TABLES, "SMBIOS tables for x86" }, { BLOBLISTT_VBOOT_CTX, "Chrome OS vboot context" },
diff --git a/include/bloblist.h b/include/bloblist.h index 080cc46a12..3a2ec91e25 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -81,7 +81,7 @@ enum {
/* Supported tags - add new ones to tag_name in bloblist.c */ enum bloblist_tag_t { - BLOBLISTT_NONE = 0, + BLOBLISTT_VOID = 0,
/* * Standard area to allocate blobs used across firmware components, for @@ -89,42 +89,34 @@ enum bloblist_tag_t { * projects. */ BLOBLISTT_AREA_FIRMWARE_TOP = 0x1, + /* + * Devicetree for use by firmware. On some platforms this is passed to + * the OS also + */ + BLOBLISTT_CONTROL_FDT = 1, + BLOBLISTT_HOB_BLOCK = 2, + BLOBLISTT_HOB_LIST = 3, + BLOBLISTT_ACPI_TABLES = 4,
/* Standard area to allocate blobs used across firmware components */ - BLOBLISTT_AREA_FIRMWARE = 0x100, + BLOBLISTT_AREA_FIRMWARE = 0x10, + BLOBLISTT_TPM2_TCG_LOG = 0x10, /* TPM v2 log space */ + BLOBLISTT_TCPA_LOG = 0x11, /* TPM log space */ /* * Advanced Configuration and Power Interface Global Non-Volatile * Sleeping table. This forms part of the ACPI tables passed to Linux. */ - BLOBLISTT_ACPI_GNVS = 0x100, - BLOBLISTT_INTEL_VBT = 0x101, /* Intel Video-BIOS table */ - BLOBLISTT_TPM2_TCG_LOG = 0x102, /* TPM v2 log space */ - BLOBLISTT_TCPA_LOG = 0x103, /* TPM log space */ - BLOBLISTT_ACPI_TABLES = 0x104, /* ACPI tables for x86 */ - BLOBLISTT_SMBIOS_TABLES = 0x105, /* SMBIOS tables for x86 */ - BLOBLISTT_VBOOT_CTX = 0x106, /* Chromium OS verified boot context */ + BLOBLISTT_ACPI_GNVS = 0x12,
- /* - * Project-specific tags are permitted here. Projects can be open source - * or not, but the format of the data must be fuily documented in an - * open source project, including all fields, bits, etc. Naming should - * be: BLOBLISTT_<project>_<purpose_here> - */ - BLOBLISTT_PROJECT_AREA = 0x8000, - BLOBLISTT_U_BOOT_SPL_HANDOFF = 0x8000, /* Hand-off info from SPL */ - BLOBLISTT_VBE = 0x8001, /* VBE per-phase state */ - BLOBLISTT_U_BOOT_VIDEO = 0x8002, /* Video information from SPL */ - - /* - * Vendor-specific tags are permitted here. Projects can be open source - * or not, but the format of the data must be fuily documented in an - * open source project, including all fields, bits, etc. Naming should - * be BLOBLISTT_<vendor>_<purpose_here> - */ - BLOBLISTT_VENDOR_AREA = 0xc000, + /* Standard area to allocate blobs used for Trusted Firmware */ + BLOBLISTT_AREA_TF = 0x100, + BLOBLISTT_OPTEE_PAGABLE_PART = 0x100,
- /* Tags after this are not allocated for now */ - BLOBLISTT_EXPANSION = 0x10000, + /* Other standard area to allocate blobs */ + BLOBLISTT_AREA_OTHER = 0x200, + BLOBLISTT_INTEL_VBT = 0x200, /* Intel Video-BIOS table */ + BLOBLISTT_SMBIOS_TABLES = 0x201, /* SMBIOS tables for x86 */ + BLOBLISTT_VBOOT_CTX = 0x202, /* Chromium OS verified boot context */
/* * Tags from here are on reserved for private use within a single @@ -133,9 +125,20 @@ enum bloblist_tag_t { * implementation, but cannot be used in upstream code. Allocate a * tag in one of the areas above if you want that. * - * This area may move in future. + * Project-specific tags are permitted here. Projects can be open source + * or not, but the format of the data must be fuily documented in an + * open source project, including all fields, bits, etc. Naming should + * be: BLOBLISTT_<project>_<purpose_here> + * + * Vendor-specific tags are also permitted. Projects can be open source + * or not, but the format of the data must be fuily documented in an + * open source project, including all fields, bits, etc. Naming should + * be BLOBLISTT_<vendor>_<purpose_here> */ - BLOBLISTT_PRIVATE_AREA = 0xffff0000, + BLOBLISTT_PRIVATE_AREA = 0xfff000, + BLOBLISTT_U_BOOT_SPL_HANDOFF = 0xfff000, /* Hand-off info from SPL */ + BLOBLISTT_VBE = 0xfff001, /* VBE per-phase state */ + BLOBLISTT_U_BOOT_VIDEO = 0xfff002, /* Video info from SPL */ };
/** diff --git a/test/bloblist.c b/test/bloblist.c index 720be7e244..efa1e32afd 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -291,9 +291,9 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts) console_record_reset(); run_command("bloblist list", 0); ut_assert_nextline("Address Size Tag Name"); - ut_assert_nextline("%08lx %8x 8000 SPL hand-off", + ut_assert_nextline("%08lx %8x fff000 SPL hand-off", (ulong)map_to_sysmem(data), TEST_SIZE); - ut_assert_nextline("%08lx %8x 106 Chrome OS vboot context", + ut_assert_nextline("%08lx %8x 202 Chrome OS vboot context", (ulong)map_to_sysmem(data2), TEST_SIZE2); ut_assert_console_end(); ut_unsilence_console(uts);

On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
Align bloblist tags with the FW handoff spec v0.9. The most common ones are from 0. TF related ones are from 0x100. All non-standard ones from 0xfff000.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Align bloblist tags to FW handoff spec v0.9.
common/bloblist.c | 16 +++++++++--- include/bloblist.h | 65 ++++++++++++++++++++++++---------------------- test/bloblist.c | 4 +-- 3 files changed, 48 insertions(+), 37 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

Hi all,
[...]
common/bloblist.c | 16 +++++++++--- include/bloblist.h | 65 ++++++++++++++++++++++++---------------------- test/bloblist.c | 4 +-- 3 files changed, 48 insertions(+), 37 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index a22f6c12b0..349ceddea5 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -36,16 +36,24 @@ static struct tag_name { enum bloblist_tag_t tag; const char *name; } tag_name[] = {
{ BLOBLISTT_NONE, "(none)" },
{ BLOBLISTT_VOID, "(void)" }, /* BLOBLISTT_AREA_FIRMWARE_TOP */
{ BLOBLISTT_CONTROL_FDT, "Control FDT" },
{ BLOBLISTT_HOB_BLOCK, "HOB block" },
{ BLOBLISTT_HOB_LIST, "HOB list" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" }, /* BLOBLISTT_AREA_FIRMWARE */
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" }, { BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
There are some TPM Eventlog related entries that are missing here. Can we add them?
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
/* BLOBLISTT_AREA_ARM */
{ BLOBLISTT_OPTEE_PAGABLE_PART, "OP-TEE pagable part" },
/* BLOBLISTT_AREA_OTHER */
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
[...]
Thanks /Ilias

Hi Ilias,
BLOBLISTT_AREA_ARM is now holding the ones we already defined in the FW Handoff spec for TF-A project only. The TPM eventlog related ones are undefined in the spec yet, they stay in the group BLOBLISTT_AREA_FIRMWARE.
/* BLOBLISTT_AREA_FIRMWARE */
- { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
- { BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
{ BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" },
- { BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
- { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
Thanks and regards, Raymond
On Mon, 4 Dec 2023 at 03:25, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi all,
[...]
common/bloblist.c | 16 +++++++++--- include/bloblist.h | 65 ++++++++++++++++++++++++---------------------- test/bloblist.c | 4 +-- 3 files changed, 48 insertions(+), 37 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index a22f6c12b0..349ceddea5 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -36,16 +36,24 @@ static struct tag_name { enum bloblist_tag_t tag; const char *name; } tag_name[] = {
{ BLOBLISTT_NONE, "(none)" },
{ BLOBLISTT_VOID, "(void)" }, /* BLOBLISTT_AREA_FIRMWARE_TOP */
{ BLOBLISTT_CONTROL_FDT, "Control FDT" },
{ BLOBLISTT_HOB_BLOCK, "HOB block" },
{ BLOBLISTT_HOB_LIST, "HOB list" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" }, /* BLOBLISTT_AREA_FIRMWARE */
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" }, { BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
There are some TPM Eventlog related entries that are missing here. Can we add them?
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
/* BLOBLISTT_AREA_ARM */
{ BLOBLISTT_OPTEE_PAGABLE_PART, "OP-TEE pagable part" },
/* BLOBLISTT_AREA_OTHER */
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
[...]
Thanks /Ilias

On Mon, 4 Dec 2023 at 18:25, Raymond Mao raymond.mao@linaro.org wrote:
Hi Ilias,
BLOBLISTT_AREA_ARM is now holding the ones we already defined in the FW Handoff spec for TF-A project only. The TPM eventlog related ones are undefined in the spec yet, they stay in the group BLOBLISTT_AREA_FIRMWARE.
We did define them past 0.9 [0]. So I think we should add them regardless. They are part of the main doc now [1]
[0] https://github.com/FirmwareHandoff/firmware_handoff/pull/16/files [1] https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/transfe...
Regards /Ilias
/* BLOBLISTT_AREA_FIRMWARE */
- { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
- { BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
{ BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" },
- { BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
- { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
Thanks and regards, Raymond
On Mon, 4 Dec 2023 at 03:25, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi all,
[...]
common/bloblist.c | 16 +++++++++--- include/bloblist.h | 65 ++++++++++++++++++++++++---------------------- test/bloblist.c | 4 +-- 3 files changed, 48 insertions(+), 37 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index a22f6c12b0..349ceddea5 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -36,16 +36,24 @@ static struct tag_name { enum bloblist_tag_t tag; const char *name; } tag_name[] = {
{ BLOBLISTT_NONE, "(none)" },
{ BLOBLISTT_VOID, "(void)" }, /* BLOBLISTT_AREA_FIRMWARE_TOP */
{ BLOBLISTT_CONTROL_FDT, "Control FDT" },
{ BLOBLISTT_HOB_BLOCK, "HOB block" },
{ BLOBLISTT_HOB_LIST, "HOB list" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" }, /* BLOBLISTT_AREA_FIRMWARE */
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" }, { BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
There are some TPM Eventlog related entries that are missing here. Can we add them?
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
/* BLOBLISTT_AREA_ARM */
{ BLOBLISTT_OPTEE_PAGABLE_PART, "OP-TEE pagable part" },
/* BLOBLISTT_AREA_OTHER */
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
[...]
Thanks /Ilias

Hi Ilias,
What is the difference between the new added XFERLIST_EVLOG and the existing BLOBLISTT_TPM2_TCG_LOG and BLOBLISTT_TCPA_LOG in U-Boot?
Thanks and regards, Raymond
On Mon, 4 Dec 2023 at 12:52, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
On Mon, 4 Dec 2023 at 18:25, Raymond Mao raymond.mao@linaro.org wrote:
Hi Ilias,
BLOBLISTT_AREA_ARM is now holding the ones we already defined in the FW
Handoff spec for TF-A project only.
The TPM eventlog related ones are undefined in the spec yet, they stay
in the group BLOBLISTT_AREA_FIRMWARE.
We did define them past 0.9 [0]. So I think we should add them regardless. They are part of the main doc now [1]
[0] https://github.com/FirmwareHandoff/firmware_handoff/pull/16/files [1] https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/transfe...
Regards /Ilias
/* BLOBLISTT_AREA_FIRMWARE */
- { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
- { BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
{ BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" },
- { BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
- { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
Thanks and regards, Raymond
On Mon, 4 Dec 2023 at 03:25, Ilias Apalodimas <
ilias.apalodimas@linaro.org> wrote:
Hi all,
[...]
common/bloblist.c | 16 +++++++++--- include/bloblist.h | 65
++++++++++++++++++++++++----------------------
test/bloblist.c | 4 +-- 3 files changed, 48 insertions(+), 37 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index a22f6c12b0..349ceddea5 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -36,16 +36,24 @@ static struct tag_name { enum bloblist_tag_t tag; const char *name; } tag_name[] = {
{ BLOBLISTT_NONE, "(none)" },
{ BLOBLISTT_VOID, "(void)" }, /* BLOBLISTT_AREA_FIRMWARE_TOP */
{ BLOBLISTT_CONTROL_FDT, "Control FDT" },
{ BLOBLISTT_HOB_BLOCK, "HOB block" },
{ BLOBLISTT_HOB_LIST, "HOB list" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" }, /* BLOBLISTT_AREA_FIRMWARE */
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" }, { BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
There are some TPM Eventlog related entries that are missing here. Can we add them?
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
/* BLOBLISTT_AREA_ARM */
{ BLOBLISTT_OPTEE_PAGABLE_PART, "OP-TEE pagable part" },
/* BLOBLISTT_AREA_OTHER */
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
[...]
Thanks /Ilias

On Mon, 4 Dec 2023 at 20:55, Raymond Mao raymond.mao@linaro.org wrote:
Hi Ilias,
What is the difference between the new added XFERLIST_EVLOG and the existing BLOBLISTT_TPM2_TCG_LOG and BLOBLISTT_TCPA_LOG in U-Boot?
I am not really sure what the existing options are supposed to mean. Having discrete options for v1 and v2 makes little sense since the EvenLog format already contains that info.
The newly added options is supposed to - Hand you over an EventLog from a previous stage boot loader, so you can continue extending that instead of creating a new one. We do that already parsing for tpm_event_log_addr, which is what TF-A fills in. In the future we need to add the bloblist option. - Tell you whether you need to replay it or not.
Thanks /Ilias
Thanks and regards, Raymond
On Mon, 4 Dec 2023 at 12:52, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
On Mon, 4 Dec 2023 at 18:25, Raymond Mao raymond.mao@linaro.org wrote:
Hi Ilias,
BLOBLISTT_AREA_ARM is now holding the ones we already defined in the FW Handoff spec for TF-A project only. The TPM eventlog related ones are undefined in the spec yet, they stay in the group BLOBLISTT_AREA_FIRMWARE.
We did define them past 0.9 [0]. So I think we should add them regardless. They are part of the main doc now [1]
[0] https://github.com/FirmwareHandoff/firmware_handoff/pull/16/files [1] https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/transfe...
Regards /Ilias
/* BLOBLISTT_AREA_FIRMWARE */
- { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
- { BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
{ BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" },
- { BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
- { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
Thanks and regards, Raymond
On Mon, 4 Dec 2023 at 03:25, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi all,
[...]
common/bloblist.c | 16 +++++++++--- include/bloblist.h | 65 ++++++++++++++++++++++++---------------------- test/bloblist.c | 4 +-- 3 files changed, 48 insertions(+), 37 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index a22f6c12b0..349ceddea5 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -36,16 +36,24 @@ static struct tag_name { enum bloblist_tag_t tag; const char *name; } tag_name[] = {
{ BLOBLISTT_NONE, "(none)" },
{ BLOBLISTT_VOID, "(void)" }, /* BLOBLISTT_AREA_FIRMWARE_TOP */
{ BLOBLISTT_CONTROL_FDT, "Control FDT" },
{ BLOBLISTT_HOB_BLOCK, "HOB block" },
{ BLOBLISTT_HOB_LIST, "HOB list" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" }, /* BLOBLISTT_AREA_FIRMWARE */
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" }, { BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
There are some TPM Eventlog related entries that are missing here. Can we add them?
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
/* BLOBLISTT_AREA_ARM */
{ BLOBLISTT_OPTEE_PAGABLE_PART, "OP-TEE pagable part" },
/* BLOBLISTT_AREA_OTHER */
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
[...]
Thanks /Ilias

Hi Ilias,
I will add both TPM_EVLOG and TPM_CRB_BASE.
Regards, Raymond
On Wed, 6 Dec 2023 at 05:54, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
On Mon, 4 Dec 2023 at 20:55, Raymond Mao raymond.mao@linaro.org wrote:
Hi Ilias,
What is the difference between the new added XFERLIST_EVLOG and the
existing BLOBLISTT_TPM2_TCG_LOG and BLOBLISTT_TCPA_LOG in U-Boot?
I am not really sure what the existing options are supposed to mean. Having discrete options for v1 and v2 makes little sense since the EvenLog format already contains that info.
The newly added options is supposed to
- Hand you over an EventLog from a previous stage boot loader, so you
can continue extending that instead of creating a new one. We do that already parsing for tpm_event_log_addr, which is what TF-A fills in. In the future we need to add the bloblist option.
- Tell you whether you need to replay it or not.
Thanks /Ilias
Thanks and regards, Raymond
On Mon, 4 Dec 2023 at 12:52, Ilias Apalodimas <
ilias.apalodimas@linaro.org> wrote:
On Mon, 4 Dec 2023 at 18:25, Raymond Mao raymond.mao@linaro.org
wrote:
Hi Ilias,
BLOBLISTT_AREA_ARM is now holding the ones we already defined in the
FW Handoff spec for TF-A project only.
The TPM eventlog related ones are undefined in the spec yet, they
stay in the group BLOBLISTT_AREA_FIRMWARE.
We did define them past 0.9 [0]. So I think we should add them
regardless.
They are part of the main doc now [1]
[0] https://github.com/FirmwareHandoff/firmware_handoff/pull/16/files [1]
https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/transfe...
Regards /Ilias
/* BLOBLISTT_AREA_FIRMWARE */
- { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
- { BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
{ BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" },
- { BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
- { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
Thanks and regards, Raymond
On Mon, 4 Dec 2023 at 03:25, Ilias Apalodimas <
ilias.apalodimas@linaro.org> wrote:
Hi all,
[...]
common/bloblist.c | 16 +++++++++--- include/bloblist.h | 65
++++++++++++++++++++++++----------------------
test/bloblist.c | 4 +-- 3 files changed, 48 insertions(+), 37 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index a22f6c12b0..349ceddea5 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -36,16 +36,24 @@ static struct tag_name { enum bloblist_tag_t tag; const char *name; } tag_name[] = {
{ BLOBLISTT_NONE, "(none)" },
{ BLOBLISTT_VOID, "(void)" }, /* BLOBLISTT_AREA_FIRMWARE_TOP */
{ BLOBLISTT_CONTROL_FDT, "Control FDT" },
{ BLOBLISTT_HOB_BLOCK, "HOB block" },
{ BLOBLISTT_HOB_LIST, "HOB list" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" }, /* BLOBLISTT_AREA_FIRMWARE */
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" }, { BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" }, { BLOBLISTT_TCPA_LOG, "TPM log space" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
There are some TPM Eventlog related entries that are missing here. Can we add them?
{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
/* BLOBLISTT_AREA_ARM */
{ BLOBLISTT_OPTEE_PAGABLE_PART, "OP-TEE pagable part" },
/* BLOBLISTT_AREA_OTHER */
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
[...]
Thanks /Ilias

From: Simon Glass sjg@chromium.org
The updated bloblist structure stores the alignment as a power-of-two value in its structures. Adjust the API to use this, to avoid needing to calling ilog2().
Drop a stale comment while we are here.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - Update the bloblist alignment to align to FW handoff spec v0.9.
arch/x86/lib/tables.c | 3 ++- common/bloblist.c | 24 +++++++++++------------- include/bloblist.h | 12 +++++++----- test/bloblist.c | 4 ++-- 4 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c index 5b5070f7ca..d43e77d373 100644 --- a/arch/x86/lib/tables.c +++ b/arch/x86/lib/tables.c @@ -16,6 +16,7 @@ #include <asm/mpspec.h> #include <asm/tables.h> #include <asm/coreboot_tables.h> +#include <linux/log2.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -104,7 +105,7 @@ int write_tables(void) if (!gd->arch.table_end) gd->arch.table_end = rom_addr; rom_addr = (ulong)bloblist_add(table->tag, size, - table->align); + ilog2(table->align)); if (!rom_addr) return log_msg_ret("bloblist", -ENOBUFS);
diff --git a/common/bloblist.c b/common/bloblist.c index 349ceddea5..e744c2b0c0 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -26,8 +26,6 @@ * start address of the data in each blob is aligned as required. Note that * each blob's *data* is aligned to BLOBLIST_ALIGN regardless of the alignment * of the bloblist itself or the blob header. - * - * So far, only BLOBLIST_ALIGN alignment is supported. */
DECLARE_GLOBAL_DATA_PTR; @@ -126,24 +124,24 @@ static struct bloblist_rec *bloblist_findrec(uint tag) return NULL; }
-static int bloblist_addrec(uint tag, int size, int align, +static int bloblist_addrec(uint tag, int size, int align_log2, struct bloblist_rec **recp) { struct bloblist_hdr *hdr = gd->bloblist; struct bloblist_rec *rec; int data_start, new_alloced;
- if (!align) - align = BLOBLIST_ALIGN; + if (!align_log2) + align_log2 = BLOBLIST_ALIGN_LOG2;
/* Figure out where the new data will start */ data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec);
/* Align the address and then calculate the offset from ->alloced */ - data_start = ALIGN(data_start, align) - map_to_sysmem(hdr); + data_start = ALIGN(data_start, 1U << align_log2) - map_to_sysmem(hdr);
/* Calculate the new allocated total */ - new_alloced = data_start + ALIGN(size, align); + new_alloced = data_start + ALIGN(size, 1U << align_log2);
if (new_alloced > hdr->size) { log_err("Failed to allocate %x bytes size=%x, need size=%x\n", @@ -167,7 +165,7 @@ static int bloblist_addrec(uint tag, int size, int align, }
static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size, - int align) + int align_log2) { struct bloblist_rec *rec;
@@ -180,7 +178,7 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size, } else { int ret;
- ret = bloblist_addrec(tag, size, align, &rec); + ret = bloblist_addrec(tag, size, align_log2, &rec); if (ret) return ret; } @@ -202,22 +200,22 @@ void *bloblist_find(uint tag, int size) return (void *)rec + rec->hdr_size; }
-void *bloblist_add(uint tag, int size, int align) +void *bloblist_add(uint tag, int size, int align_log2) { struct bloblist_rec *rec;
- if (bloblist_addrec(tag, size, align, &rec)) + if (bloblist_addrec(tag, size, align_log2, &rec)) return NULL;
return (void *)rec + rec->hdr_size; }
-int bloblist_ensure_size(uint tag, int size, int align, void **blobp) +int bloblist_ensure_size(uint tag, int size, int align_log2, void **blobp) { struct bloblist_rec *rec; int ret;
- ret = bloblist_ensurerec(tag, &rec, size, align); + ret = bloblist_ensurerec(tag, &rec, size, align_log2); if (ret) return ret; *blobp = (void *)rec + rec->hdr_size; diff --git a/include/bloblist.h b/include/bloblist.h index 3a2ec91e25..1e4f1a6342 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -76,7 +76,9 @@ enum { BLOBLIST_VERSION = 0, BLOBLIST_MAGIC = 0xb00757a3, - BLOBLIST_ALIGN = 16, + + BLOBLIST_ALIGN_LOG2 = 3, + BLOBLIST_ALIGN = 1 << BLOBLIST_ALIGN_LOG2, };
/* Supported tags - add new ones to tag_name in bloblist.c */ @@ -252,11 +254,11 @@ void *bloblist_find(uint tag, int size); * * @tag: Tag to add (enum bloblist_tag_t) * @size: Size of the blob - * @align: Alignment of the blob (in bytes), 0 for default + * @align_log2: Alignment of the blob (in bytes log2), 0 for default * Return: pointer to the newly added block, or NULL if there is not enough * space for the blob */ -void *bloblist_add(uint tag, int size, int align); +void *bloblist_add(uint tag, int size, int align_log2);
/** * bloblist_ensure_size() - Find or add a blob @@ -266,11 +268,11 @@ void *bloblist_add(uint tag, int size, int align); * @tag: Tag to add (enum bloblist_tag_t) * @size: Size of the blob * @blobp: Returns a pointer to blob on success - * @align: Alignment of the blob (in bytes), 0 for default + * @align_log2: Alignment of the blob (in bytes log2), 0 for default * Return: 0 if OK, -ENOSPC if it is missing and could not be added due to lack * of space, or -ESPIPE it exists but has the wrong size */ -int bloblist_ensure_size(uint tag, int size, int align, void **blobp); +int bloblist_ensure_size(uint tag, int size, int align_log2, void **blobp);
/** * bloblist_ensure() - Find or add a blob diff --git a/test/bloblist.c b/test/bloblist.c index efa1e32afd..8b435e27ca 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -336,7 +336,7 @@ static int bloblist_test_align(struct unit_test_state *uts)
/* Check larger alignment */ for (i = 0; i < 3; i++) { - int align = 32 << i; + int align = 5 - i;
data = bloblist_add(3 + i, i * 4, align); ut_assertnonnull(data); @@ -351,7 +351,7 @@ static int bloblist_test_align(struct unit_test_state *uts) ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE, 0));
- data = bloblist_add(1, 5, BLOBLIST_ALIGN * 2); + data = bloblist_add(1, 5, BLOBLIST_ALIGN_LOG2 + 1); ut_assertnonnull(data); addr = map_to_sysmem(data); ut_asserteq(0, addr & (BLOBLIST_ALIGN * 2 - 1));

On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
The updated bloblist structure stores the alignment as a power-of-two value in its structures. Adjust the API to use this, to avoid needing to calling ilog2().
Drop a stale comment while we are here.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Update the bloblist alignment to align to FW handoff spec v0.9.
arch/x86/lib/tables.c | 3 ++- common/bloblist.c | 24 +++++++++++------------- include/bloblist.h | 12 +++++++----- test/bloblist.c | 4 ++-- 4 files changed, 22 insertions(+), 21 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

Hi Simon,
I am wondering if I shall put in your review tag as you are one of the authors of many patches... What is the best approach under this situation in the U-Boot community?
Thanks and regards, Raymond
On Sat, 2 Dec 2023 at 13:33, Simon Glass sjg@chromium.org wrote:
On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
The updated bloblist structure stores the alignment as a power-of-two value in its structures. Adjust the API to use this, to avoid needing to calling ilog2().
Drop a stale comment while we are here.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Update the bloblist alignment to align to FW handoff spec v0.9.
arch/x86/lib/tables.c | 3 ++- common/bloblist.c | 24 +++++++++++------------- include/bloblist.h | 12 +++++++----- test/bloblist.c | 4 ++-- 4 files changed, 22 insertions(+), 21 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

Hi Raymond,
On Wed, 6 Dec 2023 at 13:08, Raymond Mao raymond.mao@linaro.org wrote:
Hi Simon,
I am wondering if I shall put in your review tag as you are one of the authors of many patches... What is the best approach under this situation in the U-Boot community?
Well, where it is modified by you, I think it is reasonable to add my review.
Regards, Simon
Thanks and regards, Raymond
On Sat, 2 Dec 2023 at 13:33, Simon Glass sjg@chromium.org wrote:
On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
The updated bloblist structure stores the alignment as a power-of-two value in its structures. Adjust the API to use this, to avoid needing to calling ilog2().
Drop a stale comment while we are here.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Update the bloblist alignment to align to FW handoff spec v0.9.
arch/x86/lib/tables.c | 3 ++- common/bloblist.c | 24 +++++++++++------------- include/bloblist.h | 12 +++++++----- test/bloblist.c | 4 ++-- 4 files changed, 22 insertions(+), 21 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

From: Simon Glass sjg@chromium.org
This uses a new value with spec v0.9 so change it.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - Update the bloblist alignment to align to FW handoff spec v0.9.
include/bloblist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/bloblist.h b/include/bloblist.h index 1e4f1a6342..30441f922b 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -75,7 +75,7 @@
enum { BLOBLIST_VERSION = 0, - BLOBLIST_MAGIC = 0xb00757a3, + BLOBLIST_MAGIC = 0x6ed0ff,
BLOBLIST_ALIGN_LOG2 = 3, BLOBLIST_ALIGN = 1 << BLOBLIST_ALIGN_LOG2,

On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
This uses a new value with spec v0.9 so change it.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Update the bloblist alignment to align to FW handoff spec v0.9.
include/bloblist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org
But you will need a later patch (or update this one) due to [1]
diff --git a/include/bloblist.h b/include/bloblist.h index 1e4f1a6342..30441f922b 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -75,7 +75,7 @@
enum { BLOBLIST_VERSION = 0,
BLOBLIST_MAGIC = 0xb00757a3,
BLOBLIST_MAGIC = 0x6ed0ff, BLOBLIST_ALIGN_LOG2 = 3, BLOBLIST_ALIGN = 1 << BLOBLIST_ALIGN_LOG2,
-- 2.25.1
Regards, Simon
[1] https://github.com/FirmwareHandoff/firmware_handoff/pull/24

On Sat, 2 Dec 2023 at 20:33, Simon Glass sjg@chromium.org wrote:
On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
This uses a new value with spec v0.9 so change it.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Update the bloblist alignment to align to FW handoff spec v0.9.
include/bloblist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org
But you will need a later patch (or update this one) due to [1]
diff --git a/include/bloblist.h b/include/bloblist.h index 1e4f1a6342..30441f922b 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -75,7 +75,7 @@
enum { BLOBLIST_VERSION = 0,
BLOBLIST_MAGIC = 0xb00757a3,
BLOBLIST_MAGIC = 0x6ed0ff, BLOBLIST_ALIGN_LOG2 = 3, BLOBLIST_ALIGN = 1 << BLOBLIST_ALIGN_LOG2,
-- 2.25.1
Regards, Simon
[1] https://github.com/FirmwareHandoff/firmware_handoff/pull/24
With this change Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org

From: Simon Glass sjg@chromium.org
The new bloblist for v0.9 has version 1 so update this value.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - Update the bloblist alignment to align to FW handoff spec v0.9.
include/bloblist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/bloblist.h b/include/bloblist.h index 30441f922b..d70a7bad2e 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -74,7 +74,7 @@ #include <mapmem.h>
enum { - BLOBLIST_VERSION = 0, + BLOBLIST_VERSION = 1, BLOBLIST_MAGIC = 0x6ed0ff,
BLOBLIST_ALIGN_LOG2 = 3,

On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
The new bloblist for v0.9 has version 1 so update this value.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Update the bloblist alignment to align to FW handoff spec v0.9.
include/bloblist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Mon, 27 Nov 2023 at 21:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
The new bloblist for v0.9 has version 1 so update this value.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Update the bloblist alignment to align to FW handoff spec v0.9.
include/bloblist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/bloblist.h b/include/bloblist.h index 30441f922b..d70a7bad2e 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -74,7 +74,7 @@ #include <mapmem.h>
enum {
BLOBLIST_VERSION = 0,
BLOBLIST_VERSION = 1, BLOBLIST_MAGIC = 0x6ed0ff, BLOBLIST_ALIGN_LOG2 = 3,
-- 2.25.1
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org

From: Simon Glass sjg@chromium.org
These values currently use a simple field. With spec v0.9 they have moved to a packed format. Convert most accesses to use functions, so this change can be accomodated.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- common/bloblist.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index e744c2b0c0..f084a32cfc 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -82,13 +82,23 @@ static struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr) return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size); }
+static inline uint rec_hdr_size(struct bloblist_rec *rec) +{ + return rec->hdr_size; +} + +static inline uint rec_tag(struct bloblist_rec *rec) +{ + return rec->tag; +} + static ulong bloblist_blob_end_ofs(struct bloblist_hdr *hdr, struct bloblist_rec *rec) { ulong offset;
offset = (void *)rec - (void *)hdr; - offset += rec->hdr_size + ALIGN(rec->size, BLOBLIST_ALIGN); + offset += rec_hdr_size(rec) + ALIGN(rec->size, BLOBLIST_ALIGN);
return offset; } @@ -117,7 +127,7 @@ static struct bloblist_rec *bloblist_findrec(uint tag) return NULL;
foreach_rec(rec, hdr) { - if (rec->tag == tag) + if (rec_tag(rec) == tag) return rec; }
@@ -156,7 +166,7 @@ static int bloblist_addrec(uint tag, int size, int align_log2, rec->spare = 0;
/* Zero the record data */ - memset((void *)rec + rec->hdr_size, '\0', rec->size); + memset((void *)rec + rec_hdr_size(rec), '\0', rec->size);
hdr->alloced = new_alloced; *recp = rec; @@ -197,7 +207,7 @@ void *bloblist_find(uint tag, int size) if (size && size != rec->size) return NULL;
- return (void *)rec + rec->hdr_size; + return (void *)rec + rec_hdr_size(rec); }
void *bloblist_add(uint tag, int size, int align_log2) @@ -207,7 +217,7 @@ void *bloblist_add(uint tag, int size, int align_log2) if (bloblist_addrec(tag, size, align_log2, &rec)) return NULL;
- return (void *)rec + rec->hdr_size; + return (void *)rec + rec_hdr_size(rec); }
int bloblist_ensure_size(uint tag, int size, int align_log2, void **blobp) @@ -218,7 +228,7 @@ int bloblist_ensure_size(uint tag, int size, int align_log2, void **blobp) ret = bloblist_ensurerec(tag, &rec, size, align_log2); if (ret) return ret; - *blobp = (void *)rec + rec->hdr_size; + *blobp = (void *)rec + rec_hdr_size(rec);
return 0; } @@ -230,7 +240,7 @@ void *bloblist_ensure(uint tag, int size) if (bloblist_ensurerec(tag, &rec, size, 0)) return NULL;
- return (void *)rec + rec->hdr_size; + return (void *)rec + rec_hdr_size(rec); }
int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp) @@ -243,7 +253,7 @@ int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp) *sizep = rec->size; else if (ret) return ret; - *blobp = (void *)rec + rec->hdr_size; + *blobp = (void *)rec + rec_hdr_size(rec);
return 0; } @@ -279,7 +289,7 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
/* Zero the new part of the blob */ if (expand_by > 0) { - memset((void *)rec + rec->hdr_size + rec->size, '\0', + memset((void *)rec + rec_hdr_size(rec) + rec->size, '\0', new_size - rec->size); }
@@ -313,8 +323,9 @@ static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) chksum = crc32(0, (unsigned char *)hdr, offsetof(struct bloblist_hdr, chksum)); foreach_rec(rec, hdr) { - chksum = crc32(chksum, (void *)rec, rec->hdr_size); - chksum = crc32(chksum, (void *)rec + rec->hdr_size, rec->size); + chksum = crc32(chksum, (void *)rec, rec_hdr_size(rec)); + chksum = crc32(chksum, (void *)rec + rec_hdr_size(rec), + rec->size); }
return chksum; @@ -422,8 +433,9 @@ void bloblist_show_list(void) for (rec = bloblist_first_blob(hdr); rec; rec = bloblist_next_blob(hdr, rec)) { printf("%08lx %8x %4x %s\n", - (ulong)map_to_sysmem((void *)rec + rec->hdr_size), - rec->size, rec->tag, bloblist_tag_name(rec->tag)); + (ulong)map_to_sysmem((void *)rec + rec_hdr_size(rec)), + rec->size, rec_tag(rec), + bloblist_tag_name(rec_tag(rec))); } }

On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
These values currently use a simple field. With spec v0.9 they have moved to a packed format. Convert most accesses to use functions, so this change can be accomodated.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Mon, 27 Nov 2023 at 21:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
These values currently use a simple field. With spec v0.9 they have moved to a packed format. Convert most accesses to use functions, so this change can be accommodated.
I don't really understand how the commit message is related to the changes. What did the packed format affect that we need a function?
Thanks /Ilias
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index e744c2b0c0..f084a32cfc 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -82,13 +82,23 @@ static struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr) return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size); }
+static inline uint rec_hdr_size(struct bloblist_rec *rec) +{
return rec->hdr_size;
+}
+static inline uint rec_tag(struct bloblist_rec *rec) +{
return rec->tag;
+}
static ulong bloblist_blob_end_ofs(struct bloblist_hdr *hdr, struct bloblist_rec *rec) { ulong offset;
offset = (void *)rec - (void *)hdr;
offset += rec->hdr_size + ALIGN(rec->size, BLOBLIST_ALIGN);
offset += rec_hdr_size(rec) + ALIGN(rec->size, BLOBLIST_ALIGN); return offset;
} @@ -117,7 +127,7 @@ static struct bloblist_rec *bloblist_findrec(uint tag) return NULL;
foreach_rec(rec, hdr) {
if (rec->tag == tag)
if (rec_tag(rec) == tag) return rec; }
@@ -156,7 +166,7 @@ static int bloblist_addrec(uint tag, int size, int align_log2, rec->spare = 0;
/* Zero the record data */
memset((void *)rec + rec->hdr_size, '\0', rec->size);
memset((void *)rec + rec_hdr_size(rec), '\0', rec->size); hdr->alloced = new_alloced; *recp = rec;
@@ -197,7 +207,7 @@ void *bloblist_find(uint tag, int size) if (size && size != rec->size) return NULL;
return (void *)rec + rec->hdr_size;
return (void *)rec + rec_hdr_size(rec);
}
void *bloblist_add(uint tag, int size, int align_log2) @@ -207,7 +217,7 @@ void *bloblist_add(uint tag, int size, int align_log2) if (bloblist_addrec(tag, size, align_log2, &rec)) return NULL;
return (void *)rec + rec->hdr_size;
return (void *)rec + rec_hdr_size(rec);
}
int bloblist_ensure_size(uint tag, int size, int align_log2, void **blobp) @@ -218,7 +228,7 @@ int bloblist_ensure_size(uint tag, int size, int align_log2, void **blobp) ret = bloblist_ensurerec(tag, &rec, size, align_log2); if (ret) return ret;
*blobp = (void *)rec + rec->hdr_size;
*blobp = (void *)rec + rec_hdr_size(rec); return 0;
} @@ -230,7 +240,7 @@ void *bloblist_ensure(uint tag, int size) if (bloblist_ensurerec(tag, &rec, size, 0)) return NULL;
return (void *)rec + rec->hdr_size;
return (void *)rec + rec_hdr_size(rec);
}
int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp) @@ -243,7 +253,7 @@ int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp) *sizep = rec->size; else if (ret) return ret;
*blobp = (void *)rec + rec->hdr_size;
*blobp = (void *)rec + rec_hdr_size(rec); return 0;
} @@ -279,7 +289,7 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
/* Zero the new part of the blob */ if (expand_by > 0) {
memset((void *)rec + rec->hdr_size + rec->size, '\0',
memset((void *)rec + rec_hdr_size(rec) + rec->size, '\0', new_size - rec->size); }
@@ -313,8 +323,9 @@ static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) chksum = crc32(0, (unsigned char *)hdr, offsetof(struct bloblist_hdr, chksum)); foreach_rec(rec, hdr) {
chksum = crc32(chksum, (void *)rec, rec->hdr_size);
chksum = crc32(chksum, (void *)rec + rec->hdr_size, rec->size);
chksum = crc32(chksum, (void *)rec, rec_hdr_size(rec));
chksum = crc32(chksum, (void *)rec + rec_hdr_size(rec),
rec->size); } return chksum;
@@ -422,8 +433,9 @@ void bloblist_show_list(void) for (rec = bloblist_first_blob(hdr); rec; rec = bloblist_next_blob(hdr, rec)) { printf("%08lx %8x %4x %s\n",
(ulong)map_to_sysmem((void *)rec + rec->hdr_size),
rec->size, rec->tag, bloblist_tag_name(rec->tag));
(ulong)map_to_sysmem((void *)rec + rec_hdr_size(rec)),
rec->size, rec_tag(rec),
bloblist_tag_name(rec_tag(rec))); }
}
-- 2.25.1

Hi Ilias,
This patch is for later grouping the tag and hdr_size in '0011-bloblist-Reduce-blob-header-size.patch'. I can update the commit message.
Thanks and regards, Raymond
On Mon, 4 Dec 2023 at 03:31, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
On Mon, 27 Nov 2023 at 21:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
These values currently use a simple field. With spec v0.9 they have moved to a packed format. Convert most accesses to use functions, so this
change
can be accommodated.
I don't really understand how the commit message is related to the changes. What did the packed format affect that we need a function?
Thanks /Ilias
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index e744c2b0c0..f084a32cfc 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -82,13 +82,23 @@ static struct bloblist_rec
*bloblist_first_blob(struct bloblist_hdr *hdr)
return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size);
}
+static inline uint rec_hdr_size(struct bloblist_rec *rec) +{
return rec->hdr_size;
+}
+static inline uint rec_tag(struct bloblist_rec *rec) +{
return rec->tag;
+}
static ulong bloblist_blob_end_ofs(struct bloblist_hdr *hdr, struct bloblist_rec *rec) { ulong offset;
offset = (void *)rec - (void *)hdr;
offset += rec->hdr_size + ALIGN(rec->size, BLOBLIST_ALIGN);
offset += rec_hdr_size(rec) + ALIGN(rec->size, BLOBLIST_ALIGN); return offset;
} @@ -117,7 +127,7 @@ static struct bloblist_rec *bloblist_findrec(uint
tag)
return NULL; foreach_rec(rec, hdr) {
if (rec->tag == tag)
if (rec_tag(rec) == tag) return rec; }
@@ -156,7 +166,7 @@ static int bloblist_addrec(uint tag, int size, int
align_log2,
rec->spare = 0; /* Zero the record data */
memset((void *)rec + rec->hdr_size, '\0', rec->size);
memset((void *)rec + rec_hdr_size(rec), '\0', rec->size); hdr->alloced = new_alloced; *recp = rec;
@@ -197,7 +207,7 @@ void *bloblist_find(uint tag, int size) if (size && size != rec->size) return NULL;
return (void *)rec + rec->hdr_size;
return (void *)rec + rec_hdr_size(rec);
}
void *bloblist_add(uint tag, int size, int align_log2) @@ -207,7 +217,7 @@ void *bloblist_add(uint tag, int size, int
align_log2)
if (bloblist_addrec(tag, size, align_log2, &rec)) return NULL;
return (void *)rec + rec->hdr_size;
return (void *)rec + rec_hdr_size(rec);
}
int bloblist_ensure_size(uint tag, int size, int align_log2, void
**blobp)
@@ -218,7 +228,7 @@ int bloblist_ensure_size(uint tag, int size, int
align_log2, void **blobp)
ret = bloblist_ensurerec(tag, &rec, size, align_log2); if (ret) return ret;
*blobp = (void *)rec + rec->hdr_size;
*blobp = (void *)rec + rec_hdr_size(rec); return 0;
} @@ -230,7 +240,7 @@ void *bloblist_ensure(uint tag, int size) if (bloblist_ensurerec(tag, &rec, size, 0)) return NULL;
return (void *)rec + rec->hdr_size;
return (void *)rec + rec_hdr_size(rec);
}
int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp) @@ -243,7 +253,7 @@ int bloblist_ensure_size_ret(uint tag, int *sizep,
void **blobp)
*sizep = rec->size; else if (ret) return ret;
*blobp = (void *)rec + rec->hdr_size;
*blobp = (void *)rec + rec_hdr_size(rec); return 0;
} @@ -279,7 +289,7 @@ static int bloblist_resize_rec(struct bloblist_hdr
*hdr,
/* Zero the new part of the blob */ if (expand_by > 0) {
memset((void *)rec + rec->hdr_size + rec->size, '\0',
memset((void *)rec + rec_hdr_size(rec) + rec->size, '\0', new_size - rec->size); }
@@ -313,8 +323,9 @@ static u32 bloblist_calc_chksum(struct bloblist_hdr
*hdr)
chksum = crc32(0, (unsigned char *)hdr, offsetof(struct bloblist_hdr, chksum)); foreach_rec(rec, hdr) {
chksum = crc32(chksum, (void *)rec, rec->hdr_size);
chksum = crc32(chksum, (void *)rec + rec->hdr_size,
rec->size);
chksum = crc32(chksum, (void *)rec, rec_hdr_size(rec));
chksum = crc32(chksum, (void *)rec + rec_hdr_size(rec),
rec->size); } return chksum;
@@ -422,8 +433,9 @@ void bloblist_show_list(void) for (rec = bloblist_first_blob(hdr); rec; rec = bloblist_next_blob(hdr, rec)) { printf("%08lx %8x %4x %s\n",
(ulong)map_to_sysmem((void *)rec + rec->hdr_size),
rec->size, rec->tag, bloblist_tag_name(rec->tag));
(ulong)map_to_sysmem((void *)rec +
rec_hdr_size(rec)),
rec->size, rec_tag(rec),
bloblist_tag_name(rec_tag(rec))); }
}
-- 2.25.1

From: Simon Glass sjg@chromium.org
There is no flags value in spec v0.9 so drop it.
For now it is still present in the header, with an underscore, so that tests continue to pass.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- common/bloblist.c | 5 ++--- include/bloblist.h | 6 ++---- test/bloblist.c | 45 +++++++++++++++++++-------------------------- 3 files changed, 23 insertions(+), 33 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index f084a32cfc..4d01772c3b 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -331,7 +331,7 @@ static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) return chksum; }
-int bloblist_new(ulong addr, uint size, uint flags) +int bloblist_new(ulong addr, uint size) { struct bloblist_hdr *hdr;
@@ -343,7 +343,6 @@ int bloblist_new(ulong addr, uint size, uint flags) memset(hdr, '\0', sizeof(*hdr)); hdr->version = BLOBLIST_VERSION; hdr->hdr_size = sizeof(*hdr); - hdr->flags = flags; hdr->magic = BLOBLIST_MAGIC; hdr->size = size; hdr->alloced = hdr->hdr_size; @@ -490,7 +489,7 @@ int bloblist_init(void) } log_debug("Creating new bloblist size %lx at %lx\n", size, addr); - ret = bloblist_new(addr, size, 0); + ret = bloblist_new(addr, size); } else { log_debug("Found existing bloblist size %lx at %lx\n", size, addr); diff --git a/include/bloblist.h b/include/bloblist.h index d70a7bad2e..2b898d0c55 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -164,7 +164,6 @@ enum bloblist_tag_t { * @version: BLOBLIST_VERSION * @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The * first bloblist_rec starts at this offset from the start of the header - * @flags: Space for BLOBLISTF... flags (none yet) * @size: Total size of the bloblist (non-zero if valid) including this header. * The bloblist extends for this many bytes from the start of this header. * When adding new records, the bloblist can grow up to this size. @@ -182,7 +181,7 @@ struct bloblist_hdr { u32 magic; u32 version; u32 hdr_size; - u32 flags; + u32 _flags;
u32 size; u32 alloced; @@ -317,11 +316,10 @@ int bloblist_resize(uint tag, int new_size); * * @addr: Address of bloblist * @size: Initial size for bloblist - * @flags: Flags to use for bloblist * Return: 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the * area is not large enough */ -int bloblist_new(ulong addr, uint size, uint flags); +int bloblist_new(ulong addr, uint size);
/** * bloblist_check() - Check if a bloblist exists diff --git a/test/bloblist.c b/test/bloblist.c index 8b435e27ca..36994c3dd4 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -72,15 +72,15 @@ static int bloblist_test_init(struct unit_test_state *uts) hdr = clear_bloblist(); ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR)); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq_ptr(hdr, bloblist_check_magic(TEST_ADDR)); hdr->version++; ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0)); - ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0)); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10)); + ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE));
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_finish()); @@ -90,9 +90,6 @@ static int bloblist_test_init(struct unit_test_state *uts) ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR)); hdr->magic--;
- hdr->flags++; - ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); - return 1; } BLOBLIST_TEST(bloblist_test_init, 0); @@ -106,7 +103,7 @@ static int bloblist_test_blob(struct unit_test_state *uts) /* At the start there should be no records */ hdr = clear_bloblist(); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_size()); ut_asserteq(TEST_ADDR, bloblist_get_base()); ut_asserteq(map_to_sysmem(hdr), TEST_ADDR); @@ -144,7 +141,7 @@ static int bloblist_test_blob_ensure(struct unit_test_state *uts)
/* At the start there should be no records */ clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE));
/* Test with an empty bloblist */ size = TEST_SIZE; @@ -176,7 +173,7 @@ static int bloblist_test_bad_blob(struct unit_test_state *uts) void *data;
hdr = clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = hdr + 1; data += sizeof(struct bloblist_rec); ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); @@ -192,7 +189,7 @@ static int bloblist_test_checksum(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_finish()); ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
@@ -201,10 +198,6 @@ static int bloblist_test_checksum(struct unit_test_state *uts) * change the size or alloced fields, since that will crash the code. * It has to rely on these being correct. */ - hdr->flags--; - ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); - hdr->flags++; - hdr->size--; ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); hdr->size++; @@ -256,7 +249,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = bloblist_ensure(TEST_TAG, TEST_SIZE); data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@@ -282,7 +275,7 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = bloblist_ensure(TEST_TAG, TEST_SIZE); data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@@ -312,7 +305,7 @@ static int bloblist_test_align(struct unit_test_state *uts)
/* At the start there should be no records */ hdr = clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
/* Check the default alignment */ @@ -348,8 +341,8 @@ static int bloblist_test_align(struct unit_test_state *uts) hdr = map_sysmem(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE); memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); memset(hdr, '\0', sizeof(*hdr)); - ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE, - 0)); + ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, + TEST_BLOBLIST_SIZE));
data = bloblist_add(1, 5, BLOBLIST_ALIGN_LOG2 + 1); ut_assertnonnull(data); @@ -370,7 +363,7 @@ static int bloblist_test_reloc(struct unit_test_state *uts) ulong new_addr; ulong new_size;
- ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); old_ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Add one blob and then one that won't fit */ @@ -409,7 +402,7 @@ static int bloblist_test_grow(struct unit_test_state *uts) memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
/* Create two blobs */ - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1); ut_assertok(check_zero(blob1, small_size)); @@ -461,7 +454,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts) ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Create two blobs */ - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1); strcpy(blob1, test1_str); @@ -511,7 +504,7 @@ static int bloblist_test_resize_fail(struct unit_test_state *uts) ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Create two blobs */ - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1);
@@ -548,7 +541,7 @@ static int bloblist_test_resize_last(struct unit_test_state *uts) hdr = ptr;
/* Create two blobs */ - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1);
@@ -593,7 +586,7 @@ static int bloblist_test_blob_maxsize(struct unit_test_state *uts)
/* At the start there should be no records */ clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE));
/* Add a blob that takes up all space */ size = TEST_BLOBLIST_SIZE - sizeof(struct bloblist_hdr) -

On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
There is no flags value in spec v0.9 so drop it.
For now it is still present in the header, with an underscore, so that tests continue to pass.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 5 ++--- include/bloblist.h | 6 ++---- test/bloblist.c | 45 +++++++++++++++++++-------------------------- 3 files changed, 23 insertions(+), 33 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Mon, 27 Nov 2023 at 21:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
There is no flags value in spec v0.9 so drop it.
For now it is still present in the header, with an underscore, so that tests continue to pass.
Why? Can't we drop it overall?
Thanks /Ilias
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 5 ++--- include/bloblist.h | 6 ++---- test/bloblist.c | 45 +++++++++++++++++++-------------------------- 3 files changed, 23 insertions(+), 33 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index f084a32cfc..4d01772c3b 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -331,7 +331,7 @@ static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) return chksum; }
-int bloblist_new(ulong addr, uint size, uint flags) +int bloblist_new(ulong addr, uint size) { struct bloblist_hdr *hdr;
@@ -343,7 +343,6 @@ int bloblist_new(ulong addr, uint size, uint flags) memset(hdr, '\0', sizeof(*hdr)); hdr->version = BLOBLIST_VERSION; hdr->hdr_size = sizeof(*hdr);
hdr->flags = flags; hdr->magic = BLOBLIST_MAGIC; hdr->size = size; hdr->alloced = hdr->hdr_size;
@@ -490,7 +489,7 @@ int bloblist_init(void) } log_debug("Creating new bloblist size %lx at %lx\n", size, addr);
ret = bloblist_new(addr, size, 0);
ret = bloblist_new(addr, size); } else { log_debug("Found existing bloblist size %lx at %lx\n", size, addr);
diff --git a/include/bloblist.h b/include/bloblist.h index d70a7bad2e..2b898d0c55 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -164,7 +164,6 @@ enum bloblist_tag_t {
- @version: BLOBLIST_VERSION
- @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The
first bloblist_rec starts at this offset from the start of the header
- @flags: Space for BLOBLISTF... flags (none yet)
- @size: Total size of the bloblist (non-zero if valid) including this header.
The bloblist extends for this many bytes from the start of this header.
When adding new records, the bloblist can grow up to this size.
@@ -182,7 +181,7 @@ struct bloblist_hdr { u32 magic; u32 version; u32 hdr_size;
u32 flags;
u32 _flags; u32 size; u32 alloced;
@@ -317,11 +316,10 @@ int bloblist_resize(uint tag, int new_size);
- @addr: Address of bloblist
- @size: Initial size for bloblist
*/
- @flags: Flags to use for bloblist
- Return: 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the
- area is not large enough
-int bloblist_new(ulong addr, uint size, uint flags); +int bloblist_new(ulong addr, uint size);
/**
- bloblist_check() - Check if a bloblist exists
diff --git a/test/bloblist.c b/test/bloblist.c index 8b435e27ca..36994c3dd4 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -72,15 +72,15 @@ static int bloblist_test_init(struct unit_test_state *uts) hdr = clear_bloblist(); ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq_ptr(hdr, bloblist_check_magic(TEST_ADDR)); hdr->version++; ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10));
ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_finish());
@@ -90,9 +90,6 @@ static int bloblist_test_init(struct unit_test_state *uts) ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR)); hdr->magic--;
hdr->flags++;
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
return 1;
} BLOBLIST_TEST(bloblist_test_init, 0); @@ -106,7 +103,7 @@ static int bloblist_test_blob(struct unit_test_state *uts) /* At the start there should be no records */ hdr = clear_bloblist(); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_size()); ut_asserteq(TEST_ADDR, bloblist_get_base()); ut_asserteq(map_to_sysmem(hdr), TEST_ADDR);
@@ -144,7 +141,7 @@ static int bloblist_test_blob_ensure(struct unit_test_state *uts)
/* At the start there should be no records */ clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); /* Test with an empty bloblist */ size = TEST_SIZE;
@@ -176,7 +173,7 @@ static int bloblist_test_bad_blob(struct unit_test_state *uts) void *data;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = hdr + 1; data += sizeof(struct bloblist_rec); ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
@@ -192,7 +189,7 @@ static int bloblist_test_checksum(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_finish()); ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
@@ -201,10 +198,6 @@ static int bloblist_test_checksum(struct unit_test_state *uts) * change the size or alloced fields, since that will crash the code. * It has to rely on these being correct. */
hdr->flags--;
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
hdr->flags++;
hdr->size--; ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); hdr->size++;
@@ -256,7 +249,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = bloblist_ensure(TEST_TAG, TEST_SIZE); data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@@ -282,7 +275,7 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = bloblist_ensure(TEST_TAG, TEST_SIZE); data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@@ -312,7 +305,7 @@ static int bloblist_test_align(struct unit_test_state *uts)
/* At the start there should be no records */ hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); /* Check the default alignment */
@@ -348,8 +341,8 @@ static int bloblist_test_align(struct unit_test_state *uts) hdr = map_sysmem(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE); memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); memset(hdr, '\0', sizeof(*hdr));
ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE,
0));
ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN,
TEST_BLOBLIST_SIZE)); data = bloblist_add(1, 5, BLOBLIST_ALIGN_LOG2 + 1); ut_assertnonnull(data);
@@ -370,7 +363,7 @@ static int bloblist_test_reloc(struct unit_test_state *uts) ulong new_addr; ulong new_size;
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); old_ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); /* Add one blob and then one that won't fit */
@@ -409,7 +402,7 @@ static int bloblist_test_grow(struct unit_test_state *uts) memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1); ut_assertok(check_zero(blob1, small_size));
@@ -461,7 +454,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts) ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1); strcpy(blob1, test1_str);
@@ -511,7 +504,7 @@ static int bloblist_test_resize_fail(struct unit_test_state *uts) ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1);
@@ -548,7 +541,7 @@ static int bloblist_test_resize_last(struct unit_test_state *uts) hdr = ptr;
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1);
@@ -593,7 +586,7 @@ static int bloblist_test_blob_maxsize(struct unit_test_state *uts)
/* At the start there should be no records */ clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); /* Add a blob that takes up all space */ size = TEST_BLOBLIST_SIZE - sizeof(struct bloblist_hdr) -
-- 2.25.1

I just noticed that's fixed in path #12
On Mon, 4 Dec 2023 at 10:36, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
On Mon, 27 Nov 2023 at 21:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
There is no flags value in spec v0.9 so drop it.
For now it is still present in the header, with an underscore, so that tests continue to pass.
Why? Can't we drop it overall?
Thanks /Ilias
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 5 ++--- include/bloblist.h | 6 ++---- test/bloblist.c | 45 +++++++++++++++++++-------------------------- 3 files changed, 23 insertions(+), 33 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index f084a32cfc..4d01772c3b 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -331,7 +331,7 @@ static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) return chksum; }
-int bloblist_new(ulong addr, uint size, uint flags) +int bloblist_new(ulong addr, uint size) { struct bloblist_hdr *hdr;
@@ -343,7 +343,6 @@ int bloblist_new(ulong addr, uint size, uint flags) memset(hdr, '\0', sizeof(*hdr)); hdr->version = BLOBLIST_VERSION; hdr->hdr_size = sizeof(*hdr);
hdr->flags = flags; hdr->magic = BLOBLIST_MAGIC; hdr->size = size; hdr->alloced = hdr->hdr_size;
@@ -490,7 +489,7 @@ int bloblist_init(void) } log_debug("Creating new bloblist size %lx at %lx\n", size, addr);
ret = bloblist_new(addr, size, 0);
ret = bloblist_new(addr, size); } else { log_debug("Found existing bloblist size %lx at %lx\n", size, addr);
diff --git a/include/bloblist.h b/include/bloblist.h index d70a7bad2e..2b898d0c55 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -164,7 +164,6 @@ enum bloblist_tag_t {
- @version: BLOBLIST_VERSION
- @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The
first bloblist_rec starts at this offset from the start of the header
- @flags: Space for BLOBLISTF... flags (none yet)
- @size: Total size of the bloblist (non-zero if valid) including this header.
The bloblist extends for this many bytes from the start of this header.
When adding new records, the bloblist can grow up to this size.
@@ -182,7 +181,7 @@ struct bloblist_hdr { u32 magic; u32 version; u32 hdr_size;
u32 flags;
u32 _flags; u32 size; u32 alloced;
@@ -317,11 +316,10 @@ int bloblist_resize(uint tag, int new_size);
- @addr: Address of bloblist
- @size: Initial size for bloblist
*/
- @flags: Flags to use for bloblist
- Return: 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the
- area is not large enough
-int bloblist_new(ulong addr, uint size, uint flags); +int bloblist_new(ulong addr, uint size);
/**
- bloblist_check() - Check if a bloblist exists
diff --git a/test/bloblist.c b/test/bloblist.c index 8b435e27ca..36994c3dd4 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -72,15 +72,15 @@ static int bloblist_test_init(struct unit_test_state *uts) hdr = clear_bloblist(); ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq_ptr(hdr, bloblist_check_magic(TEST_ADDR)); hdr->version++; ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10));
ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_finish());
@@ -90,9 +90,6 @@ static int bloblist_test_init(struct unit_test_state *uts) ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR)); hdr->magic--;
hdr->flags++;
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
return 1;
} BLOBLIST_TEST(bloblist_test_init, 0); @@ -106,7 +103,7 @@ static int bloblist_test_blob(struct unit_test_state *uts) /* At the start there should be no records */ hdr = clear_bloblist(); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_size()); ut_asserteq(TEST_ADDR, bloblist_get_base()); ut_asserteq(map_to_sysmem(hdr), TEST_ADDR);
@@ -144,7 +141,7 @@ static int bloblist_test_blob_ensure(struct unit_test_state *uts)
/* At the start there should be no records */ clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); /* Test with an empty bloblist */ size = TEST_SIZE;
@@ -176,7 +173,7 @@ static int bloblist_test_bad_blob(struct unit_test_state *uts) void *data;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = hdr + 1; data += sizeof(struct bloblist_rec); ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
@@ -192,7 +189,7 @@ static int bloblist_test_checksum(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_finish()); ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
@@ -201,10 +198,6 @@ static int bloblist_test_checksum(struct unit_test_state *uts) * change the size or alloced fields, since that will crash the code. * It has to rely on these being correct. */
hdr->flags--;
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
hdr->flags++;
hdr->size--; ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); hdr->size++;
@@ -256,7 +249,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = bloblist_ensure(TEST_TAG, TEST_SIZE); data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@@ -282,7 +275,7 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = bloblist_ensure(TEST_TAG, TEST_SIZE); data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@@ -312,7 +305,7 @@ static int bloblist_test_align(struct unit_test_state *uts)
/* At the start there should be no records */ hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); /* Check the default alignment */
@@ -348,8 +341,8 @@ static int bloblist_test_align(struct unit_test_state *uts) hdr = map_sysmem(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE); memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); memset(hdr, '\0', sizeof(*hdr));
ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE,
0));
ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN,
TEST_BLOBLIST_SIZE)); data = bloblist_add(1, 5, BLOBLIST_ALIGN_LOG2 + 1); ut_assertnonnull(data);
@@ -370,7 +363,7 @@ static int bloblist_test_reloc(struct unit_test_state *uts) ulong new_addr; ulong new_size;
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); old_ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); /* Add one blob and then one that won't fit */
@@ -409,7 +402,7 @@ static int bloblist_test_grow(struct unit_test_state *uts) memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1); ut_assertok(check_zero(blob1, small_size));
@@ -461,7 +454,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts) ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1); strcpy(blob1, test1_str);
@@ -511,7 +504,7 @@ static int bloblist_test_resize_fail(struct unit_test_state *uts) ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1);
@@ -548,7 +541,7 @@ static int bloblist_test_resize_last(struct unit_test_state *uts) hdr = ptr;
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1);
@@ -593,7 +586,7 @@ static int bloblist_test_blob_maxsize(struct unit_test_state *uts)
/* At the start there should be no records */ clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); /* Add a blob that takes up all space */ size = TEST_BLOBLIST_SIZE - sizeof(struct bloblist_hdr) -
-- 2.25.1

Hi Ilias and Simon, I just realized that the latest FW Handoff spec introduced 'flags'. I will remove this patch from the series of next rev. Regards, Raymond
On Mon, 4 Dec 2023 at 03:40, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
I just noticed that's fixed in path #12
On Mon, 4 Dec 2023 at 10:36, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
On Mon, 27 Nov 2023 at 21:52, Raymond Mao raymond.mao@linaro.org
wrote:
From: Simon Glass sjg@chromium.org
There is no flags value in spec v0.9 so drop it.
For now it is still present in the header, with an underscore, so that tests continue to pass.
Why? Can't we drop it overall?
Thanks /Ilias
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 5 ++--- include/bloblist.h | 6 ++---- test/bloblist.c | 45 +++++++++++++++++++-------------------------- 3 files changed, 23 insertions(+), 33 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index f084a32cfc..4d01772c3b 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -331,7 +331,7 @@ static u32 bloblist_calc_chksum(struct
bloblist_hdr *hdr)
return chksum;
}
-int bloblist_new(ulong addr, uint size, uint flags) +int bloblist_new(ulong addr, uint size) { struct bloblist_hdr *hdr;
@@ -343,7 +343,6 @@ int bloblist_new(ulong addr, uint size, uint flags) memset(hdr, '\0', sizeof(*hdr)); hdr->version = BLOBLIST_VERSION; hdr->hdr_size = sizeof(*hdr);
hdr->flags = flags; hdr->magic = BLOBLIST_MAGIC; hdr->size = size; hdr->alloced = hdr->hdr_size;
@@ -490,7 +489,7 @@ int bloblist_init(void) } log_debug("Creating new bloblist size %lx at %lx\n",
size,
addr);
ret = bloblist_new(addr, size, 0);
ret = bloblist_new(addr, size); } else { log_debug("Found existing bloblist size %lx at %lx\n",
size,
addr);
diff --git a/include/bloblist.h b/include/bloblist.h index d70a7bad2e..2b898d0c55 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -164,7 +164,6 @@ enum bloblist_tag_t {
- @version: BLOBLIST_VERSION
- @hdr_size: Size of this header, normally sizeof(struct
bloblist_hdr). The
first bloblist_rec starts at this offset from the start of the
header
- @flags: Space for BLOBLISTF... flags (none yet)
- @size: Total size of the bloblist (non-zero if valid) including
this header.
The bloblist extends for this many bytes from the start of
this header.
When adding new records, the bloblist can grow up to this size.
@@ -182,7 +181,7 @@ struct bloblist_hdr { u32 magic; u32 version; u32 hdr_size;
u32 flags;
u32 _flags; u32 size; u32 alloced;
@@ -317,11 +316,10 @@ int bloblist_resize(uint tag, int new_size);
- @addr: Address of bloblist
- @size: Initial size for bloblist
- @flags: Flags to use for bloblist
- Return: 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC
is the
- area is not large enough
*/ -int bloblist_new(ulong addr, uint size, uint flags); +int bloblist_new(ulong addr, uint size);
/**
- bloblist_check() - Check if a bloblist exists
diff --git a/test/bloblist.c b/test/bloblist.c index 8b435e27ca..36994c3dd4 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -72,15 +72,15 @@ static int bloblist_test_init(struct
unit_test_state *uts)
hdr = clear_bloblist(); ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR,
TEST_BLOBLIST_SIZE));
ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq_ptr(hdr, bloblist_check_magic(TEST_ADDR)); hdr->version++; ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
TEST_BLOBLIST_SIZE));
ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10));
ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq(-EIO, bloblist_check(TEST_ADDR,
TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_finish());
@@ -90,9 +90,6 @@ static int bloblist_test_init(struct unit_test_state
*uts)
ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR)); hdr->magic--;
hdr->flags++;
ut_asserteq(-EIO, bloblist_check(TEST_ADDR,
TEST_BLOBLIST_SIZE));
return 1;
} BLOBLIST_TEST(bloblist_test_init, 0); @@ -106,7 +103,7 @@ static int bloblist_test_blob(struct
unit_test_state *uts)
/* At the start there should be no records */ hdr = clear_bloblist(); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_size()); ut_asserteq(TEST_ADDR, bloblist_get_base()); ut_asserteq(map_to_sysmem(hdr), TEST_ADDR);
@@ -144,7 +141,7 @@ static int bloblist_test_blob_ensure(struct
unit_test_state *uts)
/* At the start there should be no records */ clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); /* Test with an empty bloblist */ size = TEST_SIZE;
@@ -176,7 +173,7 @@ static int bloblist_test_bad_blob(struct
unit_test_state *uts)
void *data; hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = hdr + 1; data += sizeof(struct bloblist_rec); ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
@@ -192,7 +189,7 @@ static int bloblist_test_checksum(struct
unit_test_state *uts)
char *data, *data2; hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_finish()); ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
@@ -201,10 +198,6 @@ static int bloblist_test_checksum(struct
unit_test_state *uts)
* change the size or alloced fields, since that will crash
the code.
* It has to rely on these being correct. */
hdr->flags--;
ut_asserteq(-EIO, bloblist_check(TEST_ADDR,
TEST_BLOBLIST_SIZE));
hdr->flags++;
hdr->size--; ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR,
TEST_BLOBLIST_SIZE));
hdr->size++;
@@ -256,7 +249,7 @@ static int bloblist_test_cmd_info(struct
unit_test_state *uts)
char *data, *data2; hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = bloblist_ensure(TEST_TAG, TEST_SIZE); data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@@ -282,7 +275,7 @@ static int bloblist_test_cmd_list(struct
unit_test_state *uts)
char *data, *data2; hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); data = bloblist_ensure(TEST_TAG, TEST_SIZE); data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@@ -312,7 +305,7 @@ static int bloblist_test_align(struct
unit_test_state *uts)
/* At the start there should be no records */ hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); /* Check the default alignment */
@@ -348,8 +341,8 @@ static int bloblist_test_align(struct
unit_test_state *uts)
hdr = map_sysmem(TEST_ADDR + BLOBLIST_ALIGN,
TEST_BLOBLIST_SIZE);
memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); memset(hdr, '\0', sizeof(*hdr));
ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN,
TEST_BLOBLIST_SIZE,
0));
ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN,
TEST_BLOBLIST_SIZE)); data = bloblist_add(1, 5, BLOBLIST_ALIGN_LOG2 + 1); ut_assertnonnull(data);
@@ -370,7 +363,7 @@ static int bloblist_test_reloc(struct
unit_test_state *uts)
ulong new_addr; ulong new_size;
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); old_ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); /* Add one blob and then one that won't fit */
@@ -409,7 +402,7 @@ static int bloblist_test_grow(struct
unit_test_state *uts)
memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); /* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1); ut_assertok(check_zero(blob1, small_size));
@@ -461,7 +454,7 @@ static int bloblist_test_shrink(struct
unit_test_state *uts)
ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); /* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1); strcpy(blob1, test1_str);
@@ -511,7 +504,7 @@ static int bloblist_test_resize_fail(struct
unit_test_state *uts)
ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); /* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1);
@@ -548,7 +541,7 @@ static int bloblist_test_resize_last(struct
unit_test_state *uts)
hdr = ptr; /* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1);
@@ -593,7 +586,7 @@ static int bloblist_test_blob_maxsize(struct
unit_test_state *uts)
/* At the start there should be no records */ clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); /* Add a blob that takes up all space */ size = TEST_BLOBLIST_SIZE - sizeof(struct bloblist_hdr) -
-- 2.25.1

From: Simon Glass sjg@chromium.org
There are no spare values in spec v0.9 so drop them.
For now they are still present in the headers, with an underscore, so that tests continue to pass.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- common/bloblist.c | 1 - include/bloblist.h | 6 ++---- test/bloblist.c | 4 ---- 3 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index 4d01772c3b..691f86f600 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -163,7 +163,6 @@ static int bloblist_addrec(uint tag, int size, int align_log2, rec->tag = tag; rec->hdr_size = data_start - hdr->alloced; rec->size = size; - rec->spare = 0;
/* Zero the record data */ memset((void *)rec + rec_hdr_size(rec), '\0', rec->size); diff --git a/include/bloblist.h b/include/bloblist.h index 2b898d0c55..d46bf060d7 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -170,7 +170,6 @@ enum bloblist_tag_t { * @alloced: Total size allocated so far for this bloblist. This starts out as * sizeof(bloblist_hdr) since we need at least that much space to store a * valid bloblist - * @spare: Spare space (for future use) * @chksum: CRC32 for the entire bloblist allocated area. Since any of the * blobs can be altered after being created, this checksum is only valid * when the bloblist is finalised before jumping to the next stage of boot. @@ -185,7 +184,7 @@ struct bloblist_hdr {
u32 size; u32 alloced; - u32 spare; + u32 _spare; u32 chksum; };
@@ -202,13 +201,12 @@ struct bloblist_hdr { * record's data starts at this offset from the start of the record * @size: Size of record in bytes, excluding the header size. This does not * need to be aligned (e.g. 3 is OK). - * @spare: Spare space for other things */ struct bloblist_rec { u32 tag; u32 hdr_size; u32 size; - u32 spare; + u32 _spare; };
/** diff --git a/test/bloblist.c b/test/bloblist.c index 36994c3dd4..9e51735d83 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -202,10 +202,6 @@ static int bloblist_test_checksum(struct unit_test_state *uts) ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); hdr->size++;
- hdr->spare++; - ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); - hdr->spare--; - hdr->chksum++; ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); hdr->chksum--;

On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
There are no spare values in spec v0.9 so drop them.
For now they are still present in the headers, with an underscore, so that tests continue to pass.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 1 - include/bloblist.h | 6 ++---- test/bloblist.c | 4 ---- 3 files changed, 2 insertions(+), 9 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

From: Simon Glass sjg@chromium.org
Use a sinple 8-bit checksum for bloblist, as specified by the spec version 0.9
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- common/bloblist.c | 14 ++++++++------ include/bloblist.h | 5 ++--- 2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index 691f86f600..70ec0c13e6 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -13,6 +13,7 @@ #include <malloc.h> #include <mapmem.h> #include <spl.h> +#include <tables_csum.h> #include <asm/global_data.h> #include <u-boot/crc.h>
@@ -317,14 +318,15 @@ int bloblist_resize(uint tag, int new_size) static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) { struct bloblist_rec *rec; - u32 chksum; + u8 chksum;
- chksum = crc32(0, (unsigned char *)hdr, - offsetof(struct bloblist_hdr, chksum)); + chksum = table_compute_checksum(hdr, hdr->hdr_size); + chksum += hdr->chksum; foreach_rec(rec, hdr) { - chksum = crc32(chksum, (void *)rec, rec_hdr_size(rec)); - chksum = crc32(chksum, (void *)rec + rec_hdr_size(rec), - rec->size); + chksum -= table_compute_checksum((void *)rec, + rec_hdr_size(rec)); + chksum -= table_compute_checksum((void *)rec + + rec_hdr_size(rec), rec->size); }
return chksum; diff --git a/include/bloblist.h b/include/bloblist.h index d46bf060d7..ab7a7fc299 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -170,11 +170,10 @@ enum bloblist_tag_t { * @alloced: Total size allocated so far for this bloblist. This starts out as * sizeof(bloblist_hdr) since we need at least that much space to store a * valid bloblist - * @chksum: CRC32 for the entire bloblist allocated area. Since any of the + * @chksum: checksum for the entire bloblist allocated area. Since any of the * blobs can be altered after being created, this checksum is only valid * when the bloblist is finalised before jumping to the next stage of boot. - * Note that chksum is last to make it easier to exclude it from the - * checksum calculation. + * This is the value needed to make all checksummed bytes sum to 0 */ struct bloblist_hdr { u32 magic;

On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
Use a sinple 8-bit checksum for bloblist, as specified by the spec version 0.9
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 14 ++++++++------ include/bloblist.h | 5 ++--- 2 files changed, 10 insertions(+), 9 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

From: Simon Glass sjg@chromium.org
Spec v0.9 specifies that the entire bloblist area is checksummed, including unused portions. Update the code to follow this.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- common/bloblist.c | 9 +-------- test/bloblist.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index 70ec0c13e6..96e0a167c2 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -317,17 +317,10 @@ int bloblist_resize(uint tag, int new_size)
static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) { - struct bloblist_rec *rec; u8 chksum;
- chksum = table_compute_checksum(hdr, hdr->hdr_size); + chksum = table_compute_checksum(hdr, hdr->alloced); chksum += hdr->chksum; - foreach_rec(rec, hdr) { - chksum -= table_compute_checksum((void *)rec, - rec_hdr_size(rec)); - chksum -= table_compute_checksum((void *)rec + - rec_hdr_size(rec), rec->size); - }
return chksum; } diff --git a/test/bloblist.c b/test/bloblist.c index 9e51735d83..32256be772 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -226,12 +226,18 @@ static int bloblist_test_checksum(struct unit_test_state *uts) *data2 -= 1;
/* - * Changing data outside the range of valid data should not affect - * the checksum. + * Changing data outside the range of valid data should affect the + * checksum. */ ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); data[TEST_SIZE]++; + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + data[TEST_SIZE]--; + ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + data2[TEST_SIZE2]++; + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + data[TEST_SIZE]--; ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
return 0;

On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
Spec v0.9 specifies that the entire bloblist area is checksummed, including unused portions. Update the code to follow this.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 9 +-------- test/bloblist.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 10 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

From: Simon Glass sjg@chromium.org
Rather than setting the alignment using the header size, add an entirely new entry to cover the gap left by the alignment.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- common/bloblist.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index 96e0a167c2..59a092d4cd 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -140,7 +140,7 @@ static int bloblist_addrec(uint tag, int size, int align_log2, { struct bloblist_hdr *hdr = gd->bloblist; struct bloblist_rec *rec; - int data_start, new_alloced; + int data_start, aligned_start, new_alloced;
if (!align_log2) align_log2 = BLOBLIST_ALIGN_LOG2; @@ -149,10 +149,25 @@ static int bloblist_addrec(uint tag, int size, int align_log2, data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec);
/* Align the address and then calculate the offset from ->alloced */ - data_start = ALIGN(data_start, 1U << align_log2) - map_to_sysmem(hdr); + aligned_start = ALIGN(data_start, 1U << align_log2) - data_start; + + /* If we need to create a dummy record, create it */ + if (aligned_start) { + int void_size = aligned_start - sizeof(*rec); + struct bloblist_rec *vrec; + int ret; + + ret = bloblist_addrec(BLOBLISTT_VOID, void_size, 0, &vrec); + if (ret) + return log_msg_ret("void", ret); + + /* start the record after that */ + data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*vrec); + }
/* Calculate the new allocated total */ - new_alloced = data_start + ALIGN(size, 1U << align_log2); + new_alloced = data_start - map_to_sysmem(hdr) + + ALIGN(size, 1U << align_log2);
if (new_alloced > hdr->size) { log_err("Failed to allocate %x bytes size=%x, need size=%x\n", @@ -162,7 +177,7 @@ static int bloblist_addrec(uint tag, int size, int align_log2, rec = (void *)hdr + hdr->alloced;
rec->tag = tag; - rec->hdr_size = data_start - hdr->alloced; + rec->hdr_size = sizeof(struct bloblist_rec); rec->size = size;
/* Zero the record data */

On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
Rather than setting the alignment using the header size, add an entirely new entry to cover the gap left by the alignment.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
I am not comfortable with this approach as it makes it more complicated to reused unused areas, but it is what we have ended up with.

From: Simon Glass sjg@chromium.org
The v0.9 spec provides for an 8-byte header for each blob, with fewer fields. The blob start address should be aligned to the alignment specified by the bloblist header. Update the implementation to match this.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - Update the blob start address to align to the alignment required by the bloblist header. - Define the macros of bloblist header size and bloblist record header size as the size of their structures.
common/bloblist.c | 17 +++++++++-------- include/bloblist.h | 33 ++++++++++++++++++++++----------- test/bloblist.c | 16 ++++++++-------- 3 files changed, 39 insertions(+), 27 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index 59a092d4cd..55a7e1f591 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -85,12 +85,14 @@ static struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr)
static inline uint rec_hdr_size(struct bloblist_rec *rec) { - return rec->hdr_size; + return (rec->tag_and_hdr_size & BLOBLISTR_HDR_SIZE_MASK) >> + BLOBLISTR_HDR_SIZE_SHIFT; }
static inline uint rec_tag(struct bloblist_rec *rec) { - return rec->tag; + return (rec->tag_and_hdr_size & BLOBLISTR_TAG_MASK) >> + BLOBLISTR_TAG_SHIFT; }
static ulong bloblist_blob_end_ofs(struct bloblist_hdr *hdr, @@ -99,7 +101,7 @@ static ulong bloblist_blob_end_ofs(struct bloblist_hdr *hdr, ulong offset;
offset = (void *)rec - (void *)hdr; - offset += rec_hdr_size(rec) + ALIGN(rec->size, BLOBLIST_ALIGN); + offset += rec_hdr_size(rec) + ALIGN(rec->size, 1 << hdr->align_log2);
return offset; } @@ -143,7 +145,7 @@ static int bloblist_addrec(uint tag, int size, int align_log2, int data_start, aligned_start, new_alloced;
if (!align_log2) - align_log2 = BLOBLIST_ALIGN_LOG2; + align_log2 = BLOBLIST_BLOB_ALIGN_LOG2;
/* Figure out where the new data will start */ data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec); @@ -176,8 +178,7 @@ static int bloblist_addrec(uint tag, int size, int align_log2, } rec = (void *)hdr + hdr->alloced;
- rec->tag = tag; - rec->hdr_size = sizeof(struct bloblist_rec); + rec->tag_and_hdr_size = tag | sizeof(*rec) << BLOBLISTR_HDR_SIZE_SHIFT; rec->size = size;
/* Zero the record data */ @@ -281,8 +282,8 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr, int new_alloced; /* New value for @hdr->alloced */ ulong next_ofs; /* Offset of the record after @rec */
- expand_by = ALIGN(new_size - rec->size, BLOBLIST_ALIGN); - new_alloced = ALIGN(hdr->alloced + expand_by, BLOBLIST_ALIGN); + expand_by = ALIGN(new_size - rec->size, BLOBLIST_BLOB_ALIGN); + new_alloced = ALIGN(hdr->alloced + expand_by, BLOBLIST_BLOB_ALIGN); if (new_size < 0) { log_debug("Attempt to shrink blob size below 0 (%x)\n", new_size); diff --git a/include/bloblist.h b/include/bloblist.h index ab7a7fc299..745bcdd227 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -24,11 +24,11 @@ * which would add to code size. For Thumb-2 the code size needed in SPL is * approximately 940 bytes (e.g. for chromebook_bob). * - * 5. Bloblist uses 16-byte alignment internally and is designed to start on a - * 16-byte boundary. Its headers are multiples of 16 bytes. This makes it easier - * to deal with data structures which need this level of alignment, such as ACPI - * tables. For use in SPL and TPL the alignment can be relaxed, since it can be - * relocated to an aligned address in U-Boot proper. + * 5. Bloblist uses 8-byte alignment internally and is designed to start on a + * 8-byte boundary. Its headers are 8 bytes long. It is possible to achieve + * larger alignment (e.g. 16 bytes) by adding a dummy header, For use in SPL and + * TPL the alignment can be relaxed, since it can be relocated to an aligned + * address in U-Boot proper. * * 6. Bloblist is designed to be passed to Linux as reserved memory. While linux * doesn't understand the bloblist header, it can be passed the indivdual blobs. @@ -77,6 +77,9 @@ enum { BLOBLIST_VERSION = 1, BLOBLIST_MAGIC = 0x6ed0ff,
+ BLOBLIST_BLOB_ALIGN_LOG2 = 3, + BLOBLIST_BLOB_ALIGN = 1 << BLOBLIST_BLOB_ALIGN_LOG2, + BLOBLIST_ALIGN_LOG2 = 3, BLOBLIST_ALIGN = 1 << BLOBLIST_ALIGN_LOG2, }; @@ -195,17 +198,25 @@ struct bloblist_hdr { * * NOTE: Only exported for testing purposes. Do not use this struct. * - * @tag: Tag indicating what the record contains - * @hdr_size: Size of this header, normally sizeof(struct bloblist_rec). The - * record's data starts at this offset from the start of the record + * @tag_and_hdr_size: Tag indicating what the record contains (bottom 24 bits), and + * size of this header (top 8 bits), normally sizeof(struct bloblist_rec). + * The record's data starts at this offset from the start of the record * @size: Size of record in bytes, excluding the header size. This does not * need to be aligned (e.g. 3 is OK). */ struct bloblist_rec { - u32 tag; - u32 hdr_size; + u32 tag_and_hdr_size; u32 size; - u32 _spare; +}; + +enum { + BLOBLISTR_TAG_SHIFT = 0, + BLOBLISTR_TAG_MASK = 0xffffffU << BLOBLISTR_TAG_SHIFT, + BLOBLISTR_HDR_SIZE_SHIFT = 24, + BLOBLISTR_HDR_SIZE_MASK = 0xffU << BLOBLISTR_HDR_SIZE_SHIFT, + + BLOBLIST_HDR_SIZE = sizeof(struct bloblist_hdr), + BLOBLIST_REC_HDR_SIZE = sizeof(struct bloblist_rec), };
/** diff --git a/test/bloblist.c b/test/bloblist.c index 32256be772..7e65f30518 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -261,8 +261,8 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) run_command("bloblist info", 0); ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr)); ut_assert_nextline("size: 400 1 KiB"); - ut_assert_nextline("alloced: 70 112 Bytes"); - ut_assert_nextline("free: 390 912 Bytes"); + ut_assert_nextline("alloced: 58 88 Bytes"); + ut_assert_nextline("free: 3a8 936 Bytes"); ut_assert_console_end(); ut_unsilence_console(uts);
@@ -320,12 +320,12 @@ static int bloblist_test_align(struct unit_test_state *uts) data = bloblist_add(i, size, 0); ut_assertnonnull(data); addr = map_to_sysmem(data); - ut_asserteq(0, addr & (BLOBLIST_ALIGN - 1)); + ut_asserteq(0, addr & (BLOBLIST_BLOB_ALIGN - 1));
/* Only the bytes in the blob data should be zeroed */ for (j = 0; j < size; j++) ut_asserteq(0, data[j]); - for (; j < BLOBLIST_ALIGN; j++) + for (; j < BLOBLIST_BLOB_ALIGN; j++) ut_asserteq(ERASE_BYTE, data[j]); }
@@ -340,7 +340,7 @@ static int bloblist_test_align(struct unit_test_state *uts) }
/* Check alignment with an bloblist starting on a smaller alignment */ - hdr = map_sysmem(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE); + hdr = map_sysmem(TEST_ADDR + BLOBLIST_BLOB_ALIGN, TEST_BLOBLIST_SIZE); memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); memset(hdr, '\0', sizeof(*hdr)); ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, @@ -349,7 +349,7 @@ static int bloblist_test_align(struct unit_test_state *uts) data = bloblist_add(1, 5, BLOBLIST_ALIGN_LOG2 + 1); ut_assertnonnull(data); addr = map_to_sysmem(data); - ut_asserteq(0, addr & (BLOBLIST_ALIGN * 2 - 1)); + ut_asserteq(0, addr & (BLOBLIST_BLOB_ALIGN * 2 - 1));
return 0; } @@ -437,7 +437,7 @@ static int bloblist_test_grow(struct unit_test_state *uts) hdr = ptr; ut_asserteq(sizeof(struct bloblist_hdr) + sizeof(struct bloblist_rec) * 2 + small_size * 2 + - BLOBLIST_ALIGN, + BLOBLIST_BLOB_ALIGN, hdr->alloced);
return 0; @@ -572,7 +572,7 @@ static int bloblist_test_resize_last(struct unit_test_state *uts) ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + alloced_val + 4));
/* Check that the new top of the allocated blobs has not been touched */ - alloced_val += BLOBLIST_ALIGN; + alloced_val += BLOBLIST_BLOB_ALIGN; ut_asserteq(alloced_val, hdr->alloced); ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->alloced));

On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
The v0.9 spec provides for an 8-byte header for each blob, with fewer fields. The blob start address should be aligned to the alignment specified by the bloblist header. Update the implementation to match this.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Update the blob start address to align to the alignment required by the bloblist header.
- Define the macros of bloblist header size and bloblist record header size as the size of their structures.
common/bloblist.c | 17 +++++++++-------- include/bloblist.h | 33 ++++++++++++++++++++++----------- test/bloblist.c | 16 ++++++++-------- 3 files changed, 39 insertions(+), 27 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

From: Simon Glass sjg@chromium.org
The v0.9 spec provides for a 16-byte header with fewer fields. Update the implementation to match this.
This also adds an alignment field.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- include/bloblist.h | 26 +++++++++++++------------- test/bloblist.c | 6 +++--- 2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/include/bloblist.h b/include/bloblist.h index 745bcdd227..57625ea004 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -164,30 +164,30 @@ enum bloblist_tag_t { * from the last. * * @magic: BLOBLIST_MAGIC + * @chksum: checksum for the entire bloblist allocated area. Since any of the + * blobs can be altered after being created, this checksum is only valid + * when the bloblist is finalised before jumping to the next stage of boot. + * This is the value needed to make all chechksummed bytes sum to 0 * @version: BLOBLIST_VERSION * @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The * first bloblist_rec starts at this offset from the start of the header - * @size: Total size of the bloblist (non-zero if valid) including this header. - * The bloblist extends for this many bytes from the start of this header. - * When adding new records, the bloblist can grow up to this size. + * @align_log2: Power of two of the maximum alignment required by this list * @alloced: Total size allocated so far for this bloblist. This starts out as * sizeof(bloblist_hdr) since we need at least that much space to store a * valid bloblist - * @chksum: checksum for the entire bloblist allocated area. Since any of the - * blobs can be altered after being created, this checksum is only valid - * when the bloblist is finalised before jumping to the next stage of boot. - * This is the value needed to make all checksummed bytes sum to 0 + * @size: Total size of the bloblist (non-zero if valid) including this header. + * The bloblist extends for this many bytes from the start of this header. + * When adding new records, the bloblist can grow up to this size. */ struct bloblist_hdr { u32 magic; - u32 version; - u32 hdr_size; - u32 _flags; + u8 chksum; + u8 version; + u8 hdr_size; + u8 align_log2;
- u32 size; u32 alloced; - u32 _spare; - u32 chksum; + u32 size; };
/** diff --git a/test/bloblist.c b/test/bloblist.c index 7e65f30518..be237c6155 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -78,7 +78,7 @@ static int bloblist_test_init(struct unit_test_state *uts) ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10)); + ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0xc)); ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE));
@@ -261,8 +261,8 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) run_command("bloblist info", 0); ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr)); ut_assert_nextline("size: 400 1 KiB"); - ut_assert_nextline("alloced: 58 88 Bytes"); - ut_assert_nextline("free: 3a8 936 Bytes"); + ut_assert_nextline("alloced: 48 72 Bytes"); + ut_assert_nextline("free: 3b8 952 Bytes"); ut_assert_console_end(); ut_unsilence_console(uts);

On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
The v0.9 spec provides for a 16-byte header with fewer fields. Update the implementation to match this.
This also adds an alignment field.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
include/bloblist.h | 26 +++++++++++++------------- test/bloblist.c | 6 +++--- 2 files changed, 16 insertions(+), 16 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Sadly this will need a later patch to deal with [1]
[1] https://github.com/FirmwareHandoff/firmware_handoff/pull/17/commits/331822f1...

Ah I guess this fixes my concerns on patch #6
On Mon, 27 Nov 2023 at 21:53, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
The v0.9 spec provides for a 16-byte header with fewer fields. Update the implementation to match this.
This also adds an alignment field.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
include/bloblist.h | 26 +++++++++++++------------- test/bloblist.c | 6 +++--- 2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/include/bloblist.h b/include/bloblist.h index 745bcdd227..57625ea004 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -164,30 +164,30 @@ enum bloblist_tag_t {
- from the last.
- @magic: BLOBLIST_MAGIC
- @chksum: checksum for the entire bloblist allocated area. Since any of the
blobs can be altered after being created, this checksum is only valid
when the bloblist is finalised before jumping to the next stage of boot.
This is the value needed to make all chechksummed bytes sum to 0
typos checksummed and finalized
[...]
With the typos fixed
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org

Hi,
On Mon, 4 Dec 2023 at 01:39, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Ah I guess this fixes my concerns on patch #6
On Mon, 27 Nov 2023 at 21:53, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
The v0.9 spec provides for a 16-byte header with fewer fields. Update the implementation to match this.
This also adds an alignment field.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
include/bloblist.h | 26 +++++++++++++------------- test/bloblist.c | 6 +++--- 2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/include/bloblist.h b/include/bloblist.h index 745bcdd227..57625ea004 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -164,30 +164,30 @@ enum bloblist_tag_t {
- from the last.
- @magic: BLOBLIST_MAGIC
- @chksum: checksum for the entire bloblist allocated area. Since any of the
blobs can be altered after being created, this checksum is only valid
when the bloblist is finalised before jumping to the next stage of boot.
This is the value needed to make all chechksummed bytes sum to 0
typos checksummed and finalized
finalised is correct
[...]
With the typos fixed
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org
REgards, Simon

From: Simon Glass sjg@chromium.org
Allow the alignment to be specified when creating a bloblist.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- common/bloblist.c | 5 +++-- include/bloblist.h | 3 ++- test/bloblist.c | 40 ++++++++++++++++++++++------------------ 3 files changed, 27 insertions(+), 21 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index 55a7e1f591..0d482ecd71 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -341,7 +341,7 @@ static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) return chksum; }
-int bloblist_new(ulong addr, uint size) +int bloblist_new(ulong addr, uint size, uint align_log2) { struct bloblist_hdr *hdr;
@@ -356,6 +356,7 @@ int bloblist_new(ulong addr, uint size) hdr->magic = BLOBLIST_MAGIC; hdr->size = size; hdr->alloced = hdr->hdr_size; + hdr->align_log2 = align_log2 ?: BLOBLIST_BLOB_ALIGN_LOG2; hdr->chksum = 0; gd->bloblist = hdr;
@@ -499,7 +500,7 @@ int bloblist_init(void) } log_debug("Creating new bloblist size %lx at %lx\n", size, addr); - ret = bloblist_new(addr, size); + ret = bloblist_new(addr, size, 0); } else { log_debug("Found existing bloblist size %lx at %lx\n", size, addr); diff --git a/include/bloblist.h b/include/bloblist.h index 57625ea004..c419c0d923 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -324,10 +324,11 @@ int bloblist_resize(uint tag, int new_size); * * @addr: Address of bloblist * @size: Initial size for bloblist + * @align_log2: Log base 2 of maximum alignment provided by this bloblist * Return: 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the * area is not large enough */ -int bloblist_new(ulong addr, uint size); +int bloblist_new(ulong addr, uint size, uint align_log2);
/** * bloblist_check() - Check if a bloblist exists diff --git a/test/bloblist.c b/test/bloblist.c index be237c6155..b72603ba9a 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -72,15 +72,15 @@ static int bloblist_test_init(struct unit_test_state *uts) hdr = clear_bloblist(); ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR)); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); ut_asserteq_ptr(hdr, bloblist_check_magic(TEST_ADDR)); hdr->version++; ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0xc)); - ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE)); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0xc, 0)); + ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_finish()); @@ -103,7 +103,7 @@ static int bloblist_test_blob(struct unit_test_state *uts) /* At the start there should be no records */ hdr = clear_bloblist(); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_size()); ut_asserteq(TEST_ADDR, bloblist_get_base()); ut_asserteq(map_to_sysmem(hdr), TEST_ADDR); @@ -141,7 +141,7 @@ static int bloblist_test_blob_ensure(struct unit_test_state *uts)
/* At the start there should be no records */ clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
/* Test with an empty bloblist */ size = TEST_SIZE; @@ -173,7 +173,7 @@ static int bloblist_test_bad_blob(struct unit_test_state *uts) void *data;
hdr = clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); data = hdr + 1; data += sizeof(struct bloblist_rec); ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); @@ -189,7 +189,7 @@ static int bloblist_test_checksum(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); ut_assertok(bloblist_finish()); ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
@@ -206,6 +206,10 @@ static int bloblist_test_checksum(struct unit_test_state *uts) ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); hdr->chksum--;
+ hdr->align_log2++; + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + hdr->align_log2--; + /* Make sure the checksum changes when we add blobs */ data = bloblist_add(TEST_TAG, TEST_SIZE, 0); ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); @@ -251,7 +255,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); data = bloblist_ensure(TEST_TAG, TEST_SIZE); data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@@ -277,7 +281,7 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts) char *data, *data2;
hdr = clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); data = bloblist_ensure(TEST_TAG, TEST_SIZE); data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@@ -307,7 +311,7 @@ static int bloblist_test_align(struct unit_test_state *uts)
/* At the start there should be no records */ hdr = clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
/* Check the default alignment */ @@ -344,7 +348,7 @@ static int bloblist_test_align(struct unit_test_state *uts) memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); memset(hdr, '\0', sizeof(*hdr)); ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, - TEST_BLOBLIST_SIZE)); + TEST_BLOBLIST_SIZE, 0));
data = bloblist_add(1, 5, BLOBLIST_ALIGN_LOG2 + 1); ut_assertnonnull(data); @@ -365,7 +369,7 @@ static int bloblist_test_reloc(struct unit_test_state *uts) ulong new_addr; ulong new_size;
- ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); old_ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Add one blob and then one that won't fit */ @@ -404,7 +408,7 @@ static int bloblist_test_grow(struct unit_test_state *uts) memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
/* Create two blobs */ - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1); ut_assertok(check_zero(blob1, small_size)); @@ -456,7 +460,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts) ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Create two blobs */ - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1); strcpy(blob1, test1_str); @@ -506,7 +510,7 @@ static int bloblist_test_resize_fail(struct unit_test_state *uts) ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Create two blobs */ - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1);
@@ -543,7 +547,7 @@ static int bloblist_test_resize_last(struct unit_test_state *uts) hdr = ptr;
/* Create two blobs */ - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); blob1 = bloblist_add(TEST_TAG, small_size, 0); ut_assertnonnull(blob1);
@@ -588,7 +592,7 @@ static int bloblist_test_blob_maxsize(struct unit_test_state *uts)
/* At the start there should be no records */ clear_bloblist(); - ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
/* Add a blob that takes up all space */ size = TEST_BLOBLIST_SIZE - sizeof(struct bloblist_hdr) -

On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
Allow the alignment to be specified when creating a bloblist.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
common/bloblist.c | 5 +++-- include/bloblist.h | 3 ++- test/bloblist.c | 40 ++++++++++++++++++++++------------------ 3 files changed, 27 insertions(+), 21 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

From: Simon Glass sjg@chromium.org
Align the documentation with the v0.9 spec.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- doc/develop/bloblist.rst | 4 +++- include/bloblist.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/doc/develop/bloblist.rst b/doc/develop/bloblist.rst index 81643c7674..28431039ad 100644 --- a/doc/develop/bloblist.rst +++ b/doc/develop/bloblist.rst @@ -14,6 +14,8 @@ structure defined by the code that owns it. For the design goals of bloblist, please see the comments at the top of the `bloblist.h` header file.
+Bloblist is an implementation with the `Firmware Handoff`_ protocol. + Passing state through the boot process --------------------------------------
@@ -99,7 +101,7 @@ API documentation -----------------
.. kernel-doc:: include/bloblist.h - +.. _`Firmware Handoff`: https://github.com/FirmwareHandoff/firmware_handoff
Simon Glass sjg@chromium.org diff --git a/include/bloblist.h b/include/bloblist.h index c419c0d923..148a94fcd1 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -66,6 +66,7 @@ * * Copyright 2018 Google, Inc * Written by Simon Glass sjg@chromium.org + * Adjusted July 2023 to match Firmware handoff specification, Release 0.9 */
#ifndef __BLOBLIST_H

On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
Align the documentation with the v0.9 spec.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
doc/develop/bloblist.rst | 4 +++- include/bloblist.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org

From: Simon Glass sjg@chromium.org
Standard passage provides for a bloblist to be passed from one firmware phase to the next. That can be used to pass the devicetree along as well. If CONFIG_OF_BOARD is defined, a board custom routine will provide a bloblist or a specified memory address to retrieve the devicetree at runtime. A devicetree from a bloblist is prioritized than the one from specified memory region.
Tests for this will be added as part of the Universal Payload work.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - New patch file created for v2. Amended from the original patch "[v2,30/32] fdt: Allow the devicetree to come from a bloblist". Remove CONFIG_OF_BLOBLIST and FDTSRC_BLOBLIST, a DTB from a previous loader is defined by CONFIG_OF_BOARD. The DTB can be located either in the bloblist or from a specified memory address.
doc/develop/devicetree/control.rst | 8 +++-- dts/Kconfig | 9 ++++-- include/fdtdec.h | 3 +- lib/fdtdec.c | 52 +++++++++++++++++++++++------- 4 files changed, 53 insertions(+), 19 deletions(-)
diff --git a/doc/develop/devicetree/control.rst b/doc/develop/devicetree/control.rst index cbb65c9b17..a7f0f87841 100644 --- a/doc/develop/devicetree/control.rst +++ b/doc/develop/devicetree/control.rst @@ -104,9 +104,11 @@ in u-boot.bin so you can still just flash u-boot.bin onto your board. If you are using CONFIG_SPL_FRAMEWORK, then u-boot.img will be built to include the device tree binary.
-If CONFIG_OF_BOARD is defined, a board-specific routine will provide the -devicetree at runtime, for example if an earlier bootloader stage creates -it and passes it to U-Boot. +If CONFIG_OF_BOARD is defined, a board-specific routine will provide a bloblist +or a specified memory region to retrieve the devicetree at runtime, for example +if an earlier bootloader stage creates it and passes it to U-Boot. +A devicetree from a bloblist is prioritized than the one from a specified memory +region.
If CONFIG_SANDBOX is defined, then it will be read from a file on startup. Use the -d flag to U-Boot to specify the file to read, -D for the diff --git a/dts/Kconfig b/dts/Kconfig index 00c0aeff89..4faf4ba633 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -110,8 +110,13 @@ config OF_BOARD default y if SANDBOX || OF_HAS_PRIOR_STAGE help If this option is enabled, the device tree is provided at runtime by - a custom function called board_fdt_blob_setup(). The board must - implement this function if it wishes to provide special behaviour. + bloblist via a custom function called board_bloblist_from_boot_arg() + or a memory region from a custom function called + board_fdt_blob_setup(). The board must implement either these + functions if it wishes to provide special behaviour. + + A devicetree from a bloblist is prioritized then the one from a + specified memory region if the board provides both methods.
With this option, the device tree build by U-Boot may be overridden or ignored. See OF_HAS_PRIOR_STAGE. diff --git a/include/fdtdec.h b/include/fdtdec.h index bd1149f46d..0824fe1359 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -72,14 +72,13 @@ struct bd_info; * U-Boot is packaged as an ELF file, e.g. for debugging purposes * @FDTSRC_ENV: Provided by the fdtcontroladdr environment variable. This should * be used for debugging/development only - * @FDTSRC_NONE: No devicetree at all */ enum fdt_source_t { FDTSRC_SEPARATE, FDTSRC_FIT, FDTSRC_BOARD, FDTSRC_EMBED, - FDTSRC_ENV, + FDTSRC_ENV };
/* diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 7a69167648..025baca4a4 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -7,7 +7,11 @@ */
#ifndef USE_HOSTCC + +#define LOG_CATEGORY LOGC_DT + #include <common.h> +#include <bloblist.h> #include <boot_fit.h> #include <display_options.h> #include <dm.h> @@ -86,7 +90,7 @@ static const char *const fdt_src_name[] = { [FDTSRC_FIT] = "fit", [FDTSRC_BOARD] = "board", [FDTSRC_EMBED] = "embed", - [FDTSRC_ENV] = "env", + [FDTSRC_ENV] = "env" };
const char *fdtdec_get_srcname(void) @@ -1665,21 +1669,45 @@ int fdtdec_setup(void) { int ret;
- /* The devicetree is typically appended to U-Boot */ - if (IS_ENABLED(CONFIG_OF_SEPARATE)) { - gd->fdt_blob = fdt_find_separate(); - gd->fdt_src = FDTSRC_SEPARATE; - } else { /* embed dtb in ELF file for testing / development */ - gd->fdt_blob = dtb_dt_embedded(); - gd->fdt_src = FDTSRC_EMBED; - } - - /* Allow the board to override the fdt address. */ + /* + * The devicetree is typically appended to U-Boot. + * Option 1: From bloblist. + * Option 2: From a specified memory address. + */ if (IS_ENABLED(CONFIG_OF_BOARD)) { - gd->fdt_blob = board_fdt_blob_setup(&ret); + /* + * DTB is from board. + * Either from bloblist or a platform specified memory. + */ + ret = bloblist_maybe_init(); if (ret) return ret; + + /* Check if a DTB exists in bloblist first */ + if (IS_ENABLED(CONFIG_BLOBLIST)) { + gd->fdt_blob = bloblist_find(BLOBLISTT_CONTROL_FDT, 0); + if (gd->fdt_blob) { + log_info("Fdt from bloblist at 0x%lx\n", + (unsigned long)gd->fdt_blob); + } + } + if (!gd->fdt_blob) { + /* Apply DTB from a platform specified memory */ + gd->fdt_blob = board_fdt_blob_setup(&ret); + if (ret) + return ret; + log_info("Fdt from memory at 0x%lx\n", + (unsigned long)gd->fdt_blob); + } gd->fdt_src = FDTSRC_BOARD; + } else { + if (IS_ENABLED(CONFIG_OF_SEPARATE)) { + gd->fdt_blob = fdt_find_separate(); + gd->fdt_src = FDTSRC_SEPARATE; + } else { /* embed dtb in ELF file for testing / development */ + gd->fdt_blob = dtb_dt_embedded(); + gd->fdt_src = FDTSRC_EMBED; + } }
/* Allow the early environment to override the fdt address */

Hi Raymond,
On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
Standard passage provides for a bloblist to be passed from one firmware phase to the next. That can be used to pass the devicetree along as well. If CONFIG_OF_BOARD is defined, a board custom routine will provide a bloblist or a specified memory address to retrieve the devicetree at runtime. A devicetree from a bloblist is prioritized than the one from specified memory region.
Tests for this will be added as part of the Universal Payload work.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- New patch file created for v2. Amended from the original patch "[v2,30/32] fdt: Allow the devicetree to come from a bloblist". Remove CONFIG_OF_BLOBLIST and FDTSRC_BLOBLIST, a DTB from a previous loader is defined by CONFIG_OF_BOARD. The DTB can be located either in the bloblist or from a specified memory address.
doc/develop/devicetree/control.rst | 8 +++-- dts/Kconfig | 9 ++++-- include/fdtdec.h | 3 +- lib/fdtdec.c | 52 +++++++++++++++++++++++------- 4 files changed, 53 insertions(+), 19 deletions(-)
This is a bit mangled. I spoke to Ilias about this as osfc and thought we had it figured out, but it was a bit rushed so perhaps not.
OF_BOARD refers to a board-specific mechanism
We should have OF_BLOBLIST to reference to this, a standard mechanism and not board-specific.
Ideally all boards should use a bloblist to send their DT to U-Boot. E.g. Raspberry Pi.
So I believe my original patch was closer to what we want.
Regards, SImon

Hi Simon,
When `OF_BOARD` is defined, the FDT should be from one of the board-specific mechanisms: 1. FDT from a bloblist via boot args 2. FDT in memory I don't think we need a new build option to distinguish these two, since it can be done in runtime by checking whether the boot args follow the FW Handoff spec conventions and the FDT exists in the bloblist. If it fulfills the above conditions, we can take the FDT from bloblist, otherwise from the predefined memory address. This is fully backward compatible without adding a new build option.
Regards, Raymond
On Sat, 2 Dec 2023 at 13:32, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
From: Simon Glass sjg@chromium.org
Standard passage provides for a bloblist to be passed from one firmware phase to the next. That can be used to pass the devicetree along as well. If CONFIG_OF_BOARD is defined, a board custom routine will provide a bloblist or a specified memory address to retrieve the devicetree at runtime. A devicetree from a bloblist is prioritized than the one from specified memory region.
Tests for this will be added as part of the Universal Payload work.
Signed-off-by: Simon Glass sjg@chromium.org Co-developed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- New patch file created for v2. Amended from the original patch "[v2,30/32] fdt: Allow the devicetree to come from a bloblist". Remove CONFIG_OF_BLOBLIST and FDTSRC_BLOBLIST, a DTB from a previous loader is defined by CONFIG_OF_BOARD. The DTB can be located either in
the
bloblist or from a specified memory address.
doc/develop/devicetree/control.rst | 8 +++-- dts/Kconfig | 9 ++++-- include/fdtdec.h | 3 +- lib/fdtdec.c | 52 +++++++++++++++++++++++------- 4 files changed, 53 insertions(+), 19 deletions(-)
This is a bit mangled. I spoke to Ilias about this as osfc and thought we had it figured out, but it was a bit rushed so perhaps not.
OF_BOARD refers to a board-specific mechanism
We should have OF_BLOBLIST to reference to this, a standard mechanism and not board-specific.
Ideally all boards should use a bloblist to send their DT to U-Boot. E.g. Raspberry Pi.
So I believe my original patch was closer to what we want.
Regards, SImon

Hi Raymond,
On Mon, 4 Dec 2023 at 12:25, Raymond Mao raymond.mao@linaro.org wrote:
Hi Simon,
When `OF_BOARD` is defined, the FDT should be from one of the board-specific mechanisms:
- FDT from a bloblist via boot args
- FDT in memory
I don't think we need a new build option to distinguish these two, since it can be done in runtime by checking whether the boot args follow the FW Handoff spec conventions and the FDT exists in the bloblist.
No, I would really like this to be deterministic, so we can fail if something goes wrong. The bloblist should be 'declared' as the way to boot, for a board.
If in the future all boards a reusing bloblist for this feature, then sure, we can drop it. But we have things like rpi which do their own thing.
If it fulfills the above conditions, we can take the FDT from bloblist, otherwise from the predefined memory address. This is fully backward compatible without adding a new build option.
Again, we need to obtain the FDT from the bloblist if and only if the board requires it. It creates a lot of confusion to have it as an optional feature, when we know which way it should be.
Ultimately OF_BOARD should go away. We just need to push bloblist to other projects and closed-source firmware as the correct way to pass a DT.
Regards, Simon [.]

Hi Simon,
We did discuss this in OSFC but perhaps you forgot. The discussion was based on the mail here [0].
On Tue, 5 Dec 2023 at 02:52, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Mon, 4 Dec 2023 at 12:25, Raymond Mao raymond.mao@linaro.org wrote:
Hi Simon,
When `OF_BOARD` is defined, the FDT should be from one of the board-specific mechanisms:
- FDT from a bloblist via boot args
- FDT in memory
I don't think we need a new build option to distinguish these two, since it can be done in runtime by checking whether the boot args follow the FW Handoff spec conventions and the FDT exists in the bloblist.
No, I would really like this to be deterministic, so we can fail if something goes wrong. The bloblist should be 'declared' as the way to boot, for a board.
We *are* deterministic. I am just going to repeat what we discussed in OSFC for completeness. OF_BLOBLIST makes little sense because we are not going to add a Kconfig per blolblist entry. I haven't looked at what the patch does yet but the idea was really simple. - Under OF_BOARD (which can arguably be renamed to OF_PREVIOUS_STAGE or something like that) if CONFIG_BLOB is enabled we scan for a bloblist - If CONFIG_BLOB is enabled but no bloblist is provided we fail the boot - If CONFIG_BLOB is not enabled we do what we did up to now, maybe with a message that this is going to be obsoleted once enough boards migrate to a bloblist
IOW if support for a bloblist is enabled we expect to find one from the previous bootloader. I've lost count of how many times I repeated this, but here it goes again The device tree can come - From u-boot - From a previous stage loader *somehow* (eg. passed on a bloblist, passed on a register, read from an EEPROM etc)
We should keep that distinction and create subcategories for the 'comes from a previous stage loader', rather than adding arbitrary config options which only confuse people
Regards /Ilias
If in the future all boards a reusing bloblist for this feature, then sure, we can drop it. But we have things like rpi which do their own thing.
If it fulfills the above conditions, we can take the FDT from bloblist, otherwise from the predefined memory address. This is fully backward compatible without adding a new build option.
Again, we need to obtain the FDT from the bloblist if and only if the board requires it. It creates a lot of confusion to have it as an optional feature, when we know which way it should be.
Ultimately OF_BOARD should go away. We just need to push bloblist to other projects and closed-source firmware as the correct way to pass a DT.
Regards, Simon [.]
[0] https://lore.kernel.org/u-boot/CAPnjgZ0SqVyj_drLEQrP21zPYCco3HOP-rYD+nKJMa0B...

Hi Ilias,
On Mon, 4 Dec 2023 at 23:22, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Simon,
We did discuss this in OSFC but perhaps you forgot. The discussion was based on the mail here [0].
Perhaps I did? Or perhaps we had a different understanding of it?
On Tue, 5 Dec 2023 at 02:52, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Mon, 4 Dec 2023 at 12:25, Raymond Mao raymond.mao@linaro.org wrote:
Hi Simon,
When `OF_BOARD` is defined, the FDT should be from one of the board-specific mechanisms:
- FDT from a bloblist via boot args
- FDT in memory
I don't think we need a new build option to distinguish these two, since it can be done in runtime by checking whether the boot args follow the FW Handoff spec conventions and the FDT exists in the bloblist.
No, I would really like this to be deterministic, so we can fail if something goes wrong. The bloblist should be 'declared' as the way to boot, for a board.
We *are* deterministic. I am just going to repeat what we discussed in OSFC for completeness. OF_BLOBLIST makes little sense because we are not going to add a Kconfig per blolblist entry. I haven't looked at what the patch does yet but the idea was really simple.
- Under OF_BOARD (which can arguably be renamed to OF_PREVIOUS_STAGE
or something like that) if CONFIG_BLOB is enabled we scan for a bloblist
- If CONFIG_BLOB is enabled but no bloblist is provided we fail the boot
- If CONFIG_BLOB is not enabled we do what we did up to now, maybe
with a message that this is going to be obsoleted once enough boards migrate to a bloblist
IOW if support for a bloblist is enabled we expect to find one from the previous bootloader. I've lost count of how many times I repeated this, but here it goes again The device tree can come
- From u-boot
- From a previous stage loader *somehow* (eg. passed on a bloblist,
passed on a register, read from an EEPROM etc)
We should keep that distinction and create subcategories for the 'comes from a previous stage loader', rather than adding arbitrary config options which only confuse people
I don't know why you are so frustrated about this. This patch does not even do what you have listed above, so far as I can tell.
We have: - OF_HAS_PRIOR_STAGE which indicates that U-Boot is not the first phase - OF_BOARD which indicates that the board can do anything it likes - BLOBLIST which indicates that there is a bloblist
I proposed adding: - OF_BLOBLIST which indicates that U-Boot gets the DT from the bloblist
I understood that your intention OF_BOARD would go away since there are almost no cases that need it. I was skeptical it could be done but I definitely agreed (and still do) that it would be great if that could go away, as we would not need OF_BLOBLIST since OF_BOARD would effectively mean the same thing.
But when I look at this patch, that is not what is happening. In fact, there is no indication that the DT came from the bloblist. U-Boot will just report 'devicetree: board'. We must say where it came from.
The other thing missing here is SPL. The bloblist is designed such that it can be set up in any phase of U-Boot, then is passed to following phases. So using IS_ENABLED(BLOBLIST) doesn't do what we need. As I noted, it breaks sandbox_spl. What happens if a board wants to use bloblist in SPL but doesn't want the SPL DT to come from a prior stage? What happens if SPL wants doesn't want to pass the U-Boot DT through to U-Boot in the bloblist? It is all just horribly confusing.
So I believe, in fact, that we cannot get rid of OF_BOARD now, and perhaps for quite a long time. There is another discussion about Qualcomm where they want a gzipped DT attached to the end of U-Boot, for example. Perhaps the key problem with this patch is that it would ensure that OF_BOARD sticks around, since it means both a) Get the DT from bloblist if BLOBLIST; b) Get the DT from a board-specific mechanism if !BLOBLIST. That is not what we discussed.
Why not just take my original patch and work from there? It will save a lot of time. We can then progressively migrate boards from OF_BOARD to OF_BLOBLIST and then perhaps one day remove OF_BOARD (I remain skeptical, but hopeful). The whole 'standard passage' thing [1] was carefully thought out *two years ago* and (I believe) dealt with all of the issues above.
For now, we should apply the patches which bring in the spec changes, so we can figure out the rest of it. I have added my review tag for those.
Regards, SImon
Regards /Ilias
If in the future all boards a reusing bloblist for this feature, then sure, we can drop it. But we have things like rpi which do their own thing.
If it fulfills the above conditions, we can take the FDT from bloblist, otherwise from the predefined memory address. This is fully backward compatible without adding a new build option.
Again, we need to obtain the FDT from the bloblist if and only if the board requires it. It creates a lot of confusion to have it as an optional feature, when we know which way it should be.
Ultimately OF_BOARD should go away. We just need to push bloblist to other projects and closed-source firmware as the correct way to pass a DT.
Regards, Simon [.]
[0] https://lore.kernel.org/u-boot/CAPnjgZ0SqVyj_drLEQrP21zPYCco3HOP-rYD+nKJMa0B...
[1] https://patchwork.ozlabs.org/project/uboot/list/?series=281465&state=*

Hi Simon,
On Wed, 6 Dec 2023 at 05:57, Simon Glass sjg@chromium.org wrote:
Hi Ilias,
On Mon, 4 Dec 2023 at 23:22, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Simon,
We did discuss this in OSFC but perhaps you forgot. The discussion was based on the mail here [0].
Perhaps I did? Or perhaps we had a different understanding of it?
On Tue, 5 Dec 2023 at 02:52, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Mon, 4 Dec 2023 at 12:25, Raymond Mao raymond.mao@linaro.org wrote:
Hi Simon,
When `OF_BOARD` is defined, the FDT should be from one of the board-specific mechanisms:
- FDT from a bloblist via boot args
- FDT in memory
I don't think we need a new build option to distinguish these two, since it can be done in runtime by checking whether the boot args follow the FW Handoff spec conventions and the FDT exists in the bloblist.
No, I would really like this to be deterministic, so we can fail if something goes wrong. The bloblist should be 'declared' as the way to boot, for a board.
We *are* deterministic. I am just going to repeat what we discussed in OSFC for completeness. OF_BLOBLIST makes little sense because we are not going to add a Kconfig per blolblist entry. I haven't looked at what the patch does yet but the idea was really simple.
- Under OF_BOARD (which can arguably be renamed to OF_PREVIOUS_STAGE
or something like that) if CONFIG_BLOB is enabled we scan for a bloblist
- If CONFIG_BLOB is enabled but no bloblist is provided we fail the boot
- If CONFIG_BLOB is not enabled we do what we did up to now, maybe
with a message that this is going to be obsoleted once enough boards migrate to a bloblist
IOW if support for a bloblist is enabled we expect to find one from the previous bootloader. I've lost count of how many times I repeated this, but here it goes again The device tree can come
- From u-boot
- From a previous stage loader *somehow* (eg. passed on a bloblist,
passed on a register, read from an EEPROM etc)
We should keep that distinction and create subcategories for the 'comes from a previous stage loader', rather than adding arbitrary config options which only confuse people
I don't know why you are so frustrated about this.
Because I cleaned this up in 2e8d2f88439d, 2ea63271e522f, and d6f8ab30a2af46. HAS_OF_PRIOR_STAGE then magically reappeared in 275b4832f6bf91 without anyone acking or reviewing that patch and at the same time it does nothing useful apart from a few prints. Also because we keep going in circles. We've spent more time discussing this than coding it. Instead of cleaning this up now that we have the chance, we prefer adding more DT options until we end up with a complete mess again.
This patch does not even do what you have listed above, so far as I can tell.
Why? It scans for a bloblist if CONFIG_BLOBLIST is turned on, otherwise, it falls back to board_fdt_blob_setup(). Another thing we can do is add an 'imply OF_BLOBLIST' if BLOBLIST && OF_BOARD are selected and use that in our if cases.
We can also change this in the future and prevent the board from booting if (IS_ENABLED(OF_BLOBLIST)) fails to discover a DT. But I think that should be done once we have some boards implementing a bloblist. I had the same suggestion here [0].
We have:
- OF_HAS_PRIOR_STAGE which indicates that U-Boot is not the first phase
- OF_BOARD which indicates that the board can do anything it likes
- BLOBLIST which indicates that there is a bloblist
We also have OF_EMBED and OF_SEPARATE. Funnily OF_EMBED says 'not recommended' yet we have a ton of devices using it. On top of that, we have CONFIG_OF_BOARD_SETUP and CONFIG_OF_BOARD_FIXUP that people just use in random ways. CONFIG_OF_BOARD_FIXUP is obviously the right option (and properly documented) to fixup DTs
I proposed adding:
- OF_BLOBLIST which indicates that U-Boot gets the DT from the bloblist
I understood that your intention OF_BOARD would go away since there are almost no cases that need it.
My suggestion was to rename and clean stuff if OF_BOARD is confusing, not remove it. It certainly can't go away, because you will still have boards reading it of an EEPROM or similar.[1]
I was skeptical it could be done but I definitely agreed (and still do) that it would be great if that could go away, as we would not need OF_BLOBLIST since OF_BOARD would effectively mean the same thing.
But when I look at this patch, that is not what is happening. In fact, there is no indication that the DT came from the bloblist. U-Boot will just report 'devicetree: board'. We must say where it came from.
Yes, but we are confusing 2 things here. What do we need to print vs what the user needs to configure. The answer to this problem is not to add more Kconfig options just to be able to print stuff. An enum to the DT struct which would be set to whatever option we need to print during the DT init phase is cleaner and keeps the Kconfig options sane.
The other thing missing here is SPL. The bloblist is designed such that it can be set up in any phase of U-Boot, then is passed to following phases. So using IS_ENABLED(BLOBLIST) doesn't do what we need. As I noted, it breaks sandbox_spl. What happens if a board wants to use bloblist in SPL but doesn't want the SPL DT to come from a prior stage?
Can you explain 'bloblist in SPL'? Do you mean SPL gets the DT somehow but then wants to add it in a bloblist for U-Boot? I don't think we should be allowing things like that. You either use a bloblist or you don't.
What happens if SPL wants doesn't want to pass the U-Boot DT through to U-Boot in the bloblist? It is all just horribly confusing.
I am not sure I understand this. Do you mean that the SPL wouldn't want to pass the DT in a bloblist to U-Boot proper? If that's the case, that's a design decision we have to make and I prefer prohibiting that if BLOBLIST is enabled.
So I believe, in fact, that we cannot get rid of OF_BOARD now, and perhaps for quite a long time.
We can't. Ever.
There is another discussion about Qualcomm where they want a gzipped DT attached to the end of U-Boot, for example. Perhaps the key problem with this patch is that it would ensure that OF_BOARD sticks around, since it means both a) Get the DT from bloblist if BLOBLIST; b) Get the DT from a board-specific mechanism if !BLOBLIST. That is not what we discussed.
I haven't gone through that patch again, but I will today. OTOH I don't see a problem with this. This does exactly what you asked, a discrete way of getting the DT from a bloblist. Instead of adding yet another option it relies on if(BLOBLIST && OF_BOARD) (== OF_BLOBLIST) Vendors need time to implement standards and prohibiting their boards from working until they do make little sense to me. I am fine with the fallback scenario for now.
Why not just take my original patch and work from there? It will save a lot of time. We can then progressively migrate boards from OF_BOARD to OF_BLOBLIST and then perhaps one day remove OF_BOARD (I remain skeptical, but hopeful). The whole 'standard passage' thing [1] was carefully thought out *two years ago* and (I believe) dealt with all of the issues above.
For now, we should apply the patches which bring in the spec changes, so we can figure out the rest of it. I have added my review tag for those.
I think I prefer this iteration (with the imply OF_BLOBLIST perhaps) with a future cleanup in mind which I tried to explain in the past [1]. A few extra suggestions...
- Get rid of OF_PRIOR_STAGE which is only used in a few prints. Instead add an enum with the options you want to print, which we set during the DT setup. - Rename OF_BOARD to OF_EXTERNAL or something similar if it's still confusing. If (OF_EXTERNAL && BLOBLIST) you have your OF_BLOBLIST equivalent, without having people to have to explicitly configure it. - Once the above is implemented fail to boot boards that have (OF_EXTERNAL && BLOBLIST) enabled, but don't provide a DT in a bloblist (we can even do that now, but I don't see the point till we get users) - See if we can get rid of CONFIG_OF_BOARD_SETUP or repurpose it to do something board-specific if needed. Looking at it we can probably replace all the callsites with CONFIG_OF_BOARD_FIXUP
Then *the user* ends up with - OF_EMBED which shouldn't really be used - OF_SEPARATE which means the DT is appended to the U-Boot binary, but comes from U-Boot. - OF_EXTERNAL which means we can get the DT in a number of external ways (EEPROM, BLOBLIST, CPU registers etc).
[...]
[0] https://lore.kernel.org/u-boot/CAC_iWjLS62kkMOYT6UiGoL66o-CaFst1nYWv7xgH+GNy... [1] https://lore.kernel.org/u-boot/CAC_iWj+hkVjftjfVfRFd27uF59=cpsJ0r+6jCg++EYFq...
Thanks /Ilias
/Ilias

Hi Simon,
The other thing missing here is SPL. The bloblist is designed such that it can be set up in any phase of U-Boot, then is passed to following phases. So using IS_ENABLED(BLOBLIST) doesn't do what we need. As I noted, it breaks sandbox_spl. What happens if a board wants to use bloblist in SPL but doesn't want the SPL DT to come from a prior stage? What happens if SPL wants doesn't want to pass the U-Boot DT through to U-Boot in the bloblist? It is all just horribly confusing.
I think the logic to decide whether to take the DT from bloblist really depends on the board vendor. I will move this kind of logics into board specific functions from fdtdec.c in the next revision. Board vendors can decide the behaviors they want. This can answer the question above and for example whether they want a fallback when no DT exists in the bloblist or the DT from bloblis is corrupted, or just print a warning message. For Qemu-arm, as an example of design reference, I prefer to take the DT from the bloblist automatically when (BLOBLIST && OF_BOARD) and keep the fallback compatibility to load from `CFG_SYS_SDRAM_BASE` when DT from bloblist is corrupted. I will take a look into the sandbox_spl failures you mentioned.
Thanks and regards, Raymond
On Tue, 5 Dec 2023 at 22:57, Simon Glass sjg@chromium.org wrote:
Hi Ilias,
On Mon, 4 Dec 2023 at 23:22, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Simon,
We did discuss this in OSFC but perhaps you forgot. The discussion was based on the mail here [0].
Perhaps I did? Or perhaps we had a different understanding of it?
On Tue, 5 Dec 2023 at 02:52, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Mon, 4 Dec 2023 at 12:25, Raymond Mao raymond.mao@linaro.org
wrote:
Hi Simon,
When `OF_BOARD` is defined, the FDT should be from one of the
board-specific mechanisms:
- FDT from a bloblist via boot args
- FDT in memory
I don't think we need a new build option to distinguish these two,
since it can be done in runtime by checking whether the boot args follow the FW Handoff spec conventions and the FDT exists in the bloblist.
No, I would really like this to be deterministic, so we can fail if something goes wrong. The bloblist should be 'declared' as the way to boot, for a board.
We *are* deterministic. I am just going to repeat what we discussed in OSFC for completeness. OF_BLOBLIST makes little sense because we are not going to add a Kconfig per blolblist entry. I haven't looked at what the patch does yet but the idea was really
simple.
- Under OF_BOARD (which can arguably be renamed to OF_PREVIOUS_STAGE
or something like that) if CONFIG_BLOB is enabled we scan for a bloblist
- If CONFIG_BLOB is enabled but no bloblist is provided we fail the boot
- If CONFIG_BLOB is not enabled we do what we did up to now, maybe
with a message that this is going to be obsoleted once enough boards migrate to a bloblist
IOW if support for a bloblist is enabled we expect to find one from the previous bootloader. I've lost count of how many times I repeated this, but here it goes again The device tree can come
- From u-boot
- From a previous stage loader *somehow* (eg. passed on a bloblist,
passed on a register, read from an EEPROM etc)
We should keep that distinction and create subcategories for the 'comes from a previous stage loader', rather than adding arbitrary config options which only confuse people
I don't know why you are so frustrated about this. This patch does not even do what you have listed above, so far as I can tell.
We have:
- OF_HAS_PRIOR_STAGE which indicates that U-Boot is not the first phase
- OF_BOARD which indicates that the board can do anything it likes
- BLOBLIST which indicates that there is a bloblist
I proposed adding:
- OF_BLOBLIST which indicates that U-Boot gets the DT from the bloblist
I understood that your intention OF_BOARD would go away since there are almost no cases that need it. I was skeptical it could be done but I definitely agreed (and still do) that it would be great if that could go away, as we would not need OF_BLOBLIST since OF_BOARD would effectively mean the same thing.
But when I look at this patch, that is not what is happening. In fact, there is no indication that the DT came from the bloblist. U-Boot will just report 'devicetree: board'. We must say where it came from.
The other thing missing here is SPL. The bloblist is designed such that it can be set up in any phase of U-Boot, then is passed to following phases. So using IS_ENABLED(BLOBLIST) doesn't do what we need. As I noted, it breaks sandbox_spl. What happens if a board wants to use bloblist in SPL but doesn't want the SPL DT to come from a prior stage? What happens if SPL wants doesn't want to pass the U-Boot DT through to U-Boot in the bloblist? It is all just horribly confusing.
So I believe, in fact, that we cannot get rid of OF_BOARD now, and perhaps for quite a long time. There is another discussion about Qualcomm where they want a gzipped DT attached to the end of U-Boot, for example. Perhaps the key problem with this patch is that it would ensure that OF_BOARD sticks around, since it means both a) Get the DT from bloblist if BLOBLIST; b) Get the DT from a board-specific mechanism if !BLOBLIST. That is not what we discussed.
Why not just take my original patch and work from there? It will save a lot of time. We can then progressively migrate boards from OF_BOARD to OF_BLOBLIST and then perhaps one day remove OF_BOARD (I remain skeptical, but hopeful). The whole 'standard passage' thing [1] was carefully thought out *two years ago* and (I believe) dealt with all of the issues above.
For now, we should apply the patches which bring in the spec changes, so we can figure out the rest of it. I have added my review tag for those.
Regards, SImon
Regards /Ilias
If in the future all boards a reusing bloblist for this feature, then sure, we can drop it. But we have things like rpi which do their own thing.
If it fulfills the above conditions, we can take the FDT from
bloblist, otherwise from the predefined memory address.
This is fully backward compatible without adding a new build option.
Again, we need to obtain the FDT from the bloblist if and only if the board requires it. It creates a lot of confusion to have it as an optional feature, when we know which way it should be.
Ultimately OF_BOARD should go away. We just need to push bloblist to other projects and closed-source firmware as the correct way to pass a DT.
Regards, Simon [.]
[0]
https://lore.kernel.org/u-boot/CAPnjgZ0SqVyj_drLEQrP21zPYCco3HOP-rYD+nKJMa0B...
[1] https://patchwork.ozlabs.org/project/uboot/list/?series=281465&state=*

Hi Raymond,
On Wed, 6 Dec 2023 at 13:35, Raymond Mao raymond.mao@linaro.org wrote:
Hi Simon,
The other thing missing here is SPL. The bloblist is designed such that it can be set up in any phase of U-Boot, then is passed to following phases. So using IS_ENABLED(BLOBLIST) doesn't do what we need. As I noted, it breaks sandbox_spl. What happens if a board wants to use bloblist in SPL but doesn't want the SPL DT to come from a prior stage? What happens if SPL wants doesn't want to pass the U-Boot DT through to U-Boot in the bloblist? It is all just horribly confusing.
I think the logic to decide whether to take the DT from bloblist really depends on the board vendor. I will move this kind of logics into board specific functions from fdtdec.c in the next revision. Board vendors can decide the behaviors they want. This can answer the question above and for example whether they want a fallback when no DT exists in the bloblist or the DT from bloblis is corrupted, or just print a warning message. For Qemu-arm, as an example of design reference, I prefer to take the DT from the bloblist automatically when (BLOBLIST && OF_BOARD) and keep the fallback compatibility to load from `CFG_SYS_SDRAM_BASE` when DT from bloblist is corrupted. I will take a look into the sandbox_spl failures you mentioned.
In the interests of my sanity, could you send just the bloblist updates and move the other patches into a separate series?
Regards, SImon
Thanks and regards, Raymond
On Tue, 5 Dec 2023 at 22:57, Simon Glass sjg@chromium.org wrote:
Hi Ilias,
On Mon, 4 Dec 2023 at 23:22, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Simon,
We did discuss this in OSFC but perhaps you forgot. The discussion was based on the mail here [0].
Perhaps I did? Or perhaps we had a different understanding of it?
On Tue, 5 Dec 2023 at 02:52, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Mon, 4 Dec 2023 at 12:25, Raymond Mao raymond.mao@linaro.org wrote:
Hi Simon,
When `OF_BOARD` is defined, the FDT should be from one of the board-specific mechanisms:
- FDT from a bloblist via boot args
- FDT in memory
I don't think we need a new build option to distinguish these two, since it can be done in runtime by checking whether the boot args follow the FW Handoff spec conventions and the FDT exists in the bloblist.
No, I would really like this to be deterministic, so we can fail if something goes wrong. The bloblist should be 'declared' as the way to boot, for a board.
We *are* deterministic. I am just going to repeat what we discussed in OSFC for completeness. OF_BLOBLIST makes little sense because we are not going to add a Kconfig per blolblist entry. I haven't looked at what the patch does yet but the idea was really simple.
- Under OF_BOARD (which can arguably be renamed to OF_PREVIOUS_STAGE
or something like that) if CONFIG_BLOB is enabled we scan for a bloblist
- If CONFIG_BLOB is enabled but no bloblist is provided we fail the boot
- If CONFIG_BLOB is not enabled we do what we did up to now, maybe
with a message that this is going to be obsoleted once enough boards migrate to a bloblist
IOW if support for a bloblist is enabled we expect to find one from the previous bootloader. I've lost count of how many times I repeated this, but here it goes again The device tree can come
- From u-boot
- From a previous stage loader *somehow* (eg. passed on a bloblist,
passed on a register, read from an EEPROM etc)
We should keep that distinction and create subcategories for the 'comes from a previous stage loader', rather than adding arbitrary config options which only confuse people
I don't know why you are so frustrated about this. This patch does not even do what you have listed above, so far as I can tell.
We have:
- OF_HAS_PRIOR_STAGE which indicates that U-Boot is not the first phase
- OF_BOARD which indicates that the board can do anything it likes
- BLOBLIST which indicates that there is a bloblist
I proposed adding:
- OF_BLOBLIST which indicates that U-Boot gets the DT from the bloblist
I understood that your intention OF_BOARD would go away since there are almost no cases that need it. I was skeptical it could be done but I definitely agreed (and still do) that it would be great if that could go away, as we would not need OF_BLOBLIST since OF_BOARD would effectively mean the same thing.
But when I look at this patch, that is not what is happening. In fact, there is no indication that the DT came from the bloblist. U-Boot will just report 'devicetree: board'. We must say where it came from.
The other thing missing here is SPL. The bloblist is designed such that it can be set up in any phase of U-Boot, then is passed to following phases. So using IS_ENABLED(BLOBLIST) doesn't do what we need. As I noted, it breaks sandbox_spl. What happens if a board wants to use bloblist in SPL but doesn't want the SPL DT to come from a prior stage? What happens if SPL wants doesn't want to pass the U-Boot DT through to U-Boot in the bloblist? It is all just horribly confusing.
So I believe, in fact, that we cannot get rid of OF_BOARD now, and perhaps for quite a long time. There is another discussion about Qualcomm where they want a gzipped DT attached to the end of U-Boot, for example. Perhaps the key problem with this patch is that it would ensure that OF_BOARD sticks around, since it means both a) Get the DT from bloblist if BLOBLIST; b) Get the DT from a board-specific mechanism if !BLOBLIST. That is not what we discussed.
Why not just take my original patch and work from there? It will save a lot of time. We can then progressively migrate boards from OF_BOARD to OF_BLOBLIST and then perhaps one day remove OF_BOARD (I remain skeptical, but hopeful). The whole 'standard passage' thing [1] was carefully thought out *two years ago* and (I believe) dealt with all of the issues above.
For now, we should apply the patches which bring in the spec changes, so we can figure out the rest of it. I have added my review tag for those.
Regards, SImon
Regards /Ilias
If in the future all boards a reusing bloblist for this feature, then sure, we can drop it. But we have things like rpi which do their own thing.
If it fulfills the above conditions, we can take the FDT from bloblist, otherwise from the predefined memory address. This is fully backward compatible without adding a new build option.
Again, we need to obtain the FDT from the bloblist if and only if the board requires it. It creates a lot of confusion to have it as an optional feature, when we know which way it should be.
Ultimately OF_BOARD should go away. We just need to push bloblist to other projects and closed-source firmware as the correct way to pass a DT.
Regards, Simon [.]
[0] https://lore.kernel.org/u-boot/CAPnjgZ0SqVyj_drLEQrP21zPYCco3HOP-rYD+nKJMa0B...
[1] https://patchwork.ozlabs.org/project/uboot/list/?series=281465&state=*

Hi Simon, OK, I can try to remove them into two series.
Regards, Raymond
On Thu, 7 Dec 2023 at 22:14, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Wed, 6 Dec 2023 at 13:35, Raymond Mao raymond.mao@linaro.org wrote:
Hi Simon,
The other thing missing here is SPL. The bloblist is designed such that it can be set up in any phase of U-Boot, then is passed to following phases. So using IS_ENABLED(BLOBLIST) doesn't do what we need. As I noted, it breaks sandbox_spl. What happens if a board wants to use bloblist in SPL but doesn't want the SPL DT to come from a prior stage? What happens if SPL wants doesn't want to pass the U-Boot DT through to U-Boot in the bloblist? It is all just horribly confusing.
I think the logic to decide whether to take the DT from bloblist really
depends
on the board vendor. I will move this kind of logics into board specific functions from
fdtdec.c in the
next revision. Board vendors can decide the behaviors they want. This can answer the
question
above and for example whether they want a fallback when no DT exists in
the
bloblist or the DT from bloblis is corrupted, or just print a warning
message.
For Qemu-arm, as an example of design reference, I prefer to take the DT
from the
bloblist automatically when (BLOBLIST && OF_BOARD) and keep the fallback compatibility to load from `CFG_SYS_SDRAM_BASE` when DT from bloblist is corrupted. I will take a look into the sandbox_spl failures you mentioned.
In the interests of my sanity, could you send just the bloblist updates and move the other patches into a separate series?
Regards, SImon
Thanks and regards, Raymond
On Tue, 5 Dec 2023 at 22:57, Simon Glass sjg@chromium.org wrote:
Hi Ilias,
On Mon, 4 Dec 2023 at 23:22, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
Hi Simon,
We did discuss this in OSFC but perhaps you forgot. The discussion was based on the mail here [0].
Perhaps I did? Or perhaps we had a different understanding of it?
On Tue, 5 Dec 2023 at 02:52, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Mon, 4 Dec 2023 at 12:25, Raymond Mao raymond.mao@linaro.org
wrote:
Hi Simon,
When `OF_BOARD` is defined, the FDT should be from one of the
board-specific mechanisms:
- FDT from a bloblist via boot args
- FDT in memory
I don't think we need a new build option to distinguish these
two, since it can be done in runtime by checking whether the boot args follow the FW Handoff spec conventions and the FDT exists in the bloblist.
No, I would really like this to be deterministic, so we can fail if something goes wrong. The bloblist should be 'declared' as the way
to
boot, for a board.
We *are* deterministic. I am just going to repeat what we discussed in OSFC for completeness. OF_BLOBLIST makes little sense because we are not going to add a Kconfig per blolblist entry. I haven't looked at what the patch does yet but the idea was really
simple.
- Under OF_BOARD (which can arguably be renamed to OF_PREVIOUS_STAGE
or something like that) if CONFIG_BLOB is enabled we scan for a bloblist
- If CONFIG_BLOB is enabled but no bloblist is provided we fail the
boot
- If CONFIG_BLOB is not enabled we do what we did up to now, maybe
with a message that this is going to be obsoleted once enough boards migrate to a bloblist
IOW if support for a bloblist is enabled we expect to find one from the previous bootloader. I've lost count of how many times I repeated this, but here it goes again The device tree can come
- From u-boot
- From a previous stage loader *somehow* (eg. passed on a bloblist,
passed on a register, read from an EEPROM etc)
We should keep that distinction and create subcategories for the 'comes from a previous stage loader', rather than adding arbitrary config options which only confuse people
I don't know why you are so frustrated about this. This patch does not even do what you have listed above, so far as I can tell.
We have:
- OF_HAS_PRIOR_STAGE which indicates that U-Boot is not the first phase
- OF_BOARD which indicates that the board can do anything it likes
- BLOBLIST which indicates that there is a bloblist
I proposed adding:
- OF_BLOBLIST which indicates that U-Boot gets the DT from the bloblist
I understood that your intention OF_BOARD would go away since there are almost no cases that need it. I was skeptical it could be done but I definitely agreed (and still do) that it would be great if that could go away, as we would not need OF_BLOBLIST since OF_BOARD would effectively mean the same thing.
But when I look at this patch, that is not what is happening. In fact, there is no indication that the DT came from the bloblist. U-Boot will just report 'devicetree: board'. We must say where it came from.
The other thing missing here is SPL. The bloblist is designed such that it can be set up in any phase of U-Boot, then is passed to following phases. So using IS_ENABLED(BLOBLIST) doesn't do what we need. As I noted, it breaks sandbox_spl. What happens if a board wants to use bloblist in SPL but doesn't want the SPL DT to come from a prior stage? What happens if SPL wants doesn't want to pass the U-Boot DT through to U-Boot in the bloblist? It is all just horribly confusing.
So I believe, in fact, that we cannot get rid of OF_BOARD now, and perhaps for quite a long time. There is another discussion about Qualcomm where they want a gzipped DT attached to the end of U-Boot, for example. Perhaps the key problem with this patch is that it would ensure that OF_BOARD sticks around, since it means both a) Get the DT from bloblist if BLOBLIST; b) Get the DT from a board-specific mechanism if !BLOBLIST. That is not what we discussed.
Why not just take my original patch and work from there? It will save a lot of time. We can then progressively migrate boards from OF_BOARD to OF_BLOBLIST and then perhaps one day remove OF_BOARD (I remain skeptical, but hopeful). The whole 'standard passage' thing [1] was carefully thought out *two years ago* and (I believe) dealt with all of the issues above.
For now, we should apply the patches which bring in the spec changes, so we can figure out the rest of it. I have added my review tag for those.
Regards, SImon
Regards /Ilias
If in the future all boards a reusing bloblist for this feature,
then
sure, we can drop it. But we have things like rpi which do their own thing.
If it fulfills the above conditions, we can take the FDT from
bloblist, otherwise from the predefined memory address.
This is fully backward compatible without adding a new build
option.
Again, we need to obtain the FDT from the bloblist if and only if
the
board requires it. It creates a lot of confusion to have it as an optional feature, when we know which way it should be.
Ultimately OF_BOARD should go away. We just need to push bloblist to other projects and closed-source firmware as the correct way to
pass a
DT.
Regards, Simon [.]
[0]
https://lore.kernel.org/u-boot/CAPnjgZ0SqVyj_drLEQrP21zPYCco3HOP-rYD+nKJMa0B...
[1]
https://patchwork.ozlabs.org/project/uboot/list/?series=281465&state=*

Align used_size and total_size of the bloblist header to the definition of the FW Handoff spec v0.9. Update the related bloblist APIs and UT testcases.
Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - New patch file created for v2.
common/bloblist.c | 86 +++++++++++++++++++++++++++------------------- include/bloblist.h | 26 ++++++++------ test/bloblist.c | 35 ++++++++++--------- 3 files changed, 84 insertions(+), 63 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index 0d482ecd71..91d69e9439 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -78,7 +78,7 @@ const char *bloblist_tag_name(enum bloblist_tag_t tag)
static struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr) { - if (hdr->alloced <= hdr->hdr_size) + if (hdr->used_size <= hdr->hdr_size) return NULL; return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size); } @@ -111,7 +111,7 @@ static struct bloblist_rec *bloblist_next_blob(struct bloblist_hdr *hdr, { ulong offset = bloblist_blob_end_ofs(hdr, rec);
- if (offset >= hdr->alloced) + if (offset >= hdr->used_size) return NULL; return (struct bloblist_rec *)((void *)hdr + offset); } @@ -148,9 +148,9 @@ static int bloblist_addrec(uint tag, int size, int align_log2, align_log2 = BLOBLIST_BLOB_ALIGN_LOG2;
/* Figure out where the new data will start */ - data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec); + data_start = map_to_sysmem(hdr) + hdr->used_size + sizeof(*rec);
- /* Align the address and then calculate the offset from ->alloced */ + /* Align the address and then calculate the offset from used size */ aligned_start = ALIGN(data_start, 1U << align_log2) - data_start;
/* If we need to create a dummy record, create it */ @@ -164,19 +164,20 @@ static int bloblist_addrec(uint tag, int size, int align_log2, return log_msg_ret("void", ret);
/* start the record after that */ - data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*vrec); + data_start = map_to_sysmem(hdr) + hdr->used_size + sizeof(*vrec); }
/* Calculate the new allocated total */ new_alloced = data_start - map_to_sysmem(hdr) + ALIGN(size, 1U << align_log2);
- if (new_alloced > hdr->size) { - log_err("Failed to allocate %x bytes size=%x, need size=%x\n", - size, hdr->size, new_alloced); + if (new_alloced > hdr->total_size) { + log_err("Failed to allocate %x bytes\n", size); + log_err("Used size=%x, total size=%x\n", + hdr->used_size, hdr->total_size); return log_msg_ret("bloblist add", -ENOSPC); } - rec = (void *)hdr + hdr->alloced; + rec = (void *)hdr + hdr->used_size;
rec->tag_and_hdr_size = tag | sizeof(*rec) << BLOBLISTR_HDR_SIZE_SHIFT; rec->size = size; @@ -184,7 +185,7 @@ static int bloblist_addrec(uint tag, int size, int align_log2, /* Zero the record data */ memset((void *)rec + rec_hdr_size(rec), '\0', rec->size);
- hdr->alloced = new_alloced; + hdr->used_size = new_alloced; *recp = rec;
return 0; @@ -279,29 +280,30 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr, int new_size) { int expand_by; /* Number of bytes to expand by (-ve to contract) */ - int new_alloced; /* New value for @hdr->alloced */ + int new_alloced; ulong next_ofs; /* Offset of the record after @rec */
expand_by = ALIGN(new_size - rec->size, BLOBLIST_BLOB_ALIGN); - new_alloced = ALIGN(hdr->alloced + expand_by, BLOBLIST_BLOB_ALIGN); + new_alloced = ALIGN(hdr->used_size + expand_by, BLOBLIST_BLOB_ALIGN); if (new_size < 0) { log_debug("Attempt to shrink blob size below 0 (%x)\n", new_size); return log_msg_ret("size", -EINVAL); } - if (new_alloced > hdr->size) { - log_err("Failed to allocate %x bytes size=%x, need size=%x\n", - new_size, hdr->size, new_alloced); + if (new_alloced > hdr->total_size) { + log_err("Failed to allocate %x bytes\n", new_size); + log_err("Used size=%x, total size=%x\n", + hdr->used_size, hdr->total_size); return log_msg_ret("alloc", -ENOSPC); }
/* Move the following blobs up or down, if this is not the last */ next_ofs = bloblist_blob_end_ofs(hdr, rec); - if (next_ofs != hdr->alloced) { + if (next_ofs != hdr->used_size) { memmove((void *)hdr + next_ofs + expand_by, (void *)hdr + next_ofs, new_alloced - next_ofs); } - hdr->alloced = new_alloced; + hdr->used_size = new_alloced;
/* Zero the new part of the blob */ if (expand_by > 0) { @@ -335,7 +337,7 @@ static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) { u8 chksum;
- chksum = table_compute_checksum(hdr, hdr->alloced); + chksum = table_compute_checksum(hdr, hdr->used_size); chksum += hdr->chksum;
return chksum; @@ -354,9 +356,9 @@ int bloblist_new(ulong addr, uint size, uint align_log2) hdr->version = BLOBLIST_VERSION; hdr->hdr_size = sizeof(*hdr); hdr->magic = BLOBLIST_MAGIC; - hdr->size = size; - hdr->alloced = hdr->hdr_size; + hdr->used_size = hdr->hdr_size; hdr->align_log2 = align_log2 ?: BLOBLIST_BLOB_ALIGN_LOG2; + hdr->total_size = size; hdr->chksum = 0; gd->bloblist = hdr;
@@ -373,8 +375,13 @@ int bloblist_check(ulong addr, uint size) return log_msg_ret("Bad magic", -ENOENT); if (hdr->version != BLOBLIST_VERSION) return log_msg_ret("Bad version", -EPROTONOSUPPORT); - if (size && hdr->size != size) - return log_msg_ret("Bad size", -EFBIG); + if (!hdr->total_size || (size && hdr->total_size != size)) + return log_msg_ret("Bad total size", -EFBIG); + if (hdr->used_size > hdr->total_size) + return log_msg_ret("Bad used size", -ENOENT); + if (hdr->hdr_size != sizeof(struct bloblist_hdr)) + return log_msg_ret("Bad header size", -ENOENT); + chksum = bloblist_calc_chksum(hdr); if (hdr->chksum != chksum) { log_err("Checksum %x != %x\n", hdr->chksum, chksum); @@ -390,7 +397,7 @@ int bloblist_finish(void) struct bloblist_hdr *hdr = gd->bloblist;
hdr->chksum = bloblist_calc_chksum(hdr); - log_debug("Finished bloblist size %lx at %lx\n", (ulong)hdr->size, + log_debug("Finished bloblist size %lx at %lx\n", (ulong)hdr->used_size, (ulong)map_to_sysmem(hdr));
return 0; @@ -405,33 +412,40 @@ ulong bloblist_get_size(void) { struct bloblist_hdr *hdr = gd->bloblist;
- return hdr->size; + return hdr->used_size; +} + +ulong bloblist_get_total_size(void) +{ + struct bloblist_hdr *hdr = gd->bloblist; + + return hdr->total_size; }
-void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp) +void bloblist_get_stats(ulong *basep, ulong *tsizep, ulong *usizep) { struct bloblist_hdr *hdr = gd->bloblist;
*basep = map_to_sysmem(gd->bloblist); - *sizep = hdr->size; - *allocedp = hdr->alloced; + *tsizep = hdr->total_size; + *usizep = hdr->used_size; }
static void show_value(const char *prompt, ulong value) { - printf("%s:%*s %-5lx ", prompt, 8 - (int)strlen(prompt), "", value); + printf("%s:%*s %-5lx ", prompt, 10 - (int)strlen(prompt), "", value); print_size(value, "\n"); }
void bloblist_show_stats(void) { - ulong base, size, alloced; + ulong base, tsize, usize;
- bloblist_get_stats(&base, &size, &alloced); - printf("base: %lx\n", base); - show_value("size", size); - show_value("alloced", alloced); - show_value("free", size - alloced); + bloblist_get_stats(&base, &tsize, &usize); + printf("base: %lx\n", base); + show_value("total size", tsize); + show_value("used size", usize); + show_value("free", tsize - usize); }
void bloblist_show_list(void) @@ -455,7 +469,7 @@ void bloblist_reloc(void *to, uint to_size, void *from, uint from_size)
memcpy(to, from, from_size); hdr = to; - hdr->size = to_size; + hdr->total_size = to_size; }
int bloblist_init(void) @@ -485,7 +499,7 @@ int bloblist_init(void) addr, ret); } else { /* Get the real size, if it is not what we expected */ - size = gd->bloblist->size; + size = gd->bloblist->total_size; } } if (ret) { diff --git a/include/bloblist.h b/include/bloblist.h index 148a94fcd1..0f5afec9f4 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -173,12 +173,12 @@ enum bloblist_tag_t { * @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The * first bloblist_rec starts at this offset from the start of the header * @align_log2: Power of two of the maximum alignment required by this list - * @alloced: Total size allocated so far for this bloblist. This starts out as + * @used_size: Size allocated so far for this bloblist. This starts out as * sizeof(bloblist_hdr) since we need at least that much space to store a * valid bloblist - * @size: Total size of the bloblist (non-zero if valid) including this header. - * The bloblist extends for this many bytes from the start of this header. - * When adding new records, the bloblist can grow up to this size. + * @total_size: The number of total bytes that the bloblist can occupy. + * Any blob producer must check if there is sufficient space before adding + * a record to the bloblist. */ struct bloblist_hdr { u32 magic; @@ -186,9 +186,8 @@ struct bloblist_hdr { u8 version; u8 hdr_size; u8 align_log2; - - u32 alloced; - u32 size; + u32 used_size; + u32 total_size; };
/** @@ -360,10 +359,10 @@ int bloblist_finish(void); * This returns useful information about the bloblist * * @basep: Returns base address of bloblist - * @sizep: Returns the number of bytes used in the bloblist - * @allocedp: Returns the total space allocated to the bloblist + * @tsizep: Returns the total number of bytes of the bloblist + * @usizep: Returns the number of used bytes of the bloblist */ -void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp); +void bloblist_get_stats(ulong *basep, ulong *tsizep, ulong *usizep);
/** * bloblist_get_base() - Get the base address of the bloblist @@ -379,6 +378,13 @@ ulong bloblist_get_base(void); */ ulong bloblist_get_size(void);
+/** + * bloblist_get_total_size() - Get the total size of the bloblist + * + * Return: the size in bytes + */ +ulong bloblist_get_total_size(void); + /** * bloblist_show_stats() - Show information about the bloblist * diff --git a/test/bloblist.c b/test/bloblist.c index b72603ba9a..dd8e228ea2 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -104,7 +104,8 @@ static int bloblist_test_blob(struct unit_test_state *uts) hdr = clear_bloblist(); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); - ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_size()); + ut_asserteq(sizeof(struct bloblist_hdr), bloblist_get_size()); + ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_total_size()); ut_asserteq(TEST_ADDR, bloblist_get_base()); ut_asserteq(map_to_sysmem(hdr), TEST_ADDR);
@@ -198,9 +199,9 @@ static int bloblist_test_checksum(struct unit_test_state *uts) * change the size or alloced fields, since that will crash the code. * It has to rely on these being correct. */ - hdr->size--; + hdr->total_size--; ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); - hdr->size++; + hdr->total_size++;
hdr->chksum++; ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); @@ -263,10 +264,10 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) ut_silence_console(uts); console_record_reset(); run_command("bloblist info", 0); - ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr)); - ut_assert_nextline("size: 400 1 KiB"); - ut_assert_nextline("alloced: 48 72 Bytes"); - ut_assert_nextline("free: 3b8 952 Bytes"); + ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr)); + ut_assert_nextline("total size: 400 1 KiB"); + ut_assert_nextline("used size: 48 72 Bytes"); + ut_assert_nextline("free: 3b8 952 Bytes"); ut_assert_console_end(); ut_unsilence_console(uts);
@@ -420,7 +421,7 @@ static int bloblist_test_grow(struct unit_test_state *uts)
ut_asserteq(sizeof(struct bloblist_hdr) + sizeof(struct bloblist_rec) * 2 + small_size * 2, - hdr->alloced); + hdr->used_size);
/* Resize the first one */ ut_assertok(bloblist_resize(TEST_TAG, small_size + 4)); @@ -442,7 +443,7 @@ static int bloblist_test_grow(struct unit_test_state *uts) ut_asserteq(sizeof(struct bloblist_hdr) + sizeof(struct bloblist_rec) * 2 + small_size * 2 + BLOBLIST_BLOB_ALIGN, - hdr->alloced); + hdr->used_size);
return 0; } @@ -472,7 +473,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts) hdr = ptr; ut_asserteq(sizeof(struct bloblist_hdr) + sizeof(struct bloblist_rec) * 2 + small_size * 2, - hdr->alloced); + hdr->used_size);
/* Resize the first one */ new_size = small_size - BLOBLIST_ALIGN - 4; @@ -492,7 +493,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts) ut_asserteq(sizeof(struct bloblist_hdr) + sizeof(struct bloblist_rec) * 2 + small_size * 2 - BLOBLIST_ALIGN, - hdr->alloced); + hdr->used_size);
return 0; } @@ -520,12 +521,12 @@ static int bloblist_test_resize_fail(struct unit_test_state *uts) hdr = ptr; ut_asserteq(sizeof(struct bloblist_hdr) + sizeof(struct bloblist_rec) * 2 + small_size * 2, - hdr->alloced); + hdr->used_size);
/* Resize the first one, to check the boundary conditions */ ut_asserteq(-EINVAL, bloblist_resize(TEST_TAG, -1));
- new_size = small_size + (hdr->size - hdr->alloced); + new_size = small_size + (hdr->total_size - hdr->used_size); ut_asserteq(-ENOSPC, bloblist_resize(TEST_TAG, new_size + 1)); ut_assertok(bloblist_resize(TEST_TAG, new_size));
@@ -557,9 +558,9 @@ static int bloblist_test_resize_last(struct unit_test_state *uts) /* Check the byte after the last blob */ alloced_val = sizeof(struct bloblist_hdr) + sizeof(struct bloblist_rec) * 2 + small_size * 2; - ut_asserteq(alloced_val, hdr->alloced); + ut_asserteq(alloced_val, hdr->used_size); ut_asserteq_ptr((void *)hdr + alloced_val, blob2 + small_size); - ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->alloced)); + ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->used_size));
/* Resize the second one, checking nothing changes */ ut_asserteq(0, bloblist_resize(TEST_TAG2, small_size + 4)); @@ -577,8 +578,8 @@ static int bloblist_test_resize_last(struct unit_test_state *uts)
/* Check that the new top of the allocated blobs has not been touched */ alloced_val += BLOBLIST_BLOB_ALIGN; - ut_asserteq(alloced_val, hdr->alloced); - ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->alloced)); + ut_asserteq(alloced_val, hdr->used_size); + ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->used_size));
return 0; }

On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
Align used_size and total_size of the bloblist header to the definition of the FW Handoff spec v0.9. Update the related bloblist APIs and UT testcases.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- New patch file created for v2.
common/bloblist.c | 86 +++++++++++++++++++++++++++------------------- include/bloblist.h | 26 ++++++++------ test/bloblist.c | 35 ++++++++++--------- 3 files changed, 84 insertions(+), 63 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

Add platform custom function to get bloblist from boot arguments. Check whether boot arguments aligns with the register conventions defined in FW Handoff spec v0.9. Add bloblist related options into qemu default config.
Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - New patch file created for v2.
board/emulation/qemu-arm/Makefile | 1 + board/emulation/qemu-arm/lowlevel_init.S | 19 +++++++++ board/emulation/qemu-arm/qemu-arm.c | 54 ++++++++++++++++++++++++ configs/qemu_arm64_defconfig | 3 ++ configs/qemu_arm_defconfig | 3 ++ 5 files changed, 80 insertions(+) create mode 100644 board/emulation/qemu-arm/lowlevel_init.S
diff --git a/board/emulation/qemu-arm/Makefile b/board/emulation/qemu-arm/Makefile index a22d1237ff..12821e7083 100644 --- a/board/emulation/qemu-arm/Makefile +++ b/board/emulation/qemu-arm/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0+
obj-y += qemu-arm.o +obj-$(CONFIG_OF_BOARD) += lowlevel_init.o diff --git a/board/emulation/qemu-arm/lowlevel_init.S b/board/emulation/qemu-arm/lowlevel_init.S new file mode 100644 index 0000000000..d72d7c938a --- /dev/null +++ b/board/emulation/qemu-arm/lowlevel_init.S @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2023, Linaro Limited + */ + +#include <config.h> + +.global save_boot_params +save_boot_params: +#ifdef CONFIG_ARM64 + adr x9, qemu_saved_args + stp x0, x1, [x9] + /* Increment the address by 16 bytes for the next pair of values */ + stp x2, x3, [x9, #16] +#else + ldr r12, =qemu_saved_args + stm r12, {r0, r1, r2, r3} +#endif + b save_boot_params_ret diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c index 942f1fff57..a3892630d8 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -4,6 +4,9 @@ */
#include <common.h> +#if IS_ENABLED(CONFIG_OF_BOARD) && IS_ENABLED(CONFIG_BLOBLIST) +#include <bloblist.h> +#endif #include <cpu_func.h> #include <dm.h> #include <efi.h> @@ -102,6 +105,16 @@ static struct mm_region qemu_arm64_mem_map[] = { struct mm_region *mem_map = qemu_arm64_mem_map; #endif
+#if IS_ENABLED(CONFIG_OF_BOARD) +/* Boot parameters saved from lowlevel_init.S */ +struct { + unsigned long arg0; + unsigned long arg1; + unsigned long arg2; + unsigned long arg3; +} qemu_saved_args __section(".data"); +#endif + int board_init(void) { return 0; @@ -144,6 +157,47 @@ void *board_fdt_blob_setup(int *err) return (void *)CFG_SYS_SDRAM_BASE; }
+int board_bloblist_from_boot_arg(unsigned long __maybe_unused addr, + unsigned long __maybe_unused size) +{ + int ret = -ENOENT; + +#if IS_ENABLED(CONFIG_OF_BOARD) && IS_ENABLED(CONFIG_BLOBLIST) + unsigned long fdt; + + ret = bloblist_check(qemu_saved_args.arg3, 0); + if (ret) + return ret; + + bloblist_show_stats(); + bloblist_show_list(); + if (gd->bloblist->total_size > size) { + gd->bloblist = NULL; /* Reset the gd bloblist pointer */ + log_err("Bloblist total size:%d, board reserved size:%ld\n", + gd->bloblist->total_size, size); + return -ENOSPC; + } + + /* Check the register conventions */ + fdt = (unsigned long)bloblist_find(BLOBLISTT_CONTROL_FDT, 0); + if (IS_ENABLED(CONFIG_ARM64)) { + if (fdt != qemu_saved_args.arg0 || qemu_saved_args.arg2 != 0) + ret = -EIO; + } else { + if (fdt != qemu_saved_args.arg2 || qemu_saved_args.arg0 != 0) + ret = -EIO; + } + + if (ret) + gd->bloblist = NULL; /* Reset the gd bloblist pointer */ + else + memmove((void *)addr, (void *)qemu_saved_args.arg3, + gd->bloblist->total_size); +#endif + + return ret; +} + void enable_caches(void) { icache_enable(); diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig index 5fdf496a45..60fabb5db7 100644 --- a/configs/qemu_arm64_defconfig +++ b/configs/qemu_arm64_defconfig @@ -71,3 +71,6 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_PCI=y CONFIG_SEMIHOSTING=y CONFIG_TPM=y +CONFIG_BLOBLIST=y +CONFIG_BLOBLIST_ADDR=0x40004000 +CONFIG_BLOBLIST_SIZE=0x4000 diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig index 1347b86f34..d8a94ad038 100644 --- a/configs/qemu_arm_defconfig +++ b/configs/qemu_arm_defconfig @@ -71,3 +71,6 @@ CONFIG_TPM2_MMIO=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_PCI=y CONFIG_TPM=y +CONFIG_BLOBLIST=y +CONFIG_BLOBLIST_ADDR=0x40004000 +CONFIG_BLOBLIST_SIZE=0x4000

Hi Raymond,
On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
Add platform custom function to get bloblist from boot arguments.
This should be the same for all ARM platforms. The ultimate goal is something like [1]
Check whether boot arguments aligns with the register conventions defined in FW Handoff spec v0.9. Add bloblist related options into qemu default config.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- New patch file created for v2.
board/emulation/qemu-arm/Makefile | 1 + board/emulation/qemu-arm/lowlevel_init.S | 19 +++++++++ board/emulation/qemu-arm/qemu-arm.c | 54 ++++++++++++++++++++++++ configs/qemu_arm64_defconfig | 3 ++ configs/qemu_arm_defconfig | 3 ++ 5 files changed, 80 insertions(+) create mode 100644 board/emulation/qemu-arm/lowlevel_init.S
diff --git a/board/emulation/qemu-arm/Makefile b/board/emulation/qemu-arm/Makefile index a22d1237ff..12821e7083 100644 --- a/board/emulation/qemu-arm/Makefile +++ b/board/emulation/qemu-arm/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0+
obj-y += qemu-arm.o +obj-$(CONFIG_OF_BOARD) += lowlevel_init.o diff --git a/board/emulation/qemu-arm/lowlevel_init.S b/board/emulation/qemu-arm/lowlevel_init.S new file mode 100644 index 0000000000..d72d7c938a --- /dev/null +++ b/board/emulation/qemu-arm/lowlevel_init.S @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/*
- Copyright (c) 2023, Linaro Limited
- */
+#include <config.h>
+.global save_boot_params +save_boot_params: +#ifdef CONFIG_ARM64
adr x9, qemu_saved_args
stp x0, x1, [x9]
/* Increment the address by 16 bytes for the next pair of values */
stp x2, x3, [x9, #16]
+#else
ldr r12, =qemu_saved_args
stm r12, {r0, r1, r2, r3}
+#endif
b save_boot_params_ret
diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c index 942f1fff57..a3892630d8 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -4,6 +4,9 @@ */
#include <common.h> +#if IS_ENABLED(CONFIG_OF_BOARD) && IS_ENABLED(CONFIG_BLOBLIST) +#include <bloblist.h> +#endif #include <cpu_func.h> #include <dm.h> #include <efi.h> @@ -102,6 +105,16 @@ static struct mm_region qemu_arm64_mem_map[] = { struct mm_region *mem_map = qemu_arm64_mem_map; #endif
+#if IS_ENABLED(CONFIG_OF_BOARD)
OF_BLOBLIST and please avoid #if
+/* Boot parameters saved from lowlevel_init.S */ +struct {
unsigned long arg0;
unsigned long arg1;
unsigned long arg2;
unsigned long arg3;
+} qemu_saved_args __section(".data"); +#endif
int board_init(void) { return 0; @@ -144,6 +157,47 @@ void *board_fdt_blob_setup(int *err) return (void *)CFG_SYS_SDRAM_BASE; }
+int board_bloblist_from_boot_arg(unsigned long __maybe_unused addr,
unsigned long __maybe_unused size)
+{
int ret = -ENOENT;
+#if IS_ENABLED(CONFIG_OF_BOARD) && IS_ENABLED(CONFIG_BLOBLIST)
unsigned long fdt;
ret = bloblist_check(qemu_saved_args.arg3, 0);
if (ret)
return ret;
bloblist_show_stats();
bloblist_show_list();
if (gd->bloblist->total_size > size) {
gd->bloblist = NULL; /* Reset the gd bloblist pointer */
log_err("Bloblist total size:%d, board reserved size:%ld\n",
gd->bloblist->total_size, size);
return -ENOSPC;
}
/* Check the register conventions */
fdt = (unsigned long)bloblist_find(BLOBLISTT_CONTROL_FDT, 0);
This should happen in fdtdec.c automatically. See [2]
if (IS_ENABLED(CONFIG_ARM64)) {
if (fdt != qemu_saved_args.arg0 || qemu_saved_args.arg2 != 0)
ret = -EIO;
} else {
if (fdt != qemu_saved_args.arg2 || qemu_saved_args.arg0 != 0)
ret = -EIO;
}
if (ret)
gd->bloblist = NULL; /* Reset the gd bloblist pointer */
else
memmove((void *)addr, (void *)qemu_saved_args.arg3,
gd->bloblist->total_size);
+#endif
return ret;
+}
void enable_caches(void) { icache_enable(); diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig index 5fdf496a45..60fabb5db7 100644 --- a/configs/qemu_arm64_defconfig +++ b/configs/qemu_arm64_defconfig @@ -71,3 +71,6 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_PCI=y CONFIG_SEMIHOSTING=y CONFIG_TPM=y +CONFIG_BLOBLIST=y +CONFIG_BLOBLIST_ADDR=0x40004000 +CONFIG_BLOBLIST_SIZE=0x4000 diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig index 1347b86f34..d8a94ad038 100644 --- a/configs/qemu_arm_defconfig +++ b/configs/qemu_arm_defconfig @@ -71,3 +71,6 @@ CONFIG_TPM2_MMIO=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_PCI=y CONFIG_TPM=y +CONFIG_BLOBLIST=y +CONFIG_BLOBLIST_ADDR=0x40004000
+CONFIG_BLOBLIST_SIZE=0x4000
2.25.1
Regards, Simon
[1] https://patchwork.ozlabs.org/project/uboot/list/?series=281465&state=* [2] https://patchwork.ozlabs.org/project/uboot/patch/20230926141514.2101787-40-s...

Hi Simon
On Sat, 2 Dec 2023 at 16:16, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
Add platform custom function to get bloblist from boot arguments.
This should be the same for all ARM platforms. The ultimate goal is something like [1]
Yes, I agree. The current series just focuses on Qemu but ultimately should be adapted to all Arm platforms.
#include <common.h>
+#if IS_ENABLED(CONFIG_OF_BOARD) && IS_ENABLED(CONFIG_BLOBLIST) +#include <bloblist.h> +#endif #include <cpu_func.h> #include <dm.h> #include <efi.h> @@ -102,6 +105,16 @@ static struct mm_region qemu_arm64_mem_map[] = { struct mm_region *mem_map = qemu_arm64_mem_map; #endif
+#if IS_ENABLED(CONFIG_OF_BOARD)
OF_BLOBLIST and please avoid #if
I will remove the build option for argument copying, as they don't really depend on OF_BOARD or _BLOBLIST.
/* Check the register conventions */
fdt = (unsigned long)bloblist_find(BLOBLISTT_CONTROL_FDT, 0);
This should happen in fdtdec.c automatically. See [2]
The reason I have to call `bloblist_find()` here is to get the fdt address and compare with arg0 and arg2 (see below few lines of code) to check if it is compliant to the register conventions for AARCH64/32 defined by the FW Handoff spec. This is better to be placed here instead of fdtdec.c
if (IS_ENABLED(CONFIG_ARM64)) {
if (fdt != qemu_saved_args.arg0 || qemu_saved_args.arg2
!= 0)
ret = -EIO;
} else {
if (fdt != qemu_saved_args.arg2 || qemu_saved_args.arg0
!= 0)
ret = -EIO;
}
if (ret)
gd->bloblist = NULL; /* Reset the gd bloblist pointer */
else
memmove((void *)addr, (void *)qemu_saved_args.arg3,
gd->bloblist->total_size);
+#endif
return ret;
+}
Thanks and regards,
Raymond

Hi Raymond,
On Mon, 4 Dec 2023 at 13:06, Raymond Mao raymond.mao@linaro.org wrote:
Hi Simon
On Sat, 2 Dec 2023 at 16:16, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
Add platform custom function to get bloblist from boot arguments.
This should be the same for all ARM platforms. The ultimate goal is something like [1]
Yes, I agree. The current series just focuses on Qemu but ultimately should be adapted to all Arm platforms.
#include <common.h> +#if IS_ENABLED(CONFIG_OF_BOARD) && IS_ENABLED(CONFIG_BLOBLIST) +#include <bloblist.h> +#endif #include <cpu_func.h> #include <dm.h> #include <efi.h> @@ -102,6 +105,16 @@ static struct mm_region qemu_arm64_mem_map[] = { struct mm_region *mem_map = qemu_arm64_mem_map; #endif
+#if IS_ENABLED(CONFIG_OF_BOARD)
OF_BLOBLIST and please avoid #if
I will remove the build option for argument copying, as they don't really depend on OF_BOARD or _BLOBLIST.
/* Check the register conventions */
fdt = (unsigned long)bloblist_find(BLOBLISTT_CONTROL_FDT, 0);
This should happen in fdtdec.c automatically. See [2]
The reason I have to call `bloblist_find()` here is to get the fdt address and compare with arg0 and arg2 (see below few lines of code) to check if it is compliant to the register conventions for AARCH64/32 defined by the FW Handoff spec. This is better to be placed here instead of fdtdec.c
We should first sort out what we are doing with my patch...as mentioned elsewhere Ilias and I did discuss it, but perhaps not for long enough.
Regards, Simon

On 11/27/23 20:50, Raymond Mao wrote:
Add platform custom function to get bloblist from boot arguments. Check whether boot arguments aligns with the register conventions defined in FW Handoff spec v0.9. Add bloblist related options into qemu default config.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
New patch file created for v2.
board/emulation/qemu-arm/Makefile | 1 + board/emulation/qemu-arm/lowlevel_init.S | 19 +++++++++ board/emulation/qemu-arm/qemu-arm.c | 54 ++++++++++++++++++++++++ configs/qemu_arm64_defconfig | 3 ++ configs/qemu_arm_defconfig | 3 ++ 5 files changed, 80 insertions(+) create mode 100644 board/emulation/qemu-arm/lowlevel_init.S
diff --git a/board/emulation/qemu-arm/Makefile b/board/emulation/qemu-arm/Makefile index a22d1237ff..12821e7083 100644 --- a/board/emulation/qemu-arm/Makefile +++ b/board/emulation/qemu-arm/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0+
obj-y += qemu-arm.o +obj-$(CONFIG_OF_BOARD) += lowlevel_init.o diff --git a/board/emulation/qemu-arm/lowlevel_init.S b/board/emulation/qemu-arm/lowlevel_init.S new file mode 100644 index 0000000000..d72d7c938a --- /dev/null +++ b/board/emulation/qemu-arm/lowlevel_init.S @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/*
- Copyright (c) 2023, Linaro Limited
- */
+#include <config.h>
+.global save_boot_params +save_boot_params: +#ifdef CONFIG_ARM64
- adr x9, qemu_saved_args
Based on logic below this is available only when CONFIG_OF_BOARD is enabled. Please look below.
- stp x0, x1, [x9]
- /* Increment the address by 16 bytes for the next pair of values */
- stp x2, x3, [x9, #16]
+#else
- ldr r12, =qemu_saved_args
- stm r12, {r0, r1, r2, r3}
+#endif
- b save_boot_params_ret
diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c index 942f1fff57..a3892630d8 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -4,6 +4,9 @@ */
#include <common.h> +#if IS_ENABLED(CONFIG_OF_BOARD) && IS_ENABLED(CONFIG_BLOBLIST) +#include <bloblist.h> +#endif
you have dependency on OF_BOARD and BLOBLIST.
#include <cpu_func.h> #include <dm.h> #include <efi.h> @@ -102,6 +105,16 @@ static struct mm_region qemu_arm64_mem_map[] = { struct mm_region *mem_map = qemu_arm64_mem_map; #endif
+#if IS_ENABLED(CONFIG_OF_BOARD)
And here OF_BOARD.
Not all should be aligned but I don't think current #if
Thanks, Michal

Hi Michal,
I will remove "#if IS_ENABLED(CONFIG_OF_BOARD)" from below:
+#if IS_ENABLED(CONFIG_OF_BOARD) +/* Boot parameters saved from lowlevel_init.S */ +struct {
- unsigned long arg0;
- unsigned long arg1;
- unsigned long arg2;
- unsigned long arg3;
+} qemu_saved_args __section(".data"); +#endif
Saving the args does not really dependent on OF_BOARD or BLOBLIST
Thanks and regards, Raymond
On Mon, 4 Dec 2023 at 02:54, Michal Simek michal.simek@amd.com wrote:
On 11/27/23 20:50, Raymond Mao wrote:
Add platform custom function to get bloblist from boot arguments. Check whether boot arguments aligns with the register conventions defined in FW Handoff spec v0.9. Add bloblist related options into qemu default config.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
New patch file created for v2.
board/emulation/qemu-arm/Makefile | 1 + board/emulation/qemu-arm/lowlevel_init.S | 19 +++++++++ board/emulation/qemu-arm/qemu-arm.c | 54 ++++++++++++++++++++++++ configs/qemu_arm64_defconfig | 3 ++ configs/qemu_arm_defconfig | 3 ++ 5 files changed, 80 insertions(+) create mode 100644 board/emulation/qemu-arm/lowlevel_init.S
diff --git a/board/emulation/qemu-arm/Makefile
b/board/emulation/qemu-arm/Makefile
index a22d1237ff..12821e7083 100644 --- a/board/emulation/qemu-arm/Makefile +++ b/board/emulation/qemu-arm/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0+
obj-y += qemu-arm.o +obj-$(CONFIG_OF_BOARD) += lowlevel_init.o diff --git a/board/emulation/qemu-arm/lowlevel_init.S
b/board/emulation/qemu-arm/lowlevel_init.S
new file mode 100644 index 0000000000..d72d7c938a --- /dev/null +++ b/board/emulation/qemu-arm/lowlevel_init.S @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/*
- Copyright (c) 2023, Linaro Limited
- */
+#include <config.h>
+.global save_boot_params +save_boot_params: +#ifdef CONFIG_ARM64
adr x9, qemu_saved_args
Based on logic below this is available only when CONFIG_OF_BOARD is enabled. Please look below.
stp x0, x1, [x9]
/* Increment the address by 16 bytes for the next pair of values */
stp x2, x3, [x9, #16]
+#else
ldr r12, =qemu_saved_args
stm r12, {r0, r1, r2, r3}
+#endif
b save_boot_params_ret
diff --git a/board/emulation/qemu-arm/qemu-arm.c
b/board/emulation/qemu-arm/qemu-arm.c
index 942f1fff57..a3892630d8 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -4,6 +4,9 @@ */
#include <common.h> +#if IS_ENABLED(CONFIG_OF_BOARD) && IS_ENABLED(CONFIG_BLOBLIST) +#include <bloblist.h> +#endif
you have dependency on OF_BOARD and BLOBLIST.
#include <cpu_func.h> #include <dm.h> #include <efi.h> @@ -102,6 +105,16 @@ static struct mm_region qemu_arm64_mem_map[] = { struct mm_region *mem_map = qemu_arm64_mem_map; #endif
+#if IS_ENABLED(CONFIG_OF_BOARD)
And here OF_BOARD.
Not all should be aligned but I don't think current #if
Thanks, Michal

During bloblist initialization, when CONFIG_OF_BOARD is defined, invoke the platform custom function to load the bloblist via boot arguments from the previous loader. If the bloblist exists, copy it into the fixed bloblist memory region.
Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - New patch file created for v2.
common/bloblist.c | 29 +++++++++++++---------------- include/bloblist.h | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index 91d69e9439..251093ecfa 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -477,15 +477,8 @@ int bloblist_init(void) bool fixed = IS_ENABLED(CONFIG_BLOBLIST_FIXED); int ret = -ENOENT; ulong addr, size; - bool expected; - - /** - * We don't expect to find an existing bloblist in the first phase of - * U-Boot that runs. Also we have no way to receive the address of an - * allocated bloblist from a previous stage, so it must be at a fixed - * address. - */ - expected = fixed && !u_boot_first_phase(); + bool expected = fixed; + if (spl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST)) expected = false; if (fixed) @@ -493,14 +486,17 @@ int bloblist_init(void) CONFIG_BLOBLIST_ADDR); size = CONFIG_BLOBLIST_SIZE; if (expected) { - ret = bloblist_check(addr, size); - if (ret) { - log_warning("Expected bloblist at %lx not found (err=%d)\n", + if (IS_ENABLED(CONFIG_OF_BOARD)) + /* Get the bloblist from previous loader */ + ret = board_bloblist_from_boot_arg(addr, size); + else + ret = bloblist_check(addr, size); + + if (ret) + log_warning("Bloblist at %lx not found, err=%d\n", addr, ret); - } else { - /* Get the real size, if it is not what we expected */ + else size = gd->bloblist->total_size; - } } if (ret) { if (CONFIG_IS_ENABLED(BLOBLIST_ALLOC)) { @@ -510,7 +506,8 @@ int bloblist_init(void) return log_msg_ret("alloc", -ENOMEM); addr = map_to_sysmem(ptr); } else if (!fixed) { - return log_msg_ret("!fixed", ret); + return log_msg_ret("BLOBLIST_FIXED is not enabled", + ret); } log_debug("Creating new bloblist size %lx at %lx\n", size, addr); diff --git a/include/bloblist.h b/include/bloblist.h index 0f5afec9f4..e65cd27b90 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -438,6 +438,20 @@ void bloblist_reloc(void *to, uint to_size, void *from, uint from_size); */ int bloblist_init(void);
+#if CONFIG_IS_ENABLED(ARCH_QEMU) +int board_bloblist_from_boot_arg(unsigned long addr, unsigned long size); +#else +/* + * A board need to implement this custom function if it needs to retrieve + * bloblist from a previous loader + */ +static inline int board_bloblist_from_boot_arg(unsigned long __always_unused addr, + unsigned long __always_unused size) +{ + return -1; +} +#endif + #if CONFIG_IS_ENABLED(BLOBLIST) /** * bloblist_maybe_init() - Init the bloblist system if not already done

Hi Raymond,
On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
During bloblist initialization, when CONFIG_OF_BOARD is defined, invoke the platform custom function to load the bloblist via boot arguments from the previous loader. If the bloblist exists, copy it into the fixed bloblist memory region.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- New patch file created for v2.
common/bloblist.c | 29 +++++++++++++---------------- include/bloblist.h | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 16 deletions(-)
This should already work so I am hoping that this patch is not needed...these changes seem to break sandbox_spl
diff --git a/common/bloblist.c b/common/bloblist.c index 91d69e9439..251093ecfa 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -477,15 +477,8 @@ int bloblist_init(void) bool fixed = IS_ENABLED(CONFIG_BLOBLIST_FIXED); int ret = -ENOENT; ulong addr, size;
bool expected;
/**
* We don't expect to find an existing bloblist in the first phase of
* U-Boot that runs. Also we have no way to receive the address of an
* allocated bloblist from a previous stage, so it must be at a fixed
* address.
*/
expected = fixed && !u_boot_first_phase();
bool expected = fixed;
if (spl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST)) expected = false; if (fixed)
@@ -493,14 +486,17 @@ int bloblist_init(void) CONFIG_BLOBLIST_ADDR); size = CONFIG_BLOBLIST_SIZE; if (expected) {
ret = bloblist_check(addr, size);
if (ret) {
log_warning("Expected bloblist at %lx not found (err=%d)\n",
if (IS_ENABLED(CONFIG_OF_BOARD))
/* Get the bloblist from previous loader */
ret = board_bloblist_from_boot_arg(addr, size);
else
ret = bloblist_check(addr, size);
if (ret)
log_warning("Bloblist at %lx not found, err=%d\n", addr, ret);
} else {
/* Get the real size, if it is not what we expected */
else size = gd->bloblist->total_size;
} } if (ret) { if (CONFIG_IS_ENABLED(BLOBLIST_ALLOC)) {
@@ -510,7 +506,8 @@ int bloblist_init(void) return log_msg_ret("alloc", -ENOMEM); addr = map_to_sysmem(ptr); } else if (!fixed) {
return log_msg_ret("!fixed", ret);
return log_msg_ret("BLOBLIST_FIXED is not enabled",
ret); } log_debug("Creating new bloblist size %lx at %lx\n", size, addr);
diff --git a/include/bloblist.h b/include/bloblist.h index 0f5afec9f4..e65cd27b90 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -438,6 +438,20 @@ void bloblist_reloc(void *to, uint to_size, void *from, uint from_size); */ int bloblist_init(void);
+#if CONFIG_IS_ENABLED(ARCH_QEMU) +int board_bloblist_from_boot_arg(unsigned long addr, unsigned long size); +#else +/*
- A board need to implement this custom function if it needs to retrieve
- bloblist from a previous loader
- */
+static inline int board_bloblist_from_boot_arg(unsigned long __always_unused addr,
unsigned long __always_unused size)
+{
return -1;
+} +#endif
#if CONFIG_IS_ENABLED(BLOBLIST) /**
- bloblist_maybe_init() - Init the bloblist system if not already done
-- 2.25.1
Regards, Simon

Hi Simon,
On Sat, 2 Dec 2023 at 13:32, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
During bloblist initialization, when CONFIG_OF_BOARD is defined, invoke the platform custom function to load the bloblist via boot arguments from the previous loader. If the bloblist exists, copy it into the fixed bloblist memory region.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- New patch file created for v2.
common/bloblist.c | 29 +++++++++++++---------------- include/bloblist.h | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 16 deletions(-)
This should already work so I am hoping that this patch is not needed...these changes seem to break sandbox_spl
By "already work", do you mean any existing patches already done for loading the bloblist from the boot args?
Thanks and regards, Raymond

Hi Raymond,
On Mon, 4 Dec 2023 at 13:21, Raymond Mao raymond.mao@linaro.org wrote:
Hi Simon,
On Sat, 2 Dec 2023 at 13:32, Simon Glass sjg@chromium.org wrote:
Hi Raymond,
On Mon, 27 Nov 2023 at 12:53, Raymond Mao raymond.mao@linaro.org wrote:
During bloblist initialization, when CONFIG_OF_BOARD is defined, invoke the platform custom function to load the bloblist via boot arguments from the previous loader. If the bloblist exists, copy it into the fixed bloblist memory region.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- New patch file created for v2.
common/bloblist.c | 29 +++++++++++++---------------- include/bloblist.h | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 16 deletions(-)
This should already work so I am hoping that this patch is not needed...these changes seem to break sandbox_spl
By "already work", do you mean any existing patches already done for loading the bloblist from the boot args?
No it doesn't have that. But we need to figure out [1]. I have marked in 'new' in patchwork.
Regards, Simon
[1] https://patchwork.ozlabs.org/project/uboot/patch/20230926141514.2101787-40-s...

Hi Raymond,
On Mon, 27 Nov 2023 at 12:52, Raymond Mao raymond.mao@linaro.org wrote:
Major changes:
Update bloblist to align to Firmware Handoff spec v0.9 (https://github.com/FirmwareHandoff/firmware_handoff).
Implement Qemu-Arm platform custom functions to retrieve the bloblist (aka. Transfer List) from previous loader via boot arguments when CONFIG_OF_BOARD option is enabled.
If a board provides both custom functions for getting the bloblist and the address of external FDT, the FDT inside the bloblist will be prioritized during FDT setup.
The patch set is tested with previous done TF-A/OP-TEE patches through a complete Firmware Handoff cycle (BL2, BL31, BL32, BL33). TF-A Patches: feat(handoff): introduce firmware handoff library (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/22215) feat(qemu): implement firmware handoff on qemu (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/22178) feat(handoff): enhance transfer list library (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/23776) feat(optee): enable transfer list in opteed (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/23777) feat(qemu): enable transfer list to BL31/32 (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/23778) OP-TEE Patch: Firmware handoff (https://github.com/OP-TEE/optee_os/pull/6308) fixup of transfer list entry overriding (https://github.com/OP-TEE/optee_os/pull/6461)
Raymond Mao (3): bloblist: Align bloblist used_size and total_size to spec qemu-arm: Get bloblist from boot arguments bloblist: Load the bloblist from the previous loader
Simon Glass (15): bloblist: Update the tag numbering bloblist: Adjust API to align in powers of 2 bloblist: Change the magic value bloblist: Set version to 1 bloblist: Access record hdr_size and tag via a function bloblist: Drop the flags value bloblist: Drop the spare values bloblist: Change the checksum algorithm bloblist: Checksum the entire bloblist bloblist: Handle alignment with a void entry bloblist: Reduce blob-header size bloblist: Reduce bloblist header size bloblist: Add alignment to bloblist_new() bloblist: Update documentation and header comment fdt: Allow the devicetree to come from a bloblist
arch/x86/lib/tables.c | 3 +- board/emulation/qemu-arm/Makefile | 1 + board/emulation/qemu-arm/lowlevel_init.S | 19 ++ board/emulation/qemu-arm/qemu-arm.c | 54 ++++++ common/bloblist.c | 225 +++++++++++++---------- configs/qemu_arm64_defconfig | 3 + configs/qemu_arm_defconfig | 3 + doc/develop/bloblist.rst | 4 +- doc/develop/devicetree/control.rst | 8 +- dts/Kconfig | 9 +- include/bloblist.h | 181 ++++++++++-------- include/fdtdec.h | 3 +- lib/fdtdec.c | 52 ++++-- test/bloblist.c | 86 ++++----- 14 files changed, 420 insertions(+), 231 deletions(-) create mode 100644 board/emulation/qemu-arm/lowlevel_init.S
-- 2.25.1
Thank you for taking this on!
It is great to have a qemu test, but please do hook it into test/py so that it runs in CI.
We should also have a sandbox test. With this series this fails:
/tmp/b/sandbox_spl/spl/u-boot-spl -d /tmp/b/sandbox_spl/u-boot.dtb -m ram.bin
A simple C test could be something that checks that the bloblist is present, e.g. in test/bloblist.c :
static int bloblist_test_from_spl(struct unit_test_state *uts) { if (!IS_ENABLED(SPL)) return -EAGAIN;
ut_assertnonnull(gd->bloblist);
return 0; }
Also you could add jwerner to this as he reviewed v1
Here is my cover letter in case it helps (at u-boot-dm/blob-working):
Series-to: u-boot Series-cc: trini, Jose Marinho jose.marinho@arm.com Series-cc: Julius Werner jwerner@chromium.org, ilias, Series-cc: Dan Handley <dan.handley@arm.com > Cover-letter: bloblist: Align to firmware handoff In moving from v0.8 to v0.9 the Firmware Handoff specification made some changes, including:
- Use a packed format for headers to reduce space - Add an explicit alignment field in the header - Renumber all the tags and reduce their size to 24 bits - Drop use of the blob header to specify alignment, in favour of a 'void' blob type
This series attempts to align to that specification, including updating the API and tests. It is likely that refinements will be made as other projects implement the spec too.
As before the code is dual-licensed, to permit use in projects with a permissive license. END
Regards, Simon
participants (4)
-
Ilias Apalodimas
-
Michal Simek
-
Raymond Mao
-
Simon Glass