Hello Patrick Rudolph,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/32873
to review the following change.
Change subject: fit: Add overlay support ......................................................................
fit: Add overlay support
This patch adds support to boot FIT image configurations consisting of a base device tree and one or more overlays. Since extracting the right compatible string from overlay FDTs is problematic, we'll only support this for FIT images that have the compatible string pulled out into the config node.
This patch was adapted from depthcharge's http://crosreview.com/1555293
Change-Id: I0943f9a1869c9e416887c7ff16e33f7d91b74989 Signed-off-by: Julius Werner jwerner@chromium.org --- M src/include/fit.h M src/lib/fit.c M src/lib/fit_payload.c 3 files changed, 54 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/73/32873/1
diff --git a/src/include/fit.h b/src/include/fit.h index 758ee70..a5a9e69 100644 --- a/src/include/fit.h +++ b/src/include/fit.h @@ -39,6 +39,7 @@ const char *name; struct fit_image_node *kernel; struct fit_image_node *fdt; + struct list_node overlays; struct fit_image_node *ramdisk; struct fdt_property compat; int compat_rank; @@ -48,6 +49,12 @@ struct list_node list_node; };
+struct fit_overlay_chain +{ + struct fit_image_node *overlay; + struct list_node list_node; +}; + /* * Updates the cmdline in the devicetree. */ diff --git a/src/lib/fit.c b/src/lib/fit.c index 464be3a..1b02c6a 100644 --- a/src/lib/fit.c +++ b/src/lib/fit.c @@ -96,6 +96,31 @@ return NULL; }
+static struct fit_image_node *find_image_with_overlays(const char *name, + int bytes, struct list_node *prev) +{ + struct fit_image_node *base = find_image(name); + if (!base) + return NULL; + + int len = strnlen(name, bytes) + 1; + bytes -= len; + name += len; + while (bytes > 0) { + struct fit_overlay_chain *next = xzalloc(sizeof(*next)); + next->overlay = find_image(name); + if (!next->overlay) + return NULL; + list_insert_after(&next->list_node, prev); + prev = &next->list_node; + len = strnlen(name, bytes) + 1; + bytes -= len; + name += len; + } + + return base; +} + static void image_node(struct device_tree_node *node) { struct fit_image_node *image = xzalloc(sizeof(*image)); @@ -133,7 +158,8 @@ if (!strcmp("kernel", prop->prop.name)) config->kernel = find_image(prop->prop.data); else if (!strcmp("fdt", prop->prop.name)) - config->fdt = find_image(prop->prop.data); + config->fdt = find_image_with_overlays(prop->prop.data, + prop->prop.size, &config->overlays); else if (!strcmp("ramdisk", prop->prop.name)) config->ramdisk = find_image(prop->prop.data); else if (!strcmp("compatible", prop->prop.name)) @@ -408,6 +434,14 @@ return -1; }
+ // FDT overlays are not supported in legacy FIT images. + if (config->overlays.next) { + printk(BIOS_ERR, + "ERROR: config %s has overlay but no compat!\n", + config->name); + return -1; + } + if (fdt_find_compat(fdt_blob, fdt_offset, &config->compat)) { printk(BIOS_ERR, "ERROR: Can't find compat string in FDT %s " @@ -442,6 +476,7 @@ struct fit_image_node *image; struct fit_config_node *config; struct compat_string_entry *compat_node; + struct fit_overlay_chain *overlay_chain;
printk(BIOS_DEBUG, "FIT: Loading FIT from %p\n", fit);
@@ -505,6 +540,8 @@ } printk(BIOS_DEBUG, ", kernel %s", config->kernel->name); printk(BIOS_DEBUG, ", fdt %s", config->fdt->name); + list_for_each(overlay_chain, config->overlays, list_node) + printk(BIOS_DEBUG, " %s", overlay_chain->overlay->name); if (config->ramdisk) printk(BIOS_DEBUG, ", ramdisk %s", config->ramdisk->name); if (config->compat.name) { diff --git a/src/lib/fit_payload.c b/src/lib/fit_payload.c index b049188..8e75915 100644 --- a/src/lib/fit_payload.c +++ b/src/lib/fit_payload.c @@ -206,6 +206,15 @@ return; }
+ struct fit_overlay_chain *chain; + list_for_each(chain, config->overlays, list_node) { + struct device_tree *overlay = unpack_fdt(chain->overlay); + if (!overlay || dt_apply_overlay(dt, overlay)) { + printk(BIOS_ERR, "ERROR: Failed to apply overlay %s!\n", + chain->overlay->name); + } + } + dt_apply_fixups(dt);
/* Insert coreboot specific information */