14584e01dSLionel Debieve /* 2*9be88e75SGabriel Fernandez * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved 34584e01dSLionel Debieve * 44584e01dSLionel Debieve * SPDX-License-Identifier: BSD-3-Clause 54584e01dSLionel Debieve */ 64584e01dSLionel Debieve 74584e01dSLionel Debieve #include <assert.h> 84584e01dSLionel Debieve 94584e01dSLionel Debieve #include <common/debug.h> 104584e01dSLionel Debieve #include <common/fdt_wrappers.h> 114584e01dSLionel Debieve #include <drivers/arm/tzc400.h> 1233667d29SYann Gautier #include <drivers/clk.h> 134584e01dSLionel Debieve #include <dt-bindings/clock/stm32mp1-clks.h> 144584e01dSLionel Debieve #include <lib/fconf/fconf.h> 154584e01dSLionel Debieve #include <lib/object_pool.h> 164584e01dSLionel Debieve #include <libfdt.h> 174584e01dSLionel Debieve #include <tools_share/firmware_image_package.h> 184584e01dSLionel Debieve 194584e01dSLionel Debieve #include <platform_def.h> 204584e01dSLionel Debieve #include <stm32mp_fconf_getter.h> 214584e01dSLionel Debieve 224584e01dSLionel Debieve #define STM32MP_REGION_PARAMS 4 234584e01dSLionel Debieve #define STM32MP_MAX_REGIONS 8 244584e01dSLionel Debieve #define FORCE_SEC_REGION BIT(31) 254584e01dSLionel Debieve 264584e01dSLionel Debieve static uint32_t nb_regions; 274584e01dSLionel Debieve 284584e01dSLionel Debieve struct dt_id_attr { 294584e01dSLionel Debieve fdt32_t id_attr[STM32MP_MAX_REGIONS]; 304584e01dSLionel Debieve }; 314584e01dSLionel Debieve 324584e01dSLionel Debieve void stm32mp1_arch_security_setup(void) 334584e01dSLionel Debieve { 34*9be88e75SGabriel Fernandez #if STM32MP13 35*9be88e75SGabriel Fernandez clk_enable(TZC); 36*9be88e75SGabriel Fernandez #endif 37*9be88e75SGabriel Fernandez #if STM32MP15 3833667d29SYann Gautier clk_enable(TZC1); 3933667d29SYann Gautier clk_enable(TZC2); 40*9be88e75SGabriel Fernandez #endif 414584e01dSLionel Debieve 424584e01dSLionel Debieve tzc400_init(STM32MP1_TZC_BASE); 434584e01dSLionel Debieve tzc400_disable_filters(); 444584e01dSLionel Debieve 454584e01dSLionel Debieve /* 464584e01dSLionel Debieve * Region 0 set to cover all DRAM at 0xC000_0000 474584e01dSLionel Debieve * Only secure access is granted in read/write. 484584e01dSLionel Debieve */ 494584e01dSLionel Debieve tzc400_configure_region0(TZC_REGION_S_RDWR, 0); 504584e01dSLionel Debieve 514584e01dSLionel Debieve tzc400_set_action(TZC_ACTION_ERR); 524584e01dSLionel Debieve tzc400_enable_filters(); 534584e01dSLionel Debieve } 544584e01dSLionel Debieve 554584e01dSLionel Debieve void stm32mp1_security_setup(void) 564584e01dSLionel Debieve { 574584e01dSLionel Debieve uint8_t i; 584584e01dSLionel Debieve 594584e01dSLionel Debieve assert(nb_regions > 0U); 604584e01dSLionel Debieve 614584e01dSLionel Debieve tzc400_init(STM32MP1_TZC_BASE); 624584e01dSLionel Debieve tzc400_disable_filters(); 634584e01dSLionel Debieve 644584e01dSLionel Debieve /* 654584e01dSLionel Debieve * Region 0 set to cover all DRAM at 0xC000_0000 664584e01dSLionel Debieve * No access is allowed. 674584e01dSLionel Debieve */ 684584e01dSLionel Debieve tzc400_configure_region0(TZC_REGION_S_NONE, 0); 694584e01dSLionel Debieve 704584e01dSLionel Debieve for (i = 1U; i <= nb_regions; i++) { 714584e01dSLionel Debieve tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL); 724584e01dSLionel Debieve } 734584e01dSLionel Debieve 744584e01dSLionel Debieve tzc400_set_action(TZC_ACTION_INT); 754584e01dSLionel Debieve tzc400_enable_filters(); 764584e01dSLionel Debieve } 774584e01dSLionel Debieve 784584e01dSLionel Debieve static int fconf_populate_stm32mp1_firewall(uintptr_t config) 794584e01dSLionel Debieve { 804584e01dSLionel Debieve int node, len; 814584e01dSLionel Debieve unsigned int i; 824584e01dSLionel Debieve const struct dt_id_attr *conf_list; 834584e01dSLionel Debieve const void *dtb = (const void *)config; 844584e01dSLionel Debieve 854584e01dSLionel Debieve /* Assert the node offset point to "st,mem-firewall" compatible property */ 864584e01dSLionel Debieve const char *compatible_str = "st,mem-firewall"; 874584e01dSLionel Debieve 884584e01dSLionel Debieve node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); 894584e01dSLionel Debieve if (node < 0) { 904584e01dSLionel Debieve ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); 914584e01dSLionel Debieve return node; 924584e01dSLionel Debieve } 934584e01dSLionel Debieve 944584e01dSLionel Debieve conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len); 954584e01dSLionel Debieve if (conf_list == NULL) { 964584e01dSLionel Debieve WARN("FCONF: Read cell failed for %s\n", "memory-ranges"); 974584e01dSLionel Debieve return -1; 984584e01dSLionel Debieve } 994584e01dSLionel Debieve 1004584e01dSLionel Debieve /* Locate the memory cells and read all values */ 1014584e01dSLionel Debieve for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) { 1024584e01dSLionel Debieve uint32_t base; 1034584e01dSLionel Debieve uint32_t size; 1044584e01dSLionel Debieve uint32_t sec_attr; 1054584e01dSLionel Debieve uint32_t nsaid; 1064584e01dSLionel Debieve 1074584e01dSLionel Debieve base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]); 1084584e01dSLionel Debieve size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]); 1094584e01dSLionel Debieve sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]); 1104584e01dSLionel Debieve nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]); 1114584e01dSLionel Debieve 1124584e01dSLionel Debieve VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n", 1134584e01dSLionel Debieve base, size, sec_attr, nsaid); 1144584e01dSLionel Debieve 1154584e01dSLionel Debieve nb_regions++; 1164584e01dSLionel Debieve 1174584e01dSLionel Debieve /* Configure region but keep disabled for secure access for BL2 load */ 1184584e01dSLionel Debieve tzc400_configure_region(0U, nb_regions, (unsigned long long)base, 1194584e01dSLionel Debieve (unsigned long long)base + size - 1ULL, sec_attr, nsaid); 1204584e01dSLionel Debieve } 1214584e01dSLionel Debieve 1224584e01dSLionel Debieve /* Force flush as the value will be used cache off */ 1234584e01dSLionel Debieve flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t)); 1244584e01dSLionel Debieve 1254584e01dSLionel Debieve return 0; 1264584e01dSLionel Debieve } 1274584e01dSLionel Debieve 1284584e01dSLionel Debieve FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall); 129