[PATCH v2 07/16] passage: spl: Support adding the dtb to the passage bloblist
Simon Glass
sjg at chromium.org
Mon Jan 17 16:04:19 CET 2022
Add an option for SPL to add a devicetree to the passage bloblist, so
SPL can provide the devicetree to U-Boot.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
(no changes since v1)
common/Kconfig | 20 ++++++++++++++++++++
common/spl/spl.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
include/spl.h | 2 ++
3 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/common/Kconfig b/common/Kconfig
index 59783d66cb8..bf6bff22e71 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -881,6 +881,26 @@ config SPL_PASSAGE_IN
firmware phases to communicate state and settings to following
phases.
+config SPL_PASSAGE_OUT
+ bool "Support the standard-passage protocol in SPL (out)"
+ depends on SPL_BLOBLIST
+ default y if PASSAGE_IN
+ help
+ This enables a standard protocol for entering U-Boot, providing
+ parameters in a bloblist and a devicetree. It allows the various
+ firmware stages to communicate state and settings to following
+ stages.
+
+config SPL_PASSAGE_ADD_DTB
+ bool "Add devicetree to the outgoing passage"
+ depends on SPL_PASSAGE_OUT
+ default y if SPL_PASSAGE_OUT && !SPL_PASSAGE_IN
+ help
+ Add the devicetree into the bloblist in SPL (it is assumed to not
+ already be there) so that the next phase (U-Boot) can find it.
+
+ This option should be enabled in the phase that sets up the passage.
+
source "common/spl/Kconfig"
config IMAGE_SIGN_INFO
diff --git a/common/spl/spl.c b/common/spl/spl.c
index d54356b6a28..be770d0226c 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -56,6 +56,11 @@ binman_sym_declare(ulong, spl, image_pos);
binman_sym_declare(ulong, spl, size);
#endif
+#if CONFIG_IS_ENABLED(PASSAGE_ADD_DTB)
+binman_sym_declare(ulong, u_boot_dtb, image_pos);
+binman_sym_declare(ulong, u_boot_dtb, size);
+#endif
+
/* Define board data structure */
static struct bd_info bdata __attribute__ ((section(".data")));
@@ -406,7 +411,8 @@ static int setup_spl_handoff(void)
{
struct spl_handoff *ho;
- ho = bloblist_ensure(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
+ ho = bloblist_ensure(BLOBLISTT_U_BOOT_SPL_HANDOFF,
+ sizeof(struct spl_handoff));
if (!ho)
return -ENOENT;
@@ -423,7 +429,8 @@ static int write_spl_handoff(void)
struct spl_handoff *ho;
int ret;
- ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
+ ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF,
+ sizeof(struct spl_handoff));
if (!ho)
return -ENOENT;
handoff_save_dram(ho);
@@ -440,6 +447,33 @@ static inline int write_spl_handoff(void) { return 0; }
#endif /* HANDOFF */
+/**
+ * Write the devicetree for the next phase into the passage
+ *
+ * For now we assume the next phase is U-Boot proper
+ *
+ * @return 0 on success, -ENOSPC if it is missing and could not be added due to
+ * lack of space, or -ESPIPE it exists but has the wrong size
+ */
+static int passage_write_dtb(void)
+{
+#if CONFIG_IS_ENABLED(PASSAGE_ADD_DTB)
+ ulong start = binman_sym(ulong, u_boot_dtb, image_pos);
+ ulong size = binman_sym(ulong, u_boot_dtb, size);
+ void *dtb;
+ int ret;
+
+ log_debug("passage: Adding control dtb size %lx\n", size);
+ ret = bloblist_ensure_size(BLOBLISTT_CONTROL_DTB, size, 0,
+ (void **)&dtb);
+ if (ret)
+ return ret;
+ memcpy(dtb, map_sysmem(start, size), size);
+#endif
+
+ return 0;
+}
+
/**
* get_bootstage_id() - Get the bootstage ID to emit
*
@@ -761,6 +795,12 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
printf(SPL_TPL_PROMPT
"SPL hand-off write failed (err=%d)\n", ret);
}
+ if (CONFIG_IS_ENABLED(PASSAGE_ADD_DTB)) {
+ ret = passage_write_dtb();
+ if (ret)
+ printf(SPL_TPL_PROMPT
+ "Write DTB failed (err=%d)\n", ret);
+ }
if (CONFIG_IS_ENABLED(BLOBLIST)) {
ret = bloblist_finish();
if (ret)
diff --git a/include/spl.h b/include/spl.h
index a4d5cedad3a..472b171f5be 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -270,6 +270,8 @@ binman_sym_extern(ulong, u_boot_any, image_pos);
binman_sym_extern(ulong, u_boot_any, size);
binman_sym_extern(ulong, spl, image_pos);
binman_sym_extern(ulong, spl, size);
+binman_sym_extern(ulong, u_boot_dtb, image_pos);
+binman_sym_extern(ulong, u_boot_dtb, size);
/**
* spl_get_image_pos() - get the image position of the next phase
--
2.34.1.703.g22d0c6ccf7-goog
More information about the U-Boot
mailing list