All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] Add support for DT overlays handoff
@ 2025-07-04 13:41 Raymond Mao
  2025-07-04 13:42 ` [PATCH v2 1/6] bloblist: add blob type for DT overlay Raymond Mao
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Raymond Mao @ 2025-07-04 13:41 UTC (permalink / raw)
  To: u-boot
  Cc: michal.simek, venkatesh.abbarapu, Raymond Mao, Tom Rini,
	Simon Glass, Ilias Apalodimas, Dan Carpenter, Harrison Mutai,
	Andrew Goodbody, Patrick Rudolph, Levi Yun, Evgeny Bachinin,
	Matthias Brugger, Casey Connolly, Lad Prabhakar, Marek Vasut

The series include refactoring on bloblist and fdtdec to support handoff
of multiple DT overlays and applying them into the DT base during setup.
All changes are aligned to the spec update for supporting DT overlay
handoff[1].

Notes for testing:

Currently DT overlay is not yet enabled in TF-A, but with the test patches
I provided for TF-A and OP-TEE build, importing a DT overlay blob file from
QEMU to TF-A reserved memory is supported.
Follow below instructions to build and run for test:
$ repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml
Replace your local qemu_v8.xml with [2], which contains all necessary
changes in both TF-A and OP-TEE build.
$ repo sync
$ cd build
$ make toolchains
$ make ARM_FIRMWARE_HANDOFF=y all
Copy and rename your DT overlay blob as 'qemu_v8.dtb' into out/bin
$ make ARM_FIRMWARE_HANDOFF=y run-only

[1] Add Transfer Entry for Devicetree Overlay
https://github.com/FirmwareHandoff/firmware_handoff/pull/74

[2] https://github.com/raymo200915/optee_manifest/blob/dt_overlay_handoff/qemu_v8.xml

Raymond Mao (6):
  bloblist: add blob type for DT overlay
  bloblist: add helper functions
  bloblist: fix a potential negative size for memmove
  bloblist: expose 'expand_by' as an output argument
  bloblist: add API for applying blobs with specified tag
  fdtdec: apply DT overlays from bloblist

 common/bloblist.c      | 83 +++++++++++++++++++++++++++++++++++++-----
 include/bloblist.h     | 44 +++++++++++++++++++++-
 lib/fdtdec.c           | 81 +++++++++++++++++++++++++++++++++++++++++
 test/common/bloblist.c | 17 ++++++---
 4 files changed, 208 insertions(+), 17 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/6] bloblist: add blob type for DT overlay
  2025-07-04 13:41 [PATCH v2 0/6] Add support for DT overlays handoff Raymond Mao
@ 2025-07-04 13:42 ` Raymond Mao
  2025-07-04 13:42 ` [PATCH v2 2/6] bloblist: add helper functions Raymond Mao
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Raymond Mao @ 2025-07-04 13:42 UTC (permalink / raw)
  To: u-boot
  Cc: michal.simek, venkatesh.abbarapu, Raymond Mao, Tom Rini,
	Simon Glass, Ilias Apalodimas, Levi Yun, Andrew Goodbody,
	Patrick Rudolph, Harrison Mutai, Evgeny Bachinin,
	Matthias Brugger, Lad Prabhakar, Marek Vasut

Add blob type for DT overlay according to the update of Firmware
Handoff spec[1].
Add an inline header to represent the 'subtype' in a DT overlay
blob payload.

[1] Add Transfer Entry for Devicetree Overlay
https://github.com/FirmwareHandoff/firmware_handoff/pull/74

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
---
Changes in v2:
- Add inline header for 'subtype'.

 common/bloblist.c  |  1 +
 include/bloblist.h | 13 ++++++++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 6e4f020d7c4..1c690f58b56 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -43,6 +43,7 @@ static struct tag_name {
 	{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
 	{ BLOBLISTT_TPM_EVLOG, "TPM event log defined by TCG EFI" },
 	{ BLOBLISTT_TPM_CRB_BASE, "TPM Command Response Buffer address" },
+	{ BLOBLISTT_FDT_OVERLAY, "DT overlay" },
 
 	/* BLOBLISTT_AREA_FIRMWARE */
 	{ BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" },
diff --git a/include/bloblist.h b/include/bloblist.h
index f32faf78560..c2d3065a43c 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -110,7 +110,8 @@ enum bloblist_tag_t {
 	BLOBLISTT_ACPI_TABLES = 4,
 	BLOBLISTT_TPM_EVLOG = 5,
 	BLOBLISTT_TPM_CRB_BASE = 6,
-	BLOBLISTT_ACPI_PP = 7,
+	BLOBLISTT_FDT_OVERLAY = 7,
+	BLOBLISTT_ACPI_PP = 8,
 
 	/* Standard area to allocate blobs used across firmware components */
 	BLOBLISTT_AREA_FIRMWARE = 0x10,
@@ -231,6 +232,16 @@ enum {
 	BLOBLIST_REC_HDR_SIZE		= sizeof(struct bloblist_rec),
 };
 
+/*
+ * struct dto_blob_hdr - Blob inline header for BLOBLISTT_FDT_OVERLAY
+ *
+ * @subtype: IMP-DEF per the agreement between the DT overlay producer and
+ *	consumer. Default value is 0.
+ */
+struct dto_blob_hdr {
+	u64 subtype;
+};
+
 /**
  * bloblist_check_magic() - return a bloblist if the magic matches
  *
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/6] bloblist: add helper functions
  2025-07-04 13:41 [PATCH v2 0/6] Add support for DT overlays handoff Raymond Mao
  2025-07-04 13:42 ` [PATCH v2 1/6] bloblist: add blob type for DT overlay Raymond Mao
