From f164feba3ec2958564890fab71c04e1649285719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Lewi=C5=84ski?= Date: Thu, 16 Oct 2025 11:13:07 +0200 Subject: [PATCH] ifittool: allow adding files from a separate region MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows ifittool to add FIT entries for files that are located in a different FMAP region than the FIT table. The region from where to source the file can be specified with -R. If not given it defaults to using the value of the mandatory -r, for full backwards compatibility. Example: Tested with a custom binary with the bootblock and corresponding FIT table in a separate region, and the microcode still in the COREBOOT region: λ ./ifittool -f test_ts.rom -a -n cpu_microcode_blob.bin -t 1 \ -r BOOTBLOCK \ -R COREBOOT \ -s 4 Change-Id: I7e49247f280ec118e09cf173795d7602a4c0d7f6 Signed-off-by: Filip Lewiński Reviewed-on: https://review.coreboot.org/c/coreboot/+/89608 Reviewed-by: Sergii Dmytruk Tested-by: build bot (Jenkins) --- util/cbfstool/fit.c | 6 +++--- util/cbfstool/fit.h | 2 +- util/cbfstool/ifittool.c | 46 +++++++++++++++++++++++++++++++++------- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/util/cbfstool/fit.c b/util/cbfstool/fit.c index 0d5d4c7847..87f9dd1895 100644 --- a/util/cbfstool/fit.c +++ b/util/cbfstool/fit.c @@ -492,7 +492,7 @@ static void update_fit_key_manifest_entry(struct fit_table *fit, /* Special case for ucode CBFS file, as it might contain more than one ucode */ int fit_add_microcode_file(struct fit_table *fit, - struct cbfs_image *image, + struct cbfs_image *file_source_image, const char *blob_name, fit_offset_converter_t offset_helper, const size_t max_fit_entries) @@ -508,7 +508,7 @@ int fit_add_microcode_file(struct fit_table *fit, return 1; } - if (parse_microcode_blob(image, blob_name, &mcus_found, mcus, + if (parse_microcode_blob(file_source_image, blob_name, &mcus_found, mcus, max_fit_entries)) { free(mcus); return 1; @@ -516,7 +516,7 @@ int fit_add_microcode_file(struct fit_table *fit, for (i = 0; i < mcus_found; i++) { if (fit_add_entry(fit, - offset_to_ptr(offset_helper, &image->buffer, + offset_to_ptr(offset_helper, &file_source_image->buffer, mcus[i].offset), 0, FIT_TYPE_MICROCODE, diff --git a/util/cbfstool/fit.h b/util/cbfstool/fit.h index 6d7681f710..9df546ffa5 100644 --- a/util/cbfstool/fit.h +++ b/util/cbfstool/fit.h @@ -54,7 +54,7 @@ int fit_delete_entry(struct fit_table *fit, const size_t idx); int fit_add_microcode_file(struct fit_table *fit, - struct cbfs_image *image, + struct cbfs_image *file_source_image, const char *blob_name, fit_offset_converter_t offset_helper, const size_t max_fit_entries); diff --git a/util/cbfstool/ifittool.c b/util/cbfstool/ifittool.c index d0d9431804..d289ef746a 100644 --- a/util/cbfstool/ifittool.c +++ b/util/cbfstool/ifittool.c @@ -15,10 +15,11 @@ /* Global variables */ partitioned_file_t *image_file; -static const char *optstring = "H:j:f:r:d:t:n:s:cAaDvhF?"; +static const char *optstring = "H:j:f:r:R:d:t:n:s:cAaDvhF?"; static struct option long_options[] = { {"file", required_argument, 0, 'f' }, {"region", required_argument, 0, 'r' }, + {"file-region", required_argument, 0, 'R' }, {"add-cbfs-entry", no_argument, 0, 'a' }, {"add-region", no_argument, 0, 'A' }, {"del-entry", required_argument, 0, 'd' }, @@ -54,10 +55,12 @@ static void usage(const char *name) "\t\t-D|--dump : Dump FIT table (at end of operation)\n" "\t\t-c|--clear-table : Remove all existing entries (do not update)\n" "\t\t-j|--topswap-size : Use second FIT table if non zero\n" + "\t\t-R|--file-region : The FMAP region of the added file,\n" + "\t\t : defaults to the value of -r\n" "\tREQUIRED ARGUMENTS:\n" "\t\t-f|--file name : The file containing the CBFS\n" "\t\t-s|--max-table-size : The number of possible FIT entries in table\n" - "\t\t-r|--region : The FMAP region to operate on\n" + "\t\t-r|--region : The FMAP region of the FIT table\n" , name); } @@ -139,6 +142,7 @@ int main(int argc, char *argv[]) const char *input_file = NULL; const char *name = NULL; const char *region_name = NULL; + const char *file_region_name = NULL; enum fit_operation op = NO_OP; bool dump = false, clear_table = false; size_t max_table_size = 0; @@ -228,6 +232,9 @@ int main(int argc, char *argv[]) case 'r': region_name = optarg; break; + case 'R': + file_region_name = optarg; + break; case 's': max_table_size = atoi(optarg); break; @@ -282,7 +289,9 @@ int main(int argc, char *argv[]) op != NO_OP || clear_table); struct buffer image_region; + struct buffer file_image_region; + // Open the FIT table's region if (!partitioned_file_read_region(&image_region, image_file, region_name)) { partitioned_file_close(image_file); @@ -290,16 +299,37 @@ int main(int argc, char *argv[]) return 1; } + // If the added file region is not specified, default to the FIT table's one. + if (!file_region_name) { + file_image_region = image_region; + } else { + // Open the -n file-to-add region + if (!partitioned_file_read_region(&file_image_region, image_file, + file_region_name)) { + partitioned_file_close(image_file); + ERROR("The image will be left unmodified.\n"); + return 1; + } + } + struct buffer bootblock; // The bootblock is part of the CBFS on x86 buffer_clone(&bootblock, &image_region); + // Open the FIT table's CBFS struct cbfs_image image; if (cbfs_image_from_buffer(&image, &image_region, headeroffset)) { partitioned_file_close(image_file); return 1; } + // Open the -n file-to-add CBFS + struct cbfs_image file_source_image; + if (cbfs_image_from_buffer(&file_source_image, &file_image_region, HEADER_OFFSET_UNKNOWN)) { + partitioned_file_close(image_file); + return 1; + } + struct fit_table *fit = NULL; if (op != SET_FIT_PTR_OP) { fit = fit_get_table(&bootblock, convert_to_from_top_aligned, topswap_size); @@ -339,8 +369,8 @@ int main(int argc, char *argv[]) case ADD_CBFS_OP: { if (fit_type == FIT_TYPE_MICROCODE) { - if (fit_add_microcode_file(fit, &image, name, - convert_to_from_top_aligned, + if (fit_add_microcode_file(fit, &file_source_image, name, + convert_to_from_absolute_top_aligned, max_table_size)) { return 1; } @@ -348,7 +378,7 @@ int main(int argc, char *argv[]) uint32_t offset, len; struct cbfs_file *cbfs_file; - cbfs_file = cbfs_get_entry(&image, name); + cbfs_file = cbfs_get_entry(&file_source_image, name); if (!cbfs_file) { partitioned_file_close(image_file); ERROR("%s not found in CBFS.\n", name); @@ -356,9 +386,9 @@ int main(int argc, char *argv[]) } len = be32toh(cbfs_file->len); - offset = offset_to_ptr(convert_to_from_top_aligned, - &image.buffer, - cbfs_get_entry_addr(&image, cbfs_file) + + offset = offset_to_ptr(convert_to_from_absolute_top_aligned, + &file_source_image.buffer, + cbfs_get_entry_addr(&file_source_image, cbfs_file) + be32toh(cbfs_file->offset));