xref: /rk3399_ARM-atf/plat/st/stm32mp1/stm32mp1_fconf_firewall.c (revision 9be88e75c198b08c508d8e470964720a781294b3)
14584e01dSLionel Debieve /*
2*9be88e75SGabriel Fernandez  * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
34584e01dSLionel Debieve  *
44584e01dSLionel Debieve  * SPDX-License-Identifier: BSD-3-Clause
54584e01dSLionel Debieve  */
64584e01dSLionel Debieve 
74584e01dSLionel Debieve #include <assert.h>
84584e01dSLionel Debieve 
94584e01dSLionel Debieve #include <common/debug.h>
104584e01dSLionel Debieve #include <common/fdt_wrappers.h>
114584e01dSLionel Debieve #include <drivers/arm/tzc400.h>
1233667d29SYann Gautier #include <drivers/clk.h>
134584e01dSLionel Debieve #include <dt-bindings/clock/stm32mp1-clks.h>
144584e01dSLionel Debieve #include <lib/fconf/fconf.h>
154584e01dSLionel Debieve #include <lib/object_pool.h>
164584e01dSLionel Debieve #include <libfdt.h>
174584e01dSLionel Debieve #include <tools_share/firmware_image_package.h>
184584e01dSLionel Debieve 
194584e01dSLionel Debieve #include <platform_def.h>
204584e01dSLionel Debieve #include <stm32mp_fconf_getter.h>
214584e01dSLionel Debieve 
224584e01dSLionel Debieve #define STM32MP_REGION_PARAMS	4
234584e01dSLionel Debieve #define STM32MP_MAX_REGIONS	8
244584e01dSLionel Debieve #define FORCE_SEC_REGION	BIT(31)
254584e01dSLionel Debieve 
264584e01dSLionel Debieve static uint32_t nb_regions;
274584e01dSLionel Debieve 
284584e01dSLionel Debieve struct dt_id_attr {
294584e01dSLionel Debieve 	fdt32_t id_attr[STM32MP_MAX_REGIONS];
304584e01dSLionel Debieve };
314584e01dSLionel Debieve 
324584e01dSLionel Debieve void stm32mp1_arch_security_setup(void)
334584e01dSLionel Debieve {
34*9be88e75SGabriel Fernandez #if STM32MP13
35*9be88e75SGabriel Fernandez 	clk_enable(TZC);
36*9be88e75SGabriel Fernandez #endif
37*9be88e75SGabriel Fernandez #if STM32MP15
3833667d29SYann Gautier 	clk_enable(TZC1);
3933667d29SYann Gautier 	clk_enable(TZC2);
40*9be88e75SGabriel Fernandez #endif
414584e01dSLionel Debieve 
424584e01dSLionel Debieve 	tzc400_init(STM32MP1_TZC_BASE);
434584e01dSLionel Debieve 	tzc400_disable_filters();
444584e01dSLionel Debieve 
454584e01dSLionel Debieve 	/*
464584e01dSLionel Debieve 	 * Region 0 set to cover all DRAM at 0xC000_0000
474584e01dSLionel Debieve 	 * Only secure access is granted in read/write.
484584e01dSLionel Debieve 	 */
494584e01dSLionel Debieve 	tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
504584e01dSLionel Debieve 
514584e01dSLionel Debieve 	tzc400_set_action(TZC_ACTION_ERR);
524584e01dSLionel Debieve 	tzc400_enable_filters();
534584e01dSLionel Debieve }
544584e01dSLionel Debieve 
554584e01dSLionel Debieve void stm32mp1_security_setup(void)
564584e01dSLionel Debieve {
574584e01dSLionel Debieve 	uint8_t i;
584584e01dSLionel Debieve 
594584e01dSLionel Debieve 	assert(nb_regions > 0U);
604584e01dSLionel Debieve 
614584e01dSLionel Debieve 	tzc400_init(STM32MP1_TZC_BASE);
624584e01dSLionel Debieve 	tzc400_disable_filters();
634584e01dSLionel Debieve 
644584e01dSLionel Debieve 	/*
654584e01dSLionel Debieve 	 * Region 0 set to cover all DRAM at 0xC000_0000
664584e01dSLionel Debieve 	 * No access is allowed.
674584e01dSLionel Debieve 	 */
684584e01dSLionel Debieve 	tzc400_configure_region0(TZC_REGION_S_NONE, 0);
694584e01dSLionel Debieve 
704584e01dSLionel Debieve 	for (i = 1U; i <= nb_regions; i++) {
714584e01dSLionel Debieve 		tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL);
724584e01dSLionel Debieve 	}
734584e01dSLionel Debieve 
744584e01dSLionel Debieve 	tzc400_set_action(TZC_ACTION_INT);
754584e01dSLionel Debieve 	tzc400_enable_filters();
764584e01dSLionel Debieve }
774584e01dSLionel Debieve 
784584e01dSLionel Debieve static int fconf_populate_stm32mp1_firewall(uintptr_t config)
794584e01dSLionel Debieve {
804584e01dSLionel Debieve 	int node, len;
814584e01dSLionel Debieve 	unsigned int i;
824584e01dSLionel Debieve 	const struct dt_id_attr *conf_list;
834584e01dSLionel Debieve 	const void *dtb = (const void *)config;
844584e01dSLionel Debieve 
854584e01dSLionel Debieve 	/* Assert the node offset point to "st,mem-firewall" compatible property */
864584e01dSLionel Debieve 	const char *compatible_str = "st,mem-firewall";
874584e01dSLionel Debieve 
884584e01dSLionel Debieve 	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
894584e01dSLionel Debieve 	if (node < 0) {
904584e01dSLionel Debieve 		ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
914584e01dSLionel Debieve 		return node;
924584e01dSLionel Debieve 	}
934584e01dSLionel Debieve 
944584e01dSLionel Debieve 	conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len);
954584e01dSLionel Debieve 	if (conf_list == NULL) {
964584e01dSLionel Debieve 		WARN("FCONF: Read cell failed for %s\n", "memory-ranges");
974584e01dSLionel Debieve 		return -1;
984584e01dSLionel Debieve 	}
994584e01dSLionel Debieve 
1004584e01dSLionel Debieve 	/* Locate the memory cells and read all values */
1014584e01dSLionel Debieve 	for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) {
1024584e01dSLionel Debieve 		uint32_t base;
1034584e01dSLionel Debieve 		uint32_t size;
1044584e01dSLionel Debieve 		uint32_t sec_attr;
1054584e01dSLionel Debieve 		uint32_t nsaid;
1064584e01dSLionel Debieve 
1074584e01dSLionel Debieve 		base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]);
1084584e01dSLionel Debieve 		size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]);
1094584e01dSLionel Debieve 		sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]);
1104584e01dSLionel Debieve 		nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]);
1114584e01dSLionel Debieve 
1124584e01dSLionel Debieve 		VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
1134584e01dSLionel Debieve 			base, size, sec_attr, nsaid);
1144584e01dSLionel Debieve 
1154584e01dSLionel Debieve 		nb_regions++;
1164584e01dSLionel Debieve 
1174584e01dSLionel Debieve 		/* Configure region but keep disabled for secure access for BL2 load */
1184584e01dSLionel Debieve 		tzc400_configure_region(0U, nb_regions, (unsigned long long)base,
1194584e01dSLionel Debieve 					(unsigned long long)base + size - 1ULL, sec_attr, nsaid);
1204584e01dSLionel Debieve 	}
1214584e01dSLionel Debieve 
1224584e01dSLionel Debieve 	/* Force flush as the value will be used cache off */
1234584e01dSLionel Debieve 	flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));
1244584e01dSLionel Debieve 
1254584e01dSLionel Debieve 	return 0;
1264584e01dSLionel Debieve }
1274584e01dSLionel Debieve 
1284584e01dSLionel Debieve FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);
129