xref: /optee_os/core/drivers/firewall/stm32_etzpc.c (revision 41f3fcbb0a5095874589a55ff2a05f8400fe88d8)
1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
4  * Copyright (c) 2017-2024, 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 
13 #include <assert.h>
14 #include <drivers/clk_dt.h>
15 #include <drivers/firewall.h>
16 #include <drivers/firewall_device.h>
17 #include <drivers/stm32_etzpc.h>
18 #include <drivers/stm32mp_dt_bindings.h>
19 #ifdef CFG_STM32MP15
20 #include <drivers/stm32mp1_rcc.h>
21 #endif
22 #include <initcall.h>
23 #include <io.h>
24 #include <keep.h>
25 #include <kernel/boot.h>
26 #include <kernel/dt.h>
27 #include <kernel/panic.h>
28 #include <kernel/pm.h>
29 #include <kernel/spinlock.h>
30 #include <kernel/tee_misc.h>
31 #include <libfdt.h>
32 #include <mm/core_memprot.h>
33 #include <mm/core_mmu.h>
34 #include <stm32_util.h>
35 #include <util.h>
36 
37 /* ID Registers */
38 #define ETZPC_TZMA0_SIZE		U(0x000)
39 #define ETZPC_DECPROT0			U(0x010)
40 #define ETZPC_DECPROT_LOCK0		U(0x030)
41 #define ETZPC_HWCFGR			U(0x3F0)
42 #define ETZPC_VERR			U(0x3F4)
43 
44 /* ID Registers fields */
45 #define ETZPC_TZMA0_SIZE_LOCK		BIT(31)
46 #define ETZPC_DECPROT0_MASK		GENMASK_32(1, 0)
47 #define ETZPC_HWCFGR_NUM_TZMA_MASK	GENMASK_32(7, 0)
48 #define ETZPC_HWCFGR_NUM_TZMA_SHIFT	0
49 #define ETZPC_HWCFGR_NUM_PER_SEC_MASK	GENMASK_32(15, 8)
50 #define ETZPC_HWCFGR_NUM_PER_SEC_SHIFT	8
51 #define ETZPC_HWCFGR_NUM_AHB_SEC_MASK	GENMASK_32(23, 16)
52 #define ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT	16
53 #define ETZPC_HWCFGR_CHUNKS1N4_MASK	GENMASK_32(31, 24)
54 #define ETZPC_HWCFGR_CHUNKS1N4_SHIFT	24
55 
56 #define DECPROT_SHIFT			1
57 #define IDS_PER_DECPROT_REGS		U(16)
58 #define IDS_PER_DECPROT_LOCK_REGS	U(32)
59 
60 /*
61  * Implementation uses uint8_t to store each securable DECPROT configuration
62  * and uint16_t to store each securable TZMA configuration. When resuming
63  * from deep suspend, the DECPROT configurations are restored.
64  */
65 #define PERIPH_PM_LOCK_BIT		BIT(7)
66 #define PERIPH_PM_ATTR_MASK		GENMASK_32(2, 0)
67 #define TZMA_PM_LOCK_BIT		BIT(15)
68 #define TZMA_PM_VALUE_MASK		GENMASK_32(9, 0)
69 
70 /*
71  * struct stm32_etzpc_platdata - Driver data set at initialization
72  *
73  * @name:	Name of the peripheral
74  * @clk:	ETZPC clock
75  * @periph_cfg:	Peripheral DECPROT configuration
76  * @tzma_cfg:	TZMA configuration
77  * @base:	ETZPC IOMEM base address
78  */
79 struct stm32_etzpc_platdata {
80 	char *name;
81 	struct clk *clk;
82 	uint8_t *periph_cfg;
83 	uint16_t *tzma_cfg;
84 	struct io_pa_va base;
85 };
86 
87 /*
88  * struct stm32_etzpc_driver_data - configuration data from the hardware
89  *
90  * @num_tzma:	 Number of TZMA zones, read from the hardware
91  * @num_per_sec: Number of securable AHB & APB periphs, read from the hardware
92  * @num_ahb_sec: Number of securable AHB master zones, read from the hardware
93  */
94 struct stm32_etzpc_driver_data {
95 	unsigned int num_tzma;
96 	unsigned int num_per_sec;
97 	unsigned int num_ahb_sec;
98 };
99 
100 /*
101  * struct etzpc_device - ETZPC device driver instance
102  * @pdata:	Platform data set during initialization
103  * @ddata:	Device configuration data from the hardware
104  * @lock:	Access contention
105  */
106 struct etzpc_device {
107 	struct stm32_etzpc_platdata pdata;
108 	struct stm32_etzpc_driver_data ddata;
109 	unsigned int lock;
110 };
111 
112 static struct etzpc_device *etzpc_device;
113 
114 static const char *const etzpc_decprot_strings[] __maybe_unused = {
115 	[ETZPC_DECPROT_S_RW] = "ETZPC_DECPROT_S_RW",
116 	[ETZPC_DECPROT_NS_R_S_W] = "ETZPC_DECPROT_NS_R_S_W",
117 	[ETZPC_DECPROT_MCU_ISOLATION] = "ETZPC_DECPROT_MCU_ISOLATION",
118 	[ETZPC_DECPROT_NS_RW] = "ETZPC_DECPROT_NS_RW",
119 };
120 
121 static uint32_t etzpc_lock(void)
122 {
123 	return cpu_spin_lock_xsave(&etzpc_device->lock);
124 }
125 
126 static void etzpc_unlock(uint32_t exceptions)
127 {
128 	cpu_spin_unlock_xrestore(&etzpc_device->lock, exceptions);
129 }
130 
131 static bool valid_decprot_id(unsigned int id)
132 {
133 	return id < etzpc_device->ddata.num_per_sec;
134 }
135 
136 static bool __maybe_unused valid_tzma_id(unsigned int id)
137 {
138 	return id < etzpc_device->ddata.num_tzma;
139 }
140 
141 static enum etzpc_decprot_attributes etzpc_binding2decprot(uint32_t mode)
142 {
143 	switch (mode) {
144 	case DECPROT_S_RW:
145 		return ETZPC_DECPROT_S_RW;
146 	case DECPROT_NS_R_S_W:
147 		return ETZPC_DECPROT_NS_R_S_W;
148 #ifdef CFG_STM32MP15
149 	case DECPROT_MCU_ISOLATION:
150 		return ETZPC_DECPROT_MCU_ISOLATION;
151 #endif
152 	case DECPROT_NS_RW:
153 		return ETZPC_DECPROT_NS_RW;
154 	default:
155 		panic();
156 	}
157 }
158 
159 static void
160 sanitize_decprot_config(uint32_t decprot_id __maybe_unused,
161 			enum etzpc_decprot_attributes attr __maybe_unused)
162 {
163 #ifdef CFG_STM32MP15
164 	/*
165 	 * STM32MP15: check dependency on RCC TZEN/MCKPROT configuration
166 	 * when a ETZPC resource is secured or isolated for Cortex-M
167 	 * coprocessor.
168 	 */
169 	switch (attr) {
170 	case DECPROT_S_RW:
171 	case DECPROT_NS_R_S_W:
172 		if (!stm32_rcc_is_secure()) {
173 			IMSG("WARNING: RCC tzen:0, insecure ETZPC hardening %"PRIu32":%s",
174 			     decprot_id, etzpc_decprot_strings[attr]);
175 			if (!IS_ENABLED(CFG_INSECURE))
176 				panic();
177 		}
178 		break;
179 	case DECPROT_MCU_ISOLATION:
180 		if (!stm32_rcc_is_secure() || !stm32_rcc_is_mckprot()) {
181 			IMSG("WARNING: RCC tzen:%u mckprot:%u, insecure ETZPC hardening %"PRIu32":%s",
182 			     stm32_rcc_is_secure(), stm32_rcc_is_mckprot(),
183 			     decprot_id, etzpc_decprot_strings[attr]);
184 			if (!IS_ENABLED(CFG_INSECURE))
185 				panic();
186 		}
187 		break;
188 	case DECPROT_NS_RW:
189 		break;
190 	default:
191 		assert(0);
192 		break;
193 	}
194 #endif
195 }
196 
197 static void etzpc_configure_decprot(uint32_t decprot_id,
198 				    enum etzpc_decprot_attributes attr)
199 {
200 	size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_REGS);
201 	uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT;
202 	uint32_t masked_decprot = (uint32_t)attr & ETZPC_DECPROT0_MASK;
203 	vaddr_t base = etzpc_device->pdata.base.va;
204 	unsigned int exceptions = 0;
205 
206 	assert(valid_decprot_id(decprot_id));
207 
208 	FMSG("ID : %"PRIu32", config %i", decprot_id, attr);
209 
210 	sanitize_decprot_config(decprot_id, attr);
211 
212 	exceptions = etzpc_lock();
213 
214 	io_clrsetbits32(base + ETZPC_DECPROT0 + offset,
215 			ETZPC_DECPROT0_MASK << shift,
216 			masked_decprot << shift);
217 
218 	etzpc_unlock(exceptions);
219 }
220 
221 enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id)
222 {
223 	size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_REGS);
224 	uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT;
225 	vaddr_t base = etzpc_device->pdata.base.va;
226 	uint32_t value = 0;
227 
228 	assert(valid_decprot_id(decprot_id));
229 
230 	value = (io_read32(base + ETZPC_DECPROT0 + offset) >> shift) &
231 		ETZPC_DECPROT0_MASK;
232 
233 	return (enum etzpc_decprot_attributes)value;
234 }
235 
236 static void etzpc_lock_decprot(uint32_t decprot_id)
237 {
238 	size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_LOCK_REGS);
239 	uint32_t mask = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS);
240 	vaddr_t base = etzpc_device->pdata.base.va;
241 	uint32_t exceptions = 0;
242 
243 	assert(valid_decprot_id(decprot_id));
244 
245 	exceptions = etzpc_lock();
246 
247 	io_write32(base + offset + ETZPC_DECPROT_LOCK0, mask);
248 
249 	etzpc_unlock(exceptions);
250 }
251 
252 static bool decprot_is_locked(uint32_t decprot_id)
253 {
254 	size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_LOCK_REGS);
255 	uint32_t mask = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS);
256 	vaddr_t base = etzpc_device->pdata.base.va;
257 
258 	assert(valid_decprot_id(decprot_id));
259 
260 	return io_read32(base + offset + ETZPC_DECPROT_LOCK0) & mask;
261 }
262 
263 void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value)
264 {
265 	size_t offset = sizeof(uint32_t) * tzma_id;
266 	vaddr_t base = etzpc_device->pdata.base.va;
267 	uint32_t exceptions = 0;
268 
269 	assert(valid_tzma_id(tzma_id));
270 
271 	exceptions = etzpc_lock();
272 
273 	io_write32(base + ETZPC_TZMA0_SIZE + offset, tzma_value);
274 
275 	etzpc_unlock(exceptions);
276 }
277 
278 static uint16_t etzpc_get_tzma(uint32_t tzma_id)
279 {
280 	size_t offset = sizeof(uint32_t) * tzma_id;
281 	vaddr_t base = etzpc_device->pdata.base.va;
282 
283 	assert(valid_tzma_id(tzma_id));
284 
285 	return io_read32(base + ETZPC_TZMA0_SIZE + offset);
286 }
287 
288 static void etzpc_lock_tzma(uint32_t tzma_id)
289 {
290 	size_t offset = sizeof(uint32_t) * tzma_id;
291 	vaddr_t base = etzpc_device->pdata.base.va;
292 	uint32_t exceptions = 0;
293 
294 	assert(valid_tzma_id(tzma_id));
295 
296 	exceptions = etzpc_lock();
297 
298 	io_setbits32(base + ETZPC_TZMA0_SIZE + offset, ETZPC_TZMA0_SIZE_LOCK);
299 
300 	etzpc_unlock(exceptions);
301 }
302 
303 static bool tzma_is_locked(uint32_t tzma_id)
304 {
305 	size_t offset = sizeof(uint32_t) * tzma_id;
306 	vaddr_t base = etzpc_device->pdata.base.va;
307 
308 	assert(valid_tzma_id(tzma_id));
309 
310 	return io_read32(base + ETZPC_TZMA0_SIZE + offset) &
311 	       ETZPC_TZMA0_SIZE_LOCK;
312 }
313 
314 static TEE_Result etzpc_pm(enum pm_op op, unsigned int pm_hint __unused,
315 			   const struct pm_callback_handle *pm_handle __unused)
316 {
317 	struct stm32_etzpc_driver_data *ddata = &etzpc_device->ddata;
318 	struct stm32_etzpc_platdata *pdata = &etzpc_device->pdata;
319 	unsigned int n = 0;
320 
321 	if (op == PM_OP_SUSPEND) {
322 		for (n = 0; n < ddata->num_per_sec; n++) {
323 			pdata->periph_cfg[n] =
324 				(uint8_t)etzpc_get_decprot(n);
325 			if (decprot_is_locked(n))
326 				pdata->periph_cfg[n] |= PERIPH_PM_LOCK_BIT;
327 		}
328 
329 		for (n = 0; n < ddata->num_tzma; n++) {
330 			pdata->tzma_cfg[n] =
331 				(uint8_t)etzpc_get_tzma(n);
332 			if (tzma_is_locked(n))
333 				pdata->tzma_cfg[n] |= TZMA_PM_LOCK_BIT;
334 		}
335 
336 		return TEE_SUCCESS;
337 	}
338 
339 	/* PM_OP_RESUME */
340 	for (n = 0; n < ddata->num_per_sec; n++) {
341 		unsigned int attr = pdata->periph_cfg[n] & PERIPH_PM_ATTR_MASK;
342 
343 		etzpc_configure_decprot(n, (enum etzpc_decprot_attributes)attr);
344 
345 		if (pdata->periph_cfg[n] & PERIPH_PM_LOCK_BIT)
346 			etzpc_lock_decprot(n);
347 	}
348 
349 	for (n = 0; n < ddata->num_tzma; n++) {
350 		uint16_t value = pdata->tzma_cfg[n] & TZMA_PM_VALUE_MASK;
351 
352 		etzpc_configure_tzma(n, value);
353 
354 		if (pdata->tzma_cfg[n] & TZMA_PM_LOCK_BIT)
355 			etzpc_lock_tzma(n);
356 	}
357 
358 	return TEE_SUCCESS;
359 }
360 DECLARE_KEEP_PAGER(etzpc_pm);
361 
362 static TEE_Result stm32_etzpc_acquire_access(struct firewall_query *firewall)
363 {
364 	enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MCU_ISOLATION;
365 	uint32_t id = 0;
366 
367 	if (!firewall || firewall->arg_count != 1)
368 		return TEE_ERROR_BAD_PARAMETERS;
369 
370 	id = firewall->args[0] & ETZPC_ID_MASK;
371 	if (id < etzpc_device->ddata.num_per_sec) {
372 		attr = etzpc_get_decprot(id);
373 		if (attr != ETZPC_DECPROT_S_RW &&
374 		    attr != ETZPC_DECPROT_NS_R_S_W)
375 			return TEE_ERROR_ACCESS_DENIED;
376 	} else {
377 		return TEE_ERROR_BAD_PARAMETERS;
378 	}
379 
380 	return TEE_SUCCESS;
381 }
382 
383 static TEE_Result
384 stm32_etzpc_acquire_memory_access(struct firewall_query *firewall,
385 				  paddr_t paddr, size_t size,
386 				  bool read __unused, bool write __unused)
387 {
388 	paddr_t tzma_base = 0;
389 	size_t prot_size = 0;
390 	uint32_t id = 0;
391 
392 	if (!firewall || firewall->arg_count != 1)
393 		return TEE_ERROR_BAD_PARAMETERS;
394 
395 	id = firewall->args[0] & ETZPC_ID_MASK;
396 	switch (id) {
397 	case ETZPC_TZMA0_ID:
398 		tzma_base = ROM_BASE;
399 		prot_size = etzpc_get_tzma(0) * SMALL_PAGE_SIZE;
400 		break;
401 	case ETZPC_TZMA1_ID:
402 		tzma_base = SYSRAM_BASE;
403 		prot_size = etzpc_get_tzma(1) * SMALL_PAGE_SIZE;
404 		break;
405 	default:
406 		return TEE_ERROR_BAD_PARAMETERS;
407 	}
408 
409 	DMSG("Acquiring access for TZMA%u, secured from %#"PRIxPA" to %#"PRIxPA,
410 	     id == ETZPC_TZMA0_ID ? 0 : 1, tzma_base, tzma_base + prot_size);
411 
412 	if (core_is_buffer_inside(paddr, size, tzma_base, prot_size))
413 		return TEE_SUCCESS;
414 
415 	return TEE_ERROR_ACCESS_DENIED;
416 }
417 
418 static TEE_Result stm32_etzpc_configure(struct firewall_query *firewall)
419 {
420 	enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX;
421 	uint32_t id = 0;
422 
423 	if (firewall->arg_count != 1)
424 		return TEE_ERROR_BAD_PARAMETERS;
425 
426 	id = firewall->args[0] & ETZPC_ID_MASK;
427 
428 	if (id < etzpc_device->ddata.num_per_sec) {
429 		uint32_t mode = 0;
430 
431 		/*
432 		 * Peripheral configuration, we assume the configuration is as
433 		 * follows:
434 		 * firewall->args[0]: Firewall configuration to apply
435 		 */
436 
437 		mode = (firewall->args[0] & ETZPC_MODE_MASK) >>
438 		       ETZPC_MODE_SHIFT;
439 		attr = etzpc_binding2decprot(mode);
440 
441 		if (decprot_is_locked(id)) {
442 			EMSG("Peripheral configuration locked");
443 			return TEE_ERROR_ACCESS_DENIED;
444 		}
445 
446 		DMSG("Setting access config for periph %"PRIu32" - attr %s", id,
447 		     etzpc_decprot_strings[attr]);
448 
449 		etzpc_configure_decprot(id, attr);
450 		if (firewall->args[0] & ETZPC_LOCK_MASK)
451 			etzpc_lock_decprot(id);
452 
453 		return TEE_SUCCESS;
454 	}
455 	EMSG("Unknown firewall ID: %"PRIu32, id);
456 
457 	return TEE_ERROR_BAD_PARAMETERS;
458 }
459 
460 static void stm32_etzpc_set_driverdata(void)
461 {
462 	struct stm32_etzpc_driver_data *ddata = &etzpc_device->ddata;
463 	vaddr_t base = etzpc_device->pdata.base.va;
464 	uint32_t reg = io_read32(base + ETZPC_HWCFGR);
465 
466 	ddata->num_tzma = (reg & ETZPC_HWCFGR_NUM_TZMA_MASK) >>
467 			   ETZPC_HWCFGR_NUM_TZMA_SHIFT;
468 	ddata->num_per_sec = (reg & ETZPC_HWCFGR_NUM_PER_SEC_MASK) >>
469 			      ETZPC_HWCFGR_NUM_PER_SEC_SHIFT;
470 	ddata->num_ahb_sec = (reg & ETZPC_HWCFGR_NUM_AHB_SEC_MASK) >>
471 			      ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT;
472 
473 	DMSG("ETZPC revision 0x%02"PRIx8", per_sec %u, ahb_sec %u, tzma %u",
474 	     io_read8(base + ETZPC_VERR),
475 	     ddata->num_per_sec, ddata->num_ahb_sec, ddata->num_tzma);
476 }
477 
478 static void fdt_etzpc_conf_decprot(const void *fdt, int node)
479 {
480 	const fdt32_t *cuint = NULL;
481 	size_t i = 0;
482 	int len = 0;
483 
484 	cuint = fdt_getprop(fdt, node, "st,decprot", &len);
485 	if (!cuint) {
486 		DMSG("No ETZPC DECPROT configuration in DT");
487 		return;
488 	}
489 
490 	clk_enable(etzpc_device->pdata.clk);
491 
492 	for (i = 0; i < len / sizeof(uint32_t); i++) {
493 		uint32_t value = fdt32_to_cpu(cuint[i]);
494 		uint32_t id = value & ETZPC_ID_MASK;
495 		uint32_t mode = (value & ETZPC_MODE_MASK) >> ETZPC_MODE_SHIFT;
496 		bool lock = value & ETZPC_LOCK_MASK;
497 		enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX;
498 
499 		if (!valid_decprot_id(id)) {
500 			DMSG("Invalid DECPROT %"PRIu32, id);
501 			panic();
502 		}
503 
504 		attr = etzpc_binding2decprot(mode);
505 		etzpc_configure_decprot(id, attr);
506 
507 		if (lock)
508 			etzpc_lock_decprot(id);
509 	}
510 
511 	clk_disable(etzpc_device->pdata.clk);
512 }
513 
514 static TEE_Result
515 stm32_etzpc_dt_probe_bus(const void *fdt, int node,
516 			 struct firewall_controller *ctrl __maybe_unused)
517 {
518 	TEE_Result res = TEE_ERROR_GENERIC;
519 	struct firewall_query *fw = NULL;
520 	int subnode = 0;
521 
522 	DMSG("Populating %s firewall bus", ctrl->name);
523 
524 	fdt_for_each_subnode(subnode, fdt, node) {
525 		unsigned int i = 0;
526 
527 		if (fdt_get_status(fdt, subnode) == DT_STATUS_DISABLED)
528 			continue;
529 
530 		if (IS_ENABLED(CFG_INSECURE) &&
531 		    stm32mp_allow_probe_shared_device(fdt, subnode)) {
532 			DMSG("Skipping firewall attributes check for %s",
533 			     fdt_get_name(fdt, subnode, NULL));
534 			goto skip_check;
535 		}
536 
537 		DMSG("Acquiring firewall access for %s when probing bus",
538 		     fdt_get_name(fdt, subnode, NULL));
539 
540 		do {
541 			/*
542 			 * The access-controllers property is mandatory for
543 			 * firewall bus devices
544 			 */
545 			res = firewall_dt_get_by_index(fdt, subnode, i, &fw);
546 			if (res == TEE_ERROR_ITEM_NOT_FOUND) {
547 				/* Stop when nothing more to parse */
548 				break;
549 			} else if (res) {
550 				EMSG("%s: Error on node %s: %#"PRIx32,
551 				     ctrl->name,
552 				     fdt_get_name(fdt, subnode, NULL), res);
553 				panic();
554 			}
555 
556 			res = firewall_acquire_access(fw);
557 			if (res) {
558 				EMSG("%s: %s not accessible: %#"PRIx32,
559 				     ctrl->name,
560 				     fdt_get_name(fdt, subnode, NULL), res);
561 				panic();
562 			}
563 
564 			firewall_put(fw);
565 			i++;
566 		} while (true);
567 
568 skip_check:
569 		res = dt_driver_maybe_add_probe_node(fdt, subnode);
570 		if (res) {
571 			EMSG("Failed on node %s with %#"PRIx32,
572 			     fdt_get_name(fdt, subnode, NULL), res);
573 			panic();
574 		}
575 	}
576 
577 	return TEE_SUCCESS;
578 }
579 
580 static TEE_Result init_etzpc_from_dt(const void *fdt, int node)
581 {
582 	TEE_Result res = TEE_ERROR_GENERIC;
583 	struct dt_node_info etzpc_info = { };
584 	int len = 0;
585 
586 	fdt_fill_device_info(fdt, &etzpc_info, node);
587 	if (etzpc_info.reg == DT_INFO_INVALID_REG ||
588 	    etzpc_info.reg_size == DT_INFO_INVALID_REG_SIZE)
589 		return TEE_ERROR_ITEM_NOT_FOUND;
590 
591 	etzpc_device->pdata.base.pa = etzpc_info.reg;
592 	etzpc_device->pdata.name = strdup(fdt_get_name(fdt, node, &len));
593 	io_pa_or_va_secure(&etzpc_device->pdata.base, etzpc_info.reg_size);
594 	res = clk_dt_get_by_index(fdt, node, 0, &etzpc_device->pdata.clk);
595 	if (res)
596 		return res;
597 
598 	stm32_etzpc_set_driverdata();
599 
600 	etzpc_device->pdata.periph_cfg =
601 		calloc(etzpc_device->ddata.num_per_sec,
602 		       sizeof(*etzpc_device->pdata.periph_cfg));
603 	if (!etzpc_device->pdata.periph_cfg)
604 		return TEE_ERROR_OUT_OF_MEMORY;
605 
606 	etzpc_device->pdata.tzma_cfg =
607 		calloc(etzpc_device->ddata.num_tzma,
608 		       sizeof(*etzpc_device->pdata.tzma_cfg));
609 	if (!etzpc_device->pdata.tzma_cfg) {
610 		free(etzpc_device->pdata.periph_cfg);
611 		return TEE_ERROR_OUT_OF_MEMORY;
612 	}
613 
614 	return TEE_SUCCESS;
615 }
616 
617 static const struct firewall_controller_ops firewall_ops = {
618 	.set_conf = stm32_etzpc_configure,
619 	.acquire_access = stm32_etzpc_acquire_access,
620 	.acquire_memory_access = stm32_etzpc_acquire_memory_access,
621 };
622 
623 static TEE_Result stm32_etzpc_probe(const void *fdt, int node,
624 				    const void *compat_data __unused)
625 {
626 	TEE_Result res = TEE_ERROR_GENERIC;
627 	struct firewall_controller *controller = NULL;
628 
629 	etzpc_device = calloc(1, sizeof(*etzpc_device));
630 	if (!etzpc_device)
631 		panic();
632 
633 	res = init_etzpc_from_dt(fdt, node);
634 	if (res) {
635 		free(etzpc_device->pdata.periph_cfg);
636 		free(etzpc_device->pdata.tzma_cfg);
637 		free(etzpc_device->pdata.name);
638 		free(etzpc_device);
639 		free(controller);
640 		return res;
641 	}
642 
643 	controller = calloc(1, sizeof(*controller));
644 	if (!controller)
645 		panic();
646 
647 	controller->base = &etzpc_device->pdata.base;
648 	controller->name = etzpc_device->pdata.name;
649 	controller->priv = etzpc_device;
650 	controller->ops = &firewall_ops;
651 
652 	res = firewall_dt_controller_register(fdt, node, controller);
653 	if (res)
654 		panic("Cannot register ETZPC as a firewall controller");
655 
656 	fdt_etzpc_conf_decprot(fdt, node);
657 
658 	res = stm32_etzpc_dt_probe_bus(fdt, node, controller);
659 	if (res)
660 		panic("Cannot populate bus");
661 
662 	register_pm_core_service_cb(etzpc_pm, NULL, "stm32-etzpc");
663 
664 	return TEE_SUCCESS;
665 }
666 
667 static const struct dt_device_match etzpc_match_table[] = {
668 	{ .compatible = "st,stm32-etzpc" },
669 	{ }
670 };
671 
672 DEFINE_DT_DRIVER(etzpc_dt_driver) = {
673 	.name = "stm32-etzpc",
674 	.match_table = etzpc_match_table,
675 	.probe = stm32_etzpc_probe,
676 };
677