feat(plat/st): use FCONF to configure platform

Add required code to support FCONF on STM32MP1 platform.
The new FW_CONFIG DT file will be inside the FIP, and loaded by BL2.
It will be used to configure the addresses where to load other binaries.
BL2 should be agnostic of which BL32 is in the FIP (OP-TEE or SP_min),
so optee_utils.c is always compiled, and some OP-TEE flags are removed.

Change-Id: Id957b49b0117864136250bfc416664f815043ada
Signed-off-by: Yann Gautier <yann.gautier@foss.st.com>
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 6c7618a..817f449 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -97,6 +97,10 @@
 static const io_dev_connector_t *spi_dev_con;
 #endif
 
+static const io_uuid_spec_t fw_config_uuid_spec = {
+	.uuid = UUID_FW_CONFIG,
+};
+
 static const io_uuid_spec_t bl33_partition_spec = {
 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33
 };
@@ -175,6 +179,11 @@
 		.image_spec = (uintptr_t)&bl33_partition_spec,
 		.check = open_fip
 	},
+	[FW_CONFIG_ID] = {
+		.dev_handle = &fip_dev_handle,
+		.image_spec = (uintptr_t)&fw_config_uuid_spec,
+		.check = open_fip
+	},
 	[TOS_FW_CONFIG_ID] = {
 		.dev_handle = &fip_dev_handle,
 		.image_spec = (uintptr_t)&tos_fw_config_uuid_spec,
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 53177f6..9053a25 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -5,6 +5,7 @@
  */
 
 #include <assert.h>
+#include <errno.h>
 #include <string.h>
 
 #include <platform_def.h>
@@ -24,6 +25,8 @@
 #include <drivers/st/stm32mp1_clk.h>
 #include <drivers/st/stm32mp1_pwr.h>
 #include <drivers/st/stm32mp1_ram.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/mmio.h>
 #include <lib/optee_utils.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
@@ -341,10 +344,76 @@
 	bl_mem_params_node_t *bl32_mem_params;
 	bl_mem_params_node_t *pager_mem_params __unused;
 	bl_mem_params_node_t *paged_mem_params __unused;
+#if !STM32MP_USE_STM32IMAGE
+	const struct dyn_cfg_dtb_info_t *config_info;
+	bl_mem_params_node_t *tos_fw_mem_params;
+	unsigned int i;
+	unsigned long long ddr_top __unused;
+	const unsigned int image_ids[] = {
+		BL32_IMAGE_ID,
+		BL33_IMAGE_ID,
+		HW_CONFIG_ID,
+		TOS_FW_CONFIG_ID,
+	};
+#endif /* !STM32MP_USE_STM32IMAGE */
 
 	assert(bl_mem_params != NULL);
 
 	switch (image_id) {
+#if !STM32MP_USE_STM32IMAGE
+	case FW_CONFIG_ID:
+		/* Set global DTB info for fixed fw_config information */
+		set_config_info(STM32MP_FW_CONFIG_BASE, STM32MP_FW_CONFIG_MAX_SIZE, FW_CONFIG_ID);
+		fconf_populate("FW_CONFIG", STM32MP_FW_CONFIG_BASE);
+
+		/* Iterate through all the fw config IDs */
+		for (i = 0U; i < ARRAY_SIZE(image_ids); i++) {
+			bl_mem_params = get_bl_mem_params_node(image_ids[i]);
+			assert(bl_mem_params != NULL);
+
+			config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_ids[i]);
+			if (config_info == NULL) {
+				continue;
+			}
+
+			bl_mem_params->image_info.image_base = config_info->config_addr;
+			bl_mem_params->image_info.image_max_size = config_info->config_max_size;
+
+			bl_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+
+			switch (image_ids[i]) {
+			case BL32_IMAGE_ID:
+				bl_mem_params->ep_info.pc = config_info->config_addr;
+
+				/* In case of OPTEE, initialize address space with tos_fw addr */
+				pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+				pager_mem_params->image_info.image_base = config_info->config_addr;
+				pager_mem_params->image_info.image_max_size =
+					config_info->config_max_size;
+
+				/* Init base and size for pager if exist */
+				paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+				paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
+					(dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
+					 STM32MP_DDR_SHMEM_SIZE);
+				paged_mem_params->image_info.image_max_size = STM32MP_DDR_S_SIZE;
+				break;
+
+			case BL33_IMAGE_ID:
+				bl_mem_params->ep_info.pc = config_info->config_addr;
+				break;
+
+			case HW_CONFIG_ID:
+			case TOS_FW_CONFIG_ID:
+				break;
+
+			default:
+				return -EINVAL;
+			}
+		}
+		break;
+#endif /* !STM32MP_USE_STM32IMAGE */
+
 	case BL32_IMAGE_ID:
 		if (optee_header_is_valid(bl_mem_params->image_info.image_base)) {
 			/* BL32 is OP-TEE header */
@@ -380,6 +449,9 @@
 		} else {
 #if !STM32MP_USE_STM32IMAGE
 			bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
+			tos_fw_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
+			bl_mem_params->image_info.image_max_size +=
+				tos_fw_mem_params->image_info.image_max_size;
 #endif /* !STM32MP_USE_STM32IMAGE */
 			bl_mem_params->ep_info.args.arg0 = 0;
 		}
diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
index 0bc2b79..7963c4a 100644
--- a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
@@ -19,6 +19,22 @@
  * the next executable image id.
  ******************************************************************************/
 static bl_mem_params_node_t bl2_mem_params_descs[] = {
+	/* Fill FW_CONFIG related information if it exists */
+	{
+		.image_id = FW_CONFIG_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_PLAT_SETUP),
+
+		.image_info.image_base = STM32MP_FW_CONFIG_BASE,
+		.image_info.image_max_size = STM32MP_FW_CONFIG_MAX_SIZE,
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
 	/* Fill BL32 related information */
 	{
 		.image_id = BL32_IMAGE_ID,
@@ -27,25 +43,17 @@
 				      VERSION_2, entry_point_info_t,
 				      SECURE | EXECUTABLE | EP_FIRST_EXE),
 
-		/* Updated at runtime if OP-TEE is loaded */
-		.ep_info.pc = STM32MP_BL32_BASE,
-
 		.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
 					    SPSR_E_LITTLE,
 					    DISABLE_ALL_EXCEPTIONS),
 
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
 				      VERSION_2, image_info_t,
-				      IMAGE_ATTRIB_PLAT_SETUP),
-
-		/* Updated at runtime if OP-TEE is loaded */
-		.image_info.image_base = STM32MP_BL32_BASE,
-		.image_info.image_max_size = STM32MP_BL32_SIZE,
+				      IMAGE_ATTRIB_SKIP_LOADING),
 
 		.next_handoff_image_id = BL33_IMAGE_ID,
 	},
 
