From 1c4751fd1ac7bda72ab72ce352dc9b2131df2807 Mon Sep 17 00:00:00 2001 From: Raymond Mao Date: Sat, 3 Feb 2024 08:36:20 -0800 Subject: bloblist: add API to check the register conventions Add bloblist_check_reg_conv() to check whether the bloblist is compliant to the register conventions defined in Firmware Handoff specification. This API can be used for all Arm platforms. Signed-off-by: Raymond Mao --- common/bloblist.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'common/bloblist.c') diff --git a/common/bloblist.c b/common/bloblist.c index 2d373910b6d..980b1ddbcb4 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -542,3 +542,14 @@ int bloblist_maybe_init(void) return 0; } + +int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig) +{ + if (rzero || rsig != (BLOBLIST_MAGIC | BLOBLIST_REGCONV_VER) || + rfdt != (ulong)bloblist_find(BLOBLISTT_CONTROL_FDT, 0)) { + gd->bloblist = NULL; /* Reset the gd bloblist pointer */ + return -EIO; + } + + return 0; +} -- cgit v1.2.3 From 67254214930cd2cb52279b01690c1f820a7f83db Mon Sep 17 00:00:00 2001 From: Raymond Mao Date: Sat, 3 Feb 2024 08:36:21 -0800 Subject: bloblist: check bloblist with specified buffer size Instead of expecting the bloblist total size to be the same as the pre-allocated buffer size, practically we are more interested in whether the pre-allocated buffer size is bigger than the bloblist total size. Signed-off-by: Raymond Mao Reviewed-by: Ilias Apalodimas --- common/bloblist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common/bloblist.c') diff --git a/common/bloblist.c b/common/bloblist.c index 980b1ddbcb4..26b0ba33b11 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -384,7 +384,7 @@ int bloblist_check(ulong addr, uint size) return log_msg_ret("Bad magic", -ENOENT); if (hdr->version != BLOBLIST_VERSION) return log_msg_ret("Bad version", -EPROTONOSUPPORT); - if (!hdr->total_size || (size && hdr->total_size != size)) + if (!hdr->total_size || (size && hdr->total_size > size)) return log_msg_ret("Bad total size", -EFBIG); if (hdr->used_size > hdr->total_size) return log_msg_ret("Bad used size", -ENOENT); -- cgit v1.2.3 From 1ef43f3bf20a4a9508c299a738d01faa3dc3ce95 Mon Sep 17 00:00:00 2001 From: Raymond Mao Date: Sat, 3 Feb 2024 08:36:22 -0800 Subject: bloblist: refactor of bloblist_reloc() The current bloblist pointer and size can be retrieved from global data, so we don't need to pass them from the function arguments. This change also help to remove all external access of gd->bloblist outside of bloblist module. Signed-off-by: Raymond Mao Reviewed-by: Ilias Apalodimas --- common/bloblist.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'common/bloblist.c') diff --git a/common/bloblist.c b/common/bloblist.c index 26b0ba33b11..c2fd07575fb 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -472,13 +472,19 @@ void bloblist_show_list(void) } } -void bloblist_reloc(void *to, uint to_size, void *from, uint from_size) +int bloblist_reloc(void *to, uint to_size) { struct bloblist_hdr *hdr; - memcpy(to, from, from_size); + if (to_size < gd->bloblist->total_size) + return -ENOSPC; + + memcpy(to, gd->bloblist, gd->bloblist->total_size); hdr = to; hdr->total_size = to_size; + gd->bloblist = to; + + return 0; } int bloblist_init(void) -- cgit v1.2.3 From 66131310d8ff1ba228f989b41bd8812f43be41c3 Mon Sep 17 00:00:00 2001 From: Raymond Mao Date: Sat, 3 Feb 2024 08:36:26 -0800 Subject: bloblist: Load the bloblist from the previous loader During bloblist initialization, load the bloblist via boot arguments from the previous loader. If a valid bloblist exists in boot arguments, relocate it into the fixed bloblist memory region. If not, fallback to support BLOBLIST_ADDR or BLOBLIST_ALLOC. Signed-off-by: Raymond Mao --- common/bloblist.c | 62 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 18 deletions(-) (limited to 'common/bloblist.c') diff --git a/common/bloblist.c b/common/bloblist.c index c2fd07575fb..ad06d7a1795 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -487,37 +487,57 @@ int bloblist_reloc(void *to, uint to_size) return 0; } +/* + * Weak default function for getting bloblist from boot args. + */ +int __weak xferlist_from_boot_arg(ulong __always_unused addr, + ulong __always_unused size) +{ + return -ENOENT; +} + int bloblist_init(void) { bool fixed = IS_ENABLED(CONFIG_BLOBLIST_FIXED); int ret = -ENOENT; ulong addr, size; - bool expected; - - /** - * We don't expect to find an existing bloblist in the first phase of - * U-Boot that runs. Also we have no way to receive the address of an - * allocated bloblist from a previous stage, so it must be at a fixed + /* + * If U-Boot is not in the first phase, an existing bloblist must be + * at a fixed address. + */ + bool from_addr = fixed && !u_boot_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. */ - expected = fixed && !u_boot_first_phase(); + bool from_boot_arg = fixed && u_boot_first_phase(); + if (spl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST)) - expected = false; + from_addr = false; if (fixed) addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, CONFIG_BLOBLIST_ADDR); size = CONFIG_BLOBLIST_SIZE; - if (expected) { + + if (from_boot_arg) + ret = xferlist_from_boot_arg(addr, size); + else if (from_addr) ret = bloblist_check(addr, size); - if (ret) { - log_warning("Expected bloblist at %lx not found (err=%d)\n", - addr, ret); - } else { - /* Get the real size, if it is not what we expected */ - size = gd->bloblist->total_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) { + /* + * If we don't have a bloblist from a fixed address, or the one + * in the fixed address is not valid. we must allocate the + * memory for it now. + */ if (CONFIG_IS_ENABLED(BLOBLIST_ALLOC)) { void *ptr = memalign(BLOBLIST_ALIGN, size); @@ -525,7 +545,8 @@ int bloblist_init(void) return log_msg_ret("alloc", -ENOMEM); addr = map_to_sysmem(ptr); } else if (!fixed) { - return log_msg_ret("!fixed", ret); + return log_msg_ret("BLOBLIST_FIXED is not enabled", + ret); } log_debug("Creating new bloblist size %lx at %lx\n", size, addr); @@ -538,6 +559,11 @@ int bloblist_init(void) return log_msg_ret("ini", ret); gd->flags |= GD_FLG_BLOBLIST_READY; +#ifdef DEBUG + bloblist_show_stats(); + bloblist_show_list(); +#endif + return 0; } -- cgit v1.2.3