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"
}
}
+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;
* 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);
{
#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;
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
*/
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
*
}
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[])
{