-#if defined(AARCH32_SP_OPTEE)
 	/* Fill BL32 external 1 image related information */
 	{
 		.image_id = BL32_EXTRA1_IMAGE_ID,
@@ -74,7 +82,7 @@
 
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
-#endif /* AARCH32_SP_OPTEE */
+
 	/* Fill HW_CONFIG related information if it exists */
 	{
 		.image_id = HW_CONFIG_ID,
@@ -83,15 +91,12 @@
 				      NON_SECURE | NON_EXECUTABLE),
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
 				      VERSION_2, image_info_t,
-				      0U),
-
-		.image_info.image_base = STM32MP_HW_CONFIG_BASE,
-		.image_info.image_max_size =
-			PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_HW_CONFIG_BASE,
+				      IMAGE_ATTRIB_SKIP_LOADING),
 
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
-#if !defined(AARCH32_SP_OPTEE)
+
+	/* Fill TOS_FW_CONFIG related information if it exists */
 	{
 		.image_id = TOS_FW_CONFIG_ID,
 		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
@@ -99,13 +104,11 @@
 				      SECURE | NON_EXECUTABLE),
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
 				      VERSION_2, image_info_t,
-				      0U),
+				      IMAGE_ATTRIB_SKIP_LOADING),
 
-		.image_info.image_base = STM32MP_BL32_DTB_BASE,
-		.image_info.image_max_size = STM32MP_BL32_DTB_SIZE,
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
-#endif
+
 	/* Fill BL33 related information */
 	{
 		.image_id = BL33_IMAGE_ID,
@@ -114,17 +117,13 @@
 				      VERSION_2, entry_point_info_t,
 				      NON_SECURE | EXECUTABLE),
 
