]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
bloblist: Support relocating to a larger space
authorSimon Glass <sjg@chromium.org>
Thu, 14 Jan 2021 03:29:43 +0000 (20:29 -0700)
committerTom Rini <trini@konsulko.com>
Wed, 27 Jan 2021 22:03:16 +0000 (17:03 -0500)
Typically in TPL/SPL the bloblist is quite small. But U-Boot proper may
want to add a lot more to it, such as ACPI tables.

Add a way to expand the bloblist by relocating it in U-Boot proper, along
with the other relocation activities.

Signed-off-by: Simon Glass <sjg@chromium.org>
common/Kconfig
common/bloblist.c
common/board_f.c
include/bloblist.h
test/bloblist.c

index d8982ba37761615e8cabbe4d77cf3e16ca694cb1..45535e3501deda3fc02dacf08c9a36551c67c8ea 100644 (file)
@@ -697,6 +697,16 @@ config BLOBLIST_ADDR
          Sets the address of the bloblist, set up by the first part of U-Boot
          which runs. Subsequent U-Boot stages typically use the same address.
 
+config BLOBLIST_SIZE_RELOC
+       hex "Size of bloblist after relocation"
+       depends on BLOBLIST
+       default BLOBLIST_SIZE
+       help
+         Sets the size of the bloblist in bytes after relocation. Since U-Boot
+         has a lot more memory available then, it is possible to use a larger
+         size than the one set up by SPL. This bloblist is set up during the
+         relocation process.
+
 endmenu
 
 source "common/spl/Kconfig"
index 33b58623807380123682eb7de6f509c97fb5ac47..e32f551e27ed12b49e649a7bde36613540f61d5c 100644 (file)
@@ -317,6 +317,15 @@ void bloblist_show_list(void)
        }
 }
 
+void bloblist_reloc(void *to, uint to_size, void *from, uint from_size)
+{
+       struct bloblist_hdr *hdr;
+
+       memcpy(to, from, from_size);
+       hdr = to;
+       hdr->size = to_size;
+}
+
 int bloblist_init(void)
 {
        bool expected;
@@ -327,6 +336,8 @@ int bloblist_init(void)
         * that runs
         */
        expected = !u_boot_first_phase();
+       if (spl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST))
+               expected = false;
        if (expected)
                ret = bloblist_check(CONFIG_BLOBLIST_ADDR,
                                     CONFIG_BLOBLIST_SIZE);
index ae3001bed1b72887be1ebaa9933cd9524a4810a7..4327a43a33b6b4c033b90caa1c15d4428c7c2205 100644 (file)
@@ -568,9 +568,10 @@ static int reserve_bloblist(void)
 {
 #ifdef CONFIG_BLOBLIST
        /* Align to a 4KB boundary for easier reading of addresses */
-       gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp - CONFIG_BLOBLIST_SIZE,
-                                      0x1000);
-       gd->new_bloblist = map_sysmem(gd->start_addr_sp, CONFIG_BLOBLIST_SIZE);
+       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);
 #endif
 
        return 0;
@@ -658,7 +659,8 @@ static int reloc_bloblist(void)
 
                debug("Copying bloblist from %p to %p, size %x\n",
                      gd->bloblist, gd->new_bloblist, size);
-               memcpy(gd->new_bloblist, gd->bloblist, size);
+               bloblist_reloc(gd->new_bloblist, CONFIG_BLOBLIST_SIZE_RELOC,
+                              gd->bloblist, size);
                gd->bloblist = gd->new_bloblist;
        }
 #endif
index 8cdce61187aa668dbdd666286f3aa4f4af93aefb..964b974fdaf65e2cca3d5558debc23e22b9746ca 100644 (file)
@@ -242,6 +242,16 @@ void bloblist_show_list(void);
  */
 const char *bloblist_tag_name(enum bloblist_tag_t tag);
 
+/**
+ * bloblist_reloc() - Relocate the bloblist and optionally resize it
+ *
+ * @to: Pointer to new bloblist location (must not overlap old location)
+ * @to:size: New size for bloblist (must be larger than from_size)
+ * @from: Pointer to bloblist to relocate
+ * @from_size: Size of bloblist to relocate
+ */
+void bloblist_reloc(void *to, uint to_size, void *from, uint from_size);
+
 /**
  * bloblist_init() - Init the bloblist system with a single bloblist
  *
index 900299dd68e8d97caaaaac28ec7ff4d8c59f41d9..85a6c39680e43f3623769f67769867213676f4cb 100644 (file)
@@ -347,6 +347,42 @@ static int bloblist_test_align(struct unit_test_state *uts)
 }
 BLOBLIST_TEST(bloblist_test_align, 0);
 
+/* Test relocation of a bloblist */
+static int bloblist_test_reloc(struct unit_test_state *uts)
+{
+       const uint large_size = TEST_BLOBLIST_SIZE;
+       const uint small_size = 0x20;
+       void *old_ptr, *new_ptr;
+       void *blob1, *blob2;
+       ulong new_addr;
+       ulong new_size;
+
+       ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+       old_ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
+
+       /* Add one blob and then one that won't fit */
+       blob1 = bloblist_add(TEST_TAG, small_size, 0);
+       ut_assertnonnull(blob1);
+       blob2 = bloblist_add(TEST_TAG2, large_size, 0);
+       ut_assertnull(blob2);
+
+       /* Relocate the bloblist somewhere else, a bit larger */
+       new_addr = TEST_ADDR + TEST_BLOBLIST_SIZE;
+       new_size = TEST_BLOBLIST_SIZE + 0x100;
+       new_ptr = map_sysmem(new_addr, TEST_BLOBLIST_SIZE);
+       bloblist_reloc(new_ptr, new_size, old_ptr, TEST_BLOBLIST_SIZE);
+       gd->bloblist = new_ptr;
+
+       /* Check the old blob is there and that we can now add the bigger one */
+       ut_assertnonnull(bloblist_find(TEST_TAG, small_size));
+       ut_assertnull(bloblist_find(TEST_TAG2, small_size));
+       blob2 = bloblist_add(TEST_TAG2, large_size, 0);
+       ut_assertnonnull(blob2);
+
+       return 0;
+}
+BLOBLIST_TEST(bloblist_test_reloc, 0);
+
 int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
                   char *const argv[])
 {