From 7d521f205469b0e0ce97669919d650fb75328d2a Mon Sep 17 00:00:00 2001 From: Harrison Mutai Date: Tue, 4 Feb 2025 17:58:41 +0000 Subject: bloblist: add support for CONFIG_BLOBLIST_PASSAGE When the configuration option CONFIG_BLOBLIST_PASSAGE is selected, the bloblist present in the incoming standard passage is utilised in-place. There is no need to specify the size of the bloblist as the system automatically detects it using the header information. Signed-off-by: Harrison Mutai --- common/bloblist.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'common/bloblist.c') diff --git a/common/bloblist.c b/common/bloblist.c index 110bb9dc44a..1fcd387593c 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -475,6 +475,9 @@ int bloblist_reloc(void *to, uint to_size) { struct bloblist_hdr *hdr; + if (!to_size) + return 0; + if (to_size < gd->bloblist->total_size) return -ENOSPC; @@ -505,13 +508,6 @@ int bloblist_init(void) * at a fixed address. */ bool from_addr = fixed && !xpl_is_first_phase(); - /* - * If U-Boot is in the first phase that an arch custom routine should - * install the bloblist passed from previous loader to this fixed - * address. - */ - bool from_boot_arg = fixed && xpl_is_first_phase(); - if (xpl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST)) from_addr = false; if (fixed) @@ -519,7 +515,13 @@ int bloblist_init(void) CONFIG_BLOBLIST_ADDR); size = CONFIG_BLOBLIST_SIZE; - if (from_boot_arg) + + /* + * If the current boot stage is the first phase of U-Boot, then an + * architecture-specific routine should be used to handle the bloblist + * passed from the previous boot loader + */ + if (xpl_is_first_phase() && !IS_ENABLED(CONFIG_BLOBLIST_ALLOC)) ret = xferlist_from_boot_arg(addr, size); else if (from_addr) ret = bloblist_check(addr, size); -- cgit v1.2.3 From 6799f09069f402a33c9cb202b71e144497bd9b7a Mon Sep 17 00:00:00 2001 From: Raymond Mao Date: Wed, 19 Feb 2025 16:02:19 -0800 Subject: bloblist: refactor xferlist and bloblist Refactor the xferlist to remove the relocating when bloblist passed from the boot args. Refactor bloblist init to use incoming standard passage by default if a valid transfer list exists in the boot args. For bloblist relocation, use the actual total size if it has a smaller BLOBLIST_SIZE_RELOC. Signed-off-by: Raymond Mao Suggested-by: Ilias Apalodimas --- common/bloblist.c | 73 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 32 deletions(-) (limited to 'common/bloblist.c') diff --git a/common/bloblist.c b/common/bloblist.c index 1fcd387593c..be05f8082ff 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -492,8 +492,7 @@ int bloblist_reloc(void *to, uint to_size) /* * Weak default function for getting bloblist from boot args. */ -int __weak xferlist_from_boot_arg(ulong __always_unused addr, - ulong __always_unused size) +int __weak xferlist_from_boot_arg(ulong __always_unused *addr) { return -ENOENT; } @@ -501,37 +500,39 @@ int __weak xferlist_from_boot_arg(ulong __always_unused addr, int bloblist_init(void) { bool fixed = IS_ENABLED(CONFIG_BLOBLIST_FIXED); - int ret = -ENOENT; + int ret = 0; ulong addr = 0, size; - /* - * If U-Boot is not in the first phase, an existing bloblist must be - * at a fixed address. - */ - bool from_addr = fixed && !xpl_is_first_phase(); - if (xpl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST)) - from_addr = false; - if (fixed) - addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, - CONFIG_BLOBLIST_ADDR); - size = CONFIG_BLOBLIST_SIZE; + /* Check if a valid transfer list passed in */ + if (!xferlist_from_boot_arg(&addr)) { + size = bloblist_get_total_size(); + } else { + /* + * If U-Boot is not in the first phase, an existing bloblist must + * be at a fixed address. + */ + bool from_addr = fixed && !xpl_is_first_phase(); + + ret = -ENOENT; - /* - * If the current boot stage is the first phase of U-Boot, then an - * architecture-specific routine should be used to handle the bloblist - * passed from the previous boot loader - */ - if (xpl_is_first_phase() && !IS_ENABLED(CONFIG_BLOBLIST_ALLOC)) - ret = xferlist_from_boot_arg(addr, size); - else if (from_addr) - ret = bloblist_check(addr, size); + if (xpl_prev_phase() == PHASE_TPL && + !IS_ENABLED(CONFIG_TPL_BLOBLIST)) + from_addr = false; + if (fixed) + addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, + CONFIG_BLOBLIST_ADDR); + size = CONFIG_BLOBLIST_SIZE; - if (ret) - log_warning("Bloblist at %lx not found (err=%d)\n", - addr, ret); - else - /* Get the real size */ - size = gd->bloblist->total_size; + if (from_addr) + ret = bloblist_check(addr, size); + + if (ret) + log_warning("Bloblist at %lx not found (err=%d)\n", + addr, ret); + else + /* Get the real size */ + size = gd->bloblist->total_size; + } if (ret) { /* @@ -556,6 +557,7 @@ int bloblist_init(void) log_debug("Found existing bloblist size %lx at %lx\n", size, addr); } + if (ret) return log_msg_ret("ini", ret); gd->flags |= GD_FLG_BLOBLIST_READY; @@ -576,10 +578,11 @@ int bloblist_maybe_init(void) return 0; } -int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig) +int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig, ulong xlist) { u64 version = BLOBLIST_REGCONV_VER; ulong sigval; + int ret; if ((IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_SPL_BUILD)) || (IS_ENABLED(CONFIG_SPL_64BIT) && IS_ENABLED(CONFIG_SPL_BUILD))) { @@ -590,8 +593,14 @@ int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig) ((version & BLOBLIST_REGCONV_MASK) << BLOBLIST_REGCONV_SHIFT_32)); } - if (rzero || rsig != sigval || - rfdt != (ulong)bloblist_find(BLOBLISTT_CONTROL_FDT, 0)) { + if (rzero || rsig != sigval) + return -EIO; + + ret = bloblist_check(xlist, 0); + if (ret) + return ret; + + if (rfdt != (ulong)bloblist_find(BLOBLISTT_CONTROL_FDT, 0)) { gd->bloblist = NULL; /* Reset the gd bloblist pointer */ return -EIO; } -- cgit v1.2.3 From 03a76b1a737fc9cf511aa7520999968ec3d2fd78 Mon Sep 17 00:00:00 2001 From: Raymond Mao Date: Wed, 19 Feb 2025 16:02:20 -0800 Subject: bloblist: kconfig for mandatory incoming standard passage In previous commit, incoming standard passage is used by default when initializing the bloblist, so explicitly BLOBLIST_PASSAGE is no more needed. Rename it as BLOBLIST_PASSAGE_MANDATORY to determine the behaviors when an incoming transfer list does not exist or is invalid. When it is selected, incoming standard passage is mandatory and U-Boot will report an error when a valid incoming transfer list is missing. Signed-off-by: Raymond Mao --- common/bloblist.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'common/bloblist.c') diff --git a/common/bloblist.c b/common/bloblist.c index be05f8082ff..fb0e5af5f3a 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -513,6 +513,13 @@ int bloblist_init(void) */ bool from_addr = fixed && !xpl_is_first_phase(); + /* + * If Firmware Handoff is mandatory but no transfer list is + * observed, report it as an error. + */ + if (IS_ENABLED(CONFIG_BLOBLIST_PASSAGE_MANDATORY)) + return -ENOENT; + ret = -ENOENT; if (xpl_prev_phase() == PHASE_TPL && -- cgit v1.2.3