@ 2025-07-04 13:42 ` Raymond Mao
  2025-07-04 13:42 ` [PATCH v2 3/6] bloblist: fix a potential negative size for memmove Raymond Mao
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Raymond Mao @ 2025-07-04 13:42 UTC (permalink / raw)
  To: u-boot
  Cc: michal.simek, venkatesh.abbarapu, Raymond Mao, Tom Rini,
	Simon Glass, Ilias Apalodimas, Andrew Goodbody, Harrison Mutai,
	Levi Yun, Evgeny Bachinin, Patrick Rudolph, Matthias Brugger,
	Lad Prabhakar, Marek Vasut

Add two helper functions for:
1. marking a blob void
2. getting blob record from a given blob data pointer.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
---
Changes in v2:
- None.

 common/bloblist.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/common/bloblist.c b/common/bloblist.c
index 1c690f58b56..488908f605e 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -97,6 +97,19 @@ static inline uint rec_tag(struct bloblist_rec *rec)
 		BLOBLISTR_TAG_SHIFT;
 }
 
+static inline void void_blob(struct bloblist_rec *rec)
+{
+	if (rec_tag(rec) == BLOBLISTT_VOID)
+		return;
+	rec->tag_and_hdr_size = BLOBLISTT_VOID |
+				sizeof(*rec) << BLOBLISTR_HDR_SIZE_SHIFT;
+}
+
+static inline struct bloblist_rec *rec_from_blob(void *blob)
+{
+	return (blob - sizeof(struct bloblist_rec));
+}
+
 static ulong bloblist_blob_end_ofs(struct bloblist_hdr *hdr,
 				   struct bloblist_rec *rec)
 {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/6] bloblist: fix a potential negative size for memmove
  2025-07-04 13:41 [PATCH v2 0/6] Add support for DT overlays handoff Raymond Mao
  2025-07-04 13:42 ` [PATCH v2 1/6] bloblist: add blob type for DT overlay Raymond Mao
  2025-07-04 13:42 ` [PATCH v2 2/6] bloblist: add helper functions Raymond Mao
@ 2025-07-04 13:42 ` Raymond Mao
  2025-07-04 13:42 ` [PATCH v2 4/6] bloblist: expose 'expand_by' as an output argument Raymond Mao
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Raymond Mao @ 2025-07-04 13:42 UTC (permalink / raw)
  To: u-boot
  Cc: michal.simek, venkatesh.abbarapu, Raymond Mao, Tom Rini,
	Simon Glass, Ilias Apalodimas, Patrick Rudolph, Harrison Mutai,
	Andrew Goodbody, Levi Yun, Evgeny Bachinin, Matthias Brugger,
	Casey Connolly, Lad Prabhakar, Marek Vasut

It causes a panic when blob is shrunk and 'new_alloced' is less than
'next_ofs'. The data area that needs to be moved should end up at
'hdr->used_size'.

Fixes: 1fe59375498f ("bloblist: Support resizing a blob")
Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
---
Changes in v2:
- None.

 common/bloblist.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 488908f605e..550c0c78ffc 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -335,7 +335,7 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
 	next_ofs = bloblist_blob_end_ofs(hdr, rec);
 	if (next_ofs != hdr->used_size) {
 		memmove((void *)hdr + next_ofs + expand_by,
-			(void *)hdr + next_ofs, new_alloced - next_ofs);
+			(void *)hdr + next_ofs, hdr->used_size - next_ofs);
 	}
 	hdr->used_size = new_alloced;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 4/6] bloblist: expose 'expand_by' as an output argument
  2025-07-04 13:41 [PATCH v2 0/6] Add support for DT overlays handoff Raymond Mao
                   ` (2 preceding siblings ...)
  2025-07-04 13:42 ` [PATCH v2 3/6] bloblist: fix a potential negative size for memmove Raymond Mao
