diff options
author | Hung-Te Lin <hungte@chromium.org> | 2018-09-27 10:10:12 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-10-02 05:19:09 -0700 |
commit | 04e441e5f74e107d05578622909410259f6d6f99 (patch) | |
tree | 7b611958be3ab67d44cc994a134c384e33af9775 /futility | |
parent | 9997820ded8be4e1c94567f495d63122c88b2a03 (diff) | |
download | vboot-04e441e5f74e107d05578622909410259f6d6f99.tar.gz |
futility: updater: Add quirk 'daisy_snow_dual_model' for daisy_snow
The target AUE for daisy_snow is 74 or even longer, so we need to get a
better solution to get rid of script based updater customization (and the
painful EXTRA list in updater configuration).
The new quirk 'daisy_snow_dual_model' is assuming the input firmware image
has both daisy_snow x8 and x16 firmware packed into a single image
(because in vboot1, RW_A is identical to RW_B), and will modify A/B
contents according to target system.
BRANCH=None
BUG=chromium:881034
TEST=make futil; tests/futility/run_test_scripts.sh $(pwd)/build/futility
# Provide a fake mosys and output both MP / MPx16 to:
futility update -i bios-snow-2695.132.117-rw.bin \
--quirks daisy_snow_dual_model --emu emu.bin --sys_props 0,0x0000,0
Change-Id: I8af1b6c3117a703aed4da59902aaecb1009101f2
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1239798
Diffstat (limited to 'futility')
-rw-r--r-- | futility/updater.c | 17 | ||||
-rw-r--r-- | futility/updater.h | 26 | ||||
-rw-r--r-- | futility/updater_quirks.c | 81 |
3 files changed, 117 insertions, 7 deletions
diff --git a/futility/updater.c b/futility/updater.c index 63ed6869..d5bc88e2 100644 --- a/futility/updater.c +++ b/futility/updater.c @@ -135,7 +135,7 @@ static void strip(char *s) * If the command has failed (exit code is not zero), returns an empty string. * The caller is responsible for releasing the returned string. */ -static char *host_shell(const char *command) +char *host_shell(const char *command) { /* Currently all commands we use do not have large output. */ char buf[COMMAND_BUFFER_SIZE]; @@ -617,8 +617,7 @@ int load_image(const char *file_name, struct firmware_image *image) * Loads the active system firmware image (usually from SPI flash chip). * Returns 0 if success, non-zero if error. */ -static int load_system_image(struct updater_config *cfg, - struct firmware_image *image) +int load_system_image(struct updater_config *cfg, struct firmware_image *image) { const char *tmp_file = create_temp_file(cfg); @@ -830,16 +829,17 @@ static int write_optional_firmware(struct updater_config *cfg, return write_firmware(cfg, image, section_name); } -/* Preserves (copies) the given section (by name) from image_from to image_to. +/* + * Preserves (copies) the given section (by name) from image_from to image_to. * The offset may be different, and the section data will be directly copied. * If the section does not exist on either images, return as failure. * If the source section is larger, contents on destination be truncated. * If the source section is smaller, the remaining area is not modified. * Returns 0 if success, non-zero if error. */ -static int preserve_firmware_section(const struct firmware_image *image_from, - struct firmware_image *image_to, - const char *section_name) +int preserve_firmware_section(const struct firmware_image *image_from, + struct firmware_image *image_to, + const char *section_name) { struct firmware_section from, to; @@ -1504,6 +1504,9 @@ enum updater_error_codes update_firmware(struct updater_config *cfg) if (!image_to->data) return UPDATE_ERR_NO_IMAGE; + if (try_apply_quirk(QUIRK_DAISY_SNOW_DUAL_MODEL, cfg)) + return UPDATE_ERR_PLATFORM; + printf(">> Target image: %s (RO:%s, RW/A:%s, RW/B:%s).\n", image_to->file_name, image_to->ro_version, image_to->rw_version_a, image_to->rw_version_b); diff --git a/futility/updater.h b/futility/updater.h index 660b9649..3134bbbc 100644 --- a/futility/updater.h +++ b/futility/updater.h @@ -77,6 +77,7 @@ enum quirk_types { QUIRK_ENLARGE_IMAGE, QUIRK_MIN_PLATFORM_VERSION, QUIRK_UNLOCK_ME_FOR_UPDATE, + QUIRK_DAISY_SNOW_DUAL_MODEL, QUIRK_MAX, }; @@ -175,9 +176,27 @@ int find_firmware_section(struct firmware_section *section, const struct firmware_image *image, const char *section_name); +/* + * Preserves (copies) the given section (by name) from image_from to image_to. + * The offset may be different, and the section data will be directly copied. + * If the section does not exist on either images, return as failure. + * If the source section is larger, contents on destination be truncated. + * If the source section is smaller, the remaining area is not modified. + * Returns 0 if success, non-zero if error. + */ +int preserve_firmware_section(const struct firmware_image *image_from, + struct firmware_image *image_to, + const char *section_name); + /* Loads a firmware image from file. Returns 0 on success, otherwise failure. */ int load_image(const char *file_name, struct firmware_image *image); +/* + * Loads the active system firmware image (usually from SPI flash chip). + * Returns 0 if success, non-zero if error. + */ +int load_system_image(struct updater_config *cfg, struct firmware_image *image); + /* Frees the allocated resource from a firmware image object. */ void free_image(struct firmware_image *image); @@ -193,4 +212,11 @@ int get_system_property(enum system_property_type property_type, */ const char * const updater_get_default_quirks(struct updater_config *cfg); +/* + * Executes a command on current host and returns stripped command output. + * If the command has failed (exit code is not zero), returns an empty string. + * The caller is responsible for releasing the returned string. + */ +char *host_shell(const char *command); + #endif /* VBOOT_REFERENCE_FUTILITY_UPDATER_H_ */ diff --git a/futility/updater_quirks.c b/futility/updater_quirks.c index f65c6db9..6a3fa222 100644 --- a/futility/updater_quirks.c +++ b/futility/updater_quirks.c @@ -33,6 +33,8 @@ static const struct quirks_record quirks_records[] = { { .match = "Google_Poppy.", .quirks = "min_platform_version=6" }, { .match = "Google_Scarlet.", .quirks = "min_platform_version=1" }, + + { .match = "Google_Snow.", .quirks = "daisy_snow_dual_model" }, }; /* @@ -143,6 +145,81 @@ static int quirk_min_platform_version(struct updater_config *cfg) } /* + * Adjust firmware image according to running platform version. + * Returns 0 if success, non-zero if error. + */ +static int quirk_daisy_snow_dual_model(struct updater_config *cfg) +{ + /* + * The daisy-snow firmware should be packed as RO, RW_A=x16, RW_B=x8. + * RO update for x8 and RO EC update for all are no longer supported. + */ + struct firmware_section a, b; + int i, is_x8 = 0, is_x16 = 0; + const char * const x8_versions[] = { + "DVT", + "PVT", + "PVT2", + "MP", + }; + const char * const x16_versions[] = { + "MPx16", /* Rev 4 */ + "MP2", /* Rev 5 */ + }; + char *platform_version = host_shell("mosys platform version"); + + for (i = 0; i < ARRAY_SIZE(x8_versions) && !is_x8; i++) { + if (strcmp(x8_versions[i], platform_version) == 0) + is_x8 = 1; + } + for (i = 0; i < ARRAY_SIZE(x16_versions) && !is_x8 && !is_x16; i++) { + if (strcmp(x16_versions[i], platform_version) == 0) + is_x16 = 1; + } + printf("%s: Platform version: %s (original value: %s)\n", __FUNCTION__, + is_x8 ? "x8" : is_x16 ? "x16": "unknown", platform_version); + free(platform_version); + + find_firmware_section(&a, &cfg->image, FMAP_RW_SECTION_A); + find_firmware_section(&b, &cfg->image, FMAP_RW_SECTION_B); + + if (cfg->ec_image.data) { + ERROR("EC RO update is not supported with this quirk."); + return -1; + } + if (!a.data || !b.data || a.size != b.size) { + ERROR("Invalid firmware image: %s", cfg->image.file_name); + return -1; + } + if (memcmp(a.data, b.data, a.size) == 0) { + ERROR("Input image must have both x8 and x16 firmware."); + return -1; + } + + if (is_x16) { + memmove(b.data, a.data, a.size); + free(cfg->image.rw_version_b); + cfg->image.rw_version_b = strdup(cfg->image.rw_version_a); + } else if (is_x8) { + memmove(a.data, b.data, b.size); + free(cfg->image.rw_version_a); + cfg->image.rw_version_a = strdup(cfg->image.rw_version_b); + /* Need to use RO from current system. */ + if (!cfg->image_current.data && + load_system_image(cfg, &cfg->image_current) != 0) { + ERROR("Cannot get system RO contents"); + return -1; + } + preserve_firmware_section(&cfg->image_current, &cfg->image, + FMAP_RO_SECTION); + } else { + ERROR("Unknown platform, cannot update."); + return -1; + } + return 0; +} + +/* * Registers known quirks to a updater_config object. */ void updater_register_quirks(struct updater_config *cfg) @@ -167,6 +244,10 @@ void updater_register_quirks(struct updater_config *cfg) "board-postinst."; quirks->apply = quirk_unlock_me_for_update; + quirks = &cfg->quirks[QUIRK_DAISY_SNOW_DUAL_MODEL]; + quirks->name = "daisy_snow_dual_model"; + quirks->help = "b/35525858; needs an image RW A=[model x16], B=x8."; + quirks->apply = quirk_daisy_snow_dual_model; } /* |