feat(stm32mp2): add BL31 device tree support
BL31 will need to access a device tree for several configurations (UART,
GIC, OTP mapping...).
Create a BL31 device tree (SOC_FW_CONFIG). It is loaded in DDR, in a
spare area.
Signed-off-by: Yann Gautier <yann.gautier@foss.st.com>
Signed-off-by: Maxime Méré <maxime.mere@foss.st.com>
Change-Id: I320a05859e1aa3dd8db9a274e7201075a8c250c2
diff --git a/fdts/stm32mp25-bl2.dtsi b/fdts/stm32mp25-bl2.dtsi
index e250e3f..e6662d0 100644
--- a/fdts/stm32mp25-bl2.dtsi
+++ b/fdts/stm32mp25-bl2.dtsi
@@ -31,6 +31,7 @@
bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9";
bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
+ soc_fw_cfg_uuid = "9979814b-0376-fb46-8c8e-8d267f7859e0";
tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
};
diff --git a/fdts/stm32mp25-bl31.dtsi b/fdts/stm32mp25-bl31.dtsi
new file mode 100644
index 0000000..fa63f63
--- /dev/null
+++ b/fdts/stm32mp25-bl31.dtsi
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ */
+
+/ {
+ soc@0 {
+ rifsc@42080000 {
+ /delete-node/ mmc@48220000;
+ /delete-node/ mmc@48230000;
+ };
+ };
+};
diff --git a/fdts/stm32mp25-fw-config.dtsi b/fdts/stm32mp25-fw-config.dtsi
index 102980d..2f83f24 100644
--- a/fdts/stm32mp25-fw-config.dtsi
+++ b/fdts/stm32mp25-fw-config.dtsi
@@ -31,6 +31,10 @@
id = <BL31_IMAGE_ID>;
};
+ soc_fw-config {
+ id = <SOC_FW_CONFIG_ID>;
+ };
+
tos_fw {
id = <BL32_IMAGE_ID>;
};
diff --git a/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi b/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
index e41c6b9..5bfcf8d 100644
--- a/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
+++ b/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
@@ -11,6 +11,10 @@
/ {
dtb-registry {
+ soc_fw-config {
+ load-address = <0x0 0x81ff0000>;
+ max-size = <0x10000>;
+ };
tos_fw {
load-address = <0x0 0x82000000>;
max-size = <0x2000000>;
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 1aecece..644275e 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -77,7 +77,7 @@
#define DEFAULT_UUID_NUMBER U(7)
#ifdef __aarch64__
-#define BL31_UUID_NUMBER U(1)
+#define BL31_UUID_NUMBER U(2)
#else
#define BL31_UUID_NUMBER U(0)
#endif
@@ -115,6 +115,7 @@
{FW_CONFIG_ID, "fw_cfg_uuid"},
#ifdef __aarch64__
{BL31_IMAGE_ID, "bl31_uuid"},
+ {SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"},
#endif
{BL32_IMAGE_ID, "bl32_uuid"},
{BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"},
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index 345850b..2fabc41 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -280,6 +280,7 @@
unsigned int i;
const unsigned int image_ids[] = {
BL31_IMAGE_ID,
+ SOC_FW_CONFIG_ID,
BL32_IMAGE_ID,
BL33_IMAGE_ID,
HW_CONFIG_ID,
@@ -345,6 +346,7 @@
break;
case HW_CONFIG_ID:
+ case SOC_FW_CONFIG_ID:
break;
default:
diff --git a/plat/st/stm32mp2/bl31_plat_setup.c b/plat/st/stm32mp2/bl31_plat_setup.c
index dbf1371..eb3bcfc 100644
--- a/plat/st/stm32mp2/bl31_plat_setup.c
+++ b/plat/st/stm32mp2/bl31_plat_setup.c
@@ -8,12 +8,16 @@
#include <stdint.h>
#include <common/bl_common.h>
+#include <drivers/generic_delay_timer.h>
#include <drivers/st/stm32_console.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <platform_def.h>
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
@@ -31,6 +35,12 @@
BL_CODE_END - BL_CODE_BASE,
MT_CODE | MT_SECURE);
+ /*
+ * Map soc_fw_config device tree with secure property, i.e. default region.
+ * DDR region definitions will be finalized at BL32 level.
+ */
+ mmap_add_region(arg1, arg1, STM32MP_SOC_FW_CONFIG_MAX_SIZE, MT_RO_DATA | MT_SECURE);
+
#if USE_COHERENT_MEM
/* Map coherent memory */
mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
@@ -40,6 +50,20 @@
configure_mmu();
+ ret = dt_open_and_check(arg1);
+ if (ret < 0) {
+ EARLY_ERROR("%s: failed to open DT (%d)\n", __func__, ret);
+ panic();
+ }
+
+ ret = stm32mp2_clk_init();
+ if (ret < 0) {
+ EARLY_ERROR("%s: failed init clocks (%d)\n", __func__, ret);
+ panic();
+ }
+
+ (void)stm32mp_uart_console_setup();
+
/*
* Map upper SYSRAM where bl_params_t are stored in BL2
*/
@@ -60,6 +84,31 @@
bl_params_node_t *bl_params = params_from_bl2->head;
while (bl_params != NULL) {
+ /*
+ * Copy BL33 entry point information.
+ * They are stored in Secure RAM, in BL2's address space.
+ */
+ if (bl_params->image_id == BL33_IMAGE_ID) {
+ bl33_image_ep_info = *bl_params->ep_info;
+ /*
+ * Check if hw_configuration is given to BL32 and
+ * share it to BL33
+ */
+ if (arg2 != 0U) {
+ bl33_image_ep_info.args.arg0 = 0U;
+ bl33_image_ep_info.args.arg1 = 0U;
+ bl33_image_ep_info.args.arg2 = arg2;
+ }
+ }
+
+ if (bl_params->image_id == BL32_IMAGE_ID) {
+ bl32_image_ep_info = *bl_params->ep_info;
+
+ if (arg2 != 0U) {
+ bl32_image_ep_info.args.arg3 = arg2;
+ }
+ }
+
bl_params = bl_params->next_params_info;
}
@@ -81,5 +130,27 @@
entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
{
- return NULL;
+ entry_point_info_t *next_image_info = NULL;
+
+ assert(sec_state_is_valid(type));
+
+ switch (type) {
+ case NON_SECURE:
+ next_image_info = &bl33_image_ep_info;
+ break;
+
+ case SECURE:
+ next_image_info = &bl32_image_ep_info;
+ break;
+
+ default:
+ break;
+ }
+
+ /* None of the next images on ST platforms can have 0x0 as the entrypoint */
+ if ((next_image_info == NULL) || (next_image_info->pc == 0UL)) {
+ return NULL;
+ }
+
+ return next_image_info;
}
diff --git a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
index ecad0b4..2513180 100644
--- a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
@@ -70,6 +70,21 @@
.next_handoff_image_id = BL32_IMAGE_ID,
},
+ /* Fill SoC FW config related information */
+ {
+ .image_id = SOC_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_SKIP_LOADING),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+
/* Fill BL32 related information */
{
.image_id = BL32_IMAGE_ID,
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index c12e512..df1cacd 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -48,6 +48,8 @@
# Device tree
BL2_DTSI := stm32mp25-bl2.dtsi
FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
+BL31_DTSI := stm32mp25-bl31.dtsi
+FDT_SOURCES += $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl31.dts,$(DTB_FILE_NAME)))
# Macros and rules to build TF binary
STM32_TF_STM32 := $(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME)))
@@ -56,6 +58,7 @@
STM32MP_FW_CONFIG_NAME := $(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
STM32MP_FW_CONFIG := ${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME)
+STM32MP_SOC_FW_CONFIG := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl31.dtb,$(DTB_FILE_NAME)))
ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
STM32MP_DDR_FW_PATH ?= drivers/st/ddr/phy/firmware/bin/stm32mp2
STM32MP_DDR_FW_NAME := ${DDR_TYPE}_pmu_train.bin
@@ -64,6 +67,8 @@
FDT_SOURCES += $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME)))
# Add the FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
+# Add the SOC_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_IMG,STM32MP_SOC_FW_CONFIG,--soc-fw-config))
ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
# Add the FW_DDR to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_IMG,STM32MP_DDR_FW,--ddr-fw))
@@ -198,4 +203,11 @@
false; \
fi
+# Create DTB file for BL31
+${BUILD_PLAT}/fdts/%-bl31.dts: fdts/%.dts fdts/${BL31_DTSI} | $$(@D)/
+ @echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+ @echo '#include "${BL31_DTSI}"' >> $@
+
+${BUILD_PLAT}/fdts/%-bl31.dtb: ${BUILD_PLAT}/fdts/%-bl31.dts
+
include plat/st/common/common_rules.mk
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 73116db..b441502 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -138,7 +138,11 @@
* MAX_MMAP_REGIONS is usually:
* BL stm32mp2_mmap size + mmap regions in *_plat_arch_setup
*/
+#if defined(IMAGE_BL31)
+#define MAX_MMAP_REGIONS 7
+#else
#define MAX_MMAP_REGIONS 6
+#endif
/* DTB initialization value */
#define STM32MP_BL2_DTB_SIZE U(0x00006000) /* 24 KB for DTB */
@@ -166,6 +170,7 @@
#define STM32MP_HW_CONFIG_BASE (STM32MP_BL33_BASE + \
STM32MP_BL33_MAX_SIZE)
#define STM32MP_HW_CONFIG_MAX_SIZE U(0x40000)
+#define STM32MP_SOC_FW_CONFIG_MAX_SIZE U(0x10000) /* 64kB for BL31 DT */
/*******************************************************************************
* STM32MP2 device/io map related constants (used for MMU)
diff --git a/plat/st/stm32mp2/stm32mp2_private.c b/plat/st/stm32mp2/stm32mp2_private.c
index 7ad974f..5be4c5a 100644
--- a/plat/st/stm32mp2/stm32mp2_private.c
+++ b/plat/st/stm32mp2/stm32mp2_private.c
@@ -117,6 +117,33 @@
return CK_BUS_GPIOA + (bank - GPIO_BANK_A);
}
+#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
+/*
+ * UART Management
+ */
+static const uintptr_t stm32mp2_uart_addresses[STM32MP_NB_OF_UART] = {
+ USART1_BASE,
+ USART2_BASE,
+ USART3_BASE,
+ UART4_BASE,
+ UART5_BASE,
+ USART6_BASE,
+ UART7_BASE,
+ UART8_BASE,
+ UART9_BASE,
+};
+
+uintptr_t get_uart_address(uint32_t instance_nb)
+{
+ if ((instance_nb == 0U) ||
+ (instance_nb > STM32MP_NB_OF_UART)) {
+ return 0U;
+ }
+
+ return stm32mp2_uart_addresses[instance_nb - 1U];
+}
+#endif
+
uint32_t stm32mp_get_chip_version(void)
{
static uint32_t rev;