Add an option for SPL to add a devicetree to the passage bloblist, so SPL can provide the devicetree to U-Boot.
Fix a few long lines while we are here. Signed-off-by: Simon Glass <s...@chromium.org> --- (no changes since v2) Changes in v2: - Rebase on -master - Update the commit message to mention the long lines common/Kconfig | 20 ++++++++++++++++++++ common/spl/spl.c | 43 +++++++++++++++++++++++++++++++++++++++++-- include/spl.h | 2 ++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/common/Kconfig b/common/Kconfig index c6a8fa54363..1f908790139 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -1243,6 +1243,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 f14c68c46a5..6e38f118f48 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -66,6 +66,11 @@ binman_sym_declare(ulong, u_boot_vpl_any, size); #endif /* BINMAN_UBOOT_SYMBOLS */ +#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"))); @@ -412,7 +417,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; @@ -429,7 +435,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); @@ -446,6 +453,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_FDT, size, 0, + (void **)&dtb); + if (ret) + return ret; + memcpy(dtb, map_sysmem(start, size), size); + } + + return 0; +} + /** * get_bootstage_id() - Get the bootstage ID to emit * @@ -835,6 +869,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2) hang(); } } + if (CONFIG_IS_ENABLED(PASSAGE_ADD_DTB)) { + ret = passage_write_dtb(); + if (ret) + printf(PHASE_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 7c10c7f792e..4fa97078a31 100644 --- a/include/spl.h +++ b/include/spl.h @@ -441,6 +441,8 @@ binman_sym_extern(ulong, u_boot_spl_any, image_pos); binman_sym_extern(ulong, u_boot_spl_any, size); binman_sym_extern(ulong, u_boot_vpl_any, image_pos); binman_sym_extern(ulong, u_boot_vpl_any, 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.43.0