diff --git a/drivers/fwu/fwu.c b/drivers/fwu/fwu.c index 5c3ccf878..b6f06e0a7 100644 --- a/drivers/fwu/fwu.c +++ b/drivers/fwu/fwu.c @@ -181,6 +181,63 @@ exit: return result; } +/******************************************************************************* + * Check for an alternate bank for the platform to boot from. This function will + * mostly be called whenever the count of the number of times a platform boots + * in the Trial State exceeds a pre-set limit. + * The function first checks if the platform can boot from the previously active + * bank. If not, it tries to find another bank in the accepted state. + * And finally, if both the checks fail, as a last resort, it tries to find + * a valid bank. + * + * Returns the index of a bank to boot, else returns invalid index + * INVALID_BOOT_IDX. + ******************************************************************************/ +uint32_t fwu_get_alternate_boot_bank(void) +{ + uint32_t i; + + /* First check if the previously active bank can be used */ + if (metadata.bank_state[metadata.previous_active_index] == + FWU_BANK_STATE_ACCEPTED) { + return metadata.previous_active_index; + } + + /* Now check for any other bank in the accepted state */ + for (i = 0U; i < NR_OF_FW_BANKS; i++) { + if (i == metadata.active_index || + i == metadata.previous_active_index) { + continue; + } + + if (metadata.bank_state[i] == FWU_BANK_STATE_ACCEPTED) { + return i; + } + } + + /* + * No accepted bank found. Now try booting from a valid bank. + * Give priority to the previous active bank. + */ + if (metadata.bank_state[metadata.previous_active_index] == + FWU_BANK_STATE_VALID) { + return metadata.previous_active_index; + } + + for (i = 0U; i < NR_OF_FW_BANKS; i++) { + if (i == metadata.active_index || + i == metadata.previous_active_index) { + continue; + } + + if (metadata.bank_state[i] == FWU_BANK_STATE_VALID) { + return i; + } + } + + return INVALID_BOOT_IDX; +} + /******************************************************************************* * The platform can be in one of Valid, Invalid or Accepted states. * diff --git a/include/drivers/fwu/fwu.h b/include/drivers/fwu/fwu.h index 489d4a1e7..18e8a3163 100644 --- a/include/drivers/fwu/fwu.h +++ b/include/drivers/fwu/fwu.h @@ -13,8 +13,11 @@ #define FWU_BANK_STATE_VALID 0xFEU #define FWU_BANK_STATE_INVALID 0xFFU +#define INVALID_BOOT_IDX 0xFFFFFFFFU + void fwu_init(void); uint32_t fwu_get_active_bank_state(void); +uint32_t fwu_get_alternate_boot_bank(void); const struct fwu_metadata *fwu_get_metadata(void); #endif /* FWU_H */