From fec4206299aefba05cae3bb82421635543ca1a2b Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Thu, 16 May 2019 16:04:19 -0700 Subject: fit: Add device tree compression This patch adds support for compressing individual device trees in the FIT image. In order to make this efficient, we'll have to pull the compatible property out of the FDT and store it directly in the config node of the FIT image, so that we don't have to scan (and therefore decompress) every single FDT on boot. Device tree compression is only supported for FIT images that have this external compatible property. For older images with no compression, we still support fallback to scanning the FDT for the property. This patch was adapted from depthcharge's http://crosreview.com/1553458 Change-Id: Ifcb6997782c480c8ef6692df17b66ad96264e623 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32872 Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/lib/fit_payload.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/lib/fit_payload.c') diff --git a/src/lib/fit_payload.c b/src/lib/fit_payload.c index c977903534..b0491889c9 100644 --- a/src/lib/fit_payload.c +++ b/src/lib/fit_payload.c @@ -96,6 +96,24 @@ static bool extract(struct region *region, struct fit_image_node *node) return false; } +static struct device_tree *unpack_fdt(struct fit_image_node *image_node) +{ + void *data = image_node->data; + + if (image_node->compression != CBFS_COMPRESS_NONE) { + /* TODO: This is an ugly heuristic for how much the size will + expand on decompression, fix once FIT images support storing + the real uncompressed size. */ + struct region r = { .offset = 0, .size = image_node->size * 5 }; + data = malloc(r.size); + r.offset = (uintptr_t)data; + if (!data || extract(&r, image_node)) + return NULL; + } + + return fdt_unflatten(data); +} + /** * Add coreboot tables, CBMEM information and optional board specific strapping * IDs to the device tree loaded via FIT. @@ -181,7 +199,7 @@ void fit_payload(struct prog *payload) return; } - dt = fdt_unflatten(config->fdt->data); + dt = unpack_fdt(config->fdt); if (!dt) { printk(BIOS_ERR, "ERROR: Failed to unflatten the FDT.\n"); rdev_munmap(prog_rdev(payload), data); -- cgit v1.2.3