-		.ep_info.pc = PLAT_STM32MP_NS_IMAGE_OFFSET,
 		.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
 					    SPSR_E_LITTLE,
 					    DISABLE_ALL_EXCEPTIONS),
 
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
-				      VERSION_2, image_info_t, 0U),
-
-		.image_info.image_base = PLAT_STM32MP_NS_IMAGE_OFFSET,
-		.image_info.image_max_size = STM32MP_DDR_MAX_SIZE -
-			(PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_DDR_BASE),
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
 
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	}
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 9e72b50..d415a1e 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -70,6 +70,7 @@
 FDT_SOURCES		+=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dts,$(DTB_FILE_NAME)))
 endif
 endif
+DTC_CPPFLAGS		+=	${INCLUDES}
 DTC_FLAGS		+=	-Wno-unit_address_vs_reg
 
 # Macros and rules to build TF binary
@@ -92,6 +93,13 @@
 ifneq (${STM32MP_USE_STM32IMAGE},1)
 FIP_DEPS		+=	dtbs
 STM32MP_HW_CONFIG	:=	${BL33_CFG}
+STM32MP_FW_CONFIG_NAME	:=	$(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
+STM32MP_FW_CONFIG	:=	${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME)
+ifneq (${AARCH32_SP},none)
+FDT_SOURCES		+=	$(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME)))
+endif
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
 # Add the HW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_HW_CONFIG},--hw-config))
 ifeq ($(AARCH32_SP),sp_min)
@@ -185,6 +193,8 @@
 
 ifneq (${STM32MP_USE_STM32IMAGE},1)
 BL2_SOURCES		+=	drivers/io/io_fip.c					\
+				lib/fconf/fconf.c					\
+				lib/fconf/fconf_dyn_cfg_getter.c			\
 				plat/st/common/bl2_io_storage.c				\
 				plat/st/stm32mp1/plat_bl2_mem_params_desc.c
 else
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index e30febb..1495e02 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -45,6 +45,7 @@
 {
 	switch (id & INT_ID_MASK) {
 	case STM32MP1_IRQ_TZC400:
+		tzc400_init(STM32MP1_TZC_BASE);
 		(void)tzc400_it_handler();
 		panic();
 		break;
@@ -117,6 +118,11 @@
 	struct dt_node_info dt_uart_info;
 	int result;
 	bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
+#if STM32MP_USE_STM32IMAGE
+	uintptr_t dt_addr = STM32MP_DTB_BASE;
+#else
+	uintptr_t dt_addr = arg1;
+#endif
 
 	/* Imprecise aborts can be masked in NonSecure */
 	write_scr(read_scr() | SCR_AW_BIT);
@@ -156,7 +162,7 @@
 		bl_params = bl_params->next_params_info;
 	}
 
-	if (dt_open_and_check(STM32MP_DTB_BASE) < 0) {
+	if (dt_open_and_check(dt_addr) < 0) {
 		panic();
 	}
 
@@ -195,9 +201,6 @@
  ******************************************************************************/
 void sp_min_platform_setup(void)
 {
-	/* Initialize tzc400 after DDR initialization */
-	stm32mp1_security_setup();
-
 	generic_delay_timer_init();
 
 	stm32mp1_gic_init();
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index aa76703..f14bf8c 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -87,13 +87,6 @@
 /* DDR configuration */
 #define STM32MP_DDR_BASE		U(0xC0000000)
 #define STM32MP_DDR_MAX_SIZE		U(0x40000000)	/* Max 1GB */
-#ifdef AARCH32_SP_OPTEE
-#define STM32MP_DDR_S_SIZE		U(0x01E00000)	/* 30 MB */
-#define STM32MP_DDR_SHMEM_SIZE		U(0x00200000)	/* 2 MB */
-#else
-#define STM32MP_DDR_S_SIZE		U(0)
-#define STM32MP_DDR_SHMEM_SIZE		U(0)
-#endif
 
 /* DDR power initializations */
 #ifndef __ASSEMBLER__
diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h
index 5b9a3cb..d8561dc 100644
--- a/plat/st/stm32mp1/stm32mp1_fip_def.h
+++ b/plat/st/stm32mp1/stm32mp1_fip_def.h
@@ -7,10 +7,14 @@
 #ifndef STM32MP1_FIP_DEF_H
 #define STM32MP1_FIP_DEF_H
 
+#define STM32MP_DDR_S_SIZE		U(0x01E00000)	/* 30 MB */
+#define STM32MP_DDR_SHMEM_SIZE		U(0x00200000)	/* 2 MB */
+
 #define STM32MP_BL2_SIZE		U(0x0001B000)	/* 108 KB for BL2 */
 #define STM32MP_BL2_DTB_SIZE		U(0x00006000)	/* 24 KB for DTB */
 #define STM32MP_BL32_SIZE		U(0x00019000)	/* 100 KB for BL32 */
 #define STM32MP_BL32_DTB_SIZE		U(0x00005000)	/* 20 KB for DTB */
+#define STM32MP_FW_CONFIG_MAX_SIZE	PAGE_SIZE	/* 4 KB for FCONF DTB */
 #define STM32MP_HW_CONFIG_MAX_SIZE	U(0x40000)	/* 256 KB for HW config DTB */
 
 #define STM32MP_BL2_BASE		(STM32MP_SEC_SYSRAM_BASE + \
@@ -25,6 +29,7 @@
 #define STM32MP_BL32_BASE		(STM32MP_BL32_DTB_BASE + \
 					 STM32MP_BL32_DTB_SIZE)
 
+
 #if defined(IMAGE_BL2)
 #define STM32MP_DTB_SIZE		STM32MP_BL2_DTB_SIZE
 #define STM32MP_DTB_BASE		STM32MP_BL2_DTB_BASE
@@ -41,6 +46,9 @@
 					 STM32MP_OPTEE_BASE)
 #endif
 
+#define STM32MP_FW_CONFIG_BASE		(STM32MP_SYSRAM_BASE + \
+					 STM32MP_SYSRAM_SIZE - \
+					 PAGE_SIZE)
 #define STM32MP_HW_CONFIG_BASE		(STM32MP_BL33_BASE + \
 					STM32MP_BL33_MAX_SIZE)
 
diff --git a/plat/st/stm32mp1/stm32mp1_stm32image_def.h b/plat/st/stm32mp1/stm32mp1_stm32image_def.h
index 8bae56a..8efa342 100644
--- a/plat/st/stm32mp1/stm32mp1_stm32image_def.h
+++ b/plat/st/stm32mp1/stm32mp1_stm32image_def.h
@@ -7,6 +7,14 @@
 #ifndef STM32MP1_STM32IMAGE_DEF_H
 #define STM32MP1_STM32IMAGE_DEF_H
 
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_DDR_S_SIZE		U(0x01E00000)	/* 30 MB */
+#define STM32MP_DDR_SHMEM_SIZE		U(0x00200000)	/* 2 MB */
+#else
+#define STM32MP_DDR_S_SIZE		U(0)
+#define STM32MP_DDR_SHMEM_SIZE		U(0)
+#endif
+
 #define STM32MP_BL2_SIZE		U(0x0001C000)	/* 112 KB for BL2 */
 #define STM32MP_DTB_SIZE		U(0x00006000)	/* 24 KB for DTB */