@ 2025-07-04 13:42 ` Raymond Mao
  2025-07-04 13:42 ` [PATCH v2 5/6] bloblist: add API for applying blobs with specified tag Raymond Mao
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Raymond Mao @ 2025-07-04 13:42 UTC (permalink / raw)
  To: u-boot
  Cc: michal.simek, venkatesh.abbarapu, Raymond Mao, Tom Rini,
	Simon Glass, Ilias Apalodimas, Harrison Mutai, Dan Carpenter,
	Patrick Rudolph, Levi Yun, Andrew Goodbody, Evgeny Bachinin,
	Matthias Brugger, Marek Vasut, Lad Prabhakar

Some advanced usecases of bloblist needs to know the actual bytes
expanded or shrunk after blob resizing.
For example, to support applying DT overlay from bloblist, firstly
the FDT blob needs to be resized for potential size increasing after
applying overlay. If the DT overlay blob is one of the following blobs
of the FDT, its address will be shifted after FDT blob resizing.
Thus, returning 'expand_by' helps the caller to get the shifted data
pointer when it comes to get the overlay for applying.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
---
Changes in v2:
- None.

 common/bloblist.c      | 16 ++++++++--------
 include/bloblist.h     | 11 ++++++++++-
 test/common/bloblist.c | 17 +++++++++++------
 3 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 550c0c78ffc..ae5273785eb 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -311,14 +311,14 @@ int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp)
 
 static int bloblist_resize_rec(struct bloblist_hdr *hdr,
 			       struct bloblist_rec *rec,
-			       int new_size)
+			       int new_size, int *expand_by)
 {
-	int expand_by;	/* Number of bytes to expand by (-ve to contract) */
 	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->used_size + expand_by, BLOBLIST_BLOB_ALIGN);
+	*expand_by = ALIGN(new_size - rec->size, 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);
@@ -334,13 +334,13 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
 	/* 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->used_size) {
-		memmove((void *)hdr + next_ofs + expand_by,
+		memmove((void *)hdr + next_ofs + *expand_by,
 			(void *)hdr + next_ofs, hdr->used_size - next_ofs);
 	}
 	hdr->used_size = new_alloced;
 
 	/* Zero the new part of the blob */
-	if (expand_by > 0) {
+	if (*expand_by > 0) {
 		memset((void *)rec + rec_hdr_size(rec) + rec->size, '\0',
 		       new_size - rec->size);
 	}
@@ -351,7 +351,7 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
 	return 0;
 }
 
-int bloblist_resize(uint tag, int new_size)
+int bloblist_resize(uint tag, int new_size, int *expand_by)
 {
 	struct bloblist_hdr *hdr = gd->bloblist;
 	struct bloblist_rec *rec;
@@ -360,7 +360,7 @@ int bloblist_resize(uint tag, int new_size)
 	rec = bloblist_findrec(tag);
 	if (!rec)
 		return log_msg_ret("find", -ENOENT);
-	ret = bloblist_resize_rec(hdr, rec, new_size);
+	ret = bloblist_resize_rec(hdr, rec, new_size, expand_by);
 	if (ret)
 		return log_msg_ret("resize", ret);
 
diff --git a/include/bloblist.h b/include/bloblist.h
index c2d3065a43c..213285bbec6 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -73,6 +73,7 @@
 #define __BLOBLIST_H
 
 #include <mapmem.h>
+#include <errno.h>
 
 enum {
 	BLOBLIST_VERSION	= 1,
@@ -347,6 +348,7 @@ void *bloblist_ensure(uint tag, int size);
  */
 int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp);
 
+#if CONFIG_IS_ENABLED(BLOBLIST)
 /**
  * bloblist_resize() - resize a blob
  *
@@ -355,10 +357,17 @@ int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp);
  *
  * @tag:	Tag to add (enum bloblist_tag_t)
  * @new_size:	New size of the blob (>0 to expand, <0 to contract)
+ * @expand_by:	Number of bytes actually expanded by (-ve to contract)
  * Return: 0 if OK, -ENOSPC if the bloblist does not have enough space, -ENOENT
  * if the tag is not found
  */
-int bloblist_resize(uint tag, int new_size);
+int bloblist_resize(uint tag, int new_size, int *expand_by);
+#else
+static inline int bloblist_resize(uint tag, int new_size, int *expand_by)
+{
+	return -EPERM;
+}
+#endif
 
 /**
  * bloblist_new() - Create a new, empty bloblist of a given size
diff --git a/test/common/bloblist.c b/test/common/bloblist.c
index 797bde27025..c087d95c4b2 100644
--- a/test/common/bloblist.c
+++ b/test/common/bloblist.c
@@ -401,6 +401,7 @@ static int bloblist_test_grow(struct unit_test_state *uts)
 	void *blob1, *blob2, *blob1_new;
 	struct bloblist_hdr *hdr;
 	void *ptr;
+	int expand_by;
 
 	ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
 	hdr = ptr;
@@ -422,7 +423,7 @@ static int bloblist_test_grow(struct unit_test_state *uts)
 		    hdr->used_size);
 
 	/* Resize the first one */
-	ut_assertok(bloblist_resize(TEST_TAG, small_size + 4));
+	ut_assertok(bloblist_resize(TEST_TAG, small_size + 4, &expand_by));
 
 	/* The first one should not have moved, just got larger */
 	blob1_new = bloblist_find(TEST_TAG, small_size + 4);
@@ -455,6 +456,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts)
 	struct bloblist_hdr *hdr;
 	int new_size;
 	void *ptr;
