xref: /arm-trusted-firmware/plat/st/stm32mp1/stm32mp1_fconf_firewall.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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