During FDT setup, apply all existing DT overlays from the bloblist to the base FDT if bloblist is being used for handoff from previous boot stage.
Signed-off-by: Raymond Mao <raymond....@linaro.org> --- lib/fdtdec.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/lib/fdtdec.c b/lib/fdtdec.c index c38738b48c7..3a218d8c94a 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1687,6 +1687,60 @@ void fdtdec_setup_embed(void) gd->fdt_src = FDTSRC_EMBED; } +static int fdtdec_apply_dto_from_blob(void **blob) +{ + int ret; + struct fdt_header *live_fdt; + size_t new_fdt_size, blob_size; + int expand_by; + + if (!CONFIG_IS_ENABLED(OF_LIBFDT_OVERLAY) || + !CONFIG_IS_ENABLED(BLOBLIST)) + return -EPERM; + + live_fdt = bloblist_find(BLOBLISTT_CONTROL_FDT, 0); + ret = fdt_check_header(live_fdt); + if (ret) + return ret; + + ret = fdt_check_header(*blob); + if (ret) + return ret; + + blob_size = fdt_totalsize(*blob); + + /* Expand the FDT for spare spaces to apply the overlay */ + new_fdt_size = fdt_totalsize(live_fdt) + blob_size + 0x400; + ret = bloblist_resize(BLOBLISTT_CONTROL_FDT, new_fdt_size, &expand_by); + if (ret) + return ret; + + /* The blob is shifted if it was following the FDT */ + if (*blob > (void *)live_fdt) + *blob += expand_by; + + ret = fdt_open_into(live_fdt, live_fdt, new_fdt_size); + if (ret) + return ret; + + ret = fdt_overlay_apply_verbose(live_fdt, *blob); + if (ret) + return ret; + + /* Shrink the excessive spaces */ + fdt_pack(live_fdt); + new_fdt_size = fdt_totalsize(live_fdt); + ret = bloblist_resize(BLOBLISTT_CONTROL_FDT, new_fdt_size, &expand_by); + if (ret) + return ret; + + /* The blob is shifted if it was following the FDT */ + if (*blob > (void *)live_fdt) + *blob += expand_by; + + return ret; +} + int fdtdec_setup(void) { int ret = -ENOENT; @@ -1708,6 +1762,8 @@ int fdtdec_setup(void) gd->fdt_src = FDTSRC_BLOBLIST; log_debug("Devicetree is in bloblist at %p\n", gd->fdt_blob); + bloblist_apply_blobs(BLOBLISTT_FDT_OVERLAY, + fdtdec_apply_dto_from_blob); goto setup_fdt; } else { log_debug("No FDT found in bloblist\n"); -- 2.25.1