diff options
| author | Sughosh Ganu <[email protected]> | 2024-08-26 17:29:18 +0530 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2024-09-03 14:08:50 -0600 |
| commit | ed17a33fed296a87219b0ff702045ce488bc3771 (patch) | |
| tree | e1ac01002f7dcd0e1c1adbf5139234038ea58f8f /boot | |
| parent | a368850ae2551a4fcc5f9a2e9e8e90c056d4fe73 (diff) | |
lmb: make LMB memory map persistent and global
The current LMB API's for allocating and reserving memory use a
per-caller based memory view. Memory allocated by a caller can then be
overwritten by another caller. Make these allocations and reservations
persistent using the alloced list data structure.
Two alloced lists are declared -- one for the available(free) memory,
and one for the used memory. Once full, the list can then be extended
at runtime.
[sjg: Use a stack to store pointer of lmb struct when running lmb tests]
Signed-off-by: Sughosh Ganu <[email protected]>
Signed-off-by: Simon Glass <[email protected]>
[sjg: Optimise the logic to add a region in lmb_add_region_flags()]
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/bootm.c | 26 | ||||
| -rw-r--r-- | boot/bootm_os.c | 5 | ||||
| -rw-r--r-- | boot/image-board.c | 34 | ||||
| -rw-r--r-- | boot/image-fdt.c | 35 |
4 files changed, 44 insertions, 56 deletions
diff --git a/boot/bootm.c b/boot/bootm.c index 480f8e6a0e6..d47feddb9b4 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -240,7 +240,7 @@ static int boot_get_kernel(const char *addr_fit, struct bootm_headers *images, } #ifdef CONFIG_LMB -static void boot_start_lmb(struct bootm_headers *images) +static void boot_start_lmb(void) { phys_addr_t mem_start; phys_size_t mem_size; @@ -248,12 +248,11 @@ static void boot_start_lmb(struct bootm_headers *images) mem_start = env_get_bootm_low(); mem_size = env_get_bootm_size(); - lmb_init_and_reserve_range(&images->lmb, mem_start, - mem_size, NULL); + lmb_init_and_reserve_range(mem_start, mem_size, NULL); } #else -#define lmb_reserve(lmb, base, size) -static inline void boot_start_lmb(struct bootm_headers *images) { } +#define lmb_reserve(base, size) +static inline void boot_start_lmb(void) { } #endif static int bootm_start(void) @@ -261,7 +260,7 @@ static int bootm_start(void) memset((void *)&images, 0, sizeof(images)); images.verify = env_get_yesno("verify"); - boot_start_lmb(&images); + boot_start_lmb(); bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start"); images.state = BOOTM_STATE_START; @@ -640,7 +639,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 +713,7 @@ 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)); + lmb_reserve(images->os.load, (load_end - images->os.load)); return 0; } @@ -1029,8 +1027,9 @@ 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); @@ -1039,9 +1038,8 @@ int bootm_run_states(struct bootm_info *bmi, int states) #endif #if CONFIG_IS_ENABLED(OF_LIBFDT) && defined(CONFIG_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 f2124013046..1f8c1ac69fa 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -515,7 +515,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 @@ -534,8 +533,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; @@ -561,13 +560,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) { @@ -800,7 +800,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 * @@ -813,7 +812,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; @@ -827,7 +826,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; @@ -848,7 +847,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 @@ -859,10 +857,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()); @@ -883,17 +880,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)) 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"); @@ -902,13 +898,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)) |