+	int expand_by;
 
 	ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
 
@@ -475,7 +477,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts)
 
 	/* Resize the first one */
 	new_size = small_size - BLOBLIST_ALIGN - 4;
-	ut_assertok(bloblist_resize(TEST_TAG, new_size));
+	ut_assertok(bloblist_resize(TEST_TAG, new_size, &expand_by));
 
 	/* The first one should not have moved, just got smaller */
 	blob1_new = bloblist_find(TEST_TAG, new_size);
@@ -505,6 +507,7 @@ static int bloblist_test_resize_fail(struct unit_test_state *uts)
 	void *blob1, *blob2;
 	int new_size;
 	void *ptr;
+	int expand_by;
 
 	ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
 
@@ -522,11 +525,12 @@ static int bloblist_test_resize_fail(struct unit_test_state *uts)
 		    hdr->used_size);
 
 	/* Resize the first one, to check the boundary conditions */
-	ut_asserteq(-EINVAL, bloblist_resize(TEST_TAG, -1));
+	ut_asserteq(-EINVAL, bloblist_resize(TEST_TAG, -1, &expand_by));
 
 	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));
+	ut_asserteq(-ENOSPC, bloblist_resize(TEST_TAG, new_size + 1,
+					     &expand_by));
+	ut_assertok(bloblist_resize(TEST_TAG, new_size, &expand_by));
 
 	return 0;
 }
@@ -540,6 +544,7 @@ static int bloblist_test_resize_last(struct unit_test_state *uts)
 	void *blob1, *blob2, *blob2_new;
 	int alloced_val;
 	void *ptr;
+	int expand_by;
 
 	ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
 	memset(ptr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
@@ -561,7 +566,7 @@ static int bloblist_test_resize_last(struct unit_test_state *uts)
 	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));
+	ut_asserteq(0, bloblist_resize(TEST_TAG2, small_size + 4, &expand_by));
 
 	blob2_new = bloblist_find(TEST_TAG2, small_size + 4);
 	ut_asserteq_ptr(blob2, blob2_new);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 5/6] bloblist: add API for applying blobs with specified tag
  2025-07-04 13:41 [PATCH v2 0/6] Add support for DT overlays handoff Raymond Mao
                   ` (3 preceding siblings ...)
  2025-07-04 13:42 ` [PATCH v2 4/6] bloblist: expose 'expand_by' as an output argument Raymond Mao
