When boot_idx differs from active_idx at boot time, it indicates a rollback scenario where the firmware update failed and the system reverted to the previous working bank. In this case, mark the failed bank (active_idx) as invalid to prevent future boot attempts from that bank.
This change adds a new fwu_invalid_bank() function that sets the bank state to FWU_BANK_INVALID and syncs the metadata. This is only supported in FWU metadata version 2; version 1 provides a no-op stub. Without this change, a failed bank would remain in a valid state and could potentially be selected for boot again, leading to repeated boot failures. Signed-off-by: Kory Maincent <[email protected]> --- include/fwu.h | 8 ++++++++ lib/fwu_updates/fwu.c | 1 + lib/fwu_updates/fwu_v1.c | 10 ++++++++++ lib/fwu_updates/fwu_v2.c | 19 +++++++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/include/fwu.h b/include/fwu.h index e7bd1d492af..e4f3a062e36 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -415,6 +415,14 @@ int fwu_get_mdata_size(uint32_t *mdata_size); */ int fwu_state_machine_updates(bool trial_state, uint32_t update_index); +/** + * fwu_invalid_bank() - Invalid bank state of a specific bank + * @index: Index of the bank + * + * Only supported in version 2 of FWU metadata. + */ +void fwu_invalid_bank(uint32_t index); + /** * fwu_init() - FWU specific initialisations * diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c index 0f5ef2ba515..e54c19b0c64 100644 --- a/lib/fwu_updates/fwu.c +++ b/lib/fwu_updates/fwu.c @@ -766,6 +766,7 @@ static int fwu_boottime_checks(void) if (boot_idx != active_idx) { log_info("Boot idx %u is not matching active idx %u, changing active_idx\n", boot_idx, active_idx); + fwu_invalid_bank(active_idx); ret = fwu_set_active_index(boot_idx); if (!ret) boottime_check = 1; diff --git a/lib/fwu_updates/fwu_v1.c b/lib/fwu_updates/fwu_v1.c index 974abf216f6..c9ac1ec244d 100644 --- a/lib/fwu_updates/fwu_v1.c +++ b/lib/fwu_updates/fwu_v1.c @@ -136,6 +136,16 @@ int fwu_get_mdata_size(uint32_t *mdata_size) return 0; } +/** + * fwu_invalid_bank() - Invalid bank state of a specific bank + * @index: Index of the bank + * + * Not supported. + */ +void fwu_invalid_bank(uint32_t index) +{ +} + /** * fwu_init() - FWU specific initialisations * diff --git a/lib/fwu_updates/fwu_v2.c b/lib/fwu_updates/fwu_v2.c index 159315b45b9..3c07adfd4e0 100644 --- a/lib/fwu_updates/fwu_v2.c +++ b/lib/fwu_updates/fwu_v2.c @@ -194,6 +194,25 @@ int fwu_state_machine_updates(bool trial_state, uint32_t update_index) fwu_bank_state_update(0, update_index); } +/** + * fwu_invalid_bank() - Invalid bank state of a specific bank + * @index: Index of the bank + */ +void fwu_invalid_bank(uint32_t index) +{ + struct fwu_data *data = fwu_get_data(); + struct fwu_mdata *mdata; + int ret; + + mdata = data->fwu_mdata; + data->bank_state[index] = FWU_BANK_INVALID; + mdata->bank_state[index] = FWU_BANK_INVALID; + + ret = fwu_sync_mdata(mdata, BOTH_PARTS); + if (ret) + log_err("Unable to invalid bank %u\n", index); +} + /** * fwu_get_mdata_size() - Get the FWU metadata size * @mdata_size: Size of the metadata structure -- 2.43.0

