Merge "feat(versal-net): set lower cluster bus qos value" into integration
diff --git a/common/bl_common.c b/common/bl_common.c
index fe4de0a..2a9f32f 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -211,18 +211,18 @@
{
int err;
-/*
- * All firmware banks should be part of the same non-volatile storage as per
- * PSA FWU specification, hence don't check for any alternate boot source
- * when PSA FWU is enabled.
- */
-#if PSA_FWU_SUPPORT
- err = load_auth_image_internal(image_id, image_data);
-#else
- do {
+ if ((plat_try_img_ops == NULL) || (plat_try_img_ops->next_instance == NULL)) {
err = load_auth_image_internal(image_id, image_data);
- } while ((err != 0) && (plat_try_next_boot_source() != 0));
-#endif /* PSA_FWU_SUPPORT */
+ } else {
+ do {
+ err = load_auth_image_internal(image_id, image_data);
+ if (err != 0) {
+ if (plat_try_img_ops->next_instance(image_id) != 0) {
+ return err;
+ }
+ }
+ } while (err != 0);
+ }
if (err == 0) {
/*
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index a7600ec..5643ea1 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -1518,6 +1518,40 @@
- The function must not clobber x1, x2 and x3. It's also not safe to rely on
stack. Otherwise obey AAPCS.
+Struct: plat_try_images_ops [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This optional structure holds platform hooks for alternative images load.
+It has to be defined in platform code and registered by calling
+plat_setup_try_img_ops() function, passing it the address of the
+plat_try_images_ops struct.
+
+Function : plat_setup_try_img_ops [optional]
+............................................
+
+::
+
+ Argument : const struct plat_try_images_ops *
+ Return : void
+
+This optional function is called to register platform try images ops, given
+as argument.
+
+Function : plat_try_images_ops.next_instance [optional]
+.......................................................
+
+::
+
+ Argument : unsigned int image_id
+ Return : int
+
+This optional function tries to load images from alternative places.
+In case PSA FWU is not used, it can be any instance or media. If PSA FWU is
+used, it is mandatory that the backup image is on the same media.
+This is required for MTD devices like NAND.
+The argument is the ID of the image for which we are looking for an alternative
+place. It returns 0 in case of success and a negative errno value otherwise.
+
Modifications specific to a Boot Loader stage
---------------------------------------------
@@ -1607,9 +1641,6 @@
for performing any remaining platform-specific setup that can occur after the
MMU and data cache have been enabled.
-if support for multiple boot sources is required, it initializes the boot
-sequence used by plat_try_next_boot_source().
-
In Arm standard platforms, this function initializes the storage abstraction
layer used to load the next bootloader image.
@@ -1892,25 +1923,7 @@
This optional function performs any BL2 platform initialization
required before image loading, that is not done later in
-bl2_platform_setup(). Specifically, if support for multiple
-boot sources is required, it initializes the boot sequence used by
-plat_try_next_boot_source().
-
-Function : plat_try_next_boot_source() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : int
-
-This optional function passes to the next boot source in the redundancy
-sequence.
-
-This function moves the current boot redundancy source to the next
-element in the boot sequence. If there are no more boot sources then it
-must return 0, otherwise it must return 1. The default implementation
-of this always returns 0.
+bl2_platform_setup().
Boot Loader Stage 2 (BL2) at EL3
--------------------------------
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c
index a4a64ca..44d7c09 100644
--- a/drivers/st/gpio/stm32_gpio.c
+++ b/drivers/st/gpio/stm32_gpio.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -282,6 +282,7 @@
clk_disable(clock);
+#if STM32MP13 || STM32MP15
if (status == DT_SECURE) {
stm32mp_register_secure_gpio(bank, pin);
#if !IMAGE_BL2
@@ -294,6 +295,9 @@
set_gpio_secure_cfg(bank, pin, false);
#endif
}
+#else /* !STM32MP13 && !STM32MP15 */
+ set_gpio_secure_cfg(bank, pin, true);
+#endif /* STM32MP13 || STM32MP15 */
}
void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure)
@@ -321,3 +325,74 @@
GPIO_ALTERNATE_(0), DT_DISABLED);
set_gpio_secure_cfg(bank, pin, stm32_gpio_is_secure_at_reset(bank));
}
+
+void set_gpio_level(uint32_t bank, uint32_t pin, enum gpio_level level)
+{
+ uintptr_t base = stm32_get_gpio_bank_base(bank);
+ unsigned long clock = stm32_get_gpio_bank_clock(bank);
+
+ assert(pin <= GPIO_PIN_MAX);
+
+ clk_enable(clock);
+
+ if (level == GPIO_LEVEL_HIGH) {
+ mmio_write_32(base + GPIO_BSRR_OFFSET, BIT(pin));
+ } else {
+ mmio_write_32(base + GPIO_BSRR_OFFSET, BIT(pin + 16U));
+ }
+
+ VERBOSE("GPIO %u level set to 0x%x\n", bank,
+ mmio_read_32(base + GPIO_IDR_OFFSET));
+
+ clk_disable(clock);
+}
+
+enum gpio_level get_gpio_level(uint32_t bank, uint32_t pin)
+{
+ uintptr_t base = stm32_get_gpio_bank_base(bank);
+ unsigned long clock = stm32_get_gpio_bank_clock(bank);
+ enum gpio_level level = GPIO_LEVEL_LOW;
+
+ assert(pin <= GPIO_PIN_MAX);
+
+ clk_enable(clock);
+
+ if (mmio_read_32(base + GPIO_IDR_OFFSET) & BIT(pin)) {
+ level = GPIO_LEVEL_HIGH;
+ }
+
+ VERBOSE("GPIO %u get level 0x%x\n", bank,
+ mmio_read_32(base + GPIO_IDR_OFFSET));
+
+ clk_disable(clock);
+
+ return level;
+}
+
+void set_gpio_config(uint32_t bank, uint32_t pin, uint32_t config, uint8_t status)
+{
+ uint32_t mode = GPIO_MODE_OUTPUT;
+ uint32_t od = 0U;
+ uint32_t pull = GPIO_NO_PULL;
+
+ VERBOSE("GPIO %u:%u set config to 0x%x\n", bank, pin, config);
+
+ if (config & GPIOF_DIR_IN) {
+ mode = GPIO_MODE_INPUT;
+ }
+
+ if (config & GPIOF_OUT_INIT_HIGH) {
+ od = 1U;
+ }
+
+ if (config & GPIOF_PULL_UP) {
+ pull |= GPIO_PULL_UP;
+ }
+
+ if (config & GPIOF_PULL_DOWN) {
+ pull |= GPIO_PULL_DOWN;
+ }
+
+ set_gpio(bank, pin, mode, GPIO_TYPE_PUSH_PULL, GPIO_SPEED_LOW,
+ pull, od, GPIO_ALTERNATE_(0), status);
+}
diff --git a/include/drivers/arm/fvp/fvp_cpu_pwr.h b/include/drivers/arm/fvp/fvp_cpu_pwr.h
new file mode 100644
index 0000000..488be18
--- /dev/null
+++ b/include/drivers/arm/fvp/fvp_cpu_pwr.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_CPU_PWR_H
+#define FVP_CPU_PWR_H
+
+#ifndef __ASSEMBLER__
+#include <stdbool.h>
+#include <stdint.h>
+
+#if __aarch64__
+bool check_cpupwrctrl_el1_is_available(void);
+#endif /* __aarch64__ */
+#endif /* __ASSEMBLER__ */
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
+
+#endif /* FVP_CPU_PWR_H */
diff --git a/include/drivers/st/stm32_gpio.h b/include/drivers/st/stm32_gpio.h
index eeef9da..ef4eb04 100644
--- a/include/drivers/st/stm32_gpio.h
+++ b/include/drivers/st/stm32_gpio.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,7 @@
#define GPIO_TYPE_OFFSET U(0x04)
#define GPIO_SPEED_OFFSET U(0x08)
#define GPIO_PUPD_OFFSET U(0x0C)
+#define GPIO_IDR_OFFSET U(0x10)
#define GPIO_OD_OFFSET U(0x14)
#define GPIO_BSRR_OFFSET U(0x18)
#define GPIO_AFRL_OFFSET U(0x20)
@@ -58,6 +59,16 @@
int dt_set_pinctrl_config(int node);
void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure);
void set_gpio_reset_cfg(uint32_t bank, uint32_t pin);
+
+enum gpio_level {
+ GPIO_LEVEL_LOW,
+ GPIO_LEVEL_HIGH
+};
+
+void set_gpio_level(uint32_t bank, uint32_t pin, enum gpio_level level);
+enum gpio_level get_gpio_level(uint32_t bank, uint32_t pin);
+
+void set_gpio_config(uint32_t bank, uint32_t pin, uint32_t config, uint8_t status);
#endif /*__ASSEMBLER__*/
#endif /* STM32_GPIO_H */
diff --git a/include/dt-bindings/gpio/stm32-gpio.h b/include/dt-bindings/gpio/stm32-gpio.h
new file mode 100644
index 0000000..2c7a0f1
--- /dev/null
+++ b/include/dt-bindings/gpio/stm32-gpio.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * Copyright (C) 2024 STMicroelectronics - All Rights Reserved
+ * Author: Paillet Pascal <p.paillet@foss.st.com> for STMicroelectronics.
+ */
+
+#ifndef DT_BINDINGS_STM32_GPIO_H
+#define DT_BINDINGS_STM32_GPIO_H
+
+/* Bank IDs used in GPIO driver API */
+#define GPIO_BANK_A 0U
+#define GPIO_BANK_B 1U
+#define GPIO_BANK_C 2U
+#define GPIO_BANK_D 3U
+#define GPIO_BANK_E 4U
+#define GPIO_BANK_F 5U
+#define GPIO_BANK_G 6U
+#define GPIO_BANK_H 7U
+#define GPIO_BANK_I 8U
+#define GPIO_BANK_J 9U
+#define GPIO_BANK_K 10U
+#define GPIO_BANK_Z 25U
+
+/* Bit 0 is used to set GPIO in input mode */
+#define GPIOF_DIR_OUT 0x0
+#define GPIOF_DIR_IN 0x1
+
+/* Bit 1 is used to set GPIO high level during init */
+#define GPIOF_INIT_LOW 0x0
+#define GPIOF_INIT_HIGH 0x2
+
+#define GPIOF_IN (GPIOF_DIR_IN)
+#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW)
+#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
+
+/* Bit 2 is used to set GPIO pull up */
+#define GPIOF_PULL_UP 0x4
+/* Bit 3 is used to set GPIO pull down */
+#define GPIOF_PULL_DOWN 0x8
+
+#endif /* DT_BINDINGS_STM32_GPIO_H */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index ce5e8e0..1015fca 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -41,6 +41,16 @@
enum fw_enc_status_t;
/*******************************************************************************
+ * Structure populated by platform specific code to export routines which
+ * perform load images functions, and associated pointer to platform ops
+ ******************************************************************************/
+struct plat_try_images_ops {
+ int (*next_instance)(unsigned int image_id);
+};
+
+extern const struct plat_try_images_ops *plat_try_img_ops;
+
+/*******************************************************************************
* plat_get_rotpk_info() flags
******************************************************************************/
#define ROTPK_IS_HASH (1 << 0)
@@ -154,7 +164,7 @@
void plat_system_reset(void) __dead2;
const char *plat_log_get_prefix(unsigned int log_level);
void bl2_plat_preload_setup(void);
-int plat_try_next_boot_source(void);
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops);
#if MEASURED_BOOT
int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data);
diff --git a/include/tools_share/cca_oid.h b/include/tools_share/cca_oid.h
index 8c53ef9..6f89c16 100644
--- a/include/tools_share/cca_oid.h
+++ b/include/tools_share/cca_oid.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,15 +30,17 @@
/*
* First undef previous definitions from tbbr_oid.h.
- * CCA ROTPK authenticates BL31 and its configuration image in
+ * CCA ROTPK authenticates BL31, SCP_BL2 and its configuration image in
* CCA CoT.
**/
#undef BL31_IMAGE_KEY_OID
#undef SOC_FW_CONFIG_KEY_OID
#undef HW_CONFIG_KEY_OID
+#undef SCP_BL2_IMAGE_KEY_OID
#define BL31_IMAGE_KEY_OID ZERO_OID
#define SOC_FW_CONFIG_KEY_OID ZERO_OID
#define HW_CONFIG_KEY_OID ZERO_OID
+#define SCP_BL2_IMAGE_KEY_OID ZERO_OID
#define RMM_IMAGE_KEY_OID ZERO_OID
#endif /* CCA_OID_H */
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index 8efc238..46fb44a 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -6,9 +6,10 @@
#include <arch.h>
#include <asm_macros.S>
+#include <drivers/arm/fvp/fvp_cpu_pwr.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
#include <drivers/arm/gicv2.h>
#include <drivers/arm/gicv3.h>
-#include <drivers/arm/fvp/fvp_pwrc.h>
#include <platform_def.h>
.globl plat_secondary_cold_boot_setup
@@ -29,6 +30,21 @@
*/
func plat_secondary_cold_boot_setup
#ifndef EL3_PAYLOAD_BASE
+
+ /* --------------------------------------------
+ * Check if core supports powering down, if it
+ * supports power down then set core power down
+ * bit before requesting for the cores to be
+ * powered off from base power controller.
+ * ---------------------------------------------
+ */
+ bl check_cpupwrctrl_el1_is_available
+ cbz x0, base_power_off
+
+ mrs x1, CPUPWRCTLR_EL1
+ orr x1, x1, #CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+ msr CPUPWRCTLR_EL1, x1
+
/* ---------------------------------------------
* Power down this cpu.
* TODO: Do we need to worry about powering the
@@ -37,6 +53,7 @@
* loader zeroes out the zi section.
* ---------------------------------------------
*/
+base_power_off:
mrs x0, mpidr_el1
mov_imm x1, PWRC_BASE
str w0, [x1, #PPOFFR_OFF]
diff --git a/plat/arm/board/fvp/fvp_cpu_pwr.c b/plat/arm/board/fvp/fvp_cpu_pwr.c
new file mode 100644
index 0000000..f2771c2
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_cpu_pwr.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if __aarch64__
+
+#include <aem_generic.h>
+#include <arch_helpers.h>
+#include <cortex_a35.h>
+#include <cortex_a53.h>
+#include <cortex_a57.h>
+#include <cortex_a72.h>
+#include <cortex_a73.h>
+#include <cortex_a78_ae.h>
+#include <drivers/arm/fvp/fvp_cpu_pwr.h>
+#include <lib/utils_def.h>
+#include <neoverse_e1.h>
+
+bool check_cpupwrctrl_el1_is_available(void)
+{
+ /* Poupulate list of CPU midr that doesn't support CPUPWRCTL_EL1 */
+ const unsigned int midr_no_cpupwrctl[] = {
+ BASE_AEM_MIDR,
+ CORTEX_A35_MIDR,
+ CORTEX_A53_MIDR,
+ CORTEX_A57_MIDR,
+ CORTEX_A72_MIDR,
+ CORTEX_A73_MIDR,
+ CORTEX_A78_AE_MIDR,
+ NEOVERSE_E1_MIDR
+ };
+ unsigned int midr = (unsigned int)read_midr();
+
+ for (unsigned int i = 0U; i < ARRAY_SIZE(midr_no_cpupwrctl); i++) {
+ if (midr_no_cpupwrctl[i] == midr) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+#endif /* __arch64__ */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 033eb7c..af2b78d 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -222,6 +222,7 @@
lib/semihosting/${ARCH}/semihosting_call.S \
plat/arm/board/fvp/${ARCH}/fvp_helpers.S \
plat/arm/board/fvp/fvp_bl1_setup.c \
+ plat/arm/board/fvp/fvp_cpu_pwr.c \
plat/arm/board/fvp/fvp_err.c \
plat/arm/board/fvp/fvp_io_storage.c \
plat/arm/board/fvp/fvp_topology.c \
@@ -252,7 +253,8 @@
endif
ifeq (${ENABLE_RME},1)
-BL2_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S
+BL2_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S \
+ plat/arm/board/fvp/fvp_cpu_pwr.c
BL31_SOURCES += plat/arm/board/fvp/fvp_plat_attest_token.c \
plat/arm/board/fvp/fvp_realm_attest_key.c
@@ -264,6 +266,7 @@
ifeq (${RESET_TO_BL2},1)
BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \
+ plat/arm/board/fvp/fvp_cpu_pwr.c \
plat/arm/board/fvp/fvp_bl2_el3_setup.c \
${FVP_CPU_LIBS} \
${FVP_INTERCONNECT_SOURCES}
@@ -290,6 +293,7 @@
plat/arm/board/fvp/fvp_pm.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/aarch64/fvp_helpers.S \
+ plat/arm/board/fvp/fvp_cpu_pwr.c \
plat/arm/common/arm_nor_psci_mem_protect.c \
${FVP_CPU_LIBS} \
${FVP_GIC_SOURCES} \
diff --git a/plat/arm/board/tc/tc_bl2_measured_boot.c b/plat/arm/board/tc/tc_bl2_measured_boot.c
index add871c..3957c90 100644
--- a/plat/arm/board/tc/tc_bl2_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl2_measured_boot.c
@@ -40,6 +40,13 @@
.pk_oid = SOC_FW_CONFIG_KEY_OID,
.lock_measurement = true },
{
+ .id = SCP_BL2_IMAGE_ID,
+ .slot = U(12),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = MBOOT_SCP_BL2_IMAGE_STRING,
+ .pk_oid = SCP_BL2_IMAGE_KEY_OID,
+ .lock_measurement = true },
+ {
.id = RSE_MBOOT_INVALID_ID }
};
diff --git a/plat/common/aarch32/plat_common.c b/plat/common/aarch32/plat_common.c
index 2c1a8fa..8979171 100644
--- a/plat/common/aarch32/plat_common.c
+++ b/plat/common/aarch32/plat_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,14 @@
#include <lib/xlat_tables/xlat_mmu_helpers.h>
#include <plat/common/platform.h>
+/* Pointer and function to register platform function to load alernate images */
+const struct plat_try_images_ops *plat_try_img_ops;
+
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops)
+{
+ plat_try_img_ops = plat_try_ops;
+}
+
/*
* The following platform setup functions are weakly defined. They
* provide typical implementations that may be re-used by multiple
@@ -14,7 +22,6 @@
*/
#pragma weak bl32_plat_enable_mmu
-
void bl32_plat_enable_mmu(uint32_t flags)
{
enable_mmu_svc_mon(flags);
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 54f2a03..7a228b9 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -17,6 +17,14 @@
#include <lib/xlat_tables/xlat_mmu_helpers.h>
#include <plat/common/platform.h>
+/* Pointer and function to register platform function to load alernate images */
+const struct plat_try_images_ops *plat_try_img_ops;
+
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops)
+{
+ plat_try_img_ops = plat_try_ops;
+}
+
/*
* The following platform setup functions are weakly defined. They
* provide typical implementations that may be re-used by multiple
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index 89b77ba..a603f2b 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -24,7 +24,6 @@
#pragma weak bl2_plat_preload_setup
#pragma weak bl2_plat_handle_pre_image_load
#pragma weak bl2_plat_handle_post_image_load
-#pragma weak plat_try_next_boot_source
#pragma weak plat_get_enc_key_info
#pragma weak plat_is_smccc_feature_available
#pragma weak plat_get_soc_version
@@ -69,11 +68,6 @@
return 0;
}
-int plat_try_next_boot_source(void)
-{
- return 0;
-}
-
/*
* Weak implementation to provide dummy decryption key only for test purposes,
* platforms must override this API for any real world firmware encryption
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index f8a0c18..c17ac7e 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,55 @@
}
#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;
+ }
+
+#if PSA_FWU_SUPPORT
+ if (((image_block_spec.offset < STM32MP_NAND_FIP_B_OFFSET) &&
+ ((image_block_spec.offset + nand_block_sz) >= STM32MP_NAND_FIP_B_OFFSET)) ||
+ (image_block_spec.offset + nand_block_sz >= STM32MP_NAND_FIP_B_MAX_OFFSET)) {
+ return 0;
+ }
+#endif
+
+ 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 +371,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 +381,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 +394,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 */
@@ -530,7 +581,14 @@
#if STM32MP_SPI_NAND
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
#endif
+/*
+ * With FWU Multi Bank feature enabled, the selection of
+ * the image to boot will be done by fwu_init calling the
+ * platform hook, plat_fwu_set_images_source.
+ */
+#if !PSA_FWU_SUPPORT
image_block_spec.offset = STM32MP_NAND_FIP_OFFSET;
+#endif
break;
#endif
@@ -596,7 +654,7 @@
return rc;
}
-#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
/*
* In each boot in non-trial mode, we set the BKP register to
* FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata.
@@ -710,6 +768,19 @@
}
break;
#endif
+#if (STM32MP_RAW_NAND || STM32MP_SPI_NAND)
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
+ if (guidcmp(img_guid, &STM32MP_NAND_FIP_A_GUID) == 0) {
+ image_spec->offset = STM32MP_NAND_FIP_A_OFFSET;
+ } else if (guidcmp(img_guid, &STM32MP_NAND_FIP_B_GUID) == 0) {
+ image_spec->offset = STM32MP_NAND_FIP_B_OFFSET;
+ } else {
+ ERROR("Invalid uuid mentioned in metadata\n");
+ panic();
+ }
+ break;
+#endif
default:
panic();
break;
@@ -717,9 +788,9 @@
}
}
-static int plat_set_image_source(unsigned int image_id,
- uintptr_t *handle,
- uintptr_t *image_spec)
+static int set_metadata_image_source(unsigned int image_id,
+ uintptr_t *handle,
+ uintptr_t *image_spec)
{
struct plat_io_policy *policy;
io_block_spec_t *spec __maybe_unused;
@@ -762,6 +833,19 @@
spec->length = sizeof(struct fwu_metadata);
break;
#endif
+
+#if (STM32MP_RAW_NAND || STM32MP_SPI_NAND)
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
+ if (image_id == FWU_METADATA_IMAGE_ID) {
+ spec->offset = STM32MP_NAND_METADATA1_OFFSET;
+ } else {
+ spec->offset = STM32MP_NAND_METADATA2_OFFSET;
+ }
+
+ spec->length = sizeof(struct fwu_metadata);
+ break;
+#endif
default:
panic();
break;
@@ -780,6 +864,6 @@
assert((image_id == FWU_METADATA_IMAGE_ID) ||
(image_id == BKUP_FWU_METADATA_IMAGE_ID));
- return plat_set_image_source(image_id, handle, image_spec);
+ return set_metadata_image_source(image_id, handle, image_spec);
}
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 5514c09..6ed09d9 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,12 +27,12 @@
};
#endif
-#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
static io_block_spec_t metadata_block_spec = {
.offset = 0, /* To be filled at runtime */
.length = 0, /* To be filled at runtime */
};
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
/* By default, STM32 platforms load images from the FIP */
struct plat_io_policy policies[MAX_NUMBER_IDS] = {
@@ -58,7 +58,7 @@
.check = open_storage
},
#endif
-#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
[FWU_METADATA_IMAGE_ID] = {
.dev_handle = &storage_dev_handle,
.image_spec = (uintptr_t)&metadata_block_spec,
@@ -71,7 +71,7 @@
.img_type_guid = NULL_GUID,
.check = open_storage
},
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
};
#define DEFAULT_UUID_NUMBER U(7)
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 8a1d76d..824563f 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -10,6 +10,7 @@
#include <common/tbbr/tbbr_img_def.h>
#include <drivers/st/stm32mp1_rcc.h>
#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <dt-bindings/gpio/stm32-gpio.h>
#include <dt-bindings/reset/stm32mp1-resets.h>
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
@@ -231,21 +232,7 @@
#endif
#define GPIO_BANK_OFFSET U(0x1000)
-/* Bank IDs used in GPIO driver API */
-#define GPIO_BANK_A U(0)
-#define GPIO_BANK_B U(1)
-#define GPIO_BANK_C U(2)
-#define GPIO_BANK_D U(3)
-#define GPIO_BANK_E U(4)
-#define GPIO_BANK_F U(5)
-#define GPIO_BANK_G U(6)
-#define GPIO_BANK_H U(7)
-#define GPIO_BANK_I U(8)
#if STM32MP15
-#define GPIO_BANK_J U(9)
-#define GPIO_BANK_K U(10)
-#define GPIO_BANK_Z U(25)
-
#define STM32MP_GPIOZ_PIN_MAX_COUNT 8
#endif
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index f098eb3..509bb11 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -115,14 +115,14 @@
uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
{
#if STM32MP13
- assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+ assert(bank <= GPIO_BANK_I);
#endif
#if STM32MP15
if (bank == GPIO_BANK_Z) {
return GPIOZ_BASE;
}
- assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+ assert(bank <= GPIO_BANK_K);
#endif
return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
@@ -131,14 +131,14 @@
uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
{
#if STM32MP13
- assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+ assert(bank <= GPIO_BANK_I);
#endif
#if STM32MP15
if (bank == GPIO_BANK_Z) {
return 0;
}
- assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+ assert(bank <= GPIO_BANK_K);
#endif
return bank * GPIO_BANK_OFFSET;
@@ -161,14 +161,14 @@
unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
{
#if STM32MP13
- assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+ assert(bank <= GPIO_BANK_I);
#endif
#if STM32MP15
if (bank == GPIO_BANK_Z) {
return GPIOZ;
}
- assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+ assert(bank <= GPIO_BANK_K);
#endif
return GPIOA + (bank - GPIO_BANK_A);
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 56c62e1..e3662ad 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -14,6 +14,7 @@
#include <drivers/st/stm32mp25_rcc.h>
#include <dt-bindings/clock/stm32mp25-clks.h>
#include <dt-bindings/clock/stm32mp25-clksrc.h>
+#include <dt-bindings/gpio/stm32-gpio.h>
#include <dt-bindings/reset/stm32mp25-resets.h>
#ifndef __ASSEMBLER__