xref: /rk3399_ARM-atf/plat/st/stm32mp1/stm32mp1_fconf_firewall.c (revision 33667d299bd5398ca549f542345e0f321b483d17)
14584e01dSLionel Debieve /*
24584e01dSLionel Debieve  * Copyright (c) 2021, 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>
12*33667d29SYann 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*33667d29SYann Gautier 	clk_enable(TZC1);
35*33667d29SYann Gautier 	clk_enable(TZC2);
364584e01dSLionel Debieve 
374584e01dSLionel Debieve 	tzc400_init(STM32MP1_TZC_BASE);
384584e01dSLionel Debieve 	tzc400_disable_filters();
394584e01dSLionel Debieve 
404584e01dSLionel Debieve 	/*
414584e01dSLionel Debieve 	 * Region 0 set to cover all DRAM at 0xC000_0000
424584e01dSLionel Debieve 	 * Only secure access is granted in read/write.
434584e01dSLionel Debieve 	 */
444584e01dSLionel Debieve 	tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
454584e01dSLionel Debieve 
464584e01dSLionel Debieve 	tzc400_set_action(TZC_ACTION_ERR);
474584e01dSLionel Debieve 	tzc400_enable_filters();
484584e01dSLionel Debieve }
494584e01dSLionel Debieve 
504584e01dSLionel Debieve void stm32mp1_security_setup(void)
514584e01dSLionel Debieve {
524584e01dSLionel Debieve 	uint8_t i;
534584e01dSLionel Debieve 
544584e01dSLionel Debieve 	assert(nb_regions > 0U);
554584e01dSLionel Debieve 
564584e01dSLionel Debieve 	tzc400_init(STM32MP1_TZC_BASE);
574584e01dSLionel Debieve 	tzc400_disable_filters();
584584e01dSLionel Debieve 
594584e01dSLionel Debieve 	/*
604584e01dSLionel Debieve 	 * Region 0 set to cover all DRAM at 0xC000_0000
614584e01dSLionel Debieve 	 * No access is allowed.
624584e01dSLionel Debieve 	 */
634584e01dSLionel Debieve 	tzc400_configure_region0(TZC_REGION_S_NONE, 0);
644584e01dSLionel Debieve 
654584e01dSLionel Debieve 	for (i = 1U; i <= nb_regions; i++) {
664584e01dSLionel Debieve 		tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL);
674584e01dSLionel Debieve 	}
684584e01dSLionel Debieve 
694584e01dSLionel Debieve 	tzc400_set_action(TZC_ACTION_INT);
704584e01dSLionel Debieve 	tzc400_enable_filters();
714584e01dSLionel Debieve }
724584e01dSLionel Debieve 
734584e01dSLionel Debieve static int fconf_populate_stm32mp1_firewall(uintptr_t config)
744584e01dSLionel Debieve {
754584e01dSLionel Debieve 	int node, len;
764584e01dSLionel Debieve 	unsigned int i;
774584e01dSLionel Debieve 	const struct dt_id_attr *conf_list;
784584e01dSLionel Debieve 	const void *dtb = (const void *)config;
794584e01dSLionel Debieve 
804584e01dSLionel Debieve 	/* Assert the node offset point to "st,mem-firewall" compatible property */
814584e01dSLionel Debieve 	const char *compatible_str = "st,mem-firewall";
824584e01dSLionel Debieve 
834584e01dSLionel Debieve 	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
844584e01dSLionel Debieve 	if (node < 0) {
854584e01dSLionel Debieve 		ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
864584e01dSLionel Debieve 		return node;
874584e01dSLionel Debieve 	}
884584e01dSLionel Debieve 
894584e01dSLionel Debieve 	conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len);
904584e01dSLionel Debieve 	if (conf_list == NULL) {
914584e01dSLionel Debieve 		WARN("FCONF: Read cell failed for %s\n", "memory-ranges");
924584e01dSLionel Debieve 		return -1;
934584e01dSLionel Debieve 	}
944584e01dSLionel Debieve 
954584e01dSLionel Debieve 	/* Locate the memory cells and read all values */
964584e01dSLionel Debieve 	for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) {
974584e01dSLionel Debieve 		uint32_t base;
984584e01dSLionel Debieve 		uint32_t size;
994584e01dSLionel Debieve 		uint32_t sec_attr;
1004584e01dSLionel Debieve 		uint32_t nsaid;
1014584e01dSLionel Debieve 
1024584e01dSLionel Debieve 		base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]);
1034584e01dSLionel Debieve 		size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]);
1044584e01dSLionel Debieve 		sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]);
1054584e01dSLionel Debieve 		nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]);
1064584e01dSLionel Debieve 
1074584e01dSLionel Debieve 		VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
1084584e01dSLionel Debieve 			base, size, sec_attr, nsaid);
1094584e01dSLionel Debieve 
1104584e01dSLionel Debieve 		nb_regions++;
1114584e01dSLionel Debieve 
1124584e01dSLionel Debieve 		/* Configure region but keep disabled for secure access for BL2 load */
1134584e01dSLionel Debieve 		tzc400_configure_region(0U, nb_regions, (unsigned long long)base,
1144584e01dSLionel Debieve 					(unsigned long long)base + size - 1ULL, sec_attr, nsaid);
1154584e01dSLionel Debieve 	}
1164584e01dSLionel Debieve 
1174584e01dSLionel Debieve 	/* Force flush as the value will be used cache off */
1184584e01dSLionel Debieve 	flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));
1194584e01dSLionel Debieve 
1204584e01dSLionel Debieve 	return 0;
1214584e01dSLionel Debieve }
1224584e01dSLionel Debieve 
1234584e01dSLionel Debieve FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);
124