diff options
author | Mark Dykes <mark.dykes@arm.com> | 2021-09-09 17:49:27 +0200 |
---|---|---|
committer | TrustedFirmware Code Review <review@review.trustedfirmware.org> | 2021-09-09 17:49:27 +0200 |
commit | 2ed0c59bd0a54926d3e0935155a59e6e936df735 (patch) | |
tree | 69676111e1e4ebbc75137024d0c0996721401031 | |
parent | d3f91e242ae858e459a3cda64cc0abbb69b59ce8 (diff) | |
parent | 4584e01dc643665038004f6c8a4f8bd64e14dacb (diff) | |
download | trusted-firmware-a-2ed0c59bd0a54926d3e0935155a59e6e936df735.tar.gz |
Merge "feat(plat/st): add a new DDR firewall management" into integration
-rw-r--r-- | plat/st/stm32mp1/include/stm32mp1_private.h | 4 | ||||
-rw-r--r-- | plat/st/stm32mp1/platform.mk | 7 | ||||
-rw-r--r-- | plat/st/stm32mp1/stm32mp1_fconf_firewall.c | 123 | ||||
-rw-r--r-- | plat/st/stm32mp1/stm32mp1_private.c | 2 |
4 files changed, 132 insertions, 4 deletions
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h index b6cb91efa0..729d2336bf 100644 --- a/plat/st/stm32mp1/include/stm32mp1_private.h +++ b/plat/st/stm32mp1/include/stm32mp1_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,7 +21,9 @@ void stm32mp1_syscfg_init(void); void stm32mp1_syscfg_enable_io_compensation(void); void stm32mp1_syscfg_disable_io_compensation(void); +#if STM32MP_USE_STM32IMAGE uint32_t stm32mp_get_ddr_ns_size(void); +#endif /* STM32MP_USE_STM32IMAGE */ void stm32mp1_init_scmi_server(void); #endif /* STM32MP1_PRIVATE_H */ diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 891cfa4b6d..1c2c9f0a99 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -189,7 +189,6 @@ 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 ifneq (${STM32MP_USE_STM32IMAGE},1) @@ -198,12 +197,14 @@ BL2_SOURCES += drivers/io/io_fip.c \ lib/fconf/fconf_dyn_cfg_getter.c \ plat/st/common/bl2_io_storage.c \ plat/st/common/stm32mp_fconf_io.c \ - plat/st/stm32mp1/plat_bl2_mem_params_desc.c + plat/st/stm32mp1/plat_bl2_mem_params_desc.c \ + plat/st/stm32mp1/stm32mp1_fconf_firewall.c else BL2_SOURCES += drivers/io/io_dummy.c \ drivers/st/io/io_stm32image.c \ plat/st/common/bl2_stm32_io_storage.c \ - plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c + plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c \ + plat/st/stm32mp1/stm32mp1_security.c endif BL2_SOURCES += drivers/io/io_block.c \ diff --git a/plat/st/stm32mp1/stm32mp1_fconf_firewall.c b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c new file mode 100644 index 0000000000..caf9ff12b3 --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.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 <platform_def.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(0U, 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 1af0075f24..e4065c1c99 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -452,6 +452,7 @@ uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags) } #endif +#if STM32MP_USE_STM32IMAGE /* Get the non-secure DDR size */ uint32_t stm32mp_get_ddr_ns_size(void) { @@ -472,3 +473,4 @@ uint32_t stm32mp_get_ddr_ns_size(void) return ddr_ns_size; } +#endif /* STM32MP_USE_STM32IMAGE */ |