From aa7f6cd8b363fb97efd232991eb9ccedc2316a9d Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 27 Nov 2020 14:44:04 +0100 Subject: [PATCH 1/6] feat(st): manage BL31 FCONF load_info struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the file is common with STM32MP1, which is AARCH32, the BL31 entry is put under __aarch64__ flag. Change-Id: I1efc406717842235264dc6cc3605229659364b02 Signed-off-by: Yann Gautier Signed-off-by: Maxime Méré --- plat/st/common/stm32mp_fconf_io.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c index 6ed09d9c0..7a8cf78f7 100644 --- a/plat/st/common/stm32mp_fconf_io.c +++ b/plat/st/common/stm32mp_fconf_io.c @@ -76,6 +76,12 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { #define DEFAULT_UUID_NUMBER U(7) +#ifdef __aarch64__ +#define BL31_UUID_NUMBER U(1) +#else +#define BL31_UUID_NUMBER U(0) +#endif + #if TRUSTED_BOARD_BOOT #define TBBR_UUID_NUMBER U(6) #else @@ -83,6 +89,7 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { #endif #define FCONF_ST_IO_UUID_NUMBER (DEFAULT_UUID_NUMBER + \ + BL31_UUID_NUMBER + \ TBBR_UUID_NUMBER) static io_uuid_spec_t fconf_stm32mp_uuids[FCONF_ST_IO_UUID_NUMBER]; @@ -96,6 +103,9 @@ struct policies_load_info { /* image id to property name table */ static const struct policies_load_info load_info[FCONF_ST_IO_UUID_NUMBER] = { {FW_CONFIG_ID, "fw_cfg_uuid"}, +#ifdef __aarch64__ + {BL31_IMAGE_ID, "bl31_uuid"}, +#endif {BL32_IMAGE_ID, "bl32_uuid"}, {BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"}, {BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"}, From 03020b6688b459da84bdb2a3fb58c99916bfd7f7 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 13 Jun 2023 18:45:03 +0200 Subject: [PATCH 2/6] feat(stm32mp2): add minimal support for BL31 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the required files to compile BL31 on STM32MP2. Update BL2 configuration to load BL31. The platform boots until BL31, but stops here as no other binaries are loaded as DDR is not initialized. At runtime, BL31 will use only the first half of the SYSRAM, the upper half will be used for non-secure DMA LLIs. To be sure nothing from this area is still in the cache, invalidate the upper SYSRAM before enabling BL31 cache. BL31 should then map only first half of the SYSRAM. But it must temporarily map the upper half read-only, as this is where we will retrieve BL2 parameters, used to fill registers for next boot stages. Signed-off-by: Yann Gautier Signed-off-by: Maxime Méré Change-Id: Ie91527a7a26625624b4b3c65fb6a0ca9dd355dbd --- plat/st/stm32mp2/bl2_plat_setup.c | 32 ++++- plat/st/stm32mp2/bl31_plat_setup.c | 85 ++++++++++++++ plat/st/stm32mp2/include/platform_def.h | 62 +++++++++- plat/st/stm32mp2/plat_bl2_mem_params_desc.c | 17 +++ plat/st/stm32mp2/platform.mk | 16 +++ plat/st/stm32mp2/stm32mp2_def.h | 5 + plat/st/stm32mp2/stm32mp2_pm.c | 124 ++++++++++++++++++++ plat/st/stm32mp2/stm32mp2_private.c | 17 +++ plat/st/stm32mp2/stm32mp2_topology.c | 57 +++++++++ 9 files changed, 411 insertions(+), 4 deletions(-) create mode 100644 plat/st/stm32mp2/bl31_plat_setup.c create mode 100644 plat/st/stm32mp2/stm32mp2_pm.c create mode 100644 plat/st/stm32mp2/stm32mp2_topology.c diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c index edada72c9..7fcaf8535 100644 --- a/plat/st/stm32mp2/bl2_plat_setup.c +++ b/plat/st/stm32mp2/bl2_plat_setup.c @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -229,7 +230,12 @@ skip_console_init: int bl2_plat_handle_post_image_load(unsigned int image_id) { int err = 0; - bl_mem_params_node_t *bl_mem_params __maybe_unused = get_bl_mem_params_node(image_id); + bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); + const struct dyn_cfg_dtb_info_t *config_info; + unsigned int i; + const unsigned int image_ids[] = { + BL31_IMAGE_ID, + }; assert(bl_mem_params != NULL); @@ -253,6 +259,30 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) 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 BL31_IMAGE_ID: + bl_mem_params->ep_info.pc = config_info->config_addr; + break; + default: + return -EINVAL; + } + } + /* * After this step, the BL2 device tree area will be overwritten * with BL31 binary, no other data should be read from BL2 DT. diff --git a/plat/st/stm32mp2/bl31_plat_setup.c b/plat/st/stm32mp2/bl31_plat_setup.c new file mode 100644 index 000000000..dbf137193 --- /dev/null +++ b/plat/st/stm32mp2/bl31_plat_setup.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include + +#include + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + bl_params_t *params_from_bl2; + int ret; + + /* + * Invalidate remaining data from second half of SYSRAM (used by BL2) as this area will + * be later used as non-secure. + */ + inv_dcache_range(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U, + STM32MP_SYSRAM_SIZE / 2U); + + mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, + BL_CODE_END - BL_CODE_BASE, + MT_CODE | MT_SECURE); + +#if USE_COHERENT_MEM + /* Map coherent memory */ + mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, + MT_DEVICE | MT_RW | MT_SECURE); +#endif + + configure_mmu(); + + /* + * Map upper SYSRAM where bl_params_t are stored in BL2 + */ + ret = mmap_add_dynamic_region(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U, + STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U, + STM32MP_SYSRAM_SIZE / 2U, MT_RO_DATA | MT_SECURE); + if (ret < 0) { + ERROR("BL2 params area mapping: %d\n", ret); + panic(); + } + + assert(arg0 != 0UL); + params_from_bl2 = (bl_params_t *)arg0; + assert(params_from_bl2 != NULL); + assert(params_from_bl2->h.type == PARAM_BL_PARAMS); + assert(params_from_bl2->h.version >= VERSION_2); + + bl_params_node_t *bl_params = params_from_bl2->head; + + while (bl_params != NULL) { + bl_params = bl_params->next_params_info; + } + + ret = mmap_remove_dynamic_region(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U, + STM32MP_SYSRAM_SIZE / 2U); + if (ret < 0) { + ERROR("BL2 params area unmapping: %d\n", ret); + panic(); + } +} + +void bl31_plat_arch_setup(void) +{ +} + +void bl31_platform_setup(void) +{ +} + +entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type) +{ + return NULL; +} diff --git a/plat/st/stm32mp2/include/platform_def.h b/plat/st/stm32mp2/include/platform_def.h index 0f22a93be..89ca032e3 100644 --- a/plat/st/stm32mp2/include/platform_def.h +++ b/plat/st/stm32mp2/include/platform_def.h @@ -8,6 +8,7 @@ #define PLATFORM_DEF_H #include +#include #include #include @@ -32,9 +33,9 @@ #define PLATFORM_CORE_COUNT U(2) #define PLATFORM_MAX_CPUS_PER_CLUSTER U(2) -#define PLAT_MAX_PWR_LVL U(5) -#define PLAT_MAX_CPU_SUSPEND_PWR_LVL U(5) -#define PLAT_NUM_PWR_DOMAINS U(7) +#define PLAT_MAX_PWR_LVL U(3) +#define PLAT_MIN_SUSPEND_PWR_LVL U(2) +#define PLAT_NUM_PWR_DOMAINS U(6) /* Local power state for power domains in Run state. */ #define STM32MP_LOCAL_STATE_RUN U(0) @@ -98,4 +99,59 @@ #define CACHE_WRITEBACK_SHIFT 6 #define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT) +/* + * Secure Interrupt: based on the standard ARM mapping + */ +#define ARM_IRQ_SEC_PHY_TIMER U(29) + +#define ARM_IRQ_NON_SEC_SGI_0 U(0) + +#define ARM_IRQ_SEC_SGI_0 U(8) +#define ARM_IRQ_SEC_SGI_1 U(9) +#define ARM_IRQ_SEC_SGI_2 U(10) +#define ARM_IRQ_SEC_SGI_3 U(11) +#define ARM_IRQ_SEC_SGI_4 U(12) +#define ARM_IRQ_SEC_SGI_5 U(13) +#define ARM_IRQ_SEC_SGI_6 U(14) +#define ARM_IRQ_SEC_SGI_7 U(15) + +/* Platform IRQ Priority */ +#define STM32MP_IRQ_SEC_SPI_PRIO U(0x10) + +/* + * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define PLATFORM_G1S_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, \ + GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, \ + GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, \ + GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, \ + GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, \ + GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, \ + GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, \ + GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE) + +#define PLATFORM_G0_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, \ + GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, \ + GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c index 0ef522e82..137ea6323 100644 --- a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c +++ b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c @@ -34,6 +34,23 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { .next_handoff_image_id = INVALID_IMAGE_ID, }, + + /* Fill BL31 related information */ + { + .image_id = BL31_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + + .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_SKIP_LOADING), + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, }; REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk index eacbd969b..3ab4dbff0 100644 --- a/plat/st/stm32mp2/platform.mk +++ b/plat/st/stm32mp2/platform.mk @@ -98,5 +98,21 @@ endif BL2_SOURCES += drivers/st/ddr/stm32mp2_ddr_helpers.c +# BL31 sources +BL31_SOURCES += ${FDT_WRAPPERS_SOURCES} + +BL31_SOURCES += plat/st/stm32mp2/bl31_plat_setup.c \ + plat/st/stm32mp2/stm32mp2_pm.c \ + plat/st/stm32mp2/stm32mp2_topology.c +# Generic GIC v2 +include drivers/arm/gic/v2/gicv2.mk + +BL31_SOURCES += ${GICV2_SOURCES} \ + plat/common/plat_gicv2.c \ + plat/st/common/stm32mp_gic.c + +# Generic PSCI +BL31_SOURCES += plat/common/plat_psci_common.c + # Compilation rules include plat/st/common/common_rules.mk diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h index 81fdaaed1..058616b37 100644 --- a/plat/st/stm32mp2/stm32mp2_def.h +++ b/plat/st/stm32mp2/stm32mp2_def.h @@ -71,6 +71,7 @@ ******************************************************************************/ #define STM32MP_SYSRAM_BASE U(0x0E000000) #define STM32MP_SYSRAM_SIZE U(0x00040000) +#define STM32MP_SEC_SYSRAM_SIZE STM32MP_SYSRAM_SIZE /* DDR configuration */ #define STM32MP_DDR_BASE U(0x80000000) @@ -106,6 +107,10 @@ enum ddr_type { #define STM32MP_BL2_RO_SIZE U(0x00020000) /* 128 KB */ #define STM32MP_BL2_SIZE U(0x00029000) /* 164 KB for BL2 */ +/* Allocate remaining sysram to BL31 */ +#define STM32MP_BL31_SIZE (STM32MP_SEC_SYSRAM_SIZE - \ + STM32MP_BL2_SIZE) + #define STM32MP_BL2_BASE (STM32MP_SYSRAM_BASE + \ STM32MP_SYSRAM_SIZE - \ STM32MP_BL2_SIZE) diff --git a/plat/st/stm32mp2/stm32mp2_pm.c b/plat/st/stm32mp2/stm32mp2_pm.c new file mode 100644 index 000000000..5bb381d0d --- /dev/null +++ b/plat/st/stm32mp2/stm32mp2_pm.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2024, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static uintptr_t stm32_sec_entrypoint; + +static void stm32_cpu_standby(plat_local_state_t cpu_state) +{ +} + +static int stm32_pwr_domain_on(u_register_t mpidr) +{ + return PSCI_E_INTERN_FAIL; +} + +static void stm32_pwr_domain_off(const psci_power_state_t *target_state) +{ + /* Nothing to do */ +} + +static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + /* Nothing to do, power domain is not disabled */ +} + +static void stm32_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ +} + +/******************************************************************************* + * STM32MP2 handler called when a power domain has just been powered on after + * having been suspended earlier. The target_state encodes the low power state + * that each level has woken up from. + ******************************************************************************/ +static void stm32_pwr_domain_suspend_finish(const psci_power_state_t + *target_state) +{ + /* Nothing to do, power domain is not disabled */ +} + +static void __dead2 stm32_pwr_domain_pwr_down_wfi(const psci_power_state_t + *target_state) +{ + ERROR("stm32mp2 Power Down WFI: operation not handled.\n"); + panic(); +} + +static void __dead2 stm32_system_off(void) +{ + ERROR("stm32mp2 System Off: operation not handled.\n"); + panic(); +} + +static void __dead2 stm32_system_reset(void) +{ + stm32mp_system_reset(); +} + +static int stm32_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + return PSCI_E_INVALID_PARAMS; +} + +static int stm32_validate_ns_entrypoint(uintptr_t entrypoint) +{ + /* The non-secure entry point must be in DDR */ + if (entrypoint < STM32MP_DDR_BASE) { + return PSCI_E_INVALID_ADDRESS; + } + + return PSCI_E_SUCCESS; +} + +static void stm32_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ +} + +/******************************************************************************* + * Export the platform handlers. The ARM Standard platform layer will take care + * of registering the handlers with PSCI. + ******************************************************************************/ +static const plat_psci_ops_t stm32_psci_ops = { + .cpu_standby = stm32_cpu_standby, + .pwr_domain_on = stm32_pwr_domain_on, + .pwr_domain_off = stm32_pwr_domain_off, + .pwr_domain_suspend = stm32_pwr_domain_suspend, + .pwr_domain_on_finish = stm32_pwr_domain_on_finish, + .pwr_domain_suspend_finish = stm32_pwr_domain_suspend_finish, + .pwr_domain_pwr_down_wfi = stm32_pwr_domain_pwr_down_wfi, + .system_off = stm32_system_off, + .system_reset = stm32_system_reset, + .validate_power_state = stm32_validate_power_state, + .validate_ns_entrypoint = stm32_validate_ns_entrypoint, + .get_sys_suspend_power_state = stm32_get_sys_suspend_power_state, +}; + +/******************************************************************************* + * Export the platform specific power ops. + ******************************************************************************/ +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + stm32_sec_entrypoint = sec_entrypoint; + *psci_ops = &stm32_psci_ops; + + return 0; +} diff --git a/plat/st/stm32mp2/stm32mp2_private.c b/plat/st/stm32mp2/stm32mp2_private.c index 2801a7fb0..06ff7c8b4 100644 --- a/plat/st/stm32mp2/stm32mp2_private.c +++ b/plat/st/stm32mp2/stm32mp2_private.c @@ -12,12 +12,22 @@ #define BKPR_BOOT_MODE 96U +#if defined(IMAGE_BL31) +/* BL31 only uses the first half of the SYSRAM */ +#define MAP_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ + STM32MP_SYSRAM_SIZE / 2U, \ + MT_MEMORY | \ + MT_RW | \ + MT_SECURE | \ + MT_EXECUTE_NEVER) +#else #define MAP_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ STM32MP_SYSRAM_SIZE, \ MT_MEMORY | \ MT_RW | \ MT_SECURE | \ MT_EXECUTE_NEVER) +#endif #define MAP_DEVICE MAP_REGION_FLAT(STM32MP_DEVICE_BASE, \ STM32MP_DEVICE_SIZE, \ @@ -33,6 +43,13 @@ static const mmap_region_t stm32mp2_mmap[] = { {0} }; #endif +#if defined(IMAGE_BL31) +static const mmap_region_t stm32mp2_mmap[] = { + MAP_SYSRAM, + MAP_DEVICE, + {0} +}; +#endif void configure_mmu(void) { diff --git a/plat/st/stm32mp2/stm32mp2_topology.c b/plat/st/stm32mp2/stm32mp2_topology.c new file mode 100644 index 000000000..cc2d58c01 --- /dev/null +++ b/plat/st/stm32mp2/stm32mp2_topology.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +/* 1 cluster, all cores into */ +static const unsigned char stm32mp2_power_domain_tree_desc[] = { + PLATFORM_CLUSTER_COUNT, + PLATFORM_CORE_COUNT, +}; + +/* This function returns the platform topology */ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return stm32mp2_power_domain_tree_desc; +} + +/******************************************************************************* + * This function implements a part of the critical interface between the psci + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is returned + * in case the MPIDR is invalid. + ******************************************************************************/ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + unsigned int cluster_id, cpu_id; + u_register_t mpidr_copy = mpidr; + + mpidr_copy &= MPIDR_AFFINITY_MASK; + + if ((mpidr_copy & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0U) { + return -1; + } + + cluster_id = (mpidr_copy >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + cpu_id = (mpidr_copy >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; + + if (cluster_id >= PLATFORM_CLUSTER_COUNT) { + return -1; + } + + /* + * Validate cpu_id by checking whether it represents a CPU in one + * of the two clusters present on the platform. + */ + if (cpu_id >= PLATFORM_CORE_COUNT) { + return -1; + } + + return (int)cpu_id; +} From a370c856f1f7655384f8e06f7fd84ded63838c02 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 23 May 2024 17:21:44 +0200 Subject: [PATCH 3/6] feat(stm32mp2-fdts): add BL31 info in fw-config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add BL31 load address (beginning on SYSRAM) and size in fw-config DT file. Signed-off-by: Yann Gautier Signed-off-by: Maxime Méré Change-Id: I2fcd8d326f394090401ac59b47216d59d3e911bc --- fdts/stm32mp25-fw-config.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fdts/stm32mp25-fw-config.dtsi b/fdts/stm32mp25-fw-config.dtsi index b187ad2bd..102980df8 100644 --- a/fdts/stm32mp25-fw-config.dtsi +++ b/fdts/stm32mp25-fw-config.dtsi @@ -25,6 +25,12 @@ id = ; }; + soc_fw { + load-address = <0x0 STM32MP_SYSRAM_BASE>; + max-size = ; + id = ; + }; + tos_fw { id = ; }; From 631c5f86d5438e92e1d64e7dfdab58e92ad3e24f Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Mon, 27 May 2019 14:20:50 +0200 Subject: [PATCH 4/6] feat(stm32mp2): add RISAB registers description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Describe the RISAB (Resource isolation slave unit for address space protection (block-based)) peripheral registers. Change-Id: I613a52ae6d94264137378b805119d38ee59ae762 Signed-off-by: Yann Gautier Signed-off-by: Maxime Méré --- include/drivers/st/stm32mp_risab_regs.h | 271 ++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 include/drivers/st/stm32mp_risab_regs.h diff --git a/include/drivers/st/stm32mp_risab_regs.h b/include/drivers/st/stm32mp_risab_regs.h new file mode 100644 index 000000000..1f49bf696 --- /dev/null +++ b/include/drivers/st/stm32mp_risab_regs.h @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2024, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32MP_RISAB_REGS_H +#define STM32MP_RISAB_REGS_H + +#define RISAB_CR U(0x00) +#define RISAB_IASR U(0x08) +#define RISAB_IACR U(0x0C) +#define RISAB_RIFLOCKR U(0x10) +#define RISAB_IAESR U(0x20) +#define RISAB_IADDR U(0x24) +#define RISAB_PG0_SECCFGR U(0x100) +#define RISAB_PG1_SECCFGR U(0x104) +#define RISAB_PG2_SECCFGR U(0x108) +#define RISAB_PG3_SECCFGR U(0x10C) +#define RISAB_PG4_SECCFGR U(0x110) +#define RISAB_PG5_SECCFGR U(0x114) +#define RISAB_PG6_SECCFGR U(0x118) +#define RISAB_PG7_SECCFGR U(0x11C) +#define RISAB_PG8_SECCFGR U(0x120) +#define RISAB_PG9_SECCFGR U(0x124) +#define RISAB_PG10_SECCFGR U(0x128) +#define RISAB_PG11_SECCFGR U(0x12C) +#define RISAB_PG12_SECCFGR U(0x130) +#define RISAB_PG13_SECCFGR U(0x134) +#define RISAB_PG14_SECCFGR U(0x138) +#define RISAB_PG15_SECCFGR U(0x13C) +#define RISAB_PG16_SECCFGR U(0x140) +#define RISAB_PG17_SECCFGR U(0x144) +#define RISAB_PG18_SECCFGR U(0x148) +#define RISAB_PG19_SECCFGR U(0x14C) +#define RISAB_PG20_SECCFGR U(0x150) +#define RISAB_PG21_SECCFGR U(0x154) +#define RISAB_PG22_SECCFGR U(0x158) +#define RISAB_PG23_SECCFGR U(0x15C) +#define RISAB_PG24_SECCFGR U(0x160) +#define RISAB_PG25_SECCFGR U(0x164) +#define RISAB_PG26_SECCFGR U(0x168) +#define RISAB_PG27_SECCFGR U(0x16C) +#define RISAB_PG28_SECCFGR U(0x170) +#define RISAB_PG29_SECCFGR U(0x174) +#define RISAB_PG30_SECCFGR U(0x178) +#define RISAB_PG31_SECCFGR U(0x17C) +#define RISAB_PG0_PRIVCFGR U(0x200) +#define RISAB_PG1_PRIVCFGR U(0x204) +#define RISAB_PG2_PRIVCFGR U(0x208) +#define RISAB_PG3_PRIVCFGR U(0x20C) +#define RISAB_PG4_PRIVCFGR U(0x210) +#define RISAB_PG5_PRIVCFGR U(0x214) +#define RISAB_PG6_PRIVCFGR U(0x218) +#define RISAB_PG7_PRIVCFGR U(0x21C) +#define RISAB_PG8_PRIVCFGR U(0x220) +#define RISAB_PG9_PRIVCFGR U(0x224) +#define RISAB_PG10_PRIVCFGR U(0x228) +#define RISAB_PG11_PRIVCFGR U(0x22C) +#define RISAB_PG12_PRIVCFGR U(0x230) +#define RISAB_PG13_PRIVCFGR U(0x234) +#define RISAB_PG14_PRIVCFGR U(0x238) +#define RISAB_PG15_PRIVCFGR U(0x23C) +#define RISAB_PG16_PRIVCFGR U(0x240) +#define RISAB_PG17_PRIVCFGR U(0x244) +#define RISAB_PG18_PRIVCFGR U(0x248) +#define RISAB_PG19_PRIVCFGR U(0x24C) +#define RISAB_PG20_PRIVCFGR U(0x250) +#define RISAB_PG21_PRIVCFGR U(0x254) +#define RISAB_PG22_PRIVCFGR U(0x258) +#define RISAB_PG23_PRIVCFGR U(0x25C) +#define RISAB_PG24_PRIVCFGR U(0x260) +#define RISAB_PG25_PRIVCFGR U(0x264) +#define RISAB_PG26_PRIVCFGR U(0x268) +#define RISAB_PG27_PRIVCFGR U(0x26C) +#define RISAB_PG28_PRIVCFGR U(0x270) +#define RISAB_PG29_PRIVCFGR U(0x274) +#define RISAB_PG30_PRIVCFGR U(0x278) +#define RISAB_PG31_PRIVCFGR U(0x27C) +#define RISAB_PG0_C2PRIVCFGR U(0x600) +#define RISAB_PG1_C2PRIVCFGR U(0x604) +#define RISAB_PG2_C2PRIVCFGR U(0x608) +#define RISAB_PG3_C2PRIVCFGR U(0x60C) +#define RISAB_PG4_C2PRIVCFGR U(0x610) +#define RISAB_PG5_C2PRIVCFGR U(0x614) +#define RISAB_PG6_C2PRIVCFGR U(0x618) +#define RISAB_PG7_C2PRIVCFGR U(0x61C) +#define RISAB_PG8_C2PRIVCFGR U(0x620) +#define RISAB_PG9_C2PRIVCFGR U(0x624) +#define RISAB_PG10_C2PRIVCFGR U(0x628) +#define RISAB_PG11_C2PRIVCFGR U(0x62C) +#define RISAB_PG12_C2PRIVCFGR U(0x630) +#define RISAB_PG13_C2PRIVCFGR U(0x634) +#define RISAB_PG14_C2PRIVCFGR U(0x638) +#define RISAB_PG15_C2PRIVCFGR U(0x63C) +#define RISAB_PG16_C2PRIVCFGR U(0x640) +#define RISAB_PG17_C2PRIVCFGR U(0x644) +#define RISAB_PG18_C2PRIVCFGR U(0x648) +#define RISAB_PG19_C2PRIVCFGR U(0x64C) +#define RISAB_PG20_C2PRIVCFGR U(0x650) +#define RISAB_PG21_C2PRIVCFGR U(0x654) +#define RISAB_PG22_C2PRIVCFGR U(0x658) +#define RISAB_PG23_C2PRIVCFGR U(0x65C) +#define RISAB_PG24_C2PRIVCFGR U(0x660) +#define RISAB_PG25_C2PRIVCFGR U(0x664) +#define RISAB_PG26_C2PRIVCFGR U(0x668) +#define RISAB_PG27_C2PRIVCFGR U(0x66C) +#define RISAB_PG28_C2PRIVCFGR U(0x670) +#define RISAB_PG29_C2PRIVCFGR U(0x674) +#define RISAB_PG30_C2PRIVCFGR U(0x678) +#define RISAB_PG31_C2PRIVCFGR U(0x67C) +#define RISAB_CID0PRIVCFGR U(0x800) +#define RISAB_CID0RDCFGR U(0x808) +#define RISAB_CID0WRCFGR U(0x810) +#define RISAB_CID1PRIVCFGR U(0x820) +#define RISAB_CID1RDCFGR U(0x828) +#define RISAB_CID1WRCFGR U(0x830) +#define RISAB_CID2PRIVCFGR U(0x840) +#define RISAB_CID2RDCFGR U(0x848) +#define RISAB_CID2WRCFGR U(0x850) +#define RISAB_CID3PRIVCFGR U(0x860) +#define RISAB_CID3RDCFGR U(0x868) +#define RISAB_CID3WRCFGR U(0x870) +#define RISAB_CID4PRIVCFGR U(0x880) +#define RISAB_CID4RDCFGR U(0x888) +#define RISAB_CID4WRCFGR U(0x890) +#define RISAB_CID5PRIVCFGR U(0x8A0) +#define RISAB_CID5RDCFGR U(0x8A8) +#define RISAB_CID5WRCFGR U(0x8B0) +#define RISAB_CID6PRIVCFGR U(0x8C0) +#define RISAB_CID6RDCFGR U(0x8C8) +#define RISAB_CID6WRCFGR U(0x8D0) +#define RISAB_PG0_CIDCFGR U(0xA00) +#define RISAB_PG1_CIDCFGR U(0xA04) +#define RISAB_PG2_CIDCFGR U(0xA08) +#define RISAB_PG3_CIDCFGR U(0xA0C) +#define RISAB_PG4_CIDCFGR U(0xA10) +#define RISAB_PG5_CIDCFGR U(0xA14) +#define RISAB_PG6_CIDCFGR U(0xA18) +#define RISAB_PG7_CIDCFGR U(0xA1C) +#define RISAB_PG8_CIDCFGR U(0xA20) +#define RISAB_PG9_CIDCFGR U(0xA24) +#define RISAB_PG10_CIDCFGR U(0xA28) +#define RISAB_PG11_CIDCFGR U(0xA2C) +#define RISAB_PG12_CIDCFGR U(0xA30) +#define RISAB_PG13_CIDCFGR U(0xA34) +#define RISAB_PG14_CIDCFGR U(0xA38) +#define RISAB_PG15_CIDCFGR U(0xA3C) +#define RISAB_PG16_CIDCFGR U(0xA40) +#define RISAB_PG17_CIDCFGR U(0xA44) +#define RISAB_PG18_CIDCFGR U(0xA48) +#define RISAB_PG19_CIDCFGR U(0xA4C) +#define RISAB_PG20_CIDCFGR U(0xA50) +#define RISAB_PG21_CIDCFGR U(0xA54) +#define RISAB_PG22_CIDCFGR U(0xA58) +#define RISAB_PG23_CIDCFGR U(0xA5C) +#define RISAB_PG24_CIDCFGR U(0xA60) +#define RISAB_PG25_CIDCFGR U(0xA64) +#define RISAB_PG26_CIDCFGR U(0xA68) +#define RISAB_PG27_CIDCFGR U(0xA6C) +#define RISAB_PG28_CIDCFGR U(0xA70) +#define RISAB_PG29_CIDCFGR U(0xA74) +#define RISAB_PG30_CIDCFGR U(0xA78) +#define RISAB_PG31_CIDCFGR U(0xA7C) +#define RISAB_HWCFGR3 U(0xFE8) +#define RISAB_HWCFGR2 U(0xFEC) +#define RISAB_HWCFGR1 U(0xFF0) +#define RISAB_VERR U(0xFF4) +#define RISAB_IPIDR U(0xFF8) +#define RISAB_SIDR U(0xFFC) + +/* RISAB_CR register fields */ +#define RISAB_CR_GLOCK BIT(0) +#define RISAB_CR_SRWIAD BIT(31) + +/* RISAB_IASR register fields */ +#define RISAB_IASR_CAEF BIT(0) +#define RISAB_IASR_IAEF BIT(1) + +/* RISAB_IACR register fields */ +#define RISAB_IACR_CAEF BIT(0) +#define RISAB_IACR_IAEF BIT(1) + +/* RISAB_RIFLOCKR register fields */ +#define RISAB_RIFLOCKR_RLOCK0 BIT(0) +#define RISAB_RIFLOCKR_RLOCK1 BIT(1) +#define RISAB_RIFLOCKR_RLOCK2 BIT(2) +#define RISAB_RIFLOCKR_RLOCK3 BIT(3) +#define RISAB_RIFLOCKR_RLOCK4 BIT(4) +#define RISAB_RIFLOCKR_RLOCK5 BIT(5) +#define RISAB_RIFLOCKR_RLOCK6 BIT(6) +#define RISAB_RIFLOCKR_RLOCK7 BIT(7) +#define RISAB_RIFLOCKR_RLOCK8 BIT(8) +#define RISAB_RIFLOCKR_RLOCK9 BIT(9) +#define RISAB_RIFLOCKR_RLOCK10 BIT(10) +#define RISAB_RIFLOCKR_RLOCK11 BIT(11) +#define RISAB_RIFLOCKR_RLOCK12 BIT(12) +#define RISAB_RIFLOCKR_RLOCK13 BIT(13) +#define RISAB_RIFLOCKR_RLOCK14 BIT(14) +#define RISAB_RIFLOCKR_RLOCK15 BIT(15) +#define RISAB_RIFLOCKR_RLOCK16 BIT(16) +#define RISAB_RIFLOCKR_RLOCK17 BIT(17) +#define RISAB_RIFLOCKR_RLOCK18 BIT(18) +#define RISAB_RIFLOCKR_RLOCK19 BIT(19) +#define RISAB_RIFLOCKR_RLOCK20 BIT(20) +#define RISAB_RIFLOCKR_RLOCK21 BIT(21) +#define RISAB_RIFLOCKR_RLOCK22 BIT(22) +#define RISAB_RIFLOCKR_RLOCK23 BIT(23) +#define RISAB_RIFLOCKR_RLOCK24 BIT(24) +#define RISAB_RIFLOCKR_RLOCK25 BIT(25) +#define RISAB_RIFLOCKR_RLOCK26 BIT(26) +#define RISAB_RIFLOCKR_RLOCK27 BIT(27) +#define RISAB_RIFLOCKR_RLOCK28 BIT(28) +#define RISAB_RIFLOCKR_RLOCK29 BIT(29) +#define RISAB_RIFLOCKR_RLOCK30 BIT(30) +#define RISAB_RIFLOCKR_RLOCK31 BIT(31) + +/* RISAB_IAESR register fields */ +#define RISAB_IAESR_IACID_MASK GENMASK(2, 0) +#define RISAB_IAESR_IACID_SHIFT 0 +#define RISAB_IAESR_IAPRIV BIT(4) +#define RISAB_IAESR_IASEC BIT(5) +#define RISAB_IAESR_IANRW BIT(7) + +/* RISAB_PGx_SECCFGR register fields */ +#define RISAB_PGx_SECCFGR_SEC(_y) BIT(_y) + +/* RISAB_PGx_PRIVCFGR register fields */ +#define RISAB_PGx_PRIVCFGR_PRIV(_y) BIT(_y) + +/* RISAB_PGx_CmPRIVCFGR register fields */ +#define RISAB_PGx_CmPRIVCFGR_PRIV(_y) BIT(_y) + +/* RISAB_CIDxPRIVCFGR register fields */ +#define RISAB_CIDxPRIVCFGR_PPRIV(_y) BIT(_y) + +/* RISAB_CIDxRDCFGR register fields */ +#define RISAB_CIDxRDCFGR_PRDEN(_y) BIT(_y) + +/* RISAB_CIDxWRCFGR register fields */ +#define RISAB_CIDxWRCFGR_PWREN(_y) BIT(_y) + +/* RISAB_PGx_CIDCFGR register fields */ +#define RISAB_PGx_CIDCFGR_CFEN BIT(0) +#define RISAB_PGx_CIDCFGR_DCEN BIT(2) +#define RISAB_PGx_CIDCFGR_DCCID_MASK GENMASK(6, 4) +#define RISAB_PGx_CIDCFGR_DCCID_SHIFT 4 + +/* RISAB_HWCFGR1 register fields */ +#define RISAB_HWCFGR1_CFG1_MASK GENMASK(3, 0) +#define RISAB_HWCFGR1_CFG1_SHIFT 0 +#define RISAB_HWCFGR1_CFG2_MASK GENMASK(7, 4) +#define RISAB_HWCFGR1_CFG2_SHIFT 4 +#define RISAB_HWCFGR1_CFG3_MASK GENMASK(11, 8) +#define RISAB_HWCFGR1_CFG3_SHIFT 8 +#define RISAB_HWCFGR1_CFG4_MASK GENMASK(15, 12) +#define RISAB_HWCFGR1_CFG4_SHIFT 12 +#define RISAB_HWCFGR1_CFG5_MASK GENMASK(19, 16) +#define RISAB_HWCFGR1_CFG5_SHIFT 16 +#define RISAB_HWCFGR1_CFG6_MASK GENMASK(23, 20) +#define RISAB_HWCFGR1_CFG6_SHIFT 20 +#define RISAB_HWCFGR1_CFG7_MASK GENMASK(27, 24) +#define RISAB_HWCFGR1_CFG7_SHIFT 24 + +/* RISAB_VERR register fields */ +#define RISAB_VERR_MINREV_MASK GENMASK(3, 0) +#define RISAB_VERR_MINREV_SHIFT 0 +#define RISAB_VERR_MAJREV_MASK GENMASK(7, 4) +#define RISAB_VERR_MAJREV_SHIFT 4 + +#endif /* STM32MP_RISAB_REGS_H */ From d07e9467d375bd414fefc86dead4a833572a166a Mon Sep 17 00:00:00 2001 From: Nicolas Le Bayon Date: Mon, 5 Jul 2021 15:23:54 +0200 Subject: [PATCH 5/6] feat(stm32mp2): introduce DDR type compilation flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Binary size limitation implies to define DDR type build flags. User must set one single type in the build command line. DDR_TYPE is then deduced, and will help in relative definitions. A check routine is implemented to verify correct configuration. Signed-off-by: Nicolas Le Bayon Signed-off-by: Maxime Méré Change-Id: I87d0a492196efea33831d9c090e6e434cc7c0a1e --- plat/st/stm32mp2/platform.mk | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk index 3ab4dbff0..015b20554 100644 --- a/plat/st/stm32mp2/platform.mk +++ b/plat/st/stm32mp2/platform.mk @@ -27,6 +27,20 @@ STM32_HEADER_VERSION_MINOR := 2 # Set load address for serial boot devices DWL_BUFFER_BASE ?= 0x87000000 +# DDR types +STM32MP_DDR3_TYPE ?= 0 +STM32MP_DDR4_TYPE ?= 0 +STM32MP_LPDDR4_TYPE ?= 0 +ifeq (${STM32MP_DDR3_TYPE},1) +DDR_TYPE := ddr3 +endif +ifeq (${STM32MP_DDR4_TYPE},1) +DDR_TYPE := ddr4 +endif +ifeq (${STM32MP_LPDDR4_TYPE},1) +DDR_TYPE := lpddr4 +endif + # Device tree BL2_DTSI := stm32mp25-bl2.dtsi FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME))) @@ -45,6 +59,9 @@ $(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config)) # Enable flags for C files $(eval $(call assert_booleans,\ $(sort \ + STM32MP_DDR3_TYPE \ + STM32MP_DDR4_TYPE \ + STM32MP_LPDDR4_TYPE \ STM32MP25 \ ))) @@ -61,6 +78,9 @@ $(eval $(call add_defines,\ PLAT_PARTITION_MAX_ENTRIES \ PLAT_TBBR_IMG_DEF \ STM32_TF_A_COPIES \ + STM32MP_DDR3_TYPE \ + STM32MP_DDR4_TYPE \ + STM32MP_LPDDR4_TYPE \ STM32MP25 \ ))) @@ -115,4 +135,18 @@ BL31_SOURCES += ${GICV2_SOURCES} \ BL31_SOURCES += plat/common/plat_psci_common.c # Compilation rules +.PHONY: check_ddr_type +.SUFFIXES: + +bl2: check_ddr_type + +check_ddr_type: + $(eval DDR_TYPE = $(shell echo $$(($(STM32MP_DDR3_TYPE) + \ + $(STM32MP_DDR4_TYPE) + \ + $(STM32MP_LPDDR4_TYPE))))) + @if [ ${DDR_TYPE} != 1 ]; then \ + echo "One and only one DDR type must be defined"; \ + false; \ + fi + include plat/st/common/common_rules.mk From ae84525f44ddfe8abd66644475899fdc19893481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20M=C3=A9r=C3=A9?= Date: Fri, 13 Sep 2024 17:57:58 +0200 Subject: [PATCH 6/6] feat(stm32mp2): manage DDR FW via FIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This feature is enabled by default using STM32MP_DDR_FIP_IO_STORAGE. DDR firmware binary is loaded from FIP to SRAM1 which needs to be mapped. Only half of the SRAM1 will be allocated to TF-A. RISAB3 has to be configured to allow access to SRAM1. Add image ID and update maximum number on platform side also. Fill related descriptor information, add policy and update numbers. DDR_TYPE variable is used to identify binary file, and image is now added in the fiptool command line. The DDR PHY firmware is not in TF-A repository. It can be found at https://github.com/STMicroelectronics/stm32-ddr-phy-binary To ease the selection of the firmware path, STM32MP_DDR_FW_PATH is added to platform.mk file. Change-Id: I09ab0a5c63406055a7b5ccd16d65e443de47ca2f Signed-off-by: Nicolas Le Bayon Signed-off-by: Yann Gautier Signed-off-by: Maxime Méré --- docs/plat/st/stm32mp2.rst | 25 ++++++++++++++++---- fdts/stm32mp25-bl2.dtsi | 3 +++ plat/st/common/stm32mp_fconf_io.c | 12 +++++++++- plat/st/stm32mp2/bl2_plat_setup.c | 12 ++++++++++ plat/st/stm32mp2/include/plat_tbbr_img_def.h | 8 +++++++ plat/st/stm32mp2/plat_bl2_mem_params_desc.c | 18 ++++++++++++++ plat/st/stm32mp2/platform.mk | 15 ++++++++++++ plat/st/stm32mp2/stm32mp2_def.h | 12 ++++++++++ plat/st/stm32mp2/stm32mp2_private.c | 12 ++++++++++ 9 files changed, 112 insertions(+), 5 deletions(-) diff --git a/docs/plat/st/stm32mp2.rst b/docs/plat/st/stm32mp2.rst index 5d4ab4e25..87bb6a535 100644 --- a/docs/plat/st/stm32mp2.rst +++ b/docs/plat/st/stm32mp2.rst @@ -85,7 +85,8 @@ To compile the correct DDR driver, one flag must be set among: Boot with FIP ~~~~~~~~~~~~~ -You need to build BL2, BL31, BL32 (OP-TEE) and BL33 (U-Boot) before building FIP binary. +You need to build BL2, BL31, BL32 (OP-TEE) and BL33 (U-Boot) and retrieve +DDR PHY firmware before building FIP binary. U-Boot ______ @@ -106,9 +107,24 @@ ______ ARCH=arm PLATFORM=stm32mp2 \ CFG_EMBED_DTB_SOURCE_FILE=stm32mp257f-ev1.dts -TF-A BL2 & BL31 -_______________ -To build TF-A BL2 with its STM32 header and BL31 for SD-card boot: +DDR PHY firmware +________________ +DDR PHY firmware files may not be delivered inside TF-A repository, especially +if you build directly from trustedfirmware.org repository. It then needs to be +retrieved from `STMicroelectronics DDR PHY github`_. + +You can either clone the repository to the default directory: + +.. code:: bash + + git clone https://github.com/STMicroelectronics/stm32-ddr-phy-binary.git drivers/st/ddr/phy/firmware/bin + +Or clone it somewhere else, and add ``STM32MP_DDR_FW_PATH=`` in your make command +line when building FIP. + +TF-A BL2 +________ +To build TF-A BL2 with its STM32 header for SD-card boot: .. code:: bash @@ -136,5 +152,6 @@ ___ .. _STM32MP2 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp2-series.html .. _STM32MP2 part number codification: https://wiki.st.com/stm32mpu/wiki/STM32MP25_microprocessor#Part_number_codification +.. _STMicroelectronics DDR PHY github: https://github.com/STMicroelectronics/stm32-ddr-phy-binary *Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved* diff --git a/fdts/stm32mp25-bl2.dtsi b/fdts/stm32mp25-bl2.dtsi index 769aab20e..e250e3f24 100644 --- a/fdts/stm32mp25-bl2.dtsi +++ b/fdts/stm32mp25-bl2.dtsi @@ -21,6 +21,9 @@ st-io_policies { fip-handles { compatible = "st,io-fip-handle"; +#if STM32MP_DDR_FIP_IO_STORAGE + ddr_fw_uuid = "b11249be-92dd-4b10-867c-2c6a4b47a7fb"; +#endif fw_cfg_uuid = "5807e16a-8459-47be-8ed5-648e8dddab0e"; bl31_uuid = "47d4086d-4cfe-9846-9b95-2950cbbd5a00"; bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38"; diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c index 7a8cf78f7..1aececed4 100644 --- a/plat/st/common/stm32mp_fconf_io.c +++ b/plat/st/common/stm32mp_fconf_io.c @@ -88,9 +88,16 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { #define TBBR_UUID_NUMBER U(0) #endif +#if STM32MP_DDR_FIP_IO_STORAGE +#define DDR_FW_UUID_NUMBER U(1) +#else +#define DDR_FW_UUID_NUMBER U(0) +#endif + #define FCONF_ST_IO_UUID_NUMBER (DEFAULT_UUID_NUMBER + \ BL31_UUID_NUMBER + \ - TBBR_UUID_NUMBER) + TBBR_UUID_NUMBER + \ + DDR_FW_UUID_NUMBER) static io_uuid_spec_t fconf_stm32mp_uuids[FCONF_ST_IO_UUID_NUMBER]; static OBJECT_POOL_ARRAY(fconf_stm32mp_uuids_pool, fconf_stm32mp_uuids); @@ -102,6 +109,9 @@ struct policies_load_info { /* image id to property name table */ static const struct policies_load_info load_info[FCONF_ST_IO_UUID_NUMBER] = { +#if STM32MP_DDR_FIP_IO_STORAGE + {DDR_FW_ID, "ddr_fw_uuid"}, +#endif {FW_CONFIG_ID, "fw_cfg_uuid"}, #ifdef __aarch64__ {BL31_IMAGE_ID, "bl31_uuid"}, diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c index 7fcaf8535..50d19ab2f 100644 --- a/plat/st/stm32mp2/bl2_plat_setup.c +++ b/plat/st/stm32mp2/bl2_plat_setup.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -196,6 +197,17 @@ void bl2_el3_plat_arch_setup(void) panic(); } +#if STM32MP_DDR_FIP_IO_STORAGE + /* + * RISAB3 setup (dedicated for SRAM1) + * + * Allow secure read/writes data accesses to non-secure + * blocks or pages, all RISAB registers are writable. + * DDR firmwares are saved there before being loaded in DDRPHY memory. + */ + mmio_write_32(RISAB3_BASE + RISAB_CR, RISAB_CR_SRWIAD); +#endif + stm32_save_boot_info(boot_context); if (stm32mp_uart_console_setup() != 0) { diff --git a/plat/st/stm32mp2/include/plat_tbbr_img_def.h b/plat/st/stm32mp2/include/plat_tbbr_img_def.h index 5dfd41f5f..830bf88b4 100644 --- a/plat/st/stm32mp2/include/plat_tbbr_img_def.h +++ b/plat/st/stm32mp2/include/plat_tbbr_img_def.h @@ -40,8 +40,16 @@ #define STM32MP_CONFIG_CERT_ID U(24) #define GPT_IMAGE_ID U(25) +#if STM32MP_DDR_FIP_IO_STORAGE +#define DDR_FW_ID U(26) +/* Increase the MAX_NUMBER_IDS to match the authentication pool required */ +#define MAX_NUMBER_IDS U(27) + +#else /* Increase the MAX_NUMBER_IDS to match the authentication pool required */ #define MAX_NUMBER_IDS U(26) +#endif + #endif /* PLAT_TBBR_IMG_DEF_H */ diff --git a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c index 137ea6323..f8455600e 100644 --- a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c +++ b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c @@ -19,6 +19,24 @@ * the next executable image id. ******************************************************************************/ static bl_mem_params_node_t bl2_mem_params_descs[] = { +#if STM32MP_DDR_FIP_IO_STORAGE + /* Fill FW_DDR related information if it exists */ + { + .image_id = DDR_FW_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, + 0), + + .image_info.image_base = STM32MP_DDR_FW_BASE, + .image_info.image_max_size = STM32MP_DDR_FW_MAX_SIZE, + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +#endif + /* Fill FW_CONFIG related information if it exists */ { .image_id = FW_CONFIG_ID, diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk index 015b20554..32d6235e9 100644 --- a/plat/st/stm32mp2/platform.mk +++ b/plat/st/stm32mp2/platform.mk @@ -41,6 +41,9 @@ ifeq (${STM32MP_LPDDR4_TYPE},1) DDR_TYPE := lpddr4 endif +# DDR features +STM32MP_DDR_FIP_IO_STORAGE := 1 + # Device tree BL2_DTSI := stm32mp25-bl2.dtsi FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME))) @@ -52,13 +55,23 @@ STM32_BINARY_MAPPING := plat/st/stm32mp2/${ARCH}/stm32mp2.S STM32MP_FW_CONFIG_NAME := $(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME)) STM32MP_FW_CONFIG := ${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_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 +STM32MP_DDR_FW := ${STM32MP_DDR_FW_PATH}/${STM32MP_DDR_FW_NAME} +endif 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)) +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)) +endif # Enable flags for C files $(eval $(call assert_booleans,\ $(sort \ + STM32MP_DDR_FIP_IO_STORAGE \ STM32MP_DDR3_TYPE \ STM32MP_DDR4_TYPE \ STM32MP_LPDDR4_TYPE \ @@ -75,9 +88,11 @@ $(eval $(call assert_numerics,\ $(eval $(call add_defines,\ $(sort \ DWL_BUFFER_BASE \ + PLAT_DEF_FIP_UUID \ PLAT_PARTITION_MAX_ENTRIES \ PLAT_TBBR_IMG_DEF \ STM32_TF_A_COPIES \ + STM32MP_DDR_FIP_IO_STORAGE \ STM32MP_DDR3_TYPE \ STM32MP_DDR4_TYPE \ STM32MP_LPDDR4_TYPE \ diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h index 058616b37..d3290c320 100644 --- a/plat/st/stm32mp2/stm32mp2_def.h +++ b/plat/st/stm32mp2/stm32mp2_def.h @@ -71,6 +71,8 @@ ******************************************************************************/ #define STM32MP_SYSRAM_BASE U(0x0E000000) #define STM32MP_SYSRAM_SIZE U(0x00040000) +#define SRAM1_BASE U(0x0E040000) +#define SRAM1_SIZE_FOR_TFA U(0x00010000) #define STM32MP_SEC_SYSRAM_SIZE STM32MP_SYSRAM_SIZE /* DDR configuration */ @@ -144,6 +146,11 @@ enum ddr_type { #define STM32MP_DTB_BASE STM32MP_BL2_DTB_BASE #endif +#if STM32MP_DDR_FIP_IO_STORAGE +#define STM32MP_DDR_FW_BASE SRAM1_BASE +#define STM32MP_DDR_FW_MAX_SIZE U(0x8800) +#endif + #define STM32MP_FW_CONFIG_MAX_SIZE PAGE_SIZE #define STM32MP_FW_CONFIG_BASE STM32MP_SYSRAM_BASE @@ -363,6 +370,11 @@ static inline uintptr_t tamp_bkpr(uint32_t idx) #define STGEN_BASE U(0x48080000) #define SYSCFG_BASE U(0x44230000) +/******************************************************************************* + * STM32MP RIF + ******************************************************************************/ +#define RISAB3_BASE U(0x42110000) + /******************************************************************************* * STM32MP CA35SSC ******************************************************************************/ diff --git a/plat/st/stm32mp2/stm32mp2_private.c b/plat/st/stm32mp2/stm32mp2_private.c index 06ff7c8b4..99f6be22a 100644 --- a/plat/st/stm32mp2/stm32mp2_private.c +++ b/plat/st/stm32mp2/stm32mp2_private.c @@ -29,6 +29,15 @@ MT_EXECUTE_NEVER) #endif +#if STM32MP_DDR_FIP_IO_STORAGE +#define MAP_SRAM1 MAP_REGION_FLAT(SRAM1_BASE, \ + SRAM1_SIZE_FOR_TFA, \ + MT_MEMORY | \ + MT_RW | \ + MT_SECURE | \ + MT_EXECUTE_NEVER) +#endif + #define MAP_DEVICE MAP_REGION_FLAT(STM32MP_DEVICE_BASE, \ STM32MP_DEVICE_SIZE, \ MT_DEVICE | \ @@ -39,6 +48,9 @@ #if defined(IMAGE_BL2) static const mmap_region_t stm32mp2_mmap[] = { MAP_SYSRAM, +#if STM32MP_DDR_FIP_IO_STORAGE + MAP_SRAM1, +#endif MAP_DEVICE, {0} };