Rizwan Qureshi has uploaded this change for review. ( https://review.coreboot.org/26836
Change subject: cbfstool: Update FIT entries in the second bootblock ......................................................................
cbfstool: Update FIT entries in the second bootblock
Once a second bootblock has been added using topswap (-j) option, Update the entries in second FIT using -j option with update-fit command. Additionally add a -q option which allows to insert the address of a FMAP region (which should hold a microcode) as the last entry in the second FIT.
BUG=None BRANCH=None TEST= Create ROM images with -j options and update FIT using -q option. example: ./build/util/cbfstool/cbfstool coreboot.tmp create \ -M build/fmap.fmap -r COREBOOT,FW_MAIN_A,FW_MAIN_B,RW_LEGACY build/util/cbfstool/cbfstool coreboot.tmp add \ -f build/cbfs/fallback/bootblock.bin -n bootblock -t \ bootblock -b -49152 -j 0x10000 build/util/cbfstool/cbfstool coreboot.tmp add-master-header -j 0x10000 build/util/cbfstool/cbfstool coreboot.tmp add -f build/cpu_microcode_blob.bin \ -n cpu_microcode_blob.bin -t microcode -r COREBOOT -a 16 build/util/cbfstool/cbfstool coreboot.tmp. update-fit \ -n cpu_microcode_blob.bin -x 4 -j 0x10000 -q FW_MAIN_A
Also try the failure scenarion by providing invalid topswap size.
Change-Id: I9a417031c279038903cdf1761a791f2da0fe8644 Signed-off-by: Rizwan Qureshi rizwan.qureshi@intel.com --- M util/cbfstool/cbfstool.c M util/cbfstool/fit.c M util/cbfstool/fit.h 3 files changed, 97 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/36/26836/1
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index 30873d4..a2ce4b6 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -58,6 +58,7 @@ const char *source_region; const char *bootblock; const char *ignore_section; + const char *ucode_region; uint64_t u64val; uint32_t type; uint32_t baseaddress; @@ -1204,6 +1205,51 @@ return buffer_write_file(param.image_region, param.filename); }
+ +static int update_secondary_fit(struct cbfs_image *image) +{ + if (!is_valid_topswap()) + return 1; + + int32_t num_entries = param.fit_empty_entries; + /* If a forced entry is provided add one extra row */ + if (param.ucode_region) + num_entries++; + + struct buffer bootblock2; + buffer_splice(&bootblock2, param.image_region, 0, + param.image_region->size - param.topswap_size); + + if (fit_update_table(&bootblock2, image, param.name, + num_entries, + convert_to_from_top_aligned)) { + ERROR("Couldn't update FIT in second bootblock\n"); + return 1; + } + + /* + * Now insert the provided region address at the + * available empty row. + */ + if (param.ucode_region) { + uint32_t addr; + struct buffer ucode; + + if (partitioned_file_read_region(&ucode, + param.image_file, param.ucode_region)) + addr = -convert_to_from_top_aligned(&ucode, 0); + else + return 1; + + if (fit_insert_entry(&bootblock2, num_entries, addr, + convert_to_from_top_aligned)) { + ERROR("Couldn't insert into second FIT\n"); + return 1; + } + } + return 0; +} + static int cbfs_update_fit(void) { if (!param.name) { @@ -1229,6 +1275,11 @@ if (fit_update_table(&bootblock, &image, param.name, param.fit_empty_entries, convert_to_from_top_aligned)) return 1; + /* Update second bootblock */ + if (param.topswap_size) { + if (update_secondary_fit(&image)) + return 1; + }
// The region to be written depends on the type of image, so we write it // here rather than having main() write the CBFS region back as usual. @@ -1317,7 +1368,7 @@ {"print", "H:r:vkh?", cbfs_print, true, false}, {"read", "r:f:vh?", cbfs_read, true, false}, {"remove", "H:r:n:vh?", cbfs_remove, true, true}, - {"update-fit", "H:r:n:x:vh?", cbfs_update_fit, true, true}, + {"update-fit", "H:r:n:x:vh?j:q:", cbfs_update_fit, true, true}, {"write", "r:f:i:Fudvh?", cbfs_write, true, true}, {"expand", "r:h?", cbfs_expand, true, true}, {"truncate", "r:h?", cbfs_truncate, true, true}, @@ -1351,6 +1402,7 @@ {"offset", required_argument, 0, 'o' }, {"padding", required_argument, 0, 'p' }, {"page-size", required_argument, 0, 'P' }, + {"ucode-region", required_argument, 0, 'q' }, {"size", required_argument, 0, 's' }, {"top-aligned", required_argument, 0, 'T' }, {"type", required_argument, 0, 't' }, @@ -1480,6 +1532,7 @@ "Expand CBFS to span entire region\n" " update-fit [-r image,regions] -n MICROCODE_BLOB_NAME \\n" " -x EMTPY_FIT_ENTRIES " + " [-j topswap-size [-q ucode-region]] (Intel CPUs only)" "Updates the FIT table with microcode entries\n" "\n" "OFFSETs:\n" @@ -1733,6 +1786,9 @@ param.topswap_size = strtol(optarg, NULL, 0); break; + case 'q': + param.ucode_region = optarg; + break; case 'v': verbose++; break; diff --git a/util/cbfstool/fit.c b/util/cbfstool/fit.c index e3e6c32..b2e9d30 100644 --- a/util/cbfstool/fit.c +++ b/util/cbfstool/fit.c @@ -145,7 +145,7 @@
/* Assume that the FIT table only contains the header */ if (fit_entry_size_bytes(&table->header) != sizeof(struct fit_entry)) - return NULL; + WARN("FIT contains header already\n");
return table; } @@ -252,6 +252,43 @@ return 0; }
+int fit_insert_entry(struct buffer *bootblock, int empty_entries, + uint32_t addr, fit_offset_converter_t offset_fn) +{ + struct fit_table *fit; + int i, inserted = 0; + + fit = locate_fit_table(offset_fn, bootblock); + + if (!fit) { + ERROR("FIT not found.\n"); + return 1; + } + + for (i = 0; i < empty_entries; i++) { + struct fit_entry *entry = &fit->entries[i]; + + if (entry->address == 0) { + entry->address = addr; + entry->size_reserved = 0x0000; /* doesn't matter */ + entry->type_checksum_valid = FIT_TYPE_MICROCODE; + entry->checksum = 0; + fit_entry_add_size(&fit->header, + sizeof(struct fit_entry)); + inserted = 1; + break; + } + } + + if (!inserted) { + ERROR("No Empty entries found!\n"); + return 1; + } + + update_fit_checksum(fit); + return 0; +} + int fit_update_table(struct buffer *bootblock, struct cbfs_image *image, const char *microcode_blob_name, int empty_entries, fit_offset_converter_t offset_fn) diff --git a/util/cbfstool/fit.h b/util/cbfstool/fit.h index 5f1b80b..d425590 100644 --- a/util/cbfstool/fit.h +++ b/util/cbfstool/fit.h @@ -31,4 +31,6 @@ int fit_update_table(struct buffer *bootblock, struct cbfs_image *image, const char *microcode_blob_name, int empty_entries, fit_offset_converter_t offset_fn); +int fit_insert_entry(struct buffer *bootblock, int empty_entries, + uint32_t addr, fit_offset_converter_t offset_fn); #endif