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 
stm32mp1_arch_security_setup(void)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 
stm32mp1_security_setup(void)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 
fconf_populate_stm32mp1_firewall(uintptr_t config)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 base;
103 		uint32_t size;
104 		uint32_t sec_attr;
105 		uint32_t nsaid;
106 
107 		base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]);
108 		size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]);
109 		sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]);
110 		nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]);
111 
112 		VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
113 			base, size, sec_attr, nsaid);
114 
115 		nb_regions++;
116 
117 		/* Configure region but keep disabled for secure access for BL2 load */
118 		tzc400_configure_region(0U, nb_regions, (unsigned long long)base,
119 					(unsigned long long)base + size - 1ULL, sec_attr, nsaid);
120 	}
121 
122 	/* Force flush as the value will be used cache off */
123 	flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));
124 
125 	return 0;
126 }
127 
128 FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);
129