@ 2025-07-04 13:42 ` Raymond Mao
  2025-07-04 13:42 ` [PATCH v2 6/6] fdtdec: apply DT overlays from bloblist Raymond Mao
  2025-07-11 15:45 ` [PATCH v2 0/6] Add support for DT overlays handoff Tom Rini
  6 siblings, 0 replies; 11+ messages in thread
From: Raymond Mao @ 2025-07-04 13:42 UTC (permalink / raw)
  To: u-boot
  Cc: michal.simek, venkatesh.abbarapu, Raymond Mao, Tom Rini,
	Simon Glass, Ilias Apalodimas, Dan Carpenter, Levi Yun,
	Andrew Goodbody, Harrison Mutai, Evgeny Bachinin, Patrick Rudolph,
	Matthias Brugger, Casey Connolly, Marek Vasut, Lad Prabhakar

Add an API to search for the blobs with specified tag and use the
hook function to apply the blob data.
Add a helper function to return the inline header size as according
to recent spec[1] updates, the actual data can be following an inline
header instead of following the TE header immediately.

[1] Firmware Handoff spec:
https://github.com/FirmwareHandoff/firmware_handoff

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
---
Changes in v2:
- Add inline header into the blob payload.
- Add arg 'size' to 'bloblist_apply_blobs()' for more general purpose.

 common/bloblist.c  | 51 ++++++++++++++++++++++++++++++++++++++++++++++
 include/bloblist.h | 20 ++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/common/bloblist.c b/common/bloblist.c
index ae5273785eb..b944821d9f5 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -235,6 +235,19 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size,
 	return 0;
 }
 
+static int bloblist_get_blob_data_offset(uint tag)
+{
+	switch (tag) {
+	case BLOBLISTT_FDT_OVERLAY:
+		return sizeof(struct dto_blob_hdr);
+	/*
+	 * return the data offset if it is not following the blob
+	 * header immediately.
+	 */
+	}
+	return 0;
+}
+
 void *bloblist_find(uint tag, int size)
 {
 	void *blob = NULL;
@@ -261,6 +274,44 @@ void *bloblist_get_blob(uint tag, int *sizep)
 	return (void *)rec + rec_hdr_size(rec);
 }
 
+int bloblist_apply_blobs(uint tag, int (*func)(void **data, int size))
+{
+	struct bloblist_hdr *hdr = gd->bloblist;
+	struct bloblist_rec *rec;
+
+	if (!func || !hdr)
+		return -ENOENT;
+
+	foreach_rec(rec, hdr) {
+		/* Apply all blobs with the specified tag */
+		if (rec_tag(rec) == tag) {
+			int ret;
+			int tag = rec_tag(rec);
+			void *blob = (void *)rec + rec_hdr_size(rec);
+			int dat_off = bloblist_get_blob_data_offset(tag);
+
+			blob += dat_off;
+			ret = func(&blob, rec->size - dat_off);
+			if (ret) {
+				log_err("Failed to apply blob with tag %d\n",
+					tag);
+				return ret;
+			}
+
+			rec = rec_from_blob(blob - dat_off);
+			if (rec <= 0) {
+				log_err("Blob corrupted\n");
+				return -ENOENT;
+			}
+
+			/* Mark applied blob record as void */
+			void_blob(rec);
+		}
+	}
+
+	return 0;
+}
+
 void *bloblist_add(uint tag, int size, int align_log2)
 {
 	struct bloblist_rec *rec;
diff --git a/include/bloblist.h b/include/bloblist.h
index 213285bbec6..f88b2513ee8 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -280,6 +280,26 @@ static inline void *bloblist_get_blob(uint tag, int *sizep)
 }
 #endif
 
+#if CONFIG_IS_ENABLED(BLOBLIST)
+/**
+ * bloblist_apply_blobs() - Apply the data of blobs by tag
+ *
+ * Scan the bloblist, find the blobs with the matching tag and apply the data
+ * of blobs
+ *
+ * @tag:	Tag to search for (enum bloblist_tag_t)
+ * @func:	Function to apply the data of blobs
+ * Return: 0 if OK, otherwise error.
+ */
+int bloblist_apply_blobs(uint tag, int (*func)(void **data, int size));
+#else
+static inline int bloblist_apply_blobs(uint tag,
+				       int (*func)(void **data, int size))
+{
+	return -EPERM;
+}
+#endif
+
 /**
  * bloblist_find() - Find a blob
  *
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 6/6] fdtdec: apply DT overlays from bloblist
  2025-07-04 13:41 [PATCH v2 0/6] Add support for DT overlays handoff Raymond Mao
                   ` (4 preceding siblings ...)
  2025-07-04 13:42 ` [PATCH v2 5/6] bloblist: add API for applying blobs with specified tag Raymond Mao
@ 2025-07-04 13:42 ` Raymond Mao
  2025-07-11 15:45   ` Tom Rini
  2025-07-11 15:45 ` [PATCH v2 0/6] Add support for DT overlays handoff Tom Rini
  6 siblings, 1 reply; 11+ messages in thread
From: Raymond Mao @ 2025-07-04 13:42 UTC (permalink / raw)
  To: u-boot
  Cc: michal.simek, venkatesh.abbarapu, Raymond Mao, Tom Rini,
	Simon Glass, Ilias Apalodimas, Levi Yun, Andrew Goodbody,
	Harrison Mutai, Patrick Rudolph, Evgeny Bachinin,
	Matthias Brugger, Marek Vasut, Lad Prabhakar

