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