1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
4  * Copyright (c) 2017-2019, STMicroelectronics
5  */
6 
7 /*
8  * STM32 ETPZC acts as a firewall on stm32mp SoC peripheral interfaces and
9  * internal memories. The driver expects a single instance of the controller
10  * in the platform.
11  *
12  * The driver API is defined in header file stm32_etzpc.h.
13  *
14  * Driver registers a PM callback for restoration of the access permissions
15  * when it resumes.
16  */
17 
18 #include <assert.h>
19 #include <drivers/stm32_etzpc.h>
20 #include <initcall.h>
21 #include <io.h>
22 #include <keep.h>
23 #include <kernel/dt.h>
24 #include <kernel/boot.h>
25 #include <kernel/panic.h>
26 #include <kernel/pm.h>
27 #include <libfdt.h>
28 #include <mm/core_memprot.h>
29 #include <util.h>
30 
31 /* Devicetree compatibility */
32 #define ETZPC_COMPAT			"st,stm32-etzpc"
33 
34 /* ID Registers */
35 #define ETZPC_TZMA0_SIZE		0x000U
36 #define ETZPC_DECPROT0			0x010U
37 #define ETZPC_DECPROT_LOCK0		0x030U
38 #define ETZPC_HWCFGR			0x3F0U
39 #define ETZPC_VERR			0x3F4U
40 
41 /* ID Registers fields */
42 #define ETZPC_TZMA0_SIZE_LOCK		BIT(31)
43 #define ETZPC_DECPROT0_MASK		GENMASK_32(1, 0)
44 #define ETZPC_HWCFGR_NUM_TZMA_MASK	GENMASK_32(7, 0)
45 #define ETZPC_HWCFGR_NUM_TZMA_SHIFT	0
46 #define ETZPC_HWCFGR_NUM_PER_SEC_MASK	GENMASK_32(15, 8)
47 #define ETZPC_HWCFGR_NUM_PER_SEC_SHIFT	8
48 #define ETZPC_HWCFGR_NUM_AHB_SEC_MASK	GENMASK_32(23, 16)
49 #define ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT	16
50 #define ETZPC_HWCFGR_CHUNCKS1N4_MASK	GENMASK_32(31, 24)
51 #define ETZPC_HWCFGR_CHUNCKS1N4_SHIFT	24
52 
53 #define DECPROT_SHIFT			1
54 #define IDS_PER_DECPROT_REGS		16U
55 #define IDS_PER_DECPROT_LOCK_REGS	32U
56 
57 /*
58  * Implementation uses uint8_t to store each securable DECPROT configuration
59  * and uint16_t to store each securable TZMA configuration. When resuming
60  * from deep suspend, the DECPROT configurations are restored.
61  */
62 #define PERIPH_PM_LOCK_BIT		BIT(7)
63 #define PERIPH_PM_ATTR_MASK		GENMASK_32(2, 0)
64 #define TZMA_PM_LOCK_BIT		BIT(15)
65 #define TZMA_PM_VALUE_MASK		GENMASK_32(9, 0)
66 
67 /*
68  * @base - iobase for interface base address
69  * @num_tzma - number of TZMA zone, read from the hardware
70  * @num_ahb_sec - number of securable AHB master zone, read from the hardware
71  * @num_per_sec - number of securable AHB & APB periphs, read from the hardware
72  * @periph_cfg - Backup for restoring DECPROT when resuming (PERIH_PM_*)
73  * @tzma_cfg - Backup for restoring TZMA when resuming (TZMA_PM_*)
74  */
75 struct etzpc_instance {
76 	struct io_pa_va base;
77 	unsigned int num_tzma;
78 	unsigned int num_per_sec;
79 	unsigned int num_ahb_sec;
80 	uint8_t *periph_cfg;
81 	uint16_t *tzma_cfg;
82 };
83 
84 /* Only 1 instance of the ETZPC is expected per platform */
85 static struct etzpc_instance etzpc_dev;
86 
etzpc_base(void)87 static vaddr_t etzpc_base(void)
88 {
89 	return io_pa_or_va_secure(&etzpc_dev.base, 1);
90 }
91 
valid_decprot_id(unsigned int id)92 static bool __maybe_unused valid_decprot_id(unsigned int id)
93 {
94 	return id < etzpc_dev.num_per_sec;
95 }
96 
valid_tzma_id(unsigned int id)97 static bool __maybe_unused valid_tzma_id(unsigned int id)
98 {
99 	return id < etzpc_dev.num_tzma;
100 }
101 
etzpc_configure_decprot(uint32_t decprot_id,enum etzpc_decprot_attributes decprot_attr)102 void etzpc_configure_decprot(uint32_t decprot_id,
103 			     enum etzpc_decprot_attributes decprot_attr)
104 {
105 	size_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS);
106 	uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT;
107 	uint32_t masked_decprot = (uint32_t)decprot_attr & ETZPC_DECPROT0_MASK;
108 	vaddr_t base = etzpc_base();
109 
110 	assert(valid_decprot_id(decprot_id));
111 
112 	io_clrsetbits32(base + ETZPC_DECPROT0 + offset,
113 			ETZPC_DECPROT0_MASK << shift,
114 			masked_decprot << shift);
115 
116 	/* Save for PM */
117 	assert((decprot_attr & ~PERIPH_PM_ATTR_MASK) == 0);
118 	COMPILE_TIME_ASSERT(ETZPC_DECPROT_MAX <= UINT8_MAX);
119 
120 	etzpc_dev.periph_cfg[decprot_id] &= ~PERIPH_PM_ATTR_MASK;
121 	etzpc_dev.periph_cfg[decprot_id] |= (uint8_t)decprot_attr;
122 }
123 
etzpc_get_decprot(uint32_t decprot_id)124 enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id)
125 {
126 	size_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS);
127 	uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT;
128 	vaddr_t base = etzpc_base();
129 	uint32_t value = 0;
130 
131 	assert(valid_decprot_id(decprot_id));
132 
133 	value = (io_read32(base + ETZPC_DECPROT0 + offset) >> shift) &
134 		ETZPC_DECPROT0_MASK;
135 
136 	return (enum etzpc_decprot_attributes)value;
137 }
138 
etzpc_lock_decprot(uint32_t decprot_id)139 void etzpc_lock_decprot(uint32_t decprot_id)
140 {
141 	size_t offset = 4U * (decprot_id / IDS_PER_DECPROT_LOCK_REGS);
142 	uint32_t mask = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS);
143 	vaddr_t base = etzpc_base();
144 
145 	assert(valid_decprot_id(decprot_id));
146 
147 	io_write32(base + offset + ETZPC_DECPROT_LOCK0, mask);
148 
149 	/* Save for PM */
150 	etzpc_dev.periph_cfg[decprot_id] |= PERIPH_PM_LOCK_BIT;
151 }
152 
etzpc_get_lock_decprot(uint32_t decprot_id)153 bool etzpc_get_lock_decprot(uint32_t decprot_id)
154 {
155 	size_t offset = 4U * (decprot_id / IDS_PER_DECPROT_LOCK_REGS);
156 	uint32_t mask = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS);
157 	vaddr_t base = etzpc_base();
158 
159 	assert(valid_decprot_id(decprot_id));
160 
161 	return io_read32(base + offset + ETZPC_DECPROT_LOCK0) & mask;
162 }
163 
etzpc_configure_tzma(uint32_t tzma_id,uint16_t tzma_value)164 void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value)
165 {
166 	size_t offset = sizeof(uint32_t) * tzma_id;
167 	vaddr_t base = etzpc_base();
168 
169 	assert(valid_tzma_id(tzma_id));
170 
171 	io_write32(base + ETZPC_TZMA0_SIZE + offset, tzma_value);
172 
173 	/* Save for PM */
174 	assert((tzma_value & ~TZMA_PM_VALUE_MASK) == 0);
175 	etzpc_dev.tzma_cfg[tzma_id] &= ~TZMA_PM_VALUE_MASK;
176 	etzpc_dev.tzma_cfg[tzma_id] |= tzma_value;
177 }
178 
etzpc_get_tzma(uint32_t tzma_id)179 uint16_t etzpc_get_tzma(uint32_t tzma_id)
180 {
181 	size_t offset = sizeof(uint32_t) * tzma_id;
182 	vaddr_t base = etzpc_base();
183 
184 	assert(valid_tzma_id(tzma_id));
185 
186 	return io_read32(base + ETZPC_TZMA0_SIZE + offset);
187 }
188 
etzpc_lock_tzma(uint32_t tzma_id)189 void etzpc_lock_tzma(uint32_t tzma_id)
190 {
191 	size_t offset = sizeof(uint32_t) * tzma_id;
192 	vaddr_t base = etzpc_base();
193 
194 	assert(valid_tzma_id(tzma_id));
195 
196 	io_setbits32(base + ETZPC_TZMA0_SIZE + offset, ETZPC_TZMA0_SIZE_LOCK);
197 
198 	/* Save for PM */
199 	etzpc_dev.tzma_cfg[tzma_id] |= TZMA_PM_LOCK_BIT;
200 }
201 
etzpc_get_lock_tzma(uint32_t tzma_id)202 bool etzpc_get_lock_tzma(uint32_t tzma_id)
203 {
204 	size_t offset = sizeof(uint32_t) * tzma_id;
205 	vaddr_t base = etzpc_base();
206 
207 	assert(valid_tzma_id(tzma_id));
208 
209 	return io_read32(base + ETZPC_TZMA0_SIZE + offset) &
210 	       ETZPC_TZMA0_SIZE_LOCK;
211 }
212 
etzpc_pm(enum pm_op op,unsigned int pm_hint __unused,const struct pm_callback_handle * pm_handle)213 static TEE_Result etzpc_pm(enum pm_op op, unsigned int pm_hint __unused,
214 			  const struct pm_callback_handle *pm_handle)
215 {
216 	struct etzpc_instance *dev = NULL;
217 	unsigned int n = 0;
218 
219 	if (op != PM_OP_RESUME)
220 		return TEE_SUCCESS;
221 
222 	dev = (struct etzpc_instance *)PM_CALLBACK_GET_HANDLE(pm_handle);
223 
224 	for (n = 0; n < dev->num_per_sec; n++) {
225 		unsigned int attr = dev->periph_cfg[n] & PERIPH_PM_ATTR_MASK;
226 
227 		etzpc_configure_decprot(n, (enum etzpc_decprot_attributes)attr);
228 
229 		if (dev->periph_cfg[n] & PERIPH_PM_LOCK_BIT)
230 			etzpc_lock_decprot(n);
231 	}
232 
233 	for (n = 0; n < dev->num_tzma; n++) {
234 		uint16_t value = dev->tzma_cfg[n] & TZMA_PM_VALUE_MASK;
235 
236 		etzpc_configure_tzma(n, value);
237 
238 		if (dev->tzma_cfg[n] & TZMA_PM_LOCK_BIT)
239 			etzpc_lock_tzma(n);
240 	}
241 
242 	return TEE_SUCCESS;
243 }
244 DECLARE_KEEP_PAGER(etzpc_pm);
245 
init_pm(struct etzpc_instance * dev)246 static void init_pm(struct etzpc_instance *dev)
247 {
248 	unsigned int n = 0;
249 
250 	dev->periph_cfg = calloc(dev->num_per_sec, sizeof(*dev->periph_cfg));
251 	dev->tzma_cfg = calloc(dev->num_tzma, sizeof(*dev->tzma_cfg));
252 	if (!dev->periph_cfg || !dev->tzma_cfg)
253 		panic();
254 
255 	for (n = 0; n < dev->num_per_sec; n++) {
256 		dev->periph_cfg[n] = (uint8_t)etzpc_get_decprot(n);
257 		if (etzpc_get_lock_decprot(n))
258 			dev->periph_cfg[n] |= PERIPH_PM_LOCK_BIT;
259 	}
260 
261 	for (n = 0; n < dev->num_tzma; n++) {
262 		dev->tzma_cfg[n] = (uint8_t)etzpc_get_tzma(n);
263 		if (etzpc_get_lock_tzma(n))
264 			dev->tzma_cfg[n] |= TZMA_PM_LOCK_BIT;
265 	}
266 
267 	register_pm_core_service_cb(etzpc_pm, dev, "stm32-etzpc");
268 }
269 
270 struct etzpc_hwcfg {
271 	unsigned int num_tzma;
272 	unsigned int num_per_sec;
273 	unsigned int num_ahb_sec;
274 	unsigned int chunk_size;
275 };
276 
get_hwcfg(struct etzpc_hwcfg * hwcfg)277 static void get_hwcfg(struct etzpc_hwcfg *hwcfg)
278 {
279 	uint32_t reg = io_read32(etzpc_base() + ETZPC_HWCFGR);
280 
281 	hwcfg->num_tzma = (reg & ETZPC_HWCFGR_NUM_TZMA_MASK) >>
282 			  ETZPC_HWCFGR_NUM_TZMA_SHIFT;
283 	hwcfg->num_per_sec = (reg & ETZPC_HWCFGR_NUM_PER_SEC_MASK) >>
284 			     ETZPC_HWCFGR_NUM_PER_SEC_SHIFT;
285 	hwcfg->num_ahb_sec = (reg & ETZPC_HWCFGR_NUM_AHB_SEC_MASK) >>
286 			     ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT;
287 	hwcfg->chunk_size = (reg & ETZPC_HWCFGR_CHUNCKS1N4_MASK) >>
288 			    ETZPC_HWCFGR_CHUNCKS1N4_SHIFT;
289 }
290 
init_device_from_hw_config(struct etzpc_instance * dev,paddr_t pbase)291 static void init_device_from_hw_config(struct etzpc_instance *dev,
292 				       paddr_t pbase)
293 {
294 	struct etzpc_hwcfg hwcfg = { };
295 
296 	assert(!dev->base.pa && cpu_mmu_enabled());
297 	dev->base.pa = pbase;
298 	dev->base.va = (vaddr_t)phys_to_virt(dev->base.pa, MEM_AREA_IO_SEC, 1);
299 	assert(etzpc_base());
300 
301 	get_hwcfg(&hwcfg);
302 	dev->num_tzma = hwcfg.num_tzma;
303 	dev->num_per_sec = hwcfg.num_per_sec;
304 	dev->num_ahb_sec = hwcfg.num_ahb_sec;
305 
306 	DMSG("ETZPC revison 0x02%" PRIu8 ", per_sec %u, ahb_sec %u, tzma %u",
307 	     io_read8(etzpc_base() + ETZPC_VERR),
308 	     hwcfg.num_per_sec, hwcfg.num_ahb_sec, hwcfg.num_tzma);
309 
310 	init_pm(dev);
311 }
312 
stm32_etzpc_init(paddr_t base)313 void stm32_etzpc_init(paddr_t base)
314 {
315 	init_device_from_hw_config(&etzpc_dev, base);
316 }
317 
318 #ifdef CFG_EMBED_DTB
init_etzpc_from_dt(void)319 static TEE_Result init_etzpc_from_dt(void)
320 {
321 	void *fdt = get_embedded_dt();
322 	int node = fdt_node_offset_by_compatible(fdt, -1, ETZPC_COMPAT);
323 	int status = 0;
324 	paddr_t pbase = 0;
325 
326 	/* When using DT, expect one and only one instance, secure enabled */
327 
328 	if (node < 0)
329 		panic();
330 	assert(fdt_node_offset_by_compatible(fdt, node, ETZPC_COMPAT) < 0);
331 
332 	status = _fdt_get_status(fdt, node);
333 	if (!(status & DT_STATUS_OK_SEC))
334 		panic();
335 
336 	pbase = _fdt_reg_base_address(fdt, node);
337 	if (pbase == (paddr_t)-1)
338 		panic();
339 
340 	init_device_from_hw_config(&etzpc_dev, pbase);
341 
342 	return TEE_SUCCESS;
343 }
344 
345 service_init(init_etzpc_from_dt);
346 #endif /*CFG_EMBED_DTB*/
347