Simon,

This looks ok to me, but I haven't been involved with the bootm code
much. Can you taker a quick look?

On Wed, 22 Apr 2026 at 20:10, <[email protected]> wrote:
>
> From: Randolph Sapp <[email protected]>
>
> Add a free flag and an initial call to free allocations covered by the
> global FDT. This assumes that all calls to boot_fdt_add_mem_rsv_regions
> occur before the transition to the new device tree, thus we can access
> the currently active device tree through the global data pointer.
>
> This allows us to clearly indicate to the user when a device tree
> reservation fails. How we handle this can still use some improvement.
> Right now we'll keep the default behavior and try to boot anyway.
>
> This functionality was broken in:
> 5a6aa7d ("boot: fdt: Handle already reserved memory in 
> boot_fdt_reserve_region()")
>

[...]

either operation.
> + */
> +static void boot_fdt_reserve_region(u64 addr, u64 size, u32 flags, bool free)
>  {

The function name is not accurate anymore. Perhaps call it
boot_fdt_handle_region()?

>         long ret;
>         phys_addr_t rsv_addr;
>
>         rsv_addr = (phys_addr_t)addr;
> -       ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &rsv_addr, size, flags);
> +       if (free)
> +               ret = lmb_free(rsv_addr, size, flags);
> +       else
> +               ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &rsv_addr, size,
> +                                   flags);
> +
>         if (!ret) {
> -               debug("   reserving fdt memory region: addr=%llx size=%llx 
> flags=%x\n",
> -                     (unsigned long long)addr,
> +               debug("   %s fdt memory region: addr=%llx size=%llx 
> flags=%x\n",
> +                     free ? "freed" : "reserved", (unsigned long long)addr,
>                       (unsigned long long)size, flags);
> -       } else if (ret != -EEXIST && ret != -EINVAL) {
> -               puts("ERROR: reserving fdt memory region failed ");
> -               printf("(addr=%llx size=%llx flags=%x)\n",
> -                      (unsigned long long)addr,
> -                      (unsigned long long)size, flags);
> +       } else {
> +               printf("ERROR: %s fdt memory region failed (addr=%llx 
> size=%llx flags=%x): %ld\n",
> +                      free ? "freeing" : "reserving", (unsigned long 
> long)addr,
> +                      (unsigned long long)size, flags, ret);
>         }
>  }
>
>  /**
> - * boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory
> - * sections as unusable
> + * boot_fdt_add_mem_rsv_regions - Handle FDT memreserve and reserved-memory
> + * sections
>   * @fdt_blob: pointer to fdt blob base address
> + * @free: indicate if regions are being freed
>   *
> - * 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.
> + * Adds or removes reserved-memory and memreserve 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. This function will attempt to clean the 
> currently
> + * active reservations if a new device tree blob is given.
>   */
> -void boot_fdt_add_mem_rsv_regions(void *fdt_blob)
> +void boot_fdt_add_mem_rsv_regions(void *fdt_blob, bool free)
>  {
>         uint64_t addr, size;
>         int i, total, ret;
> @@ -108,12 +124,16 @@ void boot_fdt_add_mem_rsv_regions(void *fdt_blob)
>         if (fdt_check_header(fdt_blob) != 0)
>                 return;
>
> +       /* Remove old regions */
> +       if (gd->fdt_blob != fdt_blob)
> +               boot_fdt_add_mem_rsv_regions((void *)gd->fdt_blob, true);
> +
>         /* process memreserve sections */
>         total = fdt_num_mem_rsv(fdt_blob);
>         for (i = 0; i < total; i++) {
>                 if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
>                         continue;
> -               boot_fdt_reserve_region(addr, size, LMB_NOOVERWRITE);
> +               boot_fdt_reserve_region(addr, size, LMB_NOOVERWRITE, free);
>         }
>
>         /* process reserved-memory */
> @@ -131,7 +151,8 @@ void boot_fdt_add_mem_rsv_regions(void *fdt_blob)
>                                         flags = LMB_NOMAP;
>                                 addr = res.start;
>                                 size = res.end - res.start + 1;
> -                               boot_fdt_reserve_region(addr, size, flags);
> +                               boot_fdt_reserve_region(addr, size, flags,
> +                                                       free);
>                         }
>
>                         subnode = fdt_next_subnode(fdt_blob, subnode);
> diff --git a/include/image.h b/include/image.h
> index 34efac6056d..68dfa4716ab 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -827,7 +827,7 @@ int boot_get_fdt(void *buf, const char *select, uint arch,
>                  struct bootm_headers *images, char **of_flat_tree,
>                  ulong *of_size);
>
> -void boot_fdt_add_mem_rsv_regions(void *fdt_blob);
> +void boot_fdt_add_mem_rsv_regions(void *fdt_blob, bool free);
>  int boot_relocate_fdt(char **of_flat_tree, ulong *of_size);
>
>  int boot_ramdisk_high(ulong rd_data, ulong rd_len, ulong *initrd_start,
> diff --git a/lib/lmb.c b/lib/lmb.c
> index 8f12c6ad8e5..9a8c70b778a 100644
> --- a/lib/lmb.c
> +++ b/lib/lmb.c
> @@ -581,7 +581,7 @@ static void lmb_reserve_common(void *fdt_blob)
>         lmb_reserve_uboot_region();
>
>         if (CONFIG_IS_ENABLED(OF_LIBFDT) && fdt_blob)
> -               boot_fdt_add_mem_rsv_regions(fdt_blob);
> +               boot_fdt_add_mem_rsv_regions(fdt_blob, false);
>  }
>
>  static __maybe_unused void lmb_reserve_common_spl(void)
> --
> 2.53.0
>

With the change above
Acked-by: Ilias Apalodimas <[email protected]>

Reply via email to