1 /*
2 * Copyright (c) 2021, 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/st/stm32mp1_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
stm32mp1_arch_security_setup(void)32 void stm32mp1_arch_security_setup(void)
33 {
34 stm32mp_clk_enable(TZC1);
35 stm32mp_clk_enable(TZC2);
36
37 tzc400_init(STM32MP1_TZC_BASE);
38 tzc400_disable_filters();
39
40 /*
41 * Region 0 set to cover all DRAM at 0xC000_0000
42 * Only secure access is granted in read/write.
43 */
44 tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
45
46 tzc400_set_action(TZC_ACTION_ERR);
47 tzc400_enable_filters();
48 }
49
stm32mp1_security_setup(void)50 void stm32mp1_security_setup(void)
51 {
52 uint8_t i;
53
54 assert(nb_regions > 0U);
55
56 tzc400_init(STM32MP1_TZC_BASE);
57 tzc400_disable_filters();
58
59 /*
60 * Region 0 set to cover all DRAM at 0xC000_0000
61 * No access is allowed.
62 */
63 tzc400_configure_region0(TZC_REGION_S_NONE, 0);
64
65 for (i = 1U; i <= nb_regions; i++) {
66 tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL);
67 }
68
69 tzc400_set_action(TZC_ACTION_INT);
70 tzc400_enable_filters();
71 }
72
fconf_populate_stm32mp1_firewall(uintptr_t config)73 static int fconf_populate_stm32mp1_firewall(uintptr_t config)
74 {
75 int node, len;
76 unsigned int i;
77 const struct dt_id_attr *conf_list;
78 const void *dtb = (const void *)config;
79
80 /* Assert the node offset point to "st,mem-firewall" compatible property */
81 const char *compatible_str = "st,mem-firewall";
82
83 node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
84 if (node < 0) {
85 ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
86 return node;
87 }
88
89 conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len);
90 if (conf_list == NULL) {
91 WARN("FCONF: Read cell failed for %s\n", "memory-ranges");
92 return -1;
93 }
94
95 /* Locate the memory cells and read all values */
96 for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) {
97 uint32_t base;
98 uint32_t size;
99 uint32_t sec_attr;
100 uint32_t nsaid;
101
102 base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]);
103 size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]);
104 sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]);
105 nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]);
106
107 VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
108 base, size, sec_attr, nsaid);
109
110 nb_regions++;
111
112 /* Configure region but keep disabled for secure access for BL2 load */
113 tzc400_configure_region(0U, nb_regions, (unsigned long long)base,
114 (unsigned long long)base + size - 1ULL, sec_attr, nsaid);
115 }
116
117 /* Force flush as the value will be used cache off */
118 flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));
119
120 return 0;
121 }
122
123 FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);
124