xref: /rk3399_ARM-atf/plat/st/stm32mp1/stm32mp1_fconf_firewall.c (revision 4584e01dc643665038004f6c8a4f8bd64e14dacb)
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