summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHung-Te Lin <hungte@chromium.org>2018-09-27 10:10:12 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-10-02 05:19:09 -0700
commit04e441e5f74e107d05578622909410259f6d6f99 (patch)
tree7b611958be3ab67d44cc994a134c384e33af9775
parent9997820ded8be4e1c94567f495d63122c88b2a03 (diff)
downloadvboot-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
-rw-r--r--futility/updater.c17
-rw-r--r--futility/updater.h26
-rw-r--r--futility/updater_quirks.c81
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;
}
/*