xref: /optee_os/core/drivers/firewall/stm32_etzpc.c (revision e02f17f374b6ce856b8569543e2066bfbaa64c59)
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 ETZPC_DECPROT_S_RW:
171 	case ETZPC_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 ETZPC_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 ETZPC_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 #ifdef CFG_STM32MP15
419 static bool pager_permits_decprot_config(uint32_t decprot_id,
420 					 enum etzpc_decprot_attributes attr)
421 {
422 	paddr_t ram_base = 0;
423 	size_t ram_size = 0;
424 
425 	if (!IS_ENABLED(CFG_WITH_PAGER))
426 		return true;
427 
428 	switch (decprot_id) {
429 	case ETZPC_TZMA1_ID:
430 		ram_base = SYSRAM_BASE;
431 		ram_size = SYSRAM_SEC_SIZE;
432 		break;
433 	case STM32MP1_ETZPC_SRAM1_ID:
434 		ram_base = SRAM1_BASE;
435 		ram_size = SRAM1_SIZE;
436 		break;
437 	case STM32MP1_ETZPC_SRAM2_ID:
438 		ram_base = SRAM2_BASE;
439 		ram_size = SRAM2_SIZE;
440 		break;
441 	case STM32MP1_ETZPC_SRAM3_ID:
442 		ram_base = SRAM3_BASE;
443 		ram_size = SRAM3_SIZE;
444 		break;
445 	case STM32MP1_ETZPC_SRAM4_ID:
446 		ram_base = SRAM4_BASE;
447 		ram_size = SRAM4_SIZE;
448 		break;
449 	default:
450 		return true;
451 	}
452 
453 	if (stm32mp1_ram_intersect_pager_ram(ram_base, ram_size) &&
454 	    attr != ETZPC_DECPROT_S_RW) {
455 		EMSG("Internal RAM %#"PRIxPA"..%#"PRIxPA" is used by pager, must be secure",
456 		     ram_base, ram_base + ram_size);
457 		return false;
458 	}
459 
460 	return true;
461 }
462 #endif /* CFG_STM32MP15 */
463 
464 static bool decprot_id_is_internal_ram(uint32_t id)
465 {
466 	switch (id) {
467 	case STM32MP1_ETZPC_SRAM1_ID:
468 	case STM32MP1_ETZPC_SRAM2_ID:
469 	case STM32MP1_ETZPC_SRAM3_ID:
470 #ifdef CFG_STM32MP15
471 	case STM32MP1_ETZPC_SRAM4_ID:
472 	case STM32MP1_ETZPC_RETRAM_ID:
473 #endif
474 		return true;
475 	default:
476 		return false;
477 	}
478 }
479 
480 static TEE_Result stm32_etzpc_configure_memory(struct firewall_query *firewall,
481 					       paddr_t paddr, size_t size)
482 {
483 	enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX;
484 	bool lock = false;
485 	uint32_t mode = 0;
486 	uint32_t id = 0;
487 
488 	if (firewall->arg_count != 1)
489 		return TEE_ERROR_BAD_PARAMETERS;
490 
491 	id = firewall->args[0] & ETZPC_ID_MASK;
492 	mode = (firewall->args[0] & ETZPC_MODE_MASK) >> ETZPC_MODE_SHIFT;
493 	attr = etzpc_binding2decprot(mode);
494 	lock = firewall->args[0] & ETZPC_LOCK_MASK;
495 
496 	if (decprot_id_is_internal_ram(id)) {
497 		/* Use OP-TEE SRAM addresses, not the alias one */
498 		paddr = stm32mp1_pa_or_sram_alias_pa(paddr);
499 
500 		/* Target address range must match the full SRAM range */
501 		switch (id) {
502 		case STM32MP1_ETZPC_SRAM1_ID:
503 			if (paddr != SRAM1_BASE || size != SRAM1_SIZE)
504 				return TEE_ERROR_BAD_PARAMETERS;
505 			break;
506 		case STM32MP1_ETZPC_SRAM2_ID:
507 			if (paddr != SRAM2_BASE || size != SRAM2_SIZE)
508 				return TEE_ERROR_BAD_PARAMETERS;
509 			break;
510 		case STM32MP1_ETZPC_SRAM3_ID:
511 			if (paddr != SRAM3_BASE || size != SRAM3_SIZE)
512 				return TEE_ERROR_BAD_PARAMETERS;
513 			break;
514 #ifdef CFG_STM32MP15
515 		case STM32MP1_ETZPC_SRAM4_ID:
516 			if (paddr != SRAM4_BASE || size != SRAM4_SIZE)
517 				return TEE_ERROR_BAD_PARAMETERS;
518 			break;
519 		case STM32MP1_ETZPC_RETRAM_ID:
520 			if (paddr != RETRAM_BASE || size != RETRAM_SIZE)
521 				return TEE_ERROR_BAD_PARAMETERS;
522 			break;
523 #endif /*CFG_STM32MP15*/
524 		default:
525 			panic();
526 		}
527 
528 		if (decprot_is_locked(id)) {
529 			if (etzpc_get_decprot(id) != attr) {
530 				EMSG("Internal RAM configuration locked");
531 				return TEE_ERROR_ACCESS_DENIED;
532 			}
533 
534 			return TEE_SUCCESS;
535 		}
536 
537 #ifdef CFG_STM32MP15
538 		if (!pager_permits_decprot_config(id, attr))
539 			return TEE_ERROR_ACCESS_DENIED;
540 #endif
541 
542 		etzpc_configure_decprot(id, attr);
543 		if (lock)
544 			etzpc_lock_decprot(id);
545 	} else if (id == ETZPC_TZMA0_ID || id == ETZPC_TZMA1_ID) {
546 		unsigned int tzma_id = 0;
547 		uint16_t tzma_r0size = 0;
548 		paddr_t ram_base = 0;
549 		size_t ram_size = 0;
550 
551 		switch (id) {
552 		case ETZPC_TZMA0_ID:
553 			ram_base = ROM_BASE;
554 			ram_size = ROM_SIZE;
555 			tzma_id = 0;
556 			break;
557 		case ETZPC_TZMA1_ID:
558 			ram_base = SYSRAM_BASE;
559 			ram_size = SYSRAM_SIZE;
560 			tzma_id = 1;
561 			break;
562 		default:
563 			return TEE_ERROR_BAD_PARAMETERS;
564 		}
565 
566 		/* TZMA configuration supports only page aligned sizes */
567 		if (!IS_ALIGNED(paddr, SMALL_PAGE_SIZE) ||
568 		    !IS_ALIGNED(size, SMALL_PAGE_SIZE))
569 			return TEE_ERROR_BAD_PARAMETERS;
570 
571 		/*
572 		 * TZMA supports only 2 access rights configuration
573 		 * for RAM ranges: secure or non-secure.
574 		 * Secure RAM range must start from RAM base address
575 		 * and non-secure RAM range must end at RAM top address.
576 		 */
577 		switch (attr) {
578 		case ETZPC_DECPROT_S_RW:
579 			if (paddr != ram_base || size > ram_size)
580 				return TEE_ERROR_BAD_PARAMETERS;
581 			tzma_r0size = ram_size / SMALL_PAGE_SIZE;
582 			break;
583 		case ETZPC_DECPROT_NS_RW:
584 			if (paddr < ram_base ||
585 			    paddr + size != ram_base + ram_size)
586 				return TEE_ERROR_BAD_PARAMETERS;
587 			tzma_r0size = (paddr - ram_base) / SMALL_PAGE_SIZE;
588 			break;
589 		default:
590 			EMSG("Invalid TZMA mode %"PRIu32, mode);
591 			return TEE_ERROR_BAD_PARAMETERS;
592 		}
593 
594 #ifdef CFG_STM32MP15
595 		if (!pager_permits_decprot_config(id, attr))
596 			return TEE_ERROR_ACCESS_DENIED;
597 #endif
598 
599 		if (tzma_is_locked(tzma_id)) {
600 			if (etzpc_get_tzma(tzma_id) != tzma_r0size) {
601 				EMSG("TZMA configuration locked");
602 				return TEE_ERROR_ACCESS_DENIED;
603 			}
604 
605 			return TEE_SUCCESS;
606 		}
607 
608 		etzpc_configure_tzma(tzma_id, tzma_r0size);
609 		if (lock)
610 			etzpc_lock_tzma(tzma_id);
611 	} else {
612 		EMSG("Unknown firewall ID: %"PRIu32, id);
613 
614 		return TEE_ERROR_BAD_PARAMETERS;
615 	}
616 
617 	return TEE_SUCCESS;
618 }
619 
620 static TEE_Result stm32_etzpc_configure(struct firewall_query *firewall)
621 {
622 	enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX;
623 	uint32_t id = 0;
624 
625 	if (firewall->arg_count != 1)
626 		return TEE_ERROR_BAD_PARAMETERS;
627 
628 	id = firewall->args[0] & ETZPC_ID_MASK;
629 
630 	if (id < etzpc_device->ddata.num_per_sec) {
631 		uint32_t mode = 0;
632 
633 		/*
634 		 * Peripheral configuration, we assume the configuration is as
635 		 * follows:
636 		 * firewall->args[0]: Firewall configuration to apply
637 		 */
638 
639 		mode = (firewall->args[0] & ETZPC_MODE_MASK) >>
640 		       ETZPC_MODE_SHIFT;
641 		attr = etzpc_binding2decprot(mode);
642 
643 		if (decprot_is_locked(id)) {
644 			if (etzpc_get_decprot(id) != attr) {
645 				EMSG("Peripheral configuration locked");
646 				return TEE_ERROR_ACCESS_DENIED;
647 			}
648 
649 			DMSG("Compliant locked config for periph %"PRIu32" - attr %s",
650 			     id, etzpc_decprot_strings[attr]);
651 
652 			return TEE_SUCCESS;
653 		}
654 
655 #ifdef CFG_STM32MP15
656 		if (!pager_permits_decprot_config(id, attr))
657 			return TEE_ERROR_ACCESS_DENIED;
658 #endif
659 
660 		DMSG("Setting access config for periph %"PRIu32" - attr %s", id,
661 		     etzpc_decprot_strings[attr]);
662 
663 		etzpc_configure_decprot(id, attr);
664 		if (firewall->args[0] & ETZPC_LOCK_MASK)
665 			etzpc_lock_decprot(id);
666 
667 		return TEE_SUCCESS;
668 	}
669 	EMSG("Unknown firewall ID: %"PRIu32, id);
670 
671 	return TEE_ERROR_BAD_PARAMETERS;
672 }
673 
674 static void stm32_etzpc_set_driverdata(void)
675 {
676 	struct stm32_etzpc_driver_data *ddata = &etzpc_device->ddata;
677 	vaddr_t base = etzpc_device->pdata.base.va;
678 	uint32_t reg = io_read32(base + ETZPC_HWCFGR);
679 
680 	ddata->num_tzma = (reg & ETZPC_HWCFGR_NUM_TZMA_MASK) >>
681 			   ETZPC_HWCFGR_NUM_TZMA_SHIFT;
682 	ddata->num_per_sec = (reg & ETZPC_HWCFGR_NUM_PER_SEC_MASK) >>
683 			      ETZPC_HWCFGR_NUM_PER_SEC_SHIFT;
684 	ddata->num_ahb_sec = (reg & ETZPC_HWCFGR_NUM_AHB_SEC_MASK) >>
685 			      ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT;
686 
687 	DMSG("ETZPC revision 0x%02"PRIx8", per_sec %u, ahb_sec %u, tzma %u",
688 	     io_read8(base + ETZPC_VERR),
689 	     ddata->num_per_sec, ddata->num_ahb_sec, ddata->num_tzma);
690 }
691 
692 static void fdt_etzpc_conf_decprot(const void *fdt, int node)
693 {
694 	const fdt32_t *cuint = NULL;
695 	size_t i = 0;
696 	int len = 0;
697 
698 	cuint = fdt_getprop(fdt, node, "st,decprot", &len);
699 	if (!cuint) {
700 		DMSG("No ETZPC DECPROT configuration in DT");
701 		return;
702 	}
703 
704 	clk_enable(etzpc_device->pdata.clk);
705 
706 	for (i = 0; i < len / sizeof(uint32_t); i++) {
707 		uint32_t value = fdt32_to_cpu(cuint[i]);
708 		uint32_t id = value & ETZPC_ID_MASK;
709 		uint32_t mode = (value & ETZPC_MODE_MASK) >> ETZPC_MODE_SHIFT;
710 		bool lock = value & ETZPC_LOCK_MASK;
711 		enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX;
712 
713 		if (!valid_decprot_id(id)) {
714 			DMSG("Invalid DECPROT %"PRIu32, id);
715 			panic();
716 		}
717 
718 		attr = etzpc_binding2decprot(mode);
719 
720 #ifdef CFG_STM32MP15
721 		if (!pager_permits_decprot_config(id, attr))
722 			panic();
723 #endif
724 
725 		etzpc_configure_decprot(id, attr);
726 
727 		if (lock)
728 			etzpc_lock_decprot(id);
729 	}
730 
731 	clk_disable(etzpc_device->pdata.clk);
732 }
733 
734 static TEE_Result
735 stm32_etzpc_dt_probe_bus(const void *fdt, int node,
736 			 struct firewall_controller *ctrl __maybe_unused)
737 {
738 	TEE_Result res = TEE_ERROR_GENERIC;
739 	struct firewall_query *fw = NULL;
740 	int subnode = 0;
741 
742 	DMSG("Populating %s firewall bus", ctrl->name);
743 
744 	fdt_for_each_subnode(subnode, fdt, node) {
745 		unsigned int i = 0;
746 
747 		if (fdt_get_status(fdt, subnode) == DT_STATUS_DISABLED)
748 			continue;
749 
750 		if (IS_ENABLED(CFG_INSECURE) &&
751 		    stm32mp_allow_probe_shared_device(fdt, subnode)) {
752 			DMSG("Skipping firewall attributes check for %s",
753 			     fdt_get_name(fdt, subnode, NULL));
754 			goto skip_check;
755 		}
756 
757 		DMSG("Acquiring firewall access for %s when probing bus",
758 		     fdt_get_name(fdt, subnode, NULL));
759 
760 		do {
761 			/*
762 			 * The access-controllers property is mandatory for
763 			 * firewall bus devices
764 			 */
765 			res = firewall_dt_get_by_index(fdt, subnode, i, &fw);
766 			if (res == TEE_ERROR_ITEM_NOT_FOUND) {
767 				/* Stop when nothing more to parse */
768 				break;
769 			} else if (res) {
770 				EMSG("%s: Error on node %s: %#"PRIx32,
771 				     ctrl->name,
772 				     fdt_get_name(fdt, subnode, NULL), res);
773 				panic();
774 			}
775 
776 			res = firewall_acquire_access(fw);
777 			if (res) {
778 				EMSG("%s: %s not accessible: %#"PRIx32,
779 				     ctrl->name,
780 				     fdt_get_name(fdt, subnode, NULL), res);
781 				panic();
782 			}
783 
784 			firewall_put(fw);
785 			i++;
786 		} while (true);
787 
788 skip_check:
789 		res = dt_driver_maybe_add_probe_node(fdt, subnode);
790 		if (res) {
791 			EMSG("Failed on node %s with %#"PRIx32,
792 			     fdt_get_name(fdt, subnode, NULL), res);
793 			panic();
794 		}
795 	}
796 
797 	return TEE_SUCCESS;
798 }
799 
800 static TEE_Result init_etzpc_from_dt(const void *fdt, int node)
801 {
802 	TEE_Result res = TEE_ERROR_GENERIC;
803 	struct dt_node_info etzpc_info = { };
804 	int len = 0;
805 
806 	fdt_fill_device_info(fdt, &etzpc_info, node);
807 	if (etzpc_info.reg == DT_INFO_INVALID_REG ||
808 	    etzpc_info.reg_size == DT_INFO_INVALID_REG_SIZE)
809 		return TEE_ERROR_ITEM_NOT_FOUND;
810 
811 	etzpc_device->pdata.base.pa = etzpc_info.reg;
812 	etzpc_device->pdata.name = strdup(fdt_get_name(fdt, node, &len));
813 	io_pa_or_va_secure(&etzpc_device->pdata.base, etzpc_info.reg_size);
814 	res = clk_dt_get_by_index(fdt, node, 0, &etzpc_device->pdata.clk);
815 	if (res)
816 		return res;
817 
818 	stm32_etzpc_set_driverdata();
819 
820 	etzpc_device->pdata.periph_cfg =
821 		calloc(etzpc_device->ddata.num_per_sec,
822 		       sizeof(*etzpc_device->pdata.periph_cfg));
823 	if (!etzpc_device->pdata.periph_cfg)
824 		return TEE_ERROR_OUT_OF_MEMORY;
825 
826 	etzpc_device->pdata.tzma_cfg =
827 		calloc(etzpc_device->ddata.num_tzma,
828 		       sizeof(*etzpc_device->pdata.tzma_cfg));
829 	if (!etzpc_device->pdata.tzma_cfg) {
830 		free(etzpc_device->pdata.periph_cfg);
831 		return TEE_ERROR_OUT_OF_MEMORY;
832 	}
833 
834 	return TEE_SUCCESS;
835 }
836 
837 static const struct firewall_controller_ops firewall_ops = {
838 	.set_conf = stm32_etzpc_configure,
839 	.set_memory_conf = stm32_etzpc_configure_memory,
840 	.acquire_access = stm32_etzpc_acquire_access,
841 	.acquire_memory_access = stm32_etzpc_acquire_memory_access,
842 };
843 
844 static TEE_Result stm32_etzpc_probe(const void *fdt, int node,
845 				    const void *compat_data __unused)
846 {
847 	TEE_Result res = TEE_ERROR_GENERIC;
848 	struct firewall_controller *controller = NULL;
849 
850 	etzpc_device = calloc(1, sizeof(*etzpc_device));
851 	if (!etzpc_device)
852 		panic();
853 
854 	res = init_etzpc_from_dt(fdt, node);
855 	if (res) {
856 		free(etzpc_device->pdata.periph_cfg);
857 		free(etzpc_device->pdata.tzma_cfg);
858 		free(etzpc_device->pdata.name);
859 		free(etzpc_device);
860 		free(controller);
861 		return res;
862 	}
863 
864 	controller = calloc(1, sizeof(*controller));
865 	if (!controller)
866 		panic();
867 
868 	controller->base = &etzpc_device->pdata.base;
869 	controller->name = etzpc_device->pdata.name;
870 	controller->priv = etzpc_device;
871 	controller->ops = &firewall_ops;
872 
873 	res = firewall_dt_controller_register(fdt, node, controller);
874 	if (res)
875 		panic("Cannot register ETZPC as a firewall controller");
876 
877 	fdt_etzpc_conf_decprot(fdt, node);
878 
879 	res = stm32_etzpc_dt_probe_bus(fdt, node, controller);
880 	if (res)
881 		panic("Cannot populate bus");
882 
883 	register_pm_core_service_cb(etzpc_pm, NULL, "stm32-etzpc");
884 
885 	return TEE_SUCCESS;
886 }
887 
888 static const struct dt_device_match etzpc_match_table[] = {
889 	{ .compatible = "st,stm32-etzpc" },
890 	{ }
891 };
892 
893 DEFINE_DT_DRIVER(etzpc_dt_driver) = {
894 	.name = "stm32-etzpc",
895 	.match_table = etzpc_match_table,
896 	.probe = stm32_etzpc_probe,
897 };
898