From a59bc9507265e70908ae770e9d1664ff18be0fa1 Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Wed, 15 Feb 2023 11:28:51 +0800 Subject: futility: flashrom_drv: Support partial read for multiple regions Similar to CL:3490388, support flashrom read for multiple regions. BUG=b:260531154 TEST=emerge-corsola vboot_reference BRANCH=none Change-Id: I1f75832f882004e879bc299be6862db089c2b71d Signed-off-by: Yu-Ping Wu Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/4251503 Reviewed-by: Hung-Te Lin --- futility/cmd_gbb_utility.c | 5 +++-- host/lib/flashrom_drv.c | 39 ++++++++++++++++++++++++++------------- host/lib/include/flashrom.h | 21 +++++++++++++-------- 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/futility/cmd_gbb_utility.c b/futility/cmd_gbb_utility.c index a34e9aa4..95c1a47d 100644 --- a/futility/cmd_gbb_utility.c +++ b/futility/cmd_gbb_utility.c @@ -417,8 +417,9 @@ static void teardown_flash(struct updater_config *cfg, static uint8_t *read_from_flash(struct updater_config *cfg, off_t *filesize) { #ifdef USE_FLASHROM - if (flashrom_read_image(&cfg->image_current, FMAP_RO_GBB, - cfg->verbosity + 1)) + const char * const regions[] = {FMAP_RO_GBB, NULL}; + if (flashrom_read_image(&cfg->image_current, regions, + cfg->verbosity + 1)) return NULL; uint8_t *ret = cfg->image_current.data; cfg->image_current.data = NULL; diff --git a/host/lib/flashrom_drv.c b/host/lib/flashrom_drv.c index d30d1dec..8acd3be7 100644 --- a/host/lib/flashrom_drv.c +++ b/host/lib/flashrom_drv.c @@ -46,13 +46,19 @@ static char *flashrom_extract_params(const char *str, char **prog, char **params return tmp; } +/* + * NOTE: When `regions` contains multiple regions, `region_start` and + * `region_len` will be filled with the data of the first region. + */ static int flashrom_read_image_impl(struct firmware_image *image, - const char *region, + const char * const regions[], unsigned int *region_start, unsigned int *region_len, int verbosity) { int r = 0; size_t len = 0; + *region_start = 0; + *region_len = 0; g_verbose_screen = (verbosity == -1) ? FLASHROM_MSG_INFO : verbosity; @@ -79,7 +85,8 @@ static int flashrom_read_image_impl(struct firmware_image *image, flashrom_flag_set(flashctx, FLASHROM_FLAG_SKIP_UNREADABLE_REGIONS, true); - if (region) { + if (regions) { + int i; r = flashrom_layout_read_fmap_from_rom( &layout, flashctx, 0, len); if (r > 0) { @@ -87,12 +94,15 @@ static int flashrom_read_image_impl(struct firmware_image *image, r = -1; goto err_cleanup; } - // empty region causes seg fault in API. - r |= flashrom_layout_include_region(layout, region); - if (r > 0) { - ERROR("could not include region = '%s'\n", region); - r = -1; - goto err_cleanup; + for (i = 0; regions[i]; i++) { + // empty region causes seg fault in API. + r |= flashrom_layout_include_region(layout, regions[i]); + if (r > 0) { + ERROR("could not include region = '%s'\n", + regions[i]); + r = -1; + goto err_cleanup; + } } flashrom_layout_set(flashctx, layout); } @@ -103,8 +113,8 @@ static int flashrom_read_image_impl(struct firmware_image *image, r |= flashrom_image_read(flashctx, image->data, len); - if (r == 0 && region) - r |= flashrom_layout_get_region_range(layout, region, + if (r == 0 && regions && regions[0]) + r |= flashrom_layout_get_region_range(layout, regions[0], region_start, region_len); err_cleanup: @@ -119,18 +129,21 @@ err_init: return r; } -int flashrom_read_image(struct firmware_image *image, const char *region, +int flashrom_read_image(struct firmware_image *image, + const char * const regions[], int verbosity) { unsigned int start, len; - return flashrom_read_image_impl(image, region, &start, &len, verbosity); + return flashrom_read_image_impl(image, regions, &start, &len, + verbosity); } int flashrom_read_region(struct firmware_image *image, const char *region, int verbosity) { + const char * const regions[] = {region, NULL}; unsigned int start, len; - int r = flashrom_read_image_impl(image, region, &start, &len, + int r = flashrom_read_image_impl(image, regions, &start, &len, verbosity); if (r != 0) return r; diff --git a/host/lib/include/flashrom.h b/host/lib/include/flashrom.h index e7eda28a..0c1b3716 100644 --- a/host/lib/include/flashrom.h +++ b/host/lib/include/flashrom.h @@ -30,21 +30,26 @@ struct firmware_image { }; /** - * Read using flashrom into an allocated buffer. flashrom_read subprocesses the - * flashrom binary and returns a buffer truncated to the region. - * flashrom_read_image will read the return a full sized buffer with only the - * region filled with data. flashrom_read_region will return the buffer - * truncated to the region. + * Read using flashrom into an allocated buffer. + * + * flashrom_read subprocesses the flashrom binary and returns a buffer truncated + * to the region. + * + * flashrom_read_image reads the returns a full sized buffer with only the + * regions filled with data. + * + * flashrom_read_region returns the buffer truncated to the region. * * @param image The parameter that contains the programmer, buffer and * size to use in the read operation. - * @param region The name of the fmap region to read, or NULL to - * read the entire flash chip. + * @param regions A list of the names of the fmap regions to read, or NULL + * to read the entire flash chip. * * @return VB2_SUCCESS on success, or a relevant error. */ vb2_error_t flashrom_read(struct firmware_image *image, const char *region); -int flashrom_read_image(struct firmware_image *image, const char *region, +int flashrom_read_image(struct firmware_image *image, + const char * const regions[], int verbosity); int flashrom_read_region(struct firmware_image *image, const char *region, int verbosity); -- cgit v1.2.1