feat(st): manage backup partitions for NAND devices
Register a try_nand_backup_partitions() handler to plat_try_images_ops
to manage backup partition when booting from NAND devices.
Signed-off-by: Nicolas Toromanoff <nicolas.toromanoff@foss.st.com>
Signed-off-by: Lionel Debieve <lionel.debieve@foss.st.com>
Signed-off-by: Yann Gautier <yann.gautier@st.com>
Change-Id: Ibee082b7b059b9e2ed502b7bbcda7464e5d9e251
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index f8a0c18..d5d0ff5 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -47,6 +47,7 @@
uintptr_t storage_dev_handle;
static const io_dev_connector_t *fip_dev_con;
+static uint32_t nand_block_sz __maybe_unused;
#ifndef DECRYPTION_SUPPORT_none
static const io_dev_connector_t *enc_dev_con;
@@ -310,11 +311,47 @@
}
#endif /* STM32MP_SPI_NOR */
+#if STM32MP_RAW_NAND || STM32MP_SPI_NAND
+/*
+ * This function returns 0 if it can find an alternate
+ * image to be loaded or a negative errno otherwise.
+ */
+static int try_nand_backup_partitions(unsigned int image_id)
+{
+ static unsigned int backup_id;
+ static unsigned int backup_block_nb;
+
+ /* Check if NAND storage used */
+ if (nand_block_sz == 0U) {
+ return -ENODEV;
+ }
+
+ if (backup_id != image_id) {
+ backup_block_nb = PLATFORM_MTD_MAX_PART_SIZE / nand_block_sz;
+ backup_id = image_id;
+ }
+
+ if (backup_block_nb-- == 0U) {
+ return -ENOSPC;
+ }
+
+ image_block_spec.offset += nand_block_sz;
+
+ return 0;
+}
+
+static const struct plat_try_images_ops try_img_ops = {
+ .next_instance = try_nand_backup_partitions,
+};
+#endif /* STM32MP_RAW_NAND || STM32MP_SPI_NAND */
+
#if STM32MP_RAW_NAND
static void boot_fmc2_nand(boot_api_context_t *boot_context)
{
int io_result __maybe_unused;
+ plat_setup_try_img_ops(&try_img_ops);
+
io_result = stm32_fmc2_init();
assert(io_result == 0);
@@ -326,6 +363,8 @@
io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
&storage_dev_handle);
assert(io_result == 0);
+
+ nand_block_sz = nand_dev_spec.erase_size;
}
#endif /* STM32MP_RAW_NAND */
@@ -334,6 +373,8 @@
{
int io_result __maybe_unused;
+ plat_setup_try_img_ops(&try_img_ops);
+
io_result = stm32_qspi_init();
assert(io_result == 0);
@@ -345,6 +386,8 @@
(uintptr_t)&spi_nand_dev_spec,
&storage_dev_handle);
assert(io_result == 0);
+
+ nand_block_sz = spi_nand_dev_spec.erase_size;
}
#endif /* STM32MP_SPI_NAND */