bloblist: refactor xferlist and bloblist
authorRaymond Mao <raymond.mao@linaro.org>
Thu, 20 Feb 2025 00:02:19 +0000 (16:02 -0800)
committerTom Rini <trini@konsulko.com>
Thu, 20 Feb 2025 00:49:36 +0000 (18:49 -0600)
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 <raymond.mao@linaro.org>
Suggested-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
arch/arm/lib/xferlist.c
common/bloblist.c
common/board_f.c
include/bloblist.h

index f9c5d88..6425936 100644 (file)
@@ -8,18 +8,16 @@
 #include <bloblist.h>
 #include "xferlist.h"
 
-int xferlist_from_boot_arg(ulong addr, ulong size)
+int xferlist_from_boot_arg(ulong *addr)
 {
        int ret;
 
-       ret = bloblist_check(saved_args[3], size);
-       if (ret)
-               return ret;
-
        ret = bloblist_check_reg_conv(saved_args[0], saved_args[2],
-                                     saved_args[1]);
+                                     saved_args[1], saved_args[3]);
        if (ret)
                return ret;
 
-       return bloblist_reloc((void *)addr, size);
+       *addr = bloblist_get_base();
+
+       return 0;
 }
index 1fcd387..be05f80 100644 (file)
@@ -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;
        }
index 6c5c3bf..2912320 100644 (file)
@@ -624,11 +624,14 @@ static int reserve_stacks(void)
 static int reserve_bloblist(void)
 {
 #ifdef CONFIG_BLOBLIST
+       ulong size = bloblist_get_total_size();
+
+       if (size < CONFIG_BLOBLIST_SIZE_RELOC)
+               size = CONFIG_BLOBLIST_SIZE_RELOC;
+
        /* 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->boardf->new_bloblist = map_sysmem(gd->start_addr_sp,
-                                             CONFIG_BLOBLIST_SIZE_RELOC);
+       gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp - size, 0x1000);
+       gd->boardf->new_bloblist = map_sysmem(gd->start_addr_sp, size);
 #endif
 
        return 0;
@@ -698,11 +701,14 @@ static int reloc_bloblist(void)
                return 0;
        }
        if (gd->boardf->new_bloblist) {
-               debug("Copying bloblist from %p to %p, size %x\n",
-                     gd->bloblist, gd->boardf->new_bloblist,
-       gd->bloblist->total_size);
-               return bloblist_reloc(gd->boardf->new_bloblist,
-                                     CONFIG_BLOBLIST_SIZE_RELOC);
+               ulong size = bloblist_get_total_size();
+
+               if (size < CONFIG_BLOBLIST_SIZE_RELOC)
+                       size = CONFIG_BLOBLIST_SIZE_RELOC;
+
+               debug("Copying bloblist from %p to %p, size %lx\n",
+                     gd->bloblist, gd->boardf->new_bloblist, size);
+               return bloblist_reloc(gd->boardf->new_bloblist, size);
        }
 #endif
 
index 03d9862..ff9d554 100644 (file)
@@ -483,19 +483,18 @@ static inline int bloblist_maybe_init(void)
  * @rfdt:  Register that holds the FDT base address.
  * @rzero: Register that must be zero.
  * @rsig:  Register that holds signature and register conventions version.
+ * @xlist: Register that holds the transfer list.
  * Return: 0 if OK, -EIO if the bloblist is not compliant to the register
  *        conventions.
  */
-int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig);
+int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig, ulong xlist);
 
 /**
- * xferlist_from_boot_arg() - Get bloblist from the boot args and relocate it
- *                           to the specified address.
+ * xferlist_from_boot_arg() - Get bloblist from the boot args.
  *
- * @addr: Address for the bloblist
- * @size: Size of space reserved for the bloblist
+ * @addr: Address of the bloblist
  * Return: 0 if OK, else on error
  */
-int xferlist_from_boot_arg(ulong addr, ulong size);
+int xferlist_from_boot_arg(ulong *addr);
 
 #endif /* __BLOBLIST_H */