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