summaryrefslogtreecommitdiffstats
path: root/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
diff options
context:
space:
mode:
Diffstat (limited to 'plat/st/stm32mp1/stm32mp1_fconf_firewall.c')
-rw-r--r--plat/st/stm32mp1/stm32mp1_fconf_firewall.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/plat/st/stm32mp1/stm32mp1_fconf_firewall.c b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
new file mode 100644
index 0000000..f2568ab
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/arm/tzc400.h>
+#include <drivers/clk.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <lib/fconf/fconf.h>
+#include <lib/object_pool.h>
+#include <libfdt.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <platform_def.h>
+#include <stm32mp_fconf_getter.h>
+
+#define STM32MP_REGION_PARAMS 4
+#define STM32MP_MAX_REGIONS 8
+#define FORCE_SEC_REGION BIT(31)
+
+static uint32_t nb_regions;
+
+struct dt_id_attr {
+ fdt32_t id_attr[STM32MP_MAX_REGIONS];
+};
+
+void stm32mp1_arch_security_setup(void)
+{
+#if STM32MP13
+ clk_enable(TZC);
+#endif
+#if STM32MP15
+ clk_enable(TZC1);
+ clk_enable(TZC2);
+#endif
+
+ tzc400_init(STM32MP1_TZC_BASE);
+ tzc400_disable_filters();
+
+ /*
+ * Region 0 set to cover all DRAM at 0xC000_0000
+ * Only secure access is granted in read/write.
+ */
+ tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
+
+ tzc400_set_action(TZC_ACTION_ERR);
+ tzc400_enable_filters();
+}
+
+void stm32mp1_security_setup(void)
+{
+ uint8_t i;
+
+ assert(nb_regions > 0U);
+
+ tzc400_init(STM32MP1_TZC_BASE);
+ tzc400_disable_filters();
+
+ /*
+ * Region 0 set to cover all DRAM at 0xC000_0000
+ * No access is allowed.
+ */
+ tzc400_configure_region0(TZC_REGION_S_NONE, 0);
+
+ for (i = 1U; i <= nb_regions; i++) {
+ tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL);
+ }
+
+ tzc400_set_action(TZC_ACTION_INT);
+ tzc400_enable_filters();
+}
+
+static int fconf_populate_stm32mp1_firewall(uintptr_t config)
+{
+ int node, len;
+ unsigned int i;
+ const struct dt_id_attr *conf_list;
+ const void *dtb = (const void *)config;
+
+ /* Assert the node offset point to "st,mem-firewall" compatible property */
+ const char *compatible_str = "st,mem-firewall";
+
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
+ if (node < 0) {
+ ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
+ return node;
+ }
+
+ conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len);
+ if (conf_list == NULL) {
+ WARN("FCONF: Read cell failed for %s\n", "memory-ranges");
+ return -1;
+ }
+
+ /* Locate the memory cells and read all values */
+ for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) {
+ uint32_t base;
+ uint32_t size;
+ uint32_t sec_attr;
+ uint32_t nsaid;
+
+ base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]);
+ size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]);
+ sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]);
+ nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]);
+
+ VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
+ base, size, sec_attr, nsaid);
+
+ nb_regions++;
+
+ /* Configure region but keep disabled for secure access for BL2 load */
+ tzc400_configure_region(0U, nb_regions, (unsigned long long)base,
+ (unsigned long long)base + size - 1ULL, sec_attr, nsaid);
+ }
+
+ /* Force flush as the value will be used cache off */
+ flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));
+
+ return 0;
+}
+
+FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);