blob: 7d9956409ad68a7f100905866145732f78dfdd7d [file] [log] [blame]
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +02001/*
Gabriel Fernandez1308d752020-03-11 11:30:34 +01002 * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8
9#include <common/debug.h>
10#include <common/fdt_wrappers.h>
11#include <drivers/arm/tzc400.h>
Yann Gautiera205a5c2021-08-30 15:06:54 +020012#include <drivers/clk.h>
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +020013#include <dt-bindings/clock/stm32mp1-clks.h>
14#include <lib/fconf/fconf.h>
15#include <lib/object_pool.h>
16#include <libfdt.h>
17#include <tools_share/firmware_image_package.h>
18
19#include <platform_def.h>
20#include <stm32mp_fconf_getter.h>
21
22#define STM32MP_REGION_PARAMS 4
23#define STM32MP_MAX_REGIONS 8
24#define FORCE_SEC_REGION BIT(31)
25
26static uint32_t nb_regions;
27
28struct dt_id_attr {
29 fdt32_t id_attr[STM32MP_MAX_REGIONS];
30};
31
32void stm32mp1_arch_security_setup(void)
33{
Gabriel Fernandez1308d752020-03-11 11:30:34 +010034#if STM32MP13
35 clk_enable(TZC);
36#endif
37#if STM32MP15
Yann Gautiera205a5c2021-08-30 15:06:54 +020038 clk_enable(TZC1);
39 clk_enable(TZC2);
Gabriel Fernandez1308d752020-03-11 11:30:34 +010040#endif
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +020041
42 tzc400_init(STM32MP1_TZC_BASE);
43 tzc400_disable_filters();
44
45 /*
46 * Region 0 set to cover all DRAM at 0xC000_0000
47 * Only secure access is granted in read/write.
48 */
49 tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
50
51 tzc400_set_action(TZC_ACTION_ERR);
52 tzc400_enable_filters();
53}
54
55void stm32mp1_security_setup(void)
56{
57 uint8_t i;
58
59 assert(nb_regions > 0U);
60
61 tzc400_init(STM32MP1_TZC_BASE);
62 tzc400_disable_filters();
63
64 /*
65 * Region 0 set to cover all DRAM at 0xC000_0000
66 * No access is allowed.
67 */
68 tzc400_configure_region0(TZC_REGION_S_NONE, 0);
69
70 for (i = 1U; i <= nb_regions; i++) {
71 tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL);
72 }
73
74 tzc400_set_action(TZC_ACTION_INT);
75 tzc400_enable_filters();
76}
77
78static int fconf_populate_stm32mp1_firewall(uintptr_t config)
79{
80 int node, len;
81 unsigned int i;
82 const struct dt_id_attr *conf_list;
83 const void *dtb = (const void *)config;
84
85 /* Assert the node offset point to "st,mem-firewall" compatible property */
86 const char *compatible_str = "st,mem-firewall";
87
88 node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
89 if (node < 0) {
90 ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
91 return node;
92 }
93
94 conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len);
95 if (conf_list == NULL) {
96 WARN("FCONF: Read cell failed for %s\n", "memory-ranges");
97 return -1;
98 }
99
100 /* Locate the memory cells and read all values */
101 for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) {
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100102 uint32_t idx = i * STM32MP_REGION_PARAMS;
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200103 uint32_t base;
104 uint32_t size;
105 uint32_t sec_attr;
106 uint32_t nsaid;
107
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100108 base = fdt32_to_cpu(conf_list->id_attr[idx]);
109 size = fdt32_to_cpu(conf_list->id_attr[idx + 1]);
110 sec_attr = fdt32_to_cpu(conf_list->id_attr[idx + 2]);
111 nsaid = fdt32_to_cpu(conf_list->id_attr[idx + 3]);
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200112
113 VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
114 base, size, sec_attr, nsaid);
115
116 nb_regions++;
117
118 /* Configure region but keep disabled for secure access for BL2 load */
119 tzc400_configure_region(0U, nb_regions, (unsigned long long)base,
120 (unsigned long long)base + size - 1ULL, sec_attr, nsaid);
121 }
122
123 /* Force flush as the value will be used cache off */
124 flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));
125
126 return 0;
127}
128
129FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);