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)
