diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 28cdf7286bf2b4c6f307f4376a0e621d41e60400..38140782ab30b7ea2d15f901749d8ec5f56310d5 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -668,29 +668,6 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) MT_MEMORY | MT_RW | MT_NS); assert(err == 0); - /* Configuration of TZC400 */ - stm32mp1_security_setup_begin(); - -#if STM32MP_SP_MIN_IN_DDR || defined(AARCH32_SP_OPTEE) - stm32mp1_security_add_region(sec_base_address, sec_size, true); - - if (sec_base_address > STM32MP_DDR_BASE) { - stm32mp1_security_add_region(STM32MP_DDR_BASE, - sec_base_address - STM32MP_DDR_BASE, - false); - } - - ddr_top = STM32MP_DDR_BASE + dt_get_ddr_size() - 1U; - if (sec_base_address + sec_size < ddr_top) { - stm32mp1_security_add_region(sec_base_address + sec_size, - ddr_top - (sec_base_address + sec_size) + 1U, - false); - } -#else - stm32mp1_security_add_region(STM32MP_DDR_BASE, dt_get_ddr_size(), false); -#endif - stm32mp1_security_setup_end(); - break; case BL32_IMAGE_ID: #if defined(AARCH32_SP_OPTEE) @@ -759,3 +736,8 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) return err; } + +void bl2_el3_plat_prepare_exit(void) +{ + stm32mp1_security_setup(); +} diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h index 475d7557768cdfac541cae5eb1bceb6135afb45b..cb5f84aaf7c7ef835b858cec5bf22c9fc50896ff 100644 --- a/plat/st/stm32mp1/include/stm32mp1_private.h +++ b/plat/st/stm32mp1/include/stm32mp1_private.h @@ -43,8 +43,6 @@ void stm32mp1_syscfg_init(void); void stm32mp1_syscfg_enable_io_compensation(void); void stm32mp1_syscfg_disable_io_compensation(void); -uint32_t stm32mp_get_ddr_ns_size(void); - void stm32mp1_init_scmi_server(void); void stm32mp1_pm_save_scmi_state(uint8_t *state, size_t size); void stm32mp1_pm_restore_scmi_state(uint8_t *state, size_t size); diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 6d6cf2f022231de20d6792b021ce3ed792a1a882..17820f1441e91b12b8c921d0473ee5e9104caa30 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -196,12 +196,12 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ plat/st/stm32mp1/stm32mp1_context.c \ plat/st/stm32mp1/stm32mp1_dbgmcu.c \ plat/st/stm32mp1/stm32mp1_helper.S \ - plat/st/stm32mp1/stm32mp1_security.c \ plat/st/stm32mp1/stm32mp1_syscfg.c BL2_SOURCES += lib/fconf/fconf.c \ lib/fconf/fconf_dyn_cfg_getter.c \ - plat/st/common/stm32mp_fconf_io.c + plat/st/common/stm32mp_fconf_io.c \ + plat/st/stm32mp1/stm32mp1_fconf_firewall.c BL2_SOURCES += drivers/io/io_block.c \ drivers/io/io_fip.c \ diff --git a/plat/st/stm32mp1/stm32mp1_fconf_firewall.c b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c new file mode 100644 index 0000000000000000000000000000000000000000..f2699e3765911ee488a9a60f9269ea6a8566ea3c --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2020, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <platform_def.h> + +#include <common/debug.h> +#include <common/fdt_wrappers.h> +#include <drivers/arm/tzc400.h> +#include <drivers/st/stm32mp1_clk.h> +#include <dt-bindings/clock/stm32mp1-clks.h> +#include <lib/fconf/fconf.h> +#include <lib/object_pool.h> +#include <libfdt.h> +#include <tools_share/firmware_image_package.h> + +#include <stm32mp_fconf_getter.h> + +#define STM32MP_REGION_PARAMS 4 +#define STM32MP_MAX_REGIONS 8 +#define FORCE_SEC_REGION BIT(31) + +static uint32_t nb_regions; + +struct dt_id_attr { + fdt32_t id_attr[STM32MP_MAX_REGIONS]; +}; + +void stm32mp1_arch_security_setup(void) +{ + stm32mp_clk_enable(TZC1); + stm32mp_clk_enable(TZC2); + + tzc400_init(STM32MP1_TZC_BASE); + tzc400_disable_filters(); + + /* + * Region 0 set to cover all DRAM at 0xC000_0000 + * Only secure access is granted in read/write. + */ + tzc400_configure_region0(TZC_REGION_S_RDWR, 0); + + tzc400_set_action(TZC_ACTION_ERR); + tzc400_enable_filters(); +} + +void stm32mp1_security_setup(void) +{ + uint8_t i; + + assert(nb_regions > 0U); + + tzc400_init(STM32MP1_TZC_BASE); + tzc400_disable_filters(); + + /* + * Region 0 set to cover all DRAM at 0xC000_0000 + * No access is allowed. + */ + tzc400_configure_region0(TZC_REGION_S_NONE, 0); + + for (i = 1U; i <= nb_regions; i++) { + tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL); + } + + tzc400_set_action(TZC_ACTION_INT); + tzc400_enable_filters(); +} + +static int fconf_populate_stm32mp1_firewall(uintptr_t config) +{ + int node, len; + unsigned int i; + const struct dt_id_attr *conf_list; + const void *dtb = (const void *)config; + + /* Assert the node offset point to "st,mem-firewall" compatible property */ + const char *compatible_str = "st,mem-firewall"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); + return node; + } + + conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len); + if (conf_list == NULL) { + WARN("FCONF: Read cell failed for %s\n", "memory-ranges"); + return -1; + } + + /* Locate the memory cells and read all values */ + for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) { + uint32_t base; + uint32_t size; + uint32_t sec_attr; + uint32_t nsaid; + + base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]); + size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]); + sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]); + nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]); + + VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n", + base, size, sec_attr, nsaid); + + nb_regions++; + + /* Configure region but keep disabled for secure access for BL2 load */ + tzc400_configure_region(0, nb_regions, (unsigned long long)base, + (unsigned long long)base + size - 1ULL, sec_attr, nsaid); + } + + /* Force flush as the value will be used cache off */ + flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t)); + + return 0; +} + +FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall); diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index 5c5a35f1db345dd6dbe569c50afe06c676502bf2..fe651f09c4f9574e8eec8ab3442fcd989689c504 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -749,31 +749,6 @@ int plat_bind_regulator(struct stm32mp_regulator *regu) return 0; } -/* Get the non-secure DDR size */ -uint32_t stm32mp_get_ddr_ns_size(void) -{ -#if STM32MP_SP_MIN_IN_DDR - return STM32MP_BL32_BASE - STM32MP_DDR_BASE; -#else - static uint32_t ddr_ns_size; - uint32_t ddr_size; - - if (ddr_ns_size != 0U) { - return ddr_ns_size; - } - - ddr_size = dt_get_ddr_size(); - if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) || - (ddr_size > STM32MP_DDR_MAX_SIZE)) { - panic(); - } - - ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE); - - return ddr_ns_size; -#endif -} - bool stm32mp_boot_action_is_wakeup_from_standby(void) { return (stm32mp_get_boot_action() == BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY) || diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c deleted file mode 100644 index 6bcfb6289df1a7c74875cdf12027ab4f2e1b687a..0000000000000000000000000000000000000000 --- a/plat/st/stm32mp1/stm32mp1_security.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <stdint.h> - -#include <platform_def.h> - -#include <common/debug.h> -#include <drivers/arm/tzc400.h> -#include <drivers/st/stm32mp1_clk.h> -#include <dt-bindings/clock/stm32mp1-clks.h> -#include <lib/mmio.h> - -#define TZC_REGION_NSEC_ALL_ACCESS_RDWR \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID) - -static unsigned int region_nb; - -static void init_tzc400_begin(unsigned int region0_attr) -{ - tzc400_init(STM32MP1_TZC_BASE); - tzc400_disable_filters(); - - /* Region 0 set to cover all DRAM at 0xC000_0000 */ - tzc400_configure_region0(region0_attr, 0); - - region_nb = 1U; -} - -static void init_tzc400_end(unsigned int action) -{ - tzc400_set_action(action); - tzc400_enable_filters(); -} - -static void tzc400_add_region(unsigned long long region_base, - unsigned long long region_top, bool sec) -{ - unsigned int sec_attr; - unsigned int nsaid_permissions; - - if (sec) { - sec_attr = TZC_REGION_S_RDWR; - nsaid_permissions = 0; - } else { - sec_attr = TZC_REGION_S_NONE; - nsaid_permissions = TZC_REGION_NSEC_ALL_ACCESS_RDWR; - } - - tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, region_nb, region_base, - region_top, sec_attr, nsaid_permissions); - - region_nb++; -} - -/******************************************************************************* - * Initialize the TrustZone Controller. Configure Region 0 with Secure RW access - * and allow Non-Secure masters full access. - ******************************************************************************/ -static void init_tzc400(void) -{ - unsigned long long region_base, region_top; - unsigned long long ddr_base = STM32MP_DDR_BASE; - unsigned long long ddr_ns_size = - (unsigned long long)stm32mp_get_ddr_ns_size(); - unsigned long long ddr_ns_top = ddr_base + (ddr_ns_size - 1U); - unsigned long long ddr_top __unused; - - init_tzc400_begin(TZC_REGION_S_NONE); - - /* - * Region 1 set to cover all non-secure DRAM at 0xC000_0000. Apply the - * same configuration to all filters in the TZC. - */ - region_base = ddr_base; - region_top = ddr_ns_top; - tzc400_add_region(region_base, region_top, false); - -#if (defined AARCH32_SP_OPTEE) || STM32MP_SP_MIN_IN_DDR - /* Region 2 set to cover all secure DRAM. */ - region_base = region_top + 1U; - region_top += STM32MP_DDR_S_SIZE; - tzc400_add_region(region_base, region_top, true); - - ddr_top = STM32MP_DDR_BASE + dt_get_ddr_size() - 1U; - if (region_top < ddr_top) { - /* Region 3 set to cover non-secure memory DRAM after BL32. */ - region_base = region_top + 1U; - region_top = ddr_top; - tzc400_add_region(region_base, region_top, false); - } -#endif - - /* - * Raise an interrupt (secure FIQ) if a NS device tries to access - * secure memory - */ - init_tzc400_end(TZC_ACTION_INT); -} - -/******************************************************************************* - * Initialize the TrustZone Controller. - * Early initialization create only one region with full access to secure. - * This setting is used before and during DDR initialization. - ******************************************************************************/ -static void early_init_tzc400(void) -{ - stm32mp_clk_enable(TZC1); - stm32mp_clk_enable(TZC2); - - /* Region 0 set to cover all DRAM secure at 0xC000_0000 */ - init_tzc400_begin(TZC_REGION_S_RDWR); - - /* Raise an exception if a NS device tries to access secure memory */ - init_tzc400_end(TZC_ACTION_ERR); -} - -/******************************************************************************* - * Initialize the secure environment. At this moment only the TrustZone - * Controller is initialized. - ******************************************************************************/ -void stm32mp1_arch_security_setup(void) -{ - early_init_tzc400(); -} - -/******************************************************************************* - * Initialize the secure environment. At this moment only the TrustZone - * Controller is initialized. - ******************************************************************************/ -void stm32mp1_security_setup(void) -{ - init_tzc400(); -} - -void stm32mp1_security_setup_begin(void) -{ - init_tzc400_begin(TZC_REGION_S_NONE); -} - -void stm32mp1_security_setup_end(void) -{ - init_tzc400_end(TZC_ACTION_INT); -} - -void stm32mp1_security_add_region(unsigned long long region_base, - unsigned long long region_size, bool sec) -{ - tzc400_add_region(region_base, region_base + region_size - 1ULL, sec); -}