bloblist: Support relocating to a larger space
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>
This commit is contained in:
parent
09d9ba9097
commit
9fe064646d
|
@ -697,6 +697,16 @@ config BLOBLIST_ADDR
|
||||||
Sets the address of the bloblist, set up by the first part of U-Boot
|
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.
|
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
|
endmenu
|
||||||
|
|
||||||
source "common/spl/Kconfig"
|
source "common/spl/Kconfig"
|
||||||
|
|
|
@ -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)
|
int bloblist_init(void)
|
||||||
{
|
{
|
||||||
bool expected;
|
bool expected;
|
||||||
|
@ -327,6 +336,8 @@ int bloblist_init(void)
|
||||||
* that runs
|
* that runs
|
||||||
*/
|
*/
|
||||||
expected = !u_boot_first_phase();
|
expected = !u_boot_first_phase();
|
||||||
|
if (spl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST))
|
||||||
|
expected = false;
|
||||||
if (expected)
|
if (expected)
|
||||||
ret = bloblist_check(CONFIG_BLOBLIST_ADDR,
|
ret = bloblist_check(CONFIG_BLOBLIST_ADDR,
|
||||||
CONFIG_BLOBLIST_SIZE);
|
CONFIG_BLOBLIST_SIZE);
|
||||||
|
|
|
@ -568,9 +568,10 @@ static int reserve_bloblist(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BLOBLIST
|
#ifdef CONFIG_BLOBLIST
|
||||||
/* Align to a 4KB boundary for easier reading of addresses */
|
/* Align to a 4KB boundary for easier reading of addresses */
|
||||||
gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp - CONFIG_BLOBLIST_SIZE,
|
gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp -
|
||||||
0x1000);
|
CONFIG_BLOBLIST_SIZE_RELOC, 0x1000);
|
||||||
gd->new_bloblist = map_sysmem(gd->start_addr_sp, CONFIG_BLOBLIST_SIZE);
|
gd->new_bloblist = map_sysmem(gd->start_addr_sp,
|
||||||
|
CONFIG_BLOBLIST_SIZE_RELOC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -658,7 +659,8 @@ static int reloc_bloblist(void)
|
||||||
|
|
||||||
debug("Copying bloblist from %p to %p, size %x\n",
|
debug("Copying bloblist from %p to %p, size %x\n",
|
||||||
gd->bloblist, gd->new_bloblist, size);
|
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;
|
gd->bloblist = gd->new_bloblist;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -242,6 +242,16 @@ void bloblist_show_list(void);
|
||||||
*/
|
*/
|
||||||
const char *bloblist_tag_name(enum bloblist_tag_t tag);
|
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_init() - Init the bloblist system with a single bloblist
|
||||||
*
|
*
|
||||||
|
|
|
@ -347,6 +347,42 @@ static int bloblist_test_align(struct unit_test_state *uts)
|
||||||
}
|
}
|
||||||
BLOBLIST_TEST(bloblist_test_align, 0);
|
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,
|
int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
char *const argv[])
|
char *const argv[])
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue