[PATCH v2 04/16] passage: Support an incoming passage

Simon Glass sjg at chromium.org
Mon Jan 17 16:04:16 CET 2022


Plumb in the ability for U-Boot proper to accept an incoming standard
passage from a previous phase, such as SPL or TF-A. This allows data to
be passed from binary to binary when firmware is booting.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v2:
- Rebase to master
- Rework global_data for new stdpass convention

 common/Kconfig                    | 31 ++++++++++++++++++++++++++++++
 common/bloblist.c                 |  7 ++++++-
 common/board_f.c                  | 32 ++++++++++++++++---------------
 include/asm-generic/global_data.h | 28 +++++++++++++++++++++++++++
 lib/asm-offsets.c                 |  6 ++++++
 5 files changed, 88 insertions(+), 16 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index 82cd864baf9..59783d66cb8 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -757,6 +757,14 @@ config BLOBLIST_ALLOC
 	  specify a fixed address on systems where this is unknown or can
 	  change at runtime.
 
+config BLOBLIST_PASSAGE
+	bool "Obtain bloblist from standard passage information"
+	help
+	  Rather than allocating the bloblist, get it from the standard
+	  passage provided by an earlier phase, e.g. SPL. The bloblist address
+	  and size are used as is, except that the bloblist is of course
+	  relocated when U-Boot relocates.
+
 endchoice
 
 config BLOBLIST_ADDR
@@ -815,6 +823,13 @@ config SPL_BLOBLIST_ALLOC
 	  specify a fixed address on systems where this is unknown or can
 	  change at runtime.
 
+config SPL_BLOBLIST_PASSAGE
+	bool "Obtain bloblist from standard passage information"
+	help
+	  Rather than allocating the bloblist, get it from the standard
+	  passage provided by an earlier phase, e.g. TPL. The bloblist address
+	  and size are used as is within SPL, then passed on to U-Boot.
+
 endchoice
 
 endif # SPL_BLOBLIST
@@ -850,6 +865,22 @@ endif # TPL_BLOBLIST
 
 endmenu
 
+config PASSAGE_IN
+	bool "Support the standard-passage protocol (in)"
+	help
+	  This enables a standard protocol for entering U-Boot, providing
+	  parameters in a bloblist with a devicetree. It allows the various
+	  firmware phases to communicate state and settings to following
+	  phases.
+
+config SPL_PASSAGE_IN
+	bool "Support the standard-passage protocol in SPL (in)"
+	help
+	  This enables a standard protocol for entering SPL, providing
+	  parameters in a bloblist and a devicetree. It allows the various
+	  firmware phases to communicate state and settings to following
+	  phases.
+
 source "common/spl/Kconfig"
 
 config IMAGE_SIGN_INFO
diff --git a/common/bloblist.c b/common/bloblist.c
index 406073c8105..df45d45de90 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -441,7 +441,8 @@ int bloblist_init(void)
 	 * allocated bloblist from a previous stage, so it must be at a fixed
 	 * address.
 	 */
-	expected = fixed && !u_boot_first_phase();
+	expected = (fixed || CONFIG_IS_ENABLED(BLOBLIST_PASSAGE)) &&
+		!u_boot_first_phase();
 	if (spl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST))
 		expected = false;
 	if (fixed)
@@ -449,6 +450,10 @@ int bloblist_init(void)
 				      CONFIG_BLOBLIST_ADDR);
 	size = CONFIG_BLOBLIST_SIZE;
 	if (expected) {
+		if (CONFIG_IS_ENABLED(BLOBLIST_PASSAGE)) {
+			addr = gd->passage_bloblist;
+			size = 0;
+		}
 		ret = bloblist_check(addr, size);
 		if (ret) {
 			log_warning("Expected bloblist at %lx not found (err=%d)\n",
diff --git a/common/board_f.c b/common/board_f.c
index a68760092ac..04d98366bd6 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -570,11 +570,13 @@ static int reserve_stacks(void)
 static int reserve_bloblist(void)
 {
 #ifdef CONFIG_BLOBLIST
+	int new_size = CONFIG_BLOBLIST_SIZE_RELOC;
+
+	if (!new_size)
+		new_size = bloblist_get_size();
 	/* Align to a 4KB boundary for easier reading of addresses */
-	gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp -
-				       CONFIG_BLOBLIST_SIZE_RELOC, 0x1000);
-	gd->new_bloblist = map_sysmem(gd->start_addr_sp,
-				      CONFIG_BLOBLIST_SIZE_RELOC);
+	gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp - new_size, 0x1000);
+	gd->new_bloblist = map_sysmem(gd->start_addr_sp, new_size);
 #endif
 
 	return 0;
@@ -655,21 +657,21 @@ static int reloc_bootstage(void)
 static int reloc_bloblist(void)
 {
 #ifdef CONFIG_BLOBLIST
-	/*
-	 * Relocate only if we are supposed to send it
-	 */
-	if ((gd->flags & GD_FLG_SKIP_RELOC) &&
-	    CONFIG_BLOBLIST_SIZE == CONFIG_BLOBLIST_SIZE_RELOC) {
+	int size = bloblist_get_size();
+	int new_size = CONFIG_BLOBLIST_SIZE_RELOC;
+
+	if (!new_size)
+		new_size = size;
+
+	/* Relocate only if we are supposed to send it */
+	if ((gd->flags & GD_FLG_SKIP_RELOC) && size == new_size) {
 		debug("Not relocating bloblist\n");
 		return 0;
 	}
 	if (gd->new_bloblist) {
-		int size = CONFIG_BLOBLIST_SIZE;
-
-		debug("Copying bloblist from %p to %p, size %x\n",
-		      gd->bloblist, gd->new_bloblist, size);
-		bloblist_reloc(gd->new_bloblist, CONFIG_BLOBLIST_SIZE_RELOC,
-			       gd->bloblist, size);
+		debug("Copying bloblist from %p size %x to %p, size %x\n",
+		      gd->bloblist, size, gd->new_bloblist, new_size);
+		bloblist_reloc(gd->new_bloblist, new_size, gd->bloblist, size);
 		gd->bloblist = gd->new_bloblist;
 	}
 #endif
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 104282bd479..3fe1534ed9d 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -119,6 +119,34 @@ struct global_data {
 	 */
 	unsigned long precon_buf_idx;
 #endif
+	/**
+	 * @passage_mach: Incoming machine information from standard passage
+	 *
+	 * Provides a value which indicates whether passage is used, e.g.
+	 * PASSAGE_ABI_MACH
+	 */
+	ulong passage_mach;
+	/**
+	 * @passage_bloblist: Incoming bloblist from standard passage
+	 *
+	 * Provides the address of the bloblist passed in by the previous stage
+	 * or phase. If this is zero, there is none.
+	 */
+	ulong passage_bloblist;
+
+	/**
+	 * @passage_dtb: Incoming control devicetree within standard passage
+	 *
+	 * Provides the address (typically within the bloblist) where the
+	 * control DTB is stored. If this is zero, there is none.
+	 *
+	 * Note: This must be set to the correct value if the control DTB exists
+	 * since SPL may use this and ignore the bloblist, e.g. if bloblist
+	 * support is not enabled for code-size reasons. If this value is not
+	 * valid, any devicetree passed in the passage_bloblist is ignored.
+	 */
+	ulong passage_dtb;
+
 	/**
 	 * @env_addr: address of environment structure
 	 *
diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c
index 0808cd4b0c1..624230be5f5 100644
--- a/lib/asm-offsets.c
+++ b/lib/asm-offsets.c
@@ -46,5 +46,11 @@ int main(void)
 
 	DEFINE(GD_ENV_ADDR, offsetof(struct global_data, env_addr));
 
+	DEFINE(GD_PASSAGE_MACH, offsetof(struct global_data, passage_mach));
+	DEFINE(GD_PASSAGE_BLOBLIST,
+	       offsetof(struct global_data, passage_bloblist));
+	DEFINE(GD_PASSAGE_DTB,
+	       offsetof(struct global_data, passage_dtb));
+
 	return 0;
 }
-- 
2.34.1.703.g22d0c6ccf7-goog



More information about the U-Boot mailing list