diff options
-rw-r--r-- | futility/updater.c | 20 | ||||
-rw-r--r-- | futility/updater.h | 1 | ||||
-rw-r--r-- | futility/updater_quirks.c | 51 | ||||
-rw-r--r-- | futility/updater_utils.c | 17 | ||||
-rw-r--r-- | futility/updater_utils.h | 5 |
5 files changed, 77 insertions, 17 deletions
diff --git a/futility/updater.c b/futility/updater.c index e6ba3443..c0a500fc 100644 --- a/futility/updater.c +++ b/futility/updater.c @@ -581,23 +581,6 @@ static int section_needs_update(const struct firmware_image *image_from, } /* - * Returns true if the write protection is enabled on current system. - */ -static int is_write_protection_enabled(struct updater_config *cfg) -{ - /* Default to enabled. */ - int wp = get_system_property(SYS_PROP_WP_HW, cfg); - if (wp == WP_DISABLED) - return wp; - /* For error or enabled, check WP SW. */ - wp = get_system_property(SYS_PROP_WP_SW, cfg); - /* Consider all errors as enabled. */ - if (wp != WP_DISABLED) - return WP_ENABLED; - return wp; -} - -/* * Checks if the given firmware images are compatible with current platform. * In current implementation (following Chrome OS style), we assume the platform * is identical to the name before a dot (.) in firmware version. @@ -1227,6 +1210,9 @@ enum updater_error_codes update_firmware(struct updater_config *cfg) if (try_apply_quirk(QUIRK_EVE_SMM_STORE, cfg)) return UPDATE_ERR_INVALID_IMAGE; + if (try_apply_quirk(QUIRK_CLEAR_MRC_DATA, cfg)) + return UPDATE_ERR_SYSTEM_IMAGE; + if (debugging_enabled) print_system_properties(cfg); diff --git a/futility/updater.h b/futility/updater.h index 768beece..cedeb302 100644 --- a/futility/updater.h +++ b/futility/updater.h @@ -51,6 +51,7 @@ enum quirk_types { QUIRK_NO_VERIFY, QUIRK_EXTRA_RETRIES, QUIRK_EXTERNAL_FLASHROM, + QUIRK_CLEAR_MRC_DATA, QUIRK_MAX, }; diff --git a/futility/updater_quirks.c b/futility/updater_quirks.c index dab86ec8..4975997a 100644 --- a/futility/updater_quirks.c +++ b/futility/updater_quirks.c @@ -424,6 +424,52 @@ static int quirk_preserve_me(struct updater_config *cfg) return 1; } +static int quirk_clear_mrc_data(struct updater_config *cfg) +{ + struct firmware_section section; + struct firmware_image *image = &cfg->image_current; + int i, count = 0; + int flash_now = 0; + + /* + * Devices with multiple MRC caches (RECOVERY, RW, RW_VAR) will have the + * UNIFIED_MRC_CACHE; and devices with single RW cache will only have + * RW_MRC_CACHE (for example MediaTek devices). + */ + const char * const mrc_names[] = { + "UNIFIED_MRC_CACHE", + "RW_MRC_CACHE", + }; + + if (is_write_protection_enabled(cfg) || cfg->try_update) + flash_now = 1; + + for (i = 0; i < ARRAY_SIZE(mrc_names); i++) { + const char *name = mrc_names[i]; + const char *write_names[2] = {0}; + + find_firmware_section(§ion, image, name); + if (!section.size) + continue; + + WARN("Wiping memory training data: %s\n", name); + memset(section.data, 0xff, section.size); + if (flash_now) { + write_names[0] = name; + write_system_firmware(cfg, image, write_names); + } + count++; + break; + } + + if (count) + WARN("Next boot will take a few mins for memory training.\n"); + else + ERROR("No known memory training data in the firmware image.\n"); + + return 0; +} + /* * Disable checking platform compatibility. */ @@ -522,6 +568,11 @@ void updater_register_quirks(struct updater_config *cfg) quirks->name = "external_flashrom"; quirks->help = "Use external flashrom to access the system firmware."; quirks->apply = NULL; /* Simple config. */ + + quirks = &cfg->quirks[QUIRK_CLEAR_MRC_DATA]; + quirks->name = "clear_mrc_data"; + quirks->help = "b/255617349: Clear memory training data (MRC)."; + quirks->apply = quirk_clear_mrc_data; } /* diff --git a/futility/updater_utils.c b/futility/updater_utils.c index 8895c094..cb7ac604 100644 --- a/futility/updater_utils.c +++ b/futility/updater_utils.c @@ -359,6 +359,23 @@ const struct vb2_gbb_header *find_gbb(const struct firmware_image *image) } /* + * Returns true if the write protection is enabled on current system. + */ +int is_write_protection_enabled(struct updater_config *cfg) +{ + /* Default to enabled. */ + int wp = get_system_property(SYS_PROP_WP_HW, cfg); + if (wp == WP_DISABLED) + return wp; + /* For error or enabled, check WP SW. */ + wp = get_system_property(SYS_PROP_WP_SW, cfg); + /* Consider all errors as enabled. */ + if (wp != WP_DISABLED) + return WP_ENABLED; + return wp; +} + +/* * 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. diff --git a/futility/updater_utils.h b/futility/updater_utils.h index a0dfc912..a5d012b8 100644 --- a/futility/updater_utils.h +++ b/futility/updater_utils.h @@ -176,6 +176,11 @@ void strip_string(char *s, const char *pattern); int save_file_from_stdin(const char *output); /* + * Returns true if the write protection is enabled on current system. + */ +int is_write_protection_enabled(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. |