1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <common/debug.h> 10*91f16700Schasinglulu #include <common/fdt_wrappers.h> 11*91f16700Schasinglulu #include <drivers/arm/tzc400.h> 12*91f16700Schasinglulu #include <drivers/clk.h> 13*91f16700Schasinglulu #include <dt-bindings/clock/stm32mp1-clks.h> 14*91f16700Schasinglulu #include <lib/fconf/fconf.h> 15*91f16700Schasinglulu #include <lib/object_pool.h> 16*91f16700Schasinglulu #include <libfdt.h> 17*91f16700Schasinglulu #include <tools_share/firmware_image_package.h> 18*91f16700Schasinglulu 19*91f16700Schasinglulu #include <platform_def.h> 20*91f16700Schasinglulu #include <stm32mp_fconf_getter.h> 21*91f16700Schasinglulu 22*91f16700Schasinglulu #define STM32MP_REGION_PARAMS 4 23*91f16700Schasinglulu #define STM32MP_MAX_REGIONS 8 24*91f16700Schasinglulu #define FORCE_SEC_REGION BIT(31) 25*91f16700Schasinglulu 26*91f16700Schasinglulu static uint32_t nb_regions; 27*91f16700Schasinglulu 28*91f16700Schasinglulu struct dt_id_attr { 29*91f16700Schasinglulu fdt32_t id_attr[STM32MP_MAX_REGIONS]; 30*91f16700Schasinglulu }; 31*91f16700Schasinglulu 32*91f16700Schasinglulu void stm32mp1_arch_security_setup(void) 33*91f16700Schasinglulu { 34*91f16700Schasinglulu #if STM32MP13 35*91f16700Schasinglulu clk_enable(TZC); 36*91f16700Schasinglulu #endif 37*91f16700Schasinglulu #if STM32MP15 38*91f16700Schasinglulu clk_enable(TZC1); 39*91f16700Schasinglulu clk_enable(TZC2); 40*91f16700Schasinglulu #endif 41*91f16700Schasinglulu 42*91f16700Schasinglulu tzc400_init(STM32MP1_TZC_BASE); 43*91f16700Schasinglulu tzc400_disable_filters(); 44*91f16700Schasinglulu 45*91f16700Schasinglulu /* 46*91f16700Schasinglulu * Region 0 set to cover all DRAM at 0xC000_0000 47*91f16700Schasinglulu * Only secure access is granted in read/write. 48*91f16700Schasinglulu */ 49*91f16700Schasinglulu tzc400_configure_region0(TZC_REGION_S_RDWR, 0); 50*91f16700Schasinglulu 51*91f16700Schasinglulu tzc400_set_action(TZC_ACTION_ERR); 52*91f16700Schasinglulu tzc400_enable_filters(); 53*91f16700Schasinglulu } 54*91f16700Schasinglulu 55*91f16700Schasinglulu void stm32mp1_security_setup(void) 56*91f16700Schasinglulu { 57*91f16700Schasinglulu uint8_t i; 58*91f16700Schasinglulu 59*91f16700Schasinglulu assert(nb_regions > 0U); 60*91f16700Schasinglulu 61*91f16700Schasinglulu tzc400_init(STM32MP1_TZC_BASE); 62*91f16700Schasinglulu tzc400_disable_filters(); 63*91f16700Schasinglulu 64*91f16700Schasinglulu /* 65*91f16700Schasinglulu * Region 0 set to cover all DRAM at 0xC000_0000 66*91f16700Schasinglulu * No access is allowed. 67*91f16700Schasinglulu */ 68*91f16700Schasinglulu tzc400_configure_region0(TZC_REGION_S_NONE, 0); 69*91f16700Schasinglulu 70*91f16700Schasinglulu for (i = 1U; i <= nb_regions; i++) { 71*91f16700Schasinglulu tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL); 72*91f16700Schasinglulu } 73*91f16700Schasinglulu 74*91f16700Schasinglulu tzc400_set_action(TZC_ACTION_INT); 75*91f16700Schasinglulu tzc400_enable_filters(); 76*91f16700Schasinglulu } 77*91f16700Schasinglulu 78*91f16700Schasinglulu static int fconf_populate_stm32mp1_firewall(uintptr_t config) 79*91f16700Schasinglulu { 80*91f16700Schasinglulu int node, len; 81*91f16700Schasinglulu unsigned int i; 82*91f16700Schasinglulu const struct dt_id_attr *conf_list; 83*91f16700Schasinglulu const void *dtb = (const void *)config; 84*91f16700Schasinglulu 85*91f16700Schasinglulu /* Assert the node offset point to "st,mem-firewall" compatible property */ 86*91f16700Schasinglulu const char *compatible_str = "st,mem-firewall"; 87*91f16700Schasinglulu 88*91f16700Schasinglulu node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); 89*91f16700Schasinglulu if (node < 0) { 90*91f16700Schasinglulu ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); 91*91f16700Schasinglulu return node; 92*91f16700Schasinglulu } 93*91f16700Schasinglulu 94*91f16700Schasinglulu conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len); 95*91f16700Schasinglulu if (conf_list == NULL) { 96*91f16700Schasinglulu WARN("FCONF: Read cell failed for %s\n", "memory-ranges"); 97*91f16700Schasinglulu return -1; 98*91f16700Schasinglulu } 99*91f16700Schasinglulu 100*91f16700Schasinglulu /* Locate the memory cells and read all values */ 101*91f16700Schasinglulu for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) { 102*91f16700Schasinglulu uint32_t idx = i * STM32MP_REGION_PARAMS; 103*91f16700Schasinglulu uint32_t base; 104*91f16700Schasinglulu uint32_t size; 105*91f16700Schasinglulu uint32_t sec_attr; 106*91f16700Schasinglulu uint32_t nsaid; 107*91f16700Schasinglulu 108*91f16700Schasinglulu base = fdt32_to_cpu(conf_list->id_attr[idx]); 109*91f16700Schasinglulu size = fdt32_to_cpu(conf_list->id_attr[idx + 1]); 110*91f16700Schasinglulu sec_attr = fdt32_to_cpu(conf_list->id_attr[idx + 2]); 111*91f16700Schasinglulu nsaid = fdt32_to_cpu(conf_list->id_attr[idx + 3]); 112*91f16700Schasinglulu 113*91f16700Schasinglulu VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n", 114*91f16700Schasinglulu base, size, sec_attr, nsaid); 115*91f16700Schasinglulu 116*91f16700Schasinglulu nb_regions++; 117*91f16700Schasinglulu 118*91f16700Schasinglulu /* Configure region but keep disabled for secure access for BL2 load */ 119*91f16700Schasinglulu tzc400_configure_region(0U, nb_regions, (unsigned long long)base, 120*91f16700Schasinglulu (unsigned long long)base + size - 1ULL, sec_attr, nsaid); 121*91f16700Schasinglulu } 122*91f16700Schasinglulu 123*91f16700Schasinglulu /* Force flush as the value will be used cache off */ 124*91f16700Schasinglulu flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t)); 125*91f16700Schasinglulu 126*91f16700Schasinglulu return 0; 127*91f16700Schasinglulu } 128*91f16700Schasinglulu 129*91f16700Schasinglulu FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall); 130