mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 09:34:18 +00:00
Merge changes from topic "st_fwu_bkp_reg" into integration
* changes: feat(stm32mp1): retry 3 times FWU trial boot refactor(stm32mp1): update backup reg for FWU
This commit is contained in:
commit
5b44657a97
4 changed files with 86 additions and 15 deletions
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
******************************************************************************/
|
||||
|
|
|
@ -46,7 +46,16 @@
|
|||
#define TAMP_BOOT_MODE_ITF_MASK U(0x0000FF00)
|
||||
#define TAMP_BOOT_MODE_ITF_SHIFT 8
|
||||
|
||||
#define TAMP_BOOT_COUNTER_REG_ID U(21)
|
||||
/*
|
||||
* Backup register to store fwu update information.
|
||||
* It should be writeable only by secure world, but also readable by non secure
|
||||
* (so it should be in Zone 2).
|
||||
*/
|
||||
#define TAMP_BOOT_FWU_INFO_REG_ID U(10)
|
||||
#define TAMP_BOOT_FWU_INFO_IDX_MSK U(0xF)
|
||||
#define TAMP_BOOT_FWU_INFO_IDX_OFF U(0)
|
||||
#define TAMP_BOOT_FWU_INFO_CNT_MSK U(0xF0)
|
||||
#define TAMP_BOOT_FWU_INFO_CNT_OFF U(4)
|
||||
|
||||
#if defined(IMAGE_BL2)
|
||||
#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
|
||||
|
@ -733,8 +742,41 @@ void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
|
|||
void stm32mp1_fwu_set_boot_idx(void)
|
||||
{
|
||||
clk_enable(RTCAPB);
|
||||
mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID),
|
||||
plat_fwu_get_boot_idx());
|
||||
mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
|
||||
TAMP_BOOT_FWU_INFO_IDX_MSK,
|
||||
(plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
|
||||
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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue