[PATCH 16/31] passage: Support an incoming passage
Simon Glass
sjg at chromium.org
Mon Nov 1 02:17:18 CET 2021
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>
---
common/Kconfig | 31 ++++++++++++++++++++++++++++++
common/bloblist.c | 4 ++++
common/board_f.c | 32 ++++++++++++++++---------------
include/asm-generic/global_data.h | 21 ++++++++++++++++++++
include/bloblist.h | 9 +++++++++
lib/asm-offsets.c | 5 +++++
6 files changed, 87 insertions(+), 15 deletions(-)
diff --git a/common/Kconfig b/common/Kconfig
index 2c6f5901c8a..fa7915d2acc 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -740,6 +740,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
@@ -798,6 +806,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
@@ -833,6 +848,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 29164c9b901..d36e0a94dff 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -444,6 +444,10 @@ int bloblist_init(void)
addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, 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 14e9286a70f..86c77a42847 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 99daa20c765..ef4119f27f4 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -119,6 +119,27 @@ struct global_data {
*/
unsigned long precon_buf_idx;
#endif
+ /**
+ * @passage_bloblist: Incoming bloblist from the 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_off: Offset of dtb within the passage
+ *
+ * Provides the offset 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_off;
+
/**
* @env_addr: address of environment structure
*
diff --git a/include/bloblist.h b/include/bloblist.h
index 88c62b54c54..2ede0ce3150 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -292,6 +292,15 @@ int bloblist_finish(void);
*/
void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp);
+ulong bloblist_get_base(void);
+
+/**
+ * bloblist_get_size() - Get the size of the bloblist
+ *
+ * @returns the size in bytes
+ */
+ulong bloblist_get_size(void);
+
/**
* bloblist_get_base() - Get the base address of the bloblist
*
diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c
index c691066332d..5467b95cb47 100644
--- a/lib/asm-offsets.c
+++ b/lib/asm-offsets.c
@@ -43,5 +43,10 @@ int main(void)
DEFINE(GD_ENV_ADDR, offsetof(struct global_data, env_addr));
+ DEFINE(GD_PASSAGE_BLOBLIST,
+ offsetof(struct global_data, passage_bloblist));
+ DEFINE(GD_PASSAGE_DTB_OFF,
+ offsetof(struct global_data, passage_dtb_off));
+
return 0;
}
--
2.33.1.1089.g2158813163f-goog
More information about the U-Boot
mailing list