diff --git a/tools/ifdtool.c b/tools/ifdtool.c index d966c56..1f95203 100644 --- a/tools/ifdtool.c +++ b/tools/ifdtool.c @@ -783,6 +783,47 @@ static int scan_ucode(const void *blob, char *ucode_base, int *countp, return ucode - ucode_base; } +static int remove_ucode(char *blob) +{ + int node, count; + int ret; + + /* Keep going until we find no more microcode to remove */ + do { + for (node = 0, count = 0; node >= 0;) { + int ret; + + node = fdt_node_offset_by_compatible(blob, node, + "intel,microcode"); + if (node < 0) + break; + + ret = fdt_delprop(blob, node, "data"); + + /* + * -FDT_ERR_NOTFOUND means we already removed the + * data for this one, so we just continue. + * 0 means we did remove it, so offsets may have + * changed and we need to restart our scan. + * Anything else indicates an error we should report. + */ + if (ret == -FDT_ERR_NOTFOUND) + continue; + else if (!ret) + node = 0; + else + return ret; + } + } while (count); + + /* Pack down to remove excees space */ + ret = fdt_pack(blob); + if (ret) + return ret; + + return fdt_totalsize(blob); +} + static int write_ucode(char *image, int size, struct input_file *fdt, int fdt_size, unsigned int ucode_ptr, int collate_ucode) @@ -818,8 +859,8 @@ static int write_ucode(char *image, int size, struct input_file *fdt, } /* - * Collect the microcode into a buffer and place it immediately above - * the device tree. + * Collect the microcode into a buffer, remove it from the device + * tree and place it immediately above the (now smaller) device tree. */ if (collate_ucode && count > 1) { ucode_buf = malloc(ucode_size); @@ -833,7 +874,17 @@ static int write_ucode(char *image, int size, struct input_file *fdt, if (ret < 0) return ret; + /* Remove the microcode from the device tree */ + ret = remove_ucode((char *)blob); + if (ret < 0) { + debug("Could not remove FDT microcode: %s\n", + fdt_strerror(ret)); + return -EINVAL; + } debug("Collated %d microcode block(s)\n", count); + debug("Device tree reduced from %x to %x bytes\n", + fdt_size, ret); + fdt_size = ret; /* * Place microcode area immediately above the FDT, aligned