aboutsummaryrefslogtreecommitdiffstats
path: root/boot
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2024-09-03 14:09:30 -0600
committerTom Rini <trini@konsulko.com>2024-09-03 14:09:30 -0600
commit360aaddd9cea8c256f50c576794415cadfb61819 (patch)
treec6d22aa0a5da14d3e074a47779e5811022f8300a /boot
parent2c832abc732c9f6696b5a441efe9a17483f30b8b (diff)
parentf8ffc6f3cc4c6a760458255f5b344f86ee833bef (diff)
downloadu-boot-360aaddd9cea8c256f50c576794415cadfb61819.tar.gz
Merge patch series "Make LMB memory map global and persistent"
Sughosh Ganu <sughosh.ganu@linaro.org> says: This is a follow-up from an earlier RFC series [1] for making the LMB and EFI memory allocations work together. This is a non-rfc version with only the LMB part of the patches, for making the LMB memory map global and persistent. This is part one of a set of patches which aim to have the LMB and EFI memory allocations work together. This requires making the LMB memory map global and persistent, instead of having local, caller specific maps. This is being done keeping in mind the usage of LMB memory by platforms where the same memory region can be used to load multiple different images. What is not allowed is to overwrite memory that has been allocated by the other module, currently the EFI memory module. This is being achieved by introducing a new flag, LMB_NOOVERWRITE, which represents memory which cannot be re-requested once allocated. The data structures (alloced lists) required for maintaining the LMB map are initialised during board init. The LMB module is enabled by default for the main U-Boot image, while it needs to be enabled for SPL. This version also uses a stack implementation, as suggested by Simon Glass to temporarily store the lmb structure instance which is used during normal operation when running lmb tests. This does away with the need to run the lmb tests separately. The tests have been tweaked where needed because of these changes. The second part of the patches, to be sent subsequently, would work on having the EFI allocations work with the LMB API's. [1] - https://lore.kernel.org/u-boot/20240704073544.670249-1-sughosh.ganu@linaro.org/T/#t Notes: 1) These patches are on next, as the alist patches have been applied to that branch. 2) I have tested the boot on the ST DK2 board, but it would be good to get a T-b/R-b from the ST maintainers. 3) It will be good to test these changes on a PowerPC platform (ideally an 85xx, as I do not have one).
Diffstat (limited to 'boot')
-rw-r--r--boot/bootm.c38
-rw-r--r--boot/bootm_os.c5
-rw-r--r--boot/image-board.c36
-rw-r--r--boot/image-fdt.c35
4 files changed, 43 insertions, 71 deletions
diff --git a/boot/bootm.c b/boot/bootm.c
index 480f8e6a0e6..a61bbcfb45c 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -239,30 +239,11 @@ static int boot_get_kernel(const char *addr_fit, struct bootm_headers *images,
return 0;
}
-#ifdef CONFIG_LMB
-static void boot_start_lmb(struct bootm_headers *images)
-{
- phys_addr_t mem_start;
- phys_size_t mem_size;
-
- mem_start = env_get_bootm_low();
- mem_size = env_get_bootm_size();
-
- lmb_init_and_reserve_range(&images->lmb, mem_start,
- mem_size, NULL);
-}
-#else
-#define lmb_reserve(lmb, base, size)
-static inline void boot_start_lmb(struct bootm_headers *images) { }
-#endif
-
static int bootm_start(void)
{
memset((void *)&images, 0, sizeof(images));
images.verify = env_get_yesno("verify");
- boot_start_lmb(&images);
-
bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
images.state = BOOTM_STATE_START;
@@ -640,7 +621,7 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
if (os.type == IH_TYPE_KERNEL_NOLOAD && os.comp != IH_COMP_NONE) {
ulong req_size = ALIGN(image_len * 4, SZ_1M);
- load = lmb_alloc(&images->lmb, req_size, SZ_2M);
+ load = lmb_alloc(req_size, SZ_2M);
if (!load)
return 1;
os.load = load;
@@ -714,8 +695,9 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
images->os.end = relocated_addr + image_size;
}
- lmb_reserve(&images->lmb, images->os.load, (load_end -
- images->os.load));
+ if (CONFIG_IS_ENABLED(LMB))
+ lmb_reserve(images->os.load, (load_end - images->os.load));
+
return 0;
}
@@ -1029,19 +1011,19 @@ int bootm_run_states(struct bootm_info *bmi, int states)
if (!ret && (states & BOOTM_STATE_RAMDISK)) {
ulong rd_len = images->rd_end - images->rd_start;
- ret = boot_ramdisk_high(&images->lmb, images->rd_start,
- rd_len, &images->initrd_start, &images->initrd_end);
+ ret = boot_ramdisk_high(images->rd_start, rd_len,
+ &images->initrd_start,
+ &images->initrd_end);
if (!ret) {
env_set_hex("initrd_start", images->initrd_start);
env_set_hex("initrd_end", images->initrd_end);
}
}
#endif
-#if CONFIG_IS_ENABLED(OF_LIBFDT) && defined(CONFIG_LMB)
+#if CONFIG_IS_ENABLED(OF_LIBFDT) && CONFIG_IS_ENABLED(LMB)
if (!ret && (states & BOOTM_STATE_FDT)) {
- boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
- ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
- &images->ft_len);
+ boot_fdt_add_mem_rsv_regions(images->ft_addr);
+ ret = boot_relocate_fdt(&images->ft_addr, &images->ft_len);
}
#endif
diff --git a/boot/bootm_os.c b/boot/bootm_os.c
index 6a6621706f7..e9522cd3299 100644
--- a/boot/bootm_os.c
+++ b/boot/bootm_os.c
@@ -260,12 +260,11 @@ static void do_bootvx_fdt(struct bootm_headers *images)
char *bootline;
ulong of_size = images->ft_len;
char **of_flat_tree = &images->ft_addr;
- struct lmb *lmb = &images->lmb;
if (*of_flat_tree) {
- boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
+ boot_fdt_add_mem_rsv_regions(*of_flat_tree);
- ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
+ ret = boot_relocate_fdt(of_flat_tree, &of_size);
if (ret)
return;
diff --git a/boot/image-board.c b/boot/image-board.c
index eca1b1d2bff..1757e5816d8 100644
--- a/boot/image-board.c
+++ b/boot/image-board.c
@@ -517,7 +517,6 @@ int boot_get_ramdisk(char const *select, struct bootm_headers *images,
/**
* boot_ramdisk_high - relocate init ramdisk
- * @lmb: pointer to lmb handle, will be used for memory mgmt
* @rd_data: ramdisk data start address
* @rd_len: ramdisk data length
* @initrd_start: pointer to a ulong variable, will hold final init ramdisk
@@ -536,8 +535,8 @@ int boot_get_ramdisk(char const *select, struct bootm_headers *images,
* 0 - success
* -1 - failure
*/
-int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
- ulong *initrd_start, ulong *initrd_end)
+int boot_ramdisk_high(ulong rd_data, ulong rd_len, ulong *initrd_start,
+ ulong *initrd_end)
{
char *s;
phys_addr_t initrd_high;
@@ -563,13 +562,14 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
debug(" in-place initrd\n");
*initrd_start = rd_data;
*initrd_end = rd_data + rd_len;
- lmb_reserve(lmb, rd_data, rd_len);
+ lmb_reserve(rd_data, rd_len);
} else {
if (initrd_high)
- *initrd_start = (ulong)lmb_alloc_base(lmb,
- rd_len, 0x1000, initrd_high);
+ *initrd_start = (ulong)lmb_alloc_base(rd_len,
+ 0x1000,
+ initrd_high);
else
- *initrd_start = (ulong)lmb_alloc(lmb, rd_len,
+ *initrd_start = (ulong)lmb_alloc(rd_len,
0x1000);
if (*initrd_start == 0) {
@@ -802,7 +802,6 @@ int boot_get_loadable(struct bootm_headers *images)
/**
* boot_get_cmdline - allocate and initialize kernel cmdline
- * @lmb: pointer to lmb handle, will be used for memory mgmt
* @cmd_start: pointer to a ulong variable, will hold cmdline start
* @cmd_end: pointer to a ulong variable, will hold cmdline end
*
@@ -815,7 +814,7 @@ int boot_get_loadable(struct bootm_headers *images)
* 0 - success
* -1 - failure
*/
-int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
+int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end)
{
int barg;
char *cmdline;
@@ -829,7 +828,7 @@ int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
return 0;
barg = IF_ENABLED_INT(CONFIG_SYS_BOOT_GET_CMDLINE, CONFIG_SYS_BARGSIZE);
- cmdline = (char *)(ulong)lmb_alloc_base(lmb, barg, 0xf,
+ cmdline = (char *)(ulong)lmb_alloc_base(barg, 0xf,
env_get_bootm_mapsize() + env_get_bootm_low());
if (!cmdline)
return -1;
@@ -850,7 +849,6 @@ int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
/**
* boot_get_kbd - allocate and initialize kernel copy of board info
- * @lmb: pointer to lmb handle, will be used for memory mgmt
* @kbd: double pointer to board info data
*
* boot_get_kbd() allocates space for kernel copy of board info data below
@@ -861,10 +859,9 @@ int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
* 0 - success
* -1 - failure
*/
-int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd)
+int boot_get_kbd(struct bd_info **kbd)
{
- *kbd = (struct bd_info *)(ulong)lmb_alloc_base(lmb,
- sizeof(struct bd_info),
+ *kbd = (struct bd_info *)(ulong)lmb_alloc_base(sizeof(struct bd_info),
0xf,
env_get_bootm_mapsize() +
env_get_bootm_low());
@@ -885,17 +882,16 @@ int image_setup_linux(struct bootm_headers *images)
{
ulong of_size = images->ft_len;
char **of_flat_tree = &images->ft_addr;
- struct lmb *lmb = images_lmb(images);
int ret;
/* This function cannot be called without lmb support */
- if (!IS_ENABLED(CONFIG_LMB))
+ if (!CONFIG_IS_ENABLED(LMB))
return -EFAULT;
if (CONFIG_IS_ENABLED(OF_LIBFDT))
- boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
+ boot_fdt_add_mem_rsv_regions(*of_flat_tree);
if (IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE)) {
- ret = boot_get_cmdline(lmb, &images->cmdline_start,
+ ret = boot_get_cmdline(&images->cmdline_start,
&images->cmdline_end);
if (ret) {
puts("ERROR with allocation of cmdline\n");
@@ -904,13 +900,13 @@ int image_setup_linux(struct bootm_headers *images)
}
if (CONFIG_IS_ENABLED(OF_LIBFDT)) {
- ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
+ ret = boot_relocate_fdt(of_flat_tree, &of_size);
if (ret)
return ret;
}
if (CONFIG_IS_ENABLED(OF_LIBFDT) && of_size) {
- ret = image_setup_libfdt(images, *of_flat_tree, lmb);
+ ret = image_setup_libfdt(images, *of_flat_tree, true);
if (ret)
return ret;
}
diff --git a/boot/image-fdt.c b/boot/image-fdt.c
index 8332792b8e8..8eda521693d 100644
--- a/boot/image-fdt.c
+++ b/boot/image-fdt.c
@@ -68,12 +68,11 @@ static const struct legacy_img_hdr *image_get_fdt(ulong fdt_addr)
}
#endif
-static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr,
- uint64_t size, enum lmb_flags flags)
+static void boot_fdt_reserve_region(u64 addr, u64 size, enum lmb_flags flags)
{
long ret;
- ret = lmb_reserve_flags(lmb, addr, size, flags);
+ ret = lmb_reserve_flags(addr, size, flags);
if (ret >= 0) {
debug(" reserving fdt memory region: addr=%llx size=%llx flags=%x\n",
(unsigned long long)addr,
@@ -89,14 +88,13 @@ static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr,
/**
* boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory
* sections as unusable
- * @lmb: pointer to lmb handle, will be used for memory mgmt
* @fdt_blob: pointer to fdt blob base address
*
* Adds the and reserved-memorymemreserve regions in the dtb to the lmb block.
* Adding the memreserve regions prevents u-boot from using them to store the
* initrd or the fdt blob.
*/
-void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
+void boot_fdt_add_mem_rsv_regions(void *fdt_blob)
{
uint64_t addr, size;
int i, total, ret;
@@ -112,7 +110,7 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
for (i = 0; i < total; i++) {
if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
continue;
- boot_fdt_reserve_region(lmb, addr, size, LMB_NONE);
+ boot_fdt_reserve_region(addr, size, LMB_NONE);
}
/* process reserved-memory */
@@ -130,7 +128,7 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
flags = LMB_NOMAP;
addr = res.start;
size = res.end - res.start + 1;
- boot_fdt_reserve_region(lmb, addr, size, flags);
+ boot_fdt_reserve_region(addr, size, flags);
}
subnode = fdt_next_subnode(fdt_blob, subnode);
@@ -140,7 +138,6 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
/**
* boot_relocate_fdt - relocate flat device tree
- * @lmb: pointer to lmb handle, will be used for memory mgmt
* @of_flat_tree: pointer to a char* variable, will hold fdt start address
* @of_size: pointer to a ulong variable, will hold fdt length
*
@@ -155,7 +152,7 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
* 0 - success
* 1 - failure
*/
-int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)
+int boot_relocate_fdt(char **of_flat_tree, ulong *of_size)
{
u64 start, size, usable, addr, low, mapsize;
void *fdt_blob = *of_flat_tree;
@@ -187,18 +184,17 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)
if (desired_addr == ~0UL) {
/* All ones means use fdt in place */
of_start = fdt_blob;
- lmb_reserve(lmb, map_to_sysmem(of_start), of_len);
+ lmb_reserve(map_to_sysmem(of_start), of_len);
disable_relocation = 1;
} else if (desired_addr) {
- addr = lmb_alloc_base(lmb, of_len, 0x1000,
- desired_addr);
+ addr = lmb_alloc_base(of_len, 0x1000, desired_addr);
of_start = map_sysmem(addr, of_len);
if (of_start == NULL) {
puts("Failed using fdt_high value for Device Tree");
goto error;
}
} else {
- addr = lmb_alloc(lmb, of_len, 0x1000);
+ addr = lmb_alloc(of_len, 0x1000);
of_start = map_sysmem(addr, of_len);
}
} else {
@@ -220,7 +216,7 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)
* for LMB allocation.
*/
usable = min(start + size, low + mapsize);
- addr = lmb_alloc_base(lmb, of_len, 0x1000, usable);
+ addr = lmb_alloc_base(of_len, 0x1000, usable);
of_start = map_sysmem(addr, of_len);
/* Allocation succeeded, use this block. */
if (of_start != NULL)
@@ -569,8 +565,7 @@ __weak int arch_fixup_fdt(void *blob)
return 0;
}
-int image_setup_libfdt(struct bootm_headers *images, void *blob,
- struct lmb *lmb)
+int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb)
{
ulong *initrd_start = &images->initrd_start;
ulong *initrd_end = &images->initrd_end;
@@ -670,8 +665,8 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob,
}
/* Delete the old LMB reservation */
- if (lmb)
- lmb_free(lmb, map_to_sysmem(blob), fdt_totalsize(blob));
+ if (CONFIG_IS_ENABLED(LMB) && lmb)
+ lmb_free(map_to_sysmem(blob), fdt_totalsize(blob));
ret = fdt_shrink_to_minimum(blob, 0);
if (ret < 0)
@@ -679,8 +674,8 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob,
of_size = ret;
/* Create a new LMB reservation */
- if (lmb)
- lmb_reserve(lmb, map_to_sysmem(blob), of_size);
+ if (CONFIG_IS_ENABLED(LMB) && lmb)
+ lmb_reserve(map_to_sysmem(blob), of_size);
#if defined(CONFIG_ARCH_KEYSTONE)
if (IS_ENABLED(CONFIG_OF_BOARD_SETUP))