During FDT setup, apply all existing DT overlays from the bloblist
to the base FDT if bloblist is being used for handoff from previous
boot stage.
According to the spec update for DT overlay handoff[1], an overlay
must have the same top-level compatible string as its target base
DT has.
Before applying the DTO, it checks whether sufficient space is
reserved in the base FDT region. A margin (0x400) is used during
estimating the space size required by the merged DT.
A resizing happens if the reserved space is insufficient.
After all overlays are applied, it resizes to the actual size of the
merged DT.
Note that the margin (0x400) is arbitrary from experience, it might
not cover all possible scenarios as complex overlays with many
properties might require extra spaces and lead to FDT_ERR_NOSPACE
error.

[1] Add Transfer Entry for Devicetree Overlay
https://github.com/FirmwareHandoff/firmware_handoff/pull/74

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
---
Changes in v2:
- Add more details into the commit message.
- Check and compare the top-level compatible string of DT/DTO.
- Check the reserved space in the base DT region, and skip resizing if
  the space is sufficient.
- Move the DT space shrinking to the end after all DT overlays are
  applied.

 lib/fdtdec.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index c38738b48c7..bd5e3c0aaea 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1687,6 +1687,84 @@ void fdtdec_setup_embed(void)
 	gd->fdt_src = FDTSRC_EMBED;
 }
 
+static int fdtdec_match_dto_compatible(const void *base, const void *dto)
+{
+	const char *compat_base;
+	const char *compat_dto;
+	int len;
+
+	compat_base = (const char *)fdt_getprop(base, 0, "compatible", &len);
+	if (!compat_base || len <= 0)
+		return -ENOENT;
+
+	compat_dto = (const char *)fdt_getprop(dto, 0, "compatible", &len);
+	if (!compat_dto || len <= 0)
+		return -ENOENT;
+
+	if (strcmp(compat_base, compat_dto))
+		return -EPERM;
+
+	return 0;
+}
+
+static int fdtdec_apply_dto_from_blob(void **blob, __maybe_unused int size)
+{
+	int ret;
+	struct fdt_header *live_fdt;
+	size_t new_fdt_size, actual_size;
+	int expand_by, blob_size;
+
+	if (!CONFIG_IS_ENABLED(OF_LIBFDT_OVERLAY) ||
+	    !CONFIG_IS_ENABLED(BLOBLIST))
+		return -EPERM;
+
+	ret = fdt_check_header(*blob);
+	if (ret)
+		return ret;
+
+	/* Get the total space reserved for FDT */
+	live_fdt = bloblist_get_blob(BLOBLISTT_CONTROL_FDT, &blob_size);
+	if (live_fdt != gd->fdt_blob)
+		return -ENOENT;
+
+	/* Make sure DTO has same top-level compatible string */
+	ret = fdtdec_match_dto_compatible(live_fdt, *blob);
+	if (ret)
+		return ret;
+
+	actual_size = fdt_totalsize(*blob);
+	/* Add margin for extra size growth after merging */
+	new_fdt_size = fdt_totalsize(live_fdt) + actual_size + 0x400;
+
+	/* Expand the FDT if the reserved size is not sufficient */
+	if (new_fdt_size > blob_size) {
+		ret = bloblist_resize(BLOBLISTT_CONTROL_FDT, new_fdt_size,
+				      &expand_by);
+		if (ret)
+			return ret;
+
+		/* The blob is shifted if it was following the FDT */
+		if (*blob > (void *)live_fdt)
+			*blob += expand_by;
+
+		ret = fdt_open_into(live_fdt, live_fdt, new_fdt_size);
+		if (ret)
+			return ret;
+	}
+
+	return fdt_overlay_apply_verbose(live_fdt, *blob);
+}
+
+static int fdtdec_apply_dto_done(void)
+{
+	int expand_by;
+	struct fdt_header *live_fdt = (struct fdt_header *)gd->fdt_blob;
+
+	fdt_pack(live_fdt);
+	return bloblist_resize(BLOBLISTT_CONTROL_FDT, fdt_totalsize(live_fdt),
+			       &expand_by);
+}
+
 int fdtdec_setup(void)
 {
 	int ret = -ENOENT;
@@ -1708,6 +1786,9 @@ int fdtdec_setup(void)
 				gd->fdt_src = FDTSRC_BLOBLIST;
 				log_debug("Devicetree is in bloblist at %p\n",
 					  gd->fdt_blob);
+				bloblist_apply_blobs(BLOBLISTT_FDT_OVERLAY,
+						     fdtdec_apply_dto_from_blob);
+				fdtdec_apply_dto_done();
 				goto setup_fdt;
 			} else {
 				log_debug("No FDT found in bloblist\n");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 6/6] fdtdec: apply DT overlays from bloblist
  2025-07-04 13:42 ` [PATCH v2 6/6] fdtdec: apply DT overlays from bloblist Raymond Mao
@ 2025-07-11 15:45   ` Tom Rini
  2025-07-11 17:36     ` Raymond Mao
  0 siblings, 1 reply; 11+ messages in thread
From: Tom Rini @ 2025-07-11 15:45 UTC (permalink / raw)
  To: Raymond Mao
  Cc: u-boot, michal.simek, venkatesh.abbarapu, Simon Glass,
	Ilias Apalodimas, Levi Yun, Andrew Goodbody, Harrison Mutai,
	Patrick Rudolph, Evgeny Bachinin, Matthias Brugger, Marek Vasut,
	Lad Prabhakar

[-- Attachment #1: Type: text/plain, Size: 1475 bytes --]

On Fri, Jul 04, 2025 at 06:42:05AM -0700, Raymond Mao wrote:

> During FDT setup, apply all existing DT overlays from the bloblist
> to the base FDT if bloblist is being used for handoff from previous
> boot stage.
> According to the spec update for DT overlay handoff[1], an overlay
> must have the same top-level compatible string as its target base
> DT has.
> Before applying the DTO, it checks whether sufficient space is
> reserved in the base FDT region. A margin (0x400) is used during
> estimating the space size required by the merged DT.
> A resizing happens if the reserved space is insufficient.
> After all overlays are applied, it resizes to the actual size of the
> merged DT.
> Note that the margin (0x400) is arbitrary from experience, it might
> not cover all possible scenarios as complex overlays with many
> properties might require extra spaces and lead to FDT_ERR_NOSPACE
> error.
> 
> [1] Add Transfer Entry for Devicetree Overlay
> https://github.com/FirmwareHandoff/firmware_handoff/pull/74
[snip]
> +	actual_size = fdt_totalsize(*blob);
> +	/* Add margin for extra size growth after merging */
> +	new_fdt_size = fdt_totalsize(live_fdt) + actual_size + 0x400;

This is still a fixed value and still not the right way to handle it. I
think now that we expose configuring the amount of extra space we have
for the tree it should possibly even just fail out with an error message
that points to SYS_FDT_PAD?

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 0/6] Add support for DT overlays handoff
  2025-07-04 13:41 [PATCH v2 0/6] Add support for DT overlays handoff Raymond Mao
                   ` (5 preceding siblings ...)
  2025-07-04 13:42 ` [PATCH v2 6/6] fdtdec: apply DT overlays from bloblist Raymond Mao
@ 2025-07-11 15:45 ` Tom Rini
  2025-07-11 17:41   ` Raymond Mao
  6 siblings, 1 reply; 11+ messages in thread
From: Tom Rini @ 2025-07-11 15:45 UTC (permalink / raw)
  To: Raymond Mao
  Cc: u-boot, michal.simek, venkatesh.abbarapu, Simon Glass,
	Ilias Apalodimas, Dan Carpenter, Harrison Mutai, Andrew Goodbody,
	Patrick Rudolph, Levi Yun, Evgeny Bachinin, Matthias Brugger,
	Casey Connolly, Lad Prabhakar, Marek Vasut

[-- Attachment #1: Type: text/plain, Size: 592 bytes --]

On Fri, Jul 04, 2025 at 06:41:59AM -0700, Raymond Mao wrote:
> The series include refactoring on bloblist and fdtdec to support handoff
> of multiple DT overlays and applying them into the DT base during setup.
> All changes are aligned to the spec update for supporting DT overlay
> handoff[1].

Which for the record and my tracking, isn't merged yet, and links to
the doc update which also isn't applied yet. I'm fine with the concept
but also thinking that applying this here to master isn't the first step
towards getting all the relevant projects in agreement FYI.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 6/6] fdtdec: apply DT overlays from bloblist
  2025-07-11 15:45   ` Tom Rini
