mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-30 18:05:48 +01:00 
			
		
		
		
	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:
		| @@ -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[]) | ||||||
| { | { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user