[PATCH v4 2/7] lmb: replace the lmb_alloc() and lmb_alloc_base() API's
Ilias Apalodimas
ilias.apalodimas at linaro.org
Mon Jun 16 12:17:53 CEST 2025
Thanks Sughosh
This is a nice cleanup, we only have lmb_alloc_mem() now right? (Apart
from the io_xxx versions)
On Thu, 12 Jun 2025 at 09:56, Sughosh Ganu <sughosh.ganu at linaro.org> wrote:
>
> There currently are two API's for requesting memory from the LMB
> module, lmb_alloc() and lmb_alloc_base(). The function which does the
> actual allocation is the same. Use the earlier introduced API
> lmb_alloc_mem() for both types of allocation requests.
>
> Signed-off-by: Sughosh Ganu <sughosh.ganu at linaro.org>
Acked-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
Cheers
/Ilias
> ---
> Changes since V3:
> * mach-apple: Check the return value of the lmb allocation API, and
> set the env variables only when the API returns success
> * mach-snapdragon: Check the return value of the lmb allocation API,
> and set the env variables only when the API returns success
>
> arch/arm/mach-apple/board.c | 27 ++++++++++++------
> arch/arm/mach-snapdragon/board.c | 30 ++++++++++++-------
> boot/bootm.c | 12 +++++---
> boot/image-board.c | 49 +++++++++++++++++---------------
> boot/image-fdt.c | 35 +++++++++++++----------
> include/lmb.h | 22 +++-----------
> lib/efi_loader/efi_memory.c | 14 +++++----
> lib/lmb.c | 28 ++++++++----------
> test/lib/lmb.c | 26 +++++++++++++++++
> 9 files changed, 141 insertions(+), 102 deletions(-)
>
> diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c
> index 2604c5a710e..4cd8979bdc2 100644
> --- a/arch/arm/mach-apple/board.c
> +++ b/arch/arm/mach-apple/board.c
> @@ -773,22 +773,31 @@ u64 get_page_table_size(void)
>
> #define KERNEL_COMP_SIZE SZ_128M
>
> +#define lmb_alloc(size, addr) lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE)
> +
> int board_late_init(void)
> {
> u32 status = 0;
> + phys_addr_t addr;
>
> /* somewhat based on the Linux Kernel boot requirements:
> * align by 2M and maximal FDT size 2M
> */
> - status |= env_set_hex("loadaddr", lmb_alloc(SZ_1G, SZ_2M));
> - status |= env_set_hex("fdt_addr_r", lmb_alloc(SZ_2M, SZ_2M));
> - status |= env_set_hex("kernel_addr_r", lmb_alloc(SZ_128M, SZ_2M));
> - status |= env_set_hex("ramdisk_addr_r", lmb_alloc(SZ_1G, SZ_2M));
> - status |= env_set_hex("kernel_comp_addr_r",
> - lmb_alloc(KERNEL_COMP_SIZE, SZ_2M));
> - status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE);
> - status |= env_set_hex("scriptaddr", lmb_alloc(SZ_4M, SZ_2M));
> - status |= env_set_hex("pxefile_addr_r", lmb_alloc(SZ_4M, SZ_2M));
> + status |= !lmb_alloc(SZ_1G, &addr) ? env_set_hex("loadaddr", addr) : 1;
> + status |= !lmb_alloc(SZ_2M, &addr) ?
> + env_set_hex("fdt_addr_r", addr) : 1;
> + status |= !lmb_alloc(SZ_128M, &addr) ?
> + env_set_hex("kernel_addr_r", addr) : 1;
> + status |= !lmb_alloc(SZ_1G, &addr) ?
> + env_set_hex("ramdisk_addr_r", addr) : 1;
> + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ?
> + env_set_hex("kernel_comp_addr_r", addr) : 1;
> + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ?
> + env_set_hex("kernel_comp_size", addr) : 1;
> + status |= !lmb_alloc(SZ_4M, &addr) ?
> + env_set_hex("scriptaddr", addr) : 1;
> + status |= !lmb_alloc(SZ_4M, &addr) ?
> + env_set_hex("pxefile_addr_r", addr) : 1;
>
> if (status)
> log_warning("late_init: Failed to set run time variables\n");
> diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
> index 5547d6d054f..87a173e0acb 100644
> --- a/arch/arm/mach-snapdragon/board.c
> +++ b/arch/arm/mach-snapdragon/board.c
> @@ -492,7 +492,7 @@ void __weak qcom_late_init(void)
> #define FASTBOOT_BUF_SIZE 0
> #endif
>
> -#define addr_alloc(size) lmb_alloc(size, SZ_2M)
> +#define lmb_alloc(size, addr) lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE)
>
> /* Stolen from arch/arm/mach-apple/board.c */
> int board_late_init(void)
> @@ -502,18 +502,26 @@ int board_late_init(void)
> struct fdt_header *fdt_blob = (struct fdt_header *)gd->fdt_blob;
>
> /* We need to be fairly conservative here as we support boards with just 1G of TOTAL RAM */
> - addr = addr_alloc(SZ_128M);
> + status |= !lmb_alloc(SZ_128M, &addr) ?
> + env_set_hex("loadaddr", addr) : 1;
> status |= env_set_hex("kernel_addr_r", addr);
> - status |= env_set_hex("loadaddr", addr);
> - status |= env_set_hex("ramdisk_addr_r", addr_alloc(SZ_128M));
> - status |= env_set_hex("kernel_comp_addr_r", addr_alloc(KERNEL_COMP_SIZE));
> - status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE);
> + status |= !lmb_alloc(SZ_128M, &addr) ?
> + env_set_hex("ramdisk_addr_r", addr) : 1;
> + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ?
> + env_set_hex("kernel_comp_addr_r", addr) : 1;
> + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ?
> + env_set_hex("kernel_comp_size", addr) : 1;
> + status |= !lmb_alloc(SZ_4M, &addr) ?
> + env_set_hex("scriptaddr", addr) : 1;
> + status |= !lmb_alloc(SZ_4M, &addr) ?
> + env_set_hex("pxefile_addr_r", addr) : 1;
> +
> if (IS_ENABLED(CONFIG_FASTBOOT))
> - status |= env_set_hex("fastboot_addr_r", addr_alloc(FASTBOOT_BUF_SIZE));
> - status |= env_set_hex("scriptaddr", addr_alloc(SZ_4M));
> - status |= env_set_hex("pxefile_addr_r", addr_alloc(SZ_4M));
> - addr = addr_alloc(SZ_2M);
> - status |= env_set_hex("fdt_addr_r", addr);
> + status |= !lmb_alloc(FASTBOOT_BUF_SIZE, &addr) ?
> + env_set_hex("fastboot_addr_r", addr) : 1;
> +
> + status |= !lmb_alloc(SZ_2M, &addr) ?
> + env_set_hex("fdt_addr_r", addr) : 1;
>
> if (status)
> log_warning("%s: Failed to set run time variables\n", __func__);
> diff --git a/boot/bootm.c b/boot/bootm.c
> index 3282bfc0b4b..4bdca22ea8c 100644
> --- a/boot/bootm.c
> +++ b/boot/bootm.c
> @@ -623,12 +623,16 @@ 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);
> + phys_addr_t addr;
>
> - load = lmb_alloc(req_size, SZ_2M);
> - if (!load)
> + err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, &addr,
> + req_size, LMB_NONE);
> + if (err)
> return 1;
> - os.load = load;
> - images->ep = load;
> +
> + load = (ulong)addr;
> + os.load = (ulong)addr;
> + images->ep = (ulong)addr;
> debug("Allocated %lx bytes at %lx for kernel (size %lx) decompression\n",
> req_size, load, image_len);
> }
> diff --git a/boot/image-board.c b/boot/image-board.c
> index b0fa028ceac..005d60caf5c 100644
> --- a/boot/image-board.c
> +++ b/boot/image-board.c
> @@ -16,6 +16,7 @@
> #include <fpga.h>
> #include <image.h>
> #include <init.h>
> +#include <lmb.h>
> #include <log.h>
> #include <mapmem.h>
> #include <rtc.h>
> @@ -566,27 +567,24 @@ int boot_ramdisk_high(ulong rd_data, ulong rd_len, ulong *initrd_start,
> *initrd_start = rd_data;
> *initrd_end = rd_data + rd_len;
> initrd_addr = (phys_addr_t)rd_data;
> - err = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0,
> - &initrd_addr, rd_len, LMB_NONE);
> + err = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &initrd_addr,
> + rd_len, LMB_NONE);
> if (err) {
> puts("in-place initrd alloc failed\n");
> goto error;
> }
> } else {
> - if (initrd_high)
> - *initrd_start =
> - (ulong)lmb_alloc_base(rd_len,
> - 0x1000,
> - initrd_high,
> - LMB_NONE);
> - else
> - *initrd_start = (ulong)lmb_alloc(rd_len,
> - 0x1000);
> + enum lmb_mem_type type = initrd_high ?
> + LMB_MEM_ALLOC_MAX : LMB_MEM_ALLOC_ANY;
>
> - if (*initrd_start == 0) {
> + err = lmb_alloc_mem(type, 0x1000, &initrd_high, rd_len,
> + LMB_NONE);
> + if (err) {
> puts("ramdisk - allocation error\n");
> goto error;
> }
> +
> + *initrd_start = (ulong)initrd_high;
> bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK);
>
> *initrd_end = *initrd_start + rd_len;
> @@ -837,9 +835,10 @@ int boot_get_loadable(struct bootm_headers *images)
> */
> int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end)
> {
> - int barg;
> + int barg, err;
> char *cmdline;
> char *s;
> + phys_addr_t addr;
>
> /*
> * Help the compiler detect that this function is only called when
> @@ -849,12 +848,14 @@ int boot_get_cmdline(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(barg, 0xf,
> - env_get_bootm_mapsize() + env_get_bootm_low(),
> - LMB_NONE);
> - if (!cmdline)
> + addr = env_get_bootm_mapsize() + env_get_bootm_low();
> +
> + err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, 0xf, &addr, barg, LMB_NONE);
> + if (err)
> return -1;
>
> + cmdline = (char *)(uintptr_t)addr;
> +
> s = env_get("bootargs");
> if (!s)
> s = "";
> @@ -883,14 +884,16 @@ int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end)
> */
> int boot_get_kbd(struct bd_info **kbd)
> {
> - *kbd = (struct bd_info *)(ulong)lmb_alloc_base(sizeof(struct bd_info),
> - 0xf,
> - env_get_bootm_mapsize() +
> - env_get_bootm_low(),
> - LMB_NONE);
> - if (!*kbd)
> + int err;
> + phys_addr_t addr;
> +
> + addr = env_get_bootm_mapsize() + env_get_bootm_low();
> + err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, 0xf, &addr,
> + sizeof(struct bd_info), LMB_NONE);
> + if (err)
> return -1;
>
> + *kbd = (struct bd_info *)(uintptr_t)addr;
> **kbd = *gd->bd;
>
> debug("## kernel board info at 0x%08lx\n", (ulong)*kbd);
> diff --git a/boot/image-fdt.c b/boot/image-fdt.c
> index bd5a6231140..2720ce6f6f3 100644
> --- a/boot/image-fdt.c
> +++ b/boot/image-fdt.c
> @@ -183,9 +183,9 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size)
> /* If fdt_high is set use it to select the relocation address */
> fdt_high = env_get("fdt_high");
> if (fdt_high) {
> - ulong desired_addr = hextoul(fdt_high, NULL);
> + ulong high_addr = hextoul(fdt_high, NULL);
>
> - if (desired_addr == ~0UL) {
> + if (high_addr == ~0UL) {
> /* All ones means use fdt in place */
> of_start = fdt_blob;
> addr = map_to_sysmem(fdt_blob);
> @@ -198,16 +198,17 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size)
> }
>
> disable_relocation = 1;
> - } else if (desired_addr) {
> - addr = lmb_alloc_base(of_len, 0x1000, desired_addr,
> - LMB_NONE);
> - of_start = map_sysmem(addr, of_len);
> - if (of_start == NULL) {
> - puts("Failed using fdt_high value for Device Tree");
> + } else {
> + enum lmb_mem_type type = high_addr ?
> + LMB_MEM_ALLOC_MAX : LMB_MEM_ALLOC_ANY;
> +
> + addr = high_addr;
> + err = lmb_alloc_mem(type, 0x1000, &addr, of_len,
> + LMB_NONE);
> + if (err) {
> + puts("Failed to allocate memory for Device Tree relocation\n");
> goto error;
> }
> - } else {
> - addr = lmb_alloc(of_len, 0x1000);
> of_start = map_sysmem(addr, of_len);
> }
> } else {
> @@ -229,11 +230,15 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size)
> * for LMB allocation.
> */
> usable = min(start + size, low + mapsize);
> - addr = lmb_alloc_base(of_len, 0x1000, usable, LMB_NONE);
> - of_start = map_sysmem(addr, of_len);
> - /* Allocation succeeded, use this block. */
> - if (of_start != NULL)
> - break;
> + addr = usable;
> + err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, 0x1000,
> + &addr, of_len, LMB_NONE);
> + if (!err) {
> + of_start = map_sysmem(addr, of_len);
> + /* Allocation succeeded, use this block. */
> + if (of_start)
> + break;
> + }
>
> /*
> * Reduce the mapping size in the next bank
> diff --git a/include/lmb.h b/include/lmb.h
> index 8906b42181f..34dbc25759d 100644
> --- a/include/lmb.h
> +++ b/include/lmb.h
> @@ -34,9 +34,13 @@
> /**
> * enum lmb_mem_type - type of memory allocation request
> * @LMB_MEM_ALLOC_ADDR: request for a particular region of memory
> + * @LMB_MEM_ALLOC_ANY: allocate any available memory region
> + * @LMB_MEM_ALLOC_MAX: allocate memory below a particular address
> */
> enum lmb_mem_type {
> LMB_MEM_ALLOC_ADDR = 1,
> + LMB_MEM_ALLOC_ANY,
> + LMB_MEM_ALLOC_MAX,
> };
>
> /**
> @@ -130,26 +134,8 @@ void lmb_add_memory(void);
>
> long lmb_add(phys_addr_t base, phys_size_t size);
>
> -phys_addr_t lmb_alloc(phys_size_t size, ulong align);
> phys_size_t lmb_get_free_size(phys_addr_t addr);
>
> -/**
> - * lmb_alloc_base() - Allocate specified memory region with specified
> - * attributes
> - * @size: Size of the region requested
> - * @align: Alignment of the memory region requested
> - * @max_addr: Maximum address of the requested region
> - * @flags: Memory region attributes to be set
> - *
> - * Allocate a region of memory with the attributes specified through the
> - * parameter. The max_addr parameter is used to specify the maximum address
> - * below which the requested region should be allocated.
> - *
> - * Return: Base address on success, 0 on error.
> - */
> -phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr,
> - uint flags);
> -
> /**
> * lmb_is_reserved_flags() - Test if address is in reserved region with flag
> * bits set
> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
> index 77950a267cc..466f45c98b1 100644
> --- a/lib/efi_loader/efi_memory.c
> +++ b/lib/efi_loader/efi_memory.c
> @@ -454,6 +454,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
> enum efi_memory_type memory_type,
> efi_uintn_t pages, uint64_t *memory)
> {
> + int err;
> u64 efi_addr, len;
> uint flags;
> efi_status_t ret;
> @@ -475,17 +476,18 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
> switch (type) {
> case EFI_ALLOCATE_ANY_PAGES:
> /* Any page */
> - addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE,
> - LMB_ALLOC_ANYWHERE, flags);
> - if (!addr)
> + err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, EFI_PAGE_SIZE, &addr,
> + len, flags);
> + if (err)
> return EFI_OUT_OF_RESOURCES;
> break;
> case EFI_ALLOCATE_MAX_ADDRESS:
> /* Max address */
> addr = map_to_sysmem((void *)(uintptr_t)*memory);
> - addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE, addr,
> - flags);
> - if (!addr)
> +
> + err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, EFI_PAGE_SIZE, &addr,
> + len, flags);
> + if (err)
> return EFI_OUT_OF_RESOURCES;
> break;
> case EFI_ALLOCATE_ADDRESS:
> diff --git a/lib/lmb.c b/lib/lmb.c
> index 72d4edacff0..29603335f66 100644
> --- a/lib/lmb.c
> +++ b/lib/lmb.c
> @@ -672,16 +672,18 @@ long lmb_free(phys_addr_t base, phys_size_t size)
> return lmb_free_flags(base, size, LMB_NONE);
> }
>
> -static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align,
> - phys_addr_t max_addr, u32 flags)
> +static int _lmb_alloc_base(phys_size_t size, ulong align,
> + phys_addr_t *addr, u32 flags)
> {
> int ret;
> long i, rgn;
> + phys_addr_t max_addr;
> phys_addr_t base = 0;
> phys_addr_t res_base;
> struct lmb_region *lmb_used = lmb.used_mem.data;
> struct lmb_region *lmb_memory = lmb.available_mem.data;
>
> + max_addr = *addr;
> for (i = lmb.available_mem.count - 1; i >= 0; i--) {
> phys_addr_t lmbbase = lmb_memory[i].base;
> phys_size_t lmbsize = lmb_memory[i].size;
> @@ -714,8 +716,8 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align,
> flags);
> if (ret)
> return ret;
> -
> - return base;
> + *addr = base;
> + return 0;
> }
>
> res_base = lmb_used[rgn].base;
> @@ -728,18 +730,7 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align,
> log_debug("%s: Failed to allocate 0x%lx bytes below 0x%lx\n",
> __func__, (ulong)size, (ulong)max_addr);
>
> - return 0;
> -}
> -
> -phys_addr_t lmb_alloc(phys_size_t size, ulong align)
> -{
> - return _lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE, LMB_NONE);
> -}
> -
> -phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr,
> - uint flags)
> -{
> - return _lmb_alloc_base(size, align, max_addr, flags);
> + return -1;
> }
>
> static int _lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags)
> @@ -778,6 +769,11 @@ int lmb_alloc_mem(enum lmb_mem_type type, u64 align, phys_addr_t *addr,
> return -EINVAL;
>
> switch (type) {
> + case LMB_MEM_ALLOC_ANY:
> + *addr = LMB_ALLOC_ANYWHERE;
> + case LMB_MEM_ALLOC_MAX:
> + ret = _lmb_alloc_base(size, align, addr, flags);
> + break;
> case LMB_MEM_ALLOC_ADDR:
> ret = _lmb_alloc_addr(*addr, size, flags);
> break;
> diff --git a/test/lib/lmb.c b/test/lib/lmb.c
> index 751909fc2cf..d8eab96527a 100644
> --- a/test/lib/lmb.c
> +++ b/test/lib/lmb.c
> @@ -82,6 +82,32 @@ static int lmb_reserve(phys_addr_t addr, phys_size_t size, u32 flags)
> return 0;
> }
>
> +static phys_addr_t lmb_alloc(phys_size_t size, ulong align)
> +{
> + int err;
> + phys_addr_t addr;
> +
> + err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, align, &addr, size, LMB_NONE);
> + if (err)
> + return 0;
> +
> + return addr;
> +}
> +
> +static phys_addr_t lmb_alloc_base(phys_size_t size, ulong align,
> + phys_addr_t max_addr, u32 flags)
> +{
> + int err;
> + phys_addr_t addr;
> +
> + addr = max_addr;
> + err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, align, &addr, size, flags);
> + if (err)
> + return 0;
> +
> + return addr;
> +}
> +
> #define lmb_alloc_addr(addr, size, flags) lmb_reserve(addr, size, flags)
>
> static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram,
> --
> 2.34.1
>
More information about the U-Boot
mailing list