@ 2025-07-11 17:36     ` Raymond Mao
  0 siblings, 0 replies; 11+ messages in thread
From: Raymond Mao @ 2025-07-11 17:36 UTC (permalink / raw)
  To: Tom Rini
  Cc: u-boot, michal.simek, venkatesh.abbarapu, Simon Glass,
	Ilias Apalodimas, Levi Yun, Andrew Goodbody, Harrison Mutai,
	Patrick Rudolph, Evgeny Bachinin, Matthias Brugger, Marek Vasut,
	Lad Prabhakar

Hi Tom,

On Fri, 11 Jul 2025 at 11:45, Tom Rini <trini@konsulko.com> wrote:
>
> On Fri, Jul 04, 2025 at 06:42:05AM -0700, Raymond Mao wrote:
>
> > During FDT setup, apply all existing DT overlays from the bloblist
> > to the base FDT if bloblist is being used for handoff from previous
> > boot stage.
> > According to the spec update for DT overlay handoff[1], an overlay
> > must have the same top-level compatible string as its target base
> > DT has.
> > Before applying the DTO, it checks whether sufficient space is
> > reserved in the base FDT region. A margin (0x400) is used during
> > estimating the space size required by the merged DT.
> > A resizing happens if the reserved space is insufficient.
> > After all overlays are applied, it resizes to the actual size of the
> > merged DT.
> > Note that the margin (0x400) is arbitrary from experience, it might
> > not cover all possible scenarios as complex overlays with many
> > properties might require extra spaces and lead to FDT_ERR_NOSPACE
> > error.
> >
> > [1] Add Transfer Entry for Devicetree Overlay
> > https://github.com/FirmwareHandoff/firmware_handoff/pull/74
> [snip]
> > +     actual_size = fdt_totalsize(*blob);
> > +     /* Add margin for extra size growth after merging */
> > +     new_fdt_size = fdt_totalsize(live_fdt) + actual_size + 0x400;
>
> This is still a fixed value and still not the right way to handle it. I
> think now that we expose configuring the amount of extra space we have
> for the tree it should possibly even just fail out with an error message
> that points to SYS_FDT_PAD?
>
Shall we do it following the steps below?
1. Expand to "fdt_totalsize() + SYS_FDT_PAD" without conditions.
2. Apply each overlay and out if any errors are returned.
3. Shrink to fdt_totalsize().

In this case, the expansion is only once at the beginning. Is it good?

Regards,
Raymond


> --
> Tom

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 0/6] Add support for DT overlays handoff
  2025-07-11 15:45 ` [PATCH v2 0/6] Add support for DT overlays handoff Tom Rini
@ 2025-07-11 17:41   ` Raymond Mao
  0 siblings, 0 replies; 11+ messages in thread
From: Raymond Mao @ 2025-07-11 17:41 UTC (permalink / raw)
  To: Tom Rini
  Cc: u-boot, michal.simek, venkatesh.abbarapu, Simon Glass,
	Ilias Apalodimas, Dan Carpenter, Harrison Mutai, Andrew Goodbody,
	Patrick Rudolph, Levi Yun, Evgeny Bachinin, Matthias Brugger,
	Casey Connolly, Lad Prabhakar, Marek Vasut

Hi Tom,

On Fri, 11 Jul 2025 at 11:45, Tom Rini <trini@konsulko.com> wrote:
>
> On Fri, Jul 04, 2025 at 06:41:59AM -0700, Raymond Mao wrote:
> > The series include refactoring on bloblist and fdtdec to support handoff
> > of multiple DT overlays and applying them into the DT base during setup.
> > All changes are aligned to the spec update for supporting DT overlay
> > handoff[1].
>
> Which for the record and my tracking, isn't merged yet, and links to
> the doc update which also isn't applied yet. I'm fine with the concept
> but also thinking that applying this here to master isn't the first step
> towards getting all the relevant projects in agreement FYI.
>
No worries, both the changes to the DT doc and FW handoff spec are
still under review.
It may take some time to get everyone's agreement.
I will try to keep my patch up to date with the latest docs changes
and address all comments.
You can merge it after the docs changes are accepted.

Raymond


> --
> Tom

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2025-07-11 17:41 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-04 13:41 [PATCH v2 0/6] Add support for DT overlays handoff Raymond Mao
2025-07-04 13:42 ` [PATCH v2 1/6] bloblist: add blob type for DT overlay Raymond Mao
2025-07-04 13:42 ` [PATCH v2 2/6] bloblist: add helper functions Raymond Mao
2025-07-04 13:42 ` [PATCH v2 3/6] bloblist: fix a potential negative size for memmove Raymond Mao
2025-07-04 13:42 ` [PATCH v2 4/6] bloblist: expose 'expand_by' as an output argument Raymond Mao
2025-07-04 13:42 ` [PATCH v2 5/6] bloblist: add API for applying blobs with specified tag Raymond Mao
2025-07-04 13:42 ` [PATCH v2 6/6] fdtdec: apply DT overlays from bloblist Raymond Mao
2025-07-11 15:45   ` Tom Rini
2025-07-11 17:36     ` Raymond Mao
2025-07-11 15:45 ` [PATCH v2 0/6] Add support for DT overlays handoff Tom Rini
2025-07-11 17:41   ` Raymond Mao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.