Merge changes from topic "topics/fwu_metadata_v2_migration" into integration
* changes:
style(fwu): change the metadata fields to align with specification
style(partition): use GUID values for GPT partition fields
feat(st): add logic to boot the platform from an alternate bank
feat(st): add a function to clear the FWU trial state counter
feat(fwu): add a function to obtain an alternate FWU bank to boot
feat(fwu): add some sanity checks for the FWU metadata
feat(fwu): modify the check for getting the FWU bank's state
feat(st): get the state of the active bank directly
feat(fwu): add a config flag for including image info in the FWU metadata
feat(fwu): migrate FWU metadata structure to version 2
feat(fwu): document the config flag for including image info in the FWU metadata
feat(fwu): update the URL links for the FWU specification
diff --git a/Makefile b/Makefile
index 6a1ea99..53d391e 100644
--- a/Makefile
+++ b/Makefile
@@ -1185,6 +1185,7 @@
COT_DESC_IN_DTB \
USE_SP804_TIMER \
PSA_FWU_SUPPORT \
+ PSA_FWU_METADATA_FW_STORE_DESC \
ENABLE_MPMM \
ENABLE_MPMM_FCONF \
FEATURE_DETECTION \
@@ -1360,6 +1361,7 @@
NR_OF_FW_BANKS \
NR_OF_IMAGES_IN_FW_BANK \
PSA_FWU_SUPPORT \
+ PSA_FWU_METADATA_FW_STORE_DESC \
ENABLE_BRBE_FOR_NS \
ENABLE_TRBE_FOR_NS \
ENABLE_SYS_REG_TRACE_FOR_NS \
diff --git a/docs/components/firmware-update.rst b/docs/components/firmware-update.rst
index 1ba1e1c..eda7852 100644
--- a/docs/components/firmware-update.rst
+++ b/docs/components/firmware-update.rst
@@ -494,4 +494,4 @@
.. _Universally Unique Identifier: https://tools.ietf.org/rfc/rfc4122.txt
.. |Flow Diagram| image:: ../resources/diagrams/fwu_flow.png
.. |FWU state machine| image:: ../resources/diagrams/fwu_states.png
-.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/latest/
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 37545ce..a8b40ad 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -1340,12 +1340,21 @@
This flag is used in defining the firmware update metadata structure. This
flag is by default set to '1'.
+- ``PSA_FWU_METADATA_FW_STORE_DESC``: To be enabled when the FWU
+ metadata contains image description. The default value is 1.
+
+ The version 2 of the FWU metadata allows for an opaque metadata
+ structure where a platform can choose to not include the firmware
+ store description in the metadata structure. This option indicates
+ if the firmware store description, which provides information on
+ the updatable images is part of the structure.
+
--------------
*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
.. _DEN0115: https://developer.arm.com/docs/den0115/latest
-.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/latest/
.. _PSA DRTM specification: https://developer.arm.com/documentation/den0113/a
.. _GCC: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
.. _Clang: https://clang.llvm.org/docs/DiagnosticsReference.html
diff --git a/docs/index.rst b/docs/index.rst
index cdb237a..c05c0a5 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -95,4 +95,4 @@
.. _System Control and Management Interface (SCMI): http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf
.. _Software Delegated Exception Interface (SDEI): http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
-.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/latest/
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 608866c..8c5ff9d 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -328,7 +328,6 @@
unsigned int data_len, len, i;
unsigned int plat_nv_ctr;
int rc;
- bool is_trial_run = false;
/* Get the counter value from current image. The AM expects the IPM
* to return the counter value as a DER encoded integer */
@@ -388,9 +387,14 @@
return 1;
} else if (*cert_nv_ctr > plat_nv_ctr) {
#if PSA_FWU_SUPPORT && IMAGE_BL2
- is_trial_run = fwu_is_trial_run_state();
+ if (fwu_get_active_bank_state() == FWU_BANK_STATE_ACCEPTED) {
+ *need_nv_ctr_upgrade = true;
+ } else {
+ *need_nv_ctr_upgrade = false;
+ }
+#else
+ *need_nv_ctr_upgrade = true;
#endif /* PSA_FWU_SUPPORT && IMAGE_BL2 */
- *need_nv_ctr_upgrade = !is_trial_run;
}
return 0;
diff --git a/drivers/fwu/fwu.c b/drivers/fwu/fwu.c
index ff432be..b6f06e0 100644
--- a/drivers/fwu/fwu.c
+++ b/drivers/fwu/fwu.c
@@ -24,6 +24,17 @@
CASSERT((offsetof(struct fwu_metadata, crc_32) == 0),
crc_32_must_be_first_member_of_structure);
+/*
+ * Ensure that the NR_OF_FW_BANKS selected by the platform is not
+ * zero and not greater than the maximum number of banks allowed
+ * by the specification.
+ */
+CASSERT((NR_OF_FW_BANKS > 0) && (NR_OF_FW_BANKS <= NR_OF_MAX_FW_BANKS),
+ assert_fwu_num_banks_invalid_value);
+
+#define FWU_METADATA_VERSION 2U
+#define FWU_FW_STORE_DESC_OFFSET 0x20U
+
static struct fwu_metadata metadata;
static bool is_metadata_initialized __unused;
@@ -51,16 +62,54 @@
/*******************************************************************************
* Check the sanity of FWU metadata.
*
- * return -1 on error, otherwise 0
+ * return -EINVAL on error, otherwise 0
******************************************************************************/
static int fwu_metadata_sanity_check(void)
{
- /* ToDo: add more conditions for sanity check */
- if ((metadata.active_index >= NR_OF_FW_BANKS) ||
- (metadata.previous_active_index >= NR_OF_FW_BANKS)) {
- return -1;
+ if (metadata.version != FWU_METADATA_VERSION) {
+ WARN("Incorrect FWU Metadata version of %u\n",
+ metadata.version);
+ return -EINVAL;
+ }
+
+ if (metadata.active_index >= NR_OF_FW_BANKS) {
+ WARN("Active Index value(%u) greater than the configured value(%d)",
+ metadata.active_index, NR_OF_FW_BANKS);
+ return -EINVAL;
+ }
+
+ if (metadata.previous_active_index >= NR_OF_FW_BANKS) {
+ WARN("Previous Active Index value(%u) greater than the configured value(%d)",
+ metadata.previous_active_index, NR_OF_FW_BANKS);
+ return -EINVAL;
+ }
+
+#if PSA_FWU_METADATA_FW_STORE_DESC
+ if (metadata.fw_desc.num_banks != NR_OF_FW_BANKS) {
+ WARN("Number of Banks(%u) in FWU Metadata different from the configured value(%d)",
+ metadata.fw_desc.num_banks, NR_OF_FW_BANKS);
+ return -EINVAL;
}
+ if (metadata.fw_desc.num_images != NR_OF_IMAGES_IN_FW_BANK) {
+ WARN("Number of Images(%u) in FWU Metadata different from the configured value(%d)",
+ metadata.fw_desc.num_images, NR_OF_IMAGES_IN_FW_BANK);
+ return -EINVAL;
+ }
+
+ if (metadata.desc_offset != FWU_FW_STORE_DESC_OFFSET) {
+ WARN("Descriptor Offset(0x%x) in the FWU Metadata not equal to 0x20\n",
+ metadata.desc_offset);
+ return -EINVAL;
+ }
+#else
+ if (metadata.desc_offset != 0U) {
+ WARN("Descriptor offset has non zero value of 0x%x\n",
+ metadata.desc_offset);
+ return -EINVAL;
+ }
+#endif
+
return 0;
}
@@ -133,28 +182,80 @@
}
/*******************************************************************************
- * The system runs in the trial run state if any of the images in the active
- * firmware bank has not been accepted yet.
+ * 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 true if the system is running in the trial state.
+ * Returns the index of a bank to boot, else returns invalid index
+ * INVALID_BOOT_IDX.
******************************************************************************/
-bool fwu_is_trial_run_state(void)
+uint32_t fwu_get_alternate_boot_bank(void)
{
- bool trial_run = false;
+ uint32_t i;
- assert(is_metadata_initialized);
+ /* 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;
+ }
- for (unsigned int i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
- struct fwu_image_entry *entry = &metadata.img_entry[i];
- struct fwu_image_properties *img_props =
- &entry->img_props[metadata.active_index];
- if (img_props->accepted == 0) {
- trial_run = true;
- break;
+ /* 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;
}
}
- return trial_run;
+ /*
+ * 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.
+ *
+ * Invalid - One or more images in the bank are corrupted, or partially
+ * overwritten. The bank is not to be used for booting.
+ *
+ * Valid - All images of the bank are valid but at least one image has not
+ * been accepted. This implies that the platform is in Trial State.
+ *
+ * Accepted - All images of the bank are valid and accepted.
+ *
+ * Returns the state of the current active bank
+ ******************************************************************************/
+uint32_t fwu_get_active_bank_state(void)
+{
+ assert(is_metadata_initialized);
+
+ return metadata.bank_state[metadata.active_index];
}
const struct fwu_metadata *fwu_get_metadata(void)
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 555fe7f..42e157b 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -452,14 +452,15 @@
}
/*
- * Try retrieving a partition table entry based on the GUID.
+ * Try retrieving a partition table entry based on the partition type GUID.
*/
-const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_uuid)
+const partition_entry_t *get_partition_entry_by_type(
+ const struct efi_guid *type_guid)
{
int i;
for (i = 0; i < list.entry_count; i++) {
- if (guidcmp(type_uuid, &list.list[i].type_guid) == 0) {
+ if (guidcmp(type_guid, &list.list[i].type_guid) == 0) {
return &list.list[i];
}
}
@@ -468,14 +469,15 @@
}
/*
- * Try retrieving a partition table entry based on the UUID.
+ * Try retrieving a partition table entry based on the unique partition GUID.
*/
-const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid)
+const partition_entry_t *get_partition_entry_by_guid(
+ const struct efi_guid *part_guid)
{
int i;
for (i = 0; i < list.entry_count; i++) {
- if (guidcmp(part_uuid, &list.list[i].part_guid) == 0) {
+ if (guidcmp(part_guid, &list.list[i].part_guid) == 0) {
return &list.list[i];
}
}
diff --git a/include/drivers/fwu/fwu.h b/include/drivers/fwu/fwu.h
index 9f18e22..18e8a31 100644
--- a/include/drivers/fwu/fwu.h
+++ b/include/drivers/fwu/fwu.h
@@ -9,8 +9,15 @@
#include <stdbool.h>
+#define FWU_BANK_STATE_ACCEPTED 0xFCU
+#define FWU_BANK_STATE_VALID 0xFEU
+#define FWU_BANK_STATE_INVALID 0xFFU
+
+#define INVALID_BOOT_IDX 0xFFFFFFFFU
+
void fwu_init(void);
-bool fwu_is_trial_run_state(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 */
diff --git a/include/drivers/fwu/fwu_metadata.h b/include/drivers/fwu/fwu_metadata.h
index 2e88de5..b441300 100644
--- a/include/drivers/fwu/fwu_metadata.h
+++ b/include/drivers/fwu/fwu_metadata.h
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*
* FWU metadata information as per the specification section 4.1:
- * https://developer.arm.com/documentation/den0118/a/
+ * https://developer.arm.com/documentation/den0118/latest/
*
*/
@@ -14,11 +14,13 @@
#include <stdint.h>
#include <tools_share/uuid.h>
+#define NR_OF_MAX_FW_BANKS 4
+
/* Properties of image in a bank */
-struct fwu_image_properties {
+struct fwu_image_bank_info {
- /* UUID of the image in this bank */
- uuid_t img_uuid;
+ /* GUID of the image in this bank */
+ struct efi_guid img_guid;
/* [0]: bit describing the image acceptance status –
* 1 means the image is accepted
@@ -34,17 +36,40 @@
/* Image entry information */
struct fwu_image_entry {
- /* UUID identifying the image type */
- uuid_t img_type_uuid;
+ /* GUID identifying the image type */
+ struct efi_guid img_type_guid;
- /* UUID of the storage volume where the image is located */
- uuid_t location_uuid;
+ /* GUID of the storage volume where the image is located */
+ struct efi_guid location_guid;
- /* Properties of images with img_type_uuid in the different FW banks */
- struct fwu_image_properties img_props[NR_OF_FW_BANKS];
+ /* Properties of images with img_type_guid in the different FW banks */
+ struct fwu_image_bank_info img_bank_info[NR_OF_FW_BANKS];
} __packed;
+/* Firmware Image descriptor */
+struct fwu_fw_store_descriptor {
+
+ /* Number of Banks */
+ uint8_t num_banks;
+
+ /* Reserved */
+ uint8_t reserved;
+
+ /* Number of images per bank */
+ uint16_t num_images;
+
+ /* Size of image_entry(all banks) in bytes */
+ uint16_t img_entry_size;
+
+ /* Size of image bank info structure in bytes */
+ uint16_t bank_info_entry_size;
+
+ /* Array of fwu_image_entry structs */
+ struct fwu_image_entry img_entry[NR_OF_IMAGES_IN_FW_BANK];
+
+} __packed;
+
/*
* FWU metadata filled by the updater and consumed by TF-A for
* various purposes as below:
@@ -66,8 +91,25 @@
/* Previous bank index with which device booted successfully */
uint32_t previous_active_index;
+ /* Size of the entire metadata in bytes */
+ uint32_t metadata_size;
+
+ /* Offset of the image descriptor structure */
+ uint16_t desc_offset;
+
+ /* Reserved */
+ uint16_t reserved1;
+
+ /* Bank state */
+ uint8_t bank_state[NR_OF_MAX_FW_BANKS];
+
+ /* Reserved */
+ uint32_t reserved2;
+
+#if PSA_FWU_METADATA_FW_STORE_DESC
/* Image entry information */
- struct fwu_image_entry img_entry[NR_OF_IMAGES_IN_FW_BANK];
+ struct fwu_fw_store_descriptor fw_desc;
+#endif
} __packed;
diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h
index d567d4c..4183570 100644
--- a/include/drivers/partition/partition.h
+++ b/include/drivers/partition/partition.h
@@ -46,8 +46,10 @@
int load_partition_table(unsigned int image_id);
const partition_entry_t *get_partition_entry(const char *name);
-const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_guid);
-const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid);
+const partition_entry_t *get_partition_entry_by_type(
+ const struct efi_guid *type_guid);
+const partition_entry_t *get_partition_entry_by_guid(
+ const struct efi_guid *part_guid);
const partition_entry_list_t *get_partition_entry_list(void);
void partition_init(unsigned int image_id);
int gpt_partition_init(void);
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 1802077..7fe8bf8 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -351,6 +351,14 @@
# Disable Firmware update support by default
PSA_FWU_SUPPORT := 0
+# Enable image description in FWU metadata by default when PSA_FWU_SUPPORT
+# is enabled.
+ifeq ($(PSA_FWU_SUPPORT),1)
+PSA_FWU_METADATA_FW_STORE_DESC := 1
+else
+PSA_FWU_METADATA_FW_STORE_DESC := 0
+endif
+
# Dynamic Root of Trust for Measurement support
DRTM_SUPPORT := 0
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 86795d7..f8a0c18 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -493,12 +493,10 @@
*/
#if !PSA_FWU_SUPPORT
const partition_entry_t *entry;
- const struct efi_guid img_type_guid = STM32MP_FIP_GUID;
- uuid_t img_type_uuid;
+ const struct efi_guid fip_guid = STM32MP_FIP_GUID;
- guidcpy(&img_type_uuid, &img_type_guid);
partition_init(GPT_IMAGE_ID);
- entry = get_partition_entry_by_type(&img_type_uuid);
+ entry = get_partition_entry_by_type(&fip_guid);
if (entry == NULL) {
entry = get_partition_entry(FIP_IMAGE_NAME);
if (entry == NULL) {
@@ -613,8 +611,6 @@
* - we already boot FWU_MAX_TRIAL_REBOOT times in trial mode.
* we select the previous_active_index.
*/
-#define INVALID_BOOT_IDX 0xFFFFFFFFU
-
uint32_t plat_fwu_get_boot_idx(void)
{
/*
@@ -622,32 +618,38 @@
* even if this function is called several times.
*/
static uint32_t boot_idx = INVALID_BOOT_IDX;
- const struct fwu_metadata *data;
-
- data = fwu_get_metadata();
if (boot_idx == INVALID_BOOT_IDX) {
+ const struct fwu_metadata *data = fwu_get_metadata();
+
boot_idx = data->active_index;
- if (fwu_is_trial_run_state()) {
+
+ if (data->bank_state[boot_idx] == FWU_BANK_STATE_VALID) {
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;
+ boot_idx = fwu_get_alternate_boot_bank();
}
- } else {
+ } else if (data->bank_state[boot_idx] ==
+ FWU_BANK_STATE_ACCEPTED) {
stm32_set_max_fwu_trial_boot_cnt();
+ } else {
+ ERROR("The active bank(%u) of the platform is in Invalid State.\n",
+ boot_idx);
+ boot_idx = fwu_get_alternate_boot_bank();
+ stm32_clear_fwu_trial_boot_cnt();
}
}
return boot_idx;
}
-static void *stm32_get_image_spec(const uuid_t *img_type_uuid)
+static void *stm32_get_image_spec(const struct efi_guid *img_type_guid)
{
unsigned int i;
for (i = 0U; i < MAX_NUMBER_IDS; i++) {
- if ((guidcmp(&policies[i].img_type_guid, img_type_uuid)) == 0) {
+ if ((guidcmp(&policies[i].img_type_guid, img_type_guid)) == 0) {
return (void *)policies[i].image_spec;
}
}
@@ -660,20 +662,23 @@
unsigned int i;
uint32_t boot_idx;
const partition_entry_t *entry __maybe_unused;
- const uuid_t *img_type_uuid;
- const uuid_t *img_uuid __maybe_unused;
+ const struct fwu_image_entry *img_entry;
+ const void *img_type_guid;
+ const void *img_guid;
io_block_spec_t *image_spec;
const uint16_t boot_itf = stm32mp_get_boot_itf_selected();
boot_idx = plat_fwu_get_boot_idx();
assert(boot_idx < NR_OF_FW_BANKS);
+ VERBOSE("Selecting to boot from bank %u\n", boot_idx);
+ img_entry = (void *)&metadata->fw_desc.img_entry;
for (i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
- img_type_uuid = &metadata->img_entry[i].img_type_uuid;
+ img_type_guid = &img_entry[i].img_type_guid;
- img_uuid = &metadata->img_entry[i].img_props[boot_idx].img_uuid;
+ img_guid = &img_entry[i].img_bank_info[boot_idx].img_guid;
- image_spec = stm32_get_image_spec(img_type_uuid);
+ image_spec = stm32_get_image_spec(img_type_guid);
if (image_spec == NULL) {
ERROR("Unable to get image spec for the image in the metadata\n");
panic();
@@ -683,7 +688,7 @@
#if (STM32MP_SDMMC || STM32MP_EMMC)
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
- entry = get_partition_entry_by_uuid(img_uuid);
+ entry = get_partition_entry_by_guid(img_guid);
if (entry == NULL) {
ERROR("No partition with the uuid mentioned in metadata\n");
panic();
@@ -695,9 +700,9 @@
#endif
#if STM32MP_SPI_NOR
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI:
- if (guidcmp(img_uuid, &STM32MP_NOR_FIP_A_GUID) == 0) {
+ if (guidcmp(img_guid, &STM32MP_NOR_FIP_A_GUID) == 0) {
image_spec->offset = STM32MP_NOR_FIP_A_OFFSET;
- } else if (guidcmp(img_uuid, &STM32MP_NOR_FIP_B_GUID) == 0) {
+ } else if (guidcmp(img_guid, &STM32MP_NOR_FIP_B_GUID) == 0) {
image_spec->offset = STM32MP_NOR_FIP_B_OFFSET;
} else {
ERROR("Invalid uuid mentioned in metadata\n");
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index 0ff6092..a1ed1ad 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -142,6 +142,7 @@
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);
+void stm32_clear_fwu_trial_boot_cnt(void);
#endif /* PSA_FWU_SUPPORT */
#endif /* STM32MP_COMMON_H */
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index 0e69513..f098eb3 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -714,4 +714,13 @@
TAMP_BOOT_FWU_INFO_CNT_MSK);
clk_disable(RTCAPB);
}
+
+void stm32_clear_fwu_trial_boot_cnt(void)
+{
+ uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
+
+ clk_enable(RTCAPB);
+ mmio_clrbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK);
+ clk_disable(RTCAPB);
+}
#endif /* PSA_FWU_SUPPORT */