14584e01dSLionel Debieve /*
29be88e75SGabriel 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
stm32mp1_arch_security_setup(void)324584e01dSLionel Debieve void stm32mp1_arch_security_setup(void)
334584e01dSLionel Debieve {
349be88e75SGabriel Fernandez #if STM32MP13
359be88e75SGabriel Fernandez clk_enable(TZC);
369be88e75SGabriel Fernandez #endif
379be88e75SGabriel Fernandez #if STM32MP15
3833667d29SYann Gautier clk_enable(TZC1);
3933667d29SYann Gautier clk_enable(TZC2);
409be88e75SGabriel 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
stm32mp1_security_setup(void)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
fconf_populate_stm32mp1_firewall(uintptr_t config)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++) {
102*56048fe2SYann Gautier uint32_t idx = i * STM32MP_REGION_PARAMS;
1034584e01dSLionel Debieve uint32_t base;
1044584e01dSLionel Debieve uint32_t size;
1054584e01dSLionel Debieve uint32_t sec_attr;
1064584e01dSLionel Debieve uint32_t nsaid;
1074584e01dSLionel Debieve
108*56048fe2SYann Gautier base = fdt32_to_cpu(conf_list->id_attr[idx]);
109*56048fe2SYann Gautier size = fdt32_to_cpu(conf_list->id_attr[idx + 1]);
110*56048fe2SYann Gautier sec_attr = fdt32_to_cpu(conf_list->id_attr[idx + 2]);
111*56048fe2SYann Gautier nsaid = fdt32_to_cpu(conf_list->id_attr[idx + 3]);
1124584e01dSLionel Debieve
1134584e01dSLionel Debieve VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
1144584e01dSLionel Debieve base, size, sec_attr, nsaid);
1154584e01dSLionel Debieve
1164584e01dSLionel Debieve nb_regions++;
1174584e01dSLionel Debieve
1184584e01dSLionel Debieve /* Configure region but keep disabled for secure access for BL2 load */
1194584e01dSLionel Debieve tzc400_configure_region(0U, nb_regions, (unsigned long long)base,
1204584e01dSLionel Debieve (unsigned long long)base + size - 1ULL, sec_attr, nsaid);
1214584e01dSLionel Debieve }
1224584e01dSLionel Debieve
1234584e01dSLionel Debieve /* Force flush as the value will be used cache off */
1244584e01dSLionel Debieve flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));
1254584e01dSLionel Debieve
1264584e01dSLionel Debieve return 0;
1274584e01dSLionel Debieve }
1284584e01dSLionel Debieve
1294584e01dSLionel Debieve FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);
130