boot_fdt_add_mem_rsv_regions() removes the ranges described by
gd->fdt_blob (the U-Boot control device tree) before adding those of
the new blob. It runs both in the BOOTM_STATE_FDT step and again from
image_setup_linux() during BOOTM_STATE_OS_PREP.

In a stepped boot (bootm fdt followed by bootm prep) the second call
still sees gd->fdt_blob pointing at the control device tree, so it
frees the control tree's ranges a second time. LMB tracks plain ranges,
not their owner, so this also drops parts of the OS device tree's
reservations before re-adding them; the re-add then fails with -EEXIST
for the LMB_NOMAP regions. On Xiaomi crux this lost 128 KiB of the
XBL/AOP reservation at 0x85f20000-0x85f3ffff.

Only add the reservations when the separate FDT step has not run.

Signed-off-by: Qing Li <[email protected]>
---
 boot/image-board.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/boot/image-board.c b/boot/image-board.c
index 67938fdd200..70af28b8a46 100644
--- a/boot/image-board.c
+++ b/boot/image-board.c
@@ -918,7 +918,14 @@ int image_setup_linux(struct bootm_headers *images)
        /* This function cannot be called without lmb support */
        if (!CONFIG_IS_ENABLED(LMB))
                return -EFAULT;
-       if (CONFIG_IS_ENABLED(OF_LIBFDT))
+       /*
+        * The separate "bootm fdt" state reserves these regions before FDT
+        * relocation. Don't process them again during prep: gd->fdt_blob still
+        * names the control FDT, so a second pass can free part of the Linux
+        * FDT's reservations before trying to add them again.
+        */
+       if (CONFIG_IS_ENABLED(OF_LIBFDT) &&
+           !(images->state & BOOTM_STATE_FDT))
                boot_fdt_add_mem_rsv_regions(*of_flat_tree);
 
        if (IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE)) {
-- 
2.50.1 (Apple Git-155)

Reply via email to