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