
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@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; }