feat(stm32mp1): retry 3 times FWU trial boot

If we reboot 3 times in trial mode, BL2 will select previous boot image.

Signed-off-by: Nicolas Toromanoff <nicolas.toromanoff@foss.st.com>
Change-Id: I82b423cc84f0471fdb6fa7c393fc5fe411d25c06
This commit is contained in:
Nicolas Toromanoff 2022-02-07 10:12:04 +01:00 committed by Yann Gautier
parent e633f9c52f
commit f87de907c8
4 changed files with 72 additions and 12 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -485,22 +485,46 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
/*
* Eventually, this function will return the
* boot index to be passed on to the Update
* Agent after performing certain checks like
* a watchdog timeout, or Auth failure while
* trying to load from a certain bank.
* For now, since we do not have that logic
* implemented, just pass the active_index
* read from the metadata.
* In each boot in non-trial mode, we set the BKP register to
* FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata.
*
* As long as the update agent didn't update the "accepted" field in metadata
* (i.e. we are in trial mode), we select the new active_index.
* To avoid infinite boot loop at trial boot we decrement a BKP register.
* If this counter is 0:
* - an unexpected TAMPER event raised (that resets the BKP registers to 0)
* - a power-off occurs before the update agent was able to update the
* "accepted' field
* - we already boot FWU_MAX_TRIAL_REBOOT times in trial mode.
* we select the previous_active_index.
*/
#define INVALID_BOOT_IDX 0xFFFFFFFF
uint32_t plat_fwu_get_boot_idx(void)
{
const struct fwu_metadata *metadata;
/*
* Select boot index and update boot counter only once per boot
* even if this function is called several times.
*/
static uint32_t boot_idx = INVALID_BOOT_IDX;
const struct fwu_metadata *data;
metadata = fwu_get_metadata();
data = fwu_get_metadata();
return metadata->active_index;
if (boot_idx == INVALID_BOOT_IDX) {
boot_idx = data->active_index;
if (fwu_is_trial_run_state()) {
if (stm32_get_and_dec_fwu_trial_boot_cnt() == 0U) {
WARN("Trial FWU fails %u times\n",
FWU_MAX_TRIAL_REBOOT);
boot_idx = data->previous_active_index;
}
} else {
stm32_set_max_fwu_trial_boot_cnt();
}
}
return boot_idx;
}
static void *stm32_get_image_spec(const uuid_t *img_type_uuid)

View File

@ -129,6 +129,8 @@ void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance);
#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
void stm32mp1_fwu_set_boot_idx(void);
uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void);
void stm32_set_max_fwu_trial_boot_cnt(void);
#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
#endif /* STM32MP_COMMON_H */

View File

@ -511,6 +511,9 @@ enum ddr_type {
/* UID OTP */
#define UID_WORD_NB U(3)
/* FWU configuration (max supported value is 15) */
#define FWU_MAX_TRIAL_REBOOT U(3)
/*******************************************************************************
* STM32MP1 TAMP
******************************************************************************/

View File

@ -748,4 +748,35 @@ void stm32mp1_fwu_set_boot_idx(void)
TAMP_BOOT_FWU_INFO_IDX_MSK);
clk_disable(RTCAPB);
}
uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
{
uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
uint32_t try_cnt;
clk_enable(RTCAPB);
try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
TAMP_BOOT_FWU_INFO_CNT_OFF;
assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
if (try_cnt != 0U) {
mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
(try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
}
clk_disable(RTCAPB);
return try_cnt;
}
void stm32_set_max_fwu_trial_boot_cnt(void)
{
uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
clk_enable(RTCAPB);
mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
(FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
TAMP_BOOT_FWU_INFO_CNT_MSK);
clk_disable(RTCAPB);
}
#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */