xref: /optee_os/core/drivers/firewall/stm32_etzpc.c (revision 5d5d7d0b1c038a6836be9f0b38585f5aa6a4dd01)
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/stm32mp_dt_bindings.h>
18 #ifdef CFG_STM32MP15
19 #include <drivers/stm32mp1_rcc.h>
20 #endif
21 #include <initcall.h>
22 #include <io.h>
23 #include <keep.h>
24 #include <kernel/boot.h>
25 #include <kernel/dt.h>
26 #include <kernel/panic.h>
27 #include <kernel/pm.h>
28 #include <kernel/spinlock.h>
29 #include <kernel/tee_misc.h>
30 #include <libfdt.h>
31 #include <mm/core_memprot.h>
32 #include <mm/core_mmu.h>
33 #include <stm32_util.h>
34 #include <util.h>
35 
36 /* ID Registers */
37 #define ETZPC_TZMA0_SIZE		U(0x000)
38 #define ETZPC_DECPROT0			U(0x010)
39 #define ETZPC_DECPROT_LOCK0		U(0x030)
40 #define ETZPC_HWCFGR			U(0x3F0)
41 #define ETZPC_VERR			U(0x3F4)
42 
43 /* ID Registers fields */
44 #define ETZPC_TZMA0_SIZE_LOCK		BIT(31)
45 #define ETZPC_DECPROT0_MASK		GENMASK_32(1, 0)
46 #define ETZPC_HWCFGR_NUM_TZMA_MASK	GENMASK_32(7, 0)
47 #define ETZPC_HWCFGR_NUM_TZMA_SHIFT	0
48 #define ETZPC_HWCFGR_NUM_PER_SEC_MASK	GENMASK_32(15, 8)
49 #define ETZPC_HWCFGR_NUM_PER_SEC_SHIFT	8
50 #define ETZPC_HWCFGR_NUM_AHB_SEC_MASK	GENMASK_32(23, 16)
51 #define ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT	16
52 #define ETZPC_HWCFGR_CHUNKS1N4_MASK	GENMASK_32(31, 24)
53 #define ETZPC_HWCFGR_CHUNKS1N4_SHIFT	24
54 
55 #define DECPROT_SHIFT			1
56 #define IDS_PER_DECPROT_REGS		U(16)
57 #define IDS_PER_DECPROT_LOCK_REGS	U(32)
58 
59 /*
60  * Implementation uses uint8_t to store each securable DECPROT configuration
61  * and uint16_t to store each securable TZMA configuration. When resuming
62  * from deep suspend, the DECPROT configurations are restored.
63  */
64 #define PERIPH_PM_LOCK_BIT		BIT(7)
65 #define PERIPH_PM_ATTR_MASK		GENMASK_32(2, 0)
66 #define TZMA_PM_LOCK_BIT		BIT(15)
67 #define TZMA_PM_VALUE_MASK		GENMASK_32(9, 0)
68 
69 /* ETZPC DECPROT bit field values */
70 enum etzpc_decprot_attributes {
71 	ETZPC_DECPROT_S_RW = 0,
72 	ETZPC_DECPROT_NS_R_S_W = 1,
73 	ETZPC_DECPROT_MCU_ISOLATION = 2,
74 	ETZPC_DECPROT_NS_RW = 3,
75 	ETZPC_DECPROT_MAX = 4,
76 };
77 
78 /*
79  * struct stm32_etzpc_platdata - Driver data set at initialization
80  *
81  * @name:	Name of the peripheral
82  * @clk:	ETZPC clock
83  * @periph_cfg:	Peripheral DECPROT configuration
84  * @tzma_cfg:	TZMA configuration
85  * @base:	ETZPC IOMEM base address
86  */
87 struct stm32_etzpc_platdata {
88 	char *name;
89 	struct clk *clk;
90 	uint8_t *periph_cfg;
91 	uint16_t *tzma_cfg;
92 	struct io_pa_va base;
93 };
94 
95 /*
96  * struct stm32_etzpc_driver_data - configuration data from the hardware
97  *
98  * @num_tzma:	 Number of TZMA zones, read from the hardware
99  * @num_per_sec: Number of securable AHB & APB periphs, read from the hardware
100  * @num_ahb_sec: Number of securable AHB master zones, read from the hardware
101  */
102 struct stm32_etzpc_driver_data {
103 	unsigned int num_tzma;
104 	unsigned int num_per_sec;
105 	unsigned int num_ahb_sec;
106 };
107 
108 /*
109  * struct etzpc_device - ETZPC device driver instance
110  * @pdata:	Platform data set during initialization
111  * @ddata:	Device configuration data from the hardware
112  * @lock:	Access contention
113  */
114 struct etzpc_device {
115 	struct stm32_etzpc_platdata pdata;
116 	struct stm32_etzpc_driver_data ddata;
117 	unsigned int lock;
118 };
119 
120 static struct etzpc_device *etzpc_device;
121 
122 static const char *const etzpc_decprot_strings[] __maybe_unused = {
123 	[ETZPC_DECPROT_S_RW] = "ETZPC_DECPROT_S_RW",
124 	[ETZPC_DECPROT_NS_R_S_W] = "ETZPC_DECPROT_NS_R_S_W",
125 	[ETZPC_DECPROT_MCU_ISOLATION] = "ETZPC_DECPROT_MCU_ISOLATION",
126 	[ETZPC_DECPROT_NS_RW] = "ETZPC_DECPROT_NS_RW",
127 };
128 
129 static uint32_t etzpc_lock(void)
130 {
131 	return cpu_spin_lock_xsave(&etzpc_device->lock);
132 }
133 
134 static void etzpc_unlock(uint32_t exceptions)
135 {
136 	cpu_spin_unlock_xrestore(&etzpc_device->lock, exceptions);
137 }
138 
139 static bool valid_decprot_id(unsigned int id)
140 {
141 	return id < etzpc_device->ddata.num_per_sec;
142 }
143 
144 static bool __maybe_unused valid_tzma_id(unsigned int id)
145 {
146 	return id < etzpc_device->ddata.num_tzma;
147 }
148 
149 static enum etzpc_decprot_attributes etzpc_binding2decprot(uint32_t mode)
150 {
151 	switch (mode) {
152 	case DECPROT_S_RW:
153 		return ETZPC_DECPROT_S_RW;
154 	case DECPROT_NS_R_S_W:
155 		return ETZPC_DECPROT_NS_R_S_W;
156 #ifdef CFG_STM32MP15
157 	case DECPROT_MCU_ISOLATION:
158 		return ETZPC_DECPROT_MCU_ISOLATION;
159 #endif
160 	case DECPROT_NS_RW:
161 		return ETZPC_DECPROT_NS_RW;
162 	default:
163 		panic();
164 	}
165 }
166 
167 static void
168 sanitize_decprot_config(uint32_t decprot_id __maybe_unused,
169 			enum etzpc_decprot_attributes attr __maybe_unused)
170 {
171 #ifdef CFG_STM32MP15
172 	/*
173 	 * STM32MP15: check dependency on RCC TZEN/MCKPROT configuration
174 	 * when a ETZPC resource is secured or isolated for Cortex-M
175 	 * coprocessor.
176 	 */
177 	switch (attr) {
178 	case ETZPC_DECPROT_S_RW:
179 	case ETZPC_DECPROT_NS_R_S_W:
180 		if (!stm32_rcc_is_secure()) {
181 			IMSG("WARNING: RCC tzen:0, insecure ETZPC hardening %"PRIu32":%s",
182 			     decprot_id, etzpc_decprot_strings[attr]);
183 			if (!IS_ENABLED(CFG_INSECURE))
184 				panic();
185 		}
186 		break;
187 	case ETZPC_DECPROT_MCU_ISOLATION:
188 		if (!stm32_rcc_is_secure() || !stm32_rcc_is_mckprot()) {
189 			IMSG("WARNING: RCC tzen:%u mckprot:%u, insecure ETZPC hardening %"PRIu32":%s",
190 			     stm32_rcc_is_secure(), stm32_rcc_is_mckprot(),
191 			     decprot_id, etzpc_decprot_strings[attr]);
192 			if (!IS_ENABLED(CFG_INSECURE))
193 				panic();
194 		}
195 		break;
196 	case ETZPC_DECPROT_NS_RW:
197 		break;
198 	default:
199 		assert(0);
200 		break;
201 	}
202 #endif
203 }
204 
205 static void etzpc_configure_decprot(uint32_t decprot_id,
206 				    enum etzpc_decprot_attributes attr)
207 {
208 	size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_REGS);
209 	uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT;
210 	uint32_t masked_decprot = (uint32_t)attr & ETZPC_DECPROT0_MASK;
211 	vaddr_t base = etzpc_device->pdata.base.va;
212 	unsigned int exceptions = 0;
213 
214 	assert(valid_decprot_id(decprot_id));
215 
216 	FMSG("ID : %"PRIu32", config %i", decprot_id, attr);
217 
218 	sanitize_decprot_config(decprot_id, attr);
219 
220 	exceptions = etzpc_lock();
221 
222 	io_clrsetbits32(base + ETZPC_DECPROT0 + offset,
223 			ETZPC_DECPROT0_MASK << shift,
224 			masked_decprot << shift);
225 
226 	etzpc_unlock(exceptions);
227 }
228 
229 static enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id)
230 {
231 	size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_REGS);
232 	uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT;
233 	vaddr_t base = etzpc_device->pdata.base.va;
234 	uint32_t value = 0;
235 
236 	assert(valid_decprot_id(decprot_id));
237 
238 	value = (io_read32(base + ETZPC_DECPROT0 + offset) >> shift) &
239 		ETZPC_DECPROT0_MASK;
240 
241 	return (enum etzpc_decprot_attributes)value;
242 }
243 
244 static void etzpc_lock_decprot(uint32_t decprot_id)
245 {
246 	size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_LOCK_REGS);
247 	uint32_t mask = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS);
248 	vaddr_t base = etzpc_device->pdata.base.va;
249 	uint32_t exceptions = 0;
250 
251 	assert(valid_decprot_id(decprot_id));
252 
253 	exceptions = etzpc_lock();
254 
255 	io_write32(base + offset + ETZPC_DECPROT_LOCK0, mask);
256 
257 	etzpc_unlock(exceptions);
258 }
259 
260 static bool decprot_is_locked(uint32_t decprot_id)
261 {
262 	size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_LOCK_REGS);
263 	uint32_t mask = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS);
264 	vaddr_t base = etzpc_device->pdata.base.va;
265 
266 	assert(valid_decprot_id(decprot_id));
267 
268 	return io_read32(base + offset + ETZPC_DECPROT_LOCK0) & mask;
269 }
270 
271 static void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value)
272 {
273 	size_t offset = sizeof(uint32_t) * tzma_id;
274 	vaddr_t base = etzpc_device->pdata.base.va;
275 	uint32_t exceptions = 0;
276 
277 	assert(valid_tzma_id(tzma_id));
278 
279 	exceptions = etzpc_lock();
280 
281 	io_write32(base + ETZPC_TZMA0_SIZE + offset, tzma_value);
282 
283 	etzpc_unlock(exceptions);
284 }
285 
286 static uint16_t etzpc_get_tzma(uint32_t tzma_id)
287 {
288 	size_t offset = sizeof(uint32_t) * tzma_id;
289 	vaddr_t base = etzpc_device->pdata.base.va;
290 
291 	assert(valid_tzma_id(tzma_id));
292 
293 	return io_read32(base + ETZPC_TZMA0_SIZE + offset);
294 }
295 
296 static void etzpc_lock_tzma(uint32_t tzma_id)
297 {
298 	size_t offset = sizeof(uint32_t) * tzma_id;
299 	vaddr_t base = etzpc_device->pdata.base.va;
300 	uint32_t exceptions = 0;
301 
302 	assert(valid_tzma_id(tzma_id));
303 
304 	exceptions = etzpc_lock();
305 
306 	io_setbits32(base + ETZPC_TZMA0_SIZE + offset, ETZPC_TZMA0_SIZE_LOCK);
307 
308 	etzpc_unlock(exceptions);
309 }
310 
311 static bool tzma_is_locked(uint32_t tzma_id)
312 {
313 	size_t offset = sizeof(uint32_t) * tzma_id;
314 	vaddr_t base = etzpc_device->pdata.base.va;
315 
316 	assert(valid_tzma_id(tzma_id));
317 
318 	return io_read32(base + ETZPC_TZMA0_SIZE + offset) &
319 	       ETZPC_TZMA0_SIZE_LOCK;
320 }
321 
322 static TEE_Result etzpc_pm(enum pm_op op, unsigned int pm_hint __unused,
323 			   const struct pm_callback_handle *pm_handle __unused)
324 {
325 	struct stm32_etzpc_driver_data *ddata = &etzpc_device->ddata;
326 	struct stm32_etzpc_platdata *pdata = &etzpc_device->pdata;
327 	unsigned int n = 0;
328 
329 	if (op == PM_OP_SUSPEND) {
330 		for (n = 0; n < ddata->num_per_sec; n++) {
331 			pdata->periph_cfg[n] =
332 				(uint8_t)etzpc_get_decprot(n);
333 			if (decprot_is_locked(n))
334 				pdata->periph_cfg[n] |= PERIPH_PM_LOCK_BIT;
335 		}
336 
337 		for (n = 0; n < ddata->num_tzma; n++) {
338 			pdata->tzma_cfg[n] =
339 				(uint8_t)etzpc_get_tzma(n);
340 			if (tzma_is_locked(n))
341 				pdata->tzma_cfg[n] |= TZMA_PM_LOCK_BIT;
342 		}
343 
344 		return TEE_SUCCESS;
345 	}
346 
347 	/* PM_OP_RESUME */
348 	for (n = 0; n < ddata->num_per_sec; n++) {
349 		unsigned int attr = pdata->periph_cfg[n] & PERIPH_PM_ATTR_MASK;
350 
351 		etzpc_configure_decprot(n, (enum etzpc_decprot_attributes)attr);
352 
353 		if (pdata->periph_cfg[n] & PERIPH_PM_LOCK_BIT)
354 			etzpc_lock_decprot(n);
355 	}
356 
357 	for (n = 0; n < ddata->num_tzma; n++) {
358 		uint16_t value = pdata->tzma_cfg[n] & TZMA_PM_VALUE_MASK;
359 
360 		etzpc_configure_tzma(n, value);
361 
362 		if (pdata->tzma_cfg[n] & TZMA_PM_LOCK_BIT)
363 			etzpc_lock_tzma(n);
364 	}
365 
366 	return TEE_SUCCESS;
367 }
368 DECLARE_KEEP_PAGER(etzpc_pm);
369 
370 static TEE_Result stm32_etzpc_check_access(struct firewall_query *firewall)
371 {
372 	enum etzpc_decprot_attributes attr_req = ETZPC_DECPROT_MAX;
373 	uint32_t id = 0;
374 
375 	if (!firewall || firewall->arg_count != 1)
376 		return TEE_ERROR_BAD_PARAMETERS;
377 
378 	id = firewall->args[0] & ETZPC_ID_MASK;
379 	attr_req = etzpc_binding2decprot((firewall->args[0] &
380 					  ETZPC_MODE_MASK) >> ETZPC_MODE_SHIFT);
381 
382 	if (id < etzpc_device->ddata.num_per_sec) {
383 		if (etzpc_get_decprot(id) == attr_req)
384 			return TEE_SUCCESS;
385 		else
386 			return TEE_ERROR_ACCESS_DENIED;
387 	} else {
388 		return TEE_ERROR_BAD_PARAMETERS;
389 	}
390 }
391 
392 static TEE_Result stm32_etzpc_acquire_access(struct firewall_query *firewall)
393 {
394 	enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MCU_ISOLATION;
395 	uint32_t id = 0;
396 
397 	if (!firewall || firewall->arg_count != 1)
398 		return TEE_ERROR_BAD_PARAMETERS;
399 
400 	id = firewall->args[0] & ETZPC_ID_MASK;
401 	if (id < etzpc_device->ddata.num_per_sec) {
402 		attr = etzpc_get_decprot(id);
403 		if (attr != ETZPC_DECPROT_S_RW &&
404 		    attr != ETZPC_DECPROT_NS_R_S_W)
405 			return TEE_ERROR_ACCESS_DENIED;
406 	} else {
407 		return TEE_ERROR_BAD_PARAMETERS;
408 	}
409 
410 	return TEE_SUCCESS;
411 }
412 
413 static TEE_Result
414 stm32_etzpc_acquire_memory_access(struct firewall_query *firewall,
415 				  paddr_t paddr, size_t size,
416 				  bool read __unused, bool write __unused)
417 {
418 	paddr_t tzma_base = 0;
419 	size_t prot_size = 0;
420 	uint32_t id = 0;
421 
422 	if (!firewall || firewall->arg_count != 1)
423 		return TEE_ERROR_BAD_PARAMETERS;
424 
425 	id = firewall->args[0] & ETZPC_ID_MASK;
426 	switch (id) {
427 	case ETZPC_TZMA0_ID:
428 		tzma_base = ROM_BASE;
429 		prot_size = etzpc_get_tzma(0) * SMALL_PAGE_SIZE;
430 		break;
431 	case ETZPC_TZMA1_ID:
432 		tzma_base = SYSRAM_BASE;
433 		prot_size = etzpc_get_tzma(1) * SMALL_PAGE_SIZE;
434 		break;
435 	default:
436 		return TEE_ERROR_BAD_PARAMETERS;
437 	}
438 
439 	DMSG("Acquiring access for TZMA%u, secured from %#"PRIxPA" to %#"PRIxPA,
440 	     id == ETZPC_TZMA0_ID ? 0 : 1, tzma_base, tzma_base + prot_size);
441 
442 	if (core_is_buffer_inside(paddr, size, tzma_base, prot_size))
443 		return TEE_SUCCESS;
444 
445 	return TEE_ERROR_ACCESS_DENIED;
446 }
447 
448 #ifdef CFG_STM32MP15
449 static bool pager_permits_decprot_config(uint32_t decprot_id,
450 					 enum etzpc_decprot_attributes attr)
451 {
452 	paddr_t ram_base = 0;
453 	size_t ram_size = 0;
454 
455 	if (!IS_ENABLED(CFG_WITH_PAGER))
456 		return true;
457 
458 	switch (decprot_id) {
459 	case ETZPC_TZMA1_ID:
460 		ram_base = SYSRAM_BASE;
461 		ram_size = SYSRAM_SEC_SIZE;
462 		break;
463 	case STM32MP1_ETZPC_SRAM1_ID:
464 		ram_base = SRAM1_BASE;
465 		ram_size = SRAM1_SIZE;
466 		break;
467 	case STM32MP1_ETZPC_SRAM2_ID:
468 		ram_base = SRAM2_BASE;
469 		ram_size = SRAM2_SIZE;
470 		break;
471 	case STM32MP1_ETZPC_SRAM3_ID:
472 		ram_base = SRAM3_BASE;
473 		ram_size = SRAM3_SIZE;
474 		break;
475 	case STM32MP1_ETZPC_SRAM4_ID:
476 		ram_base = SRAM4_BASE;
477 		ram_size = SRAM4_SIZE;
478 		break;
479 	default:
480 		return true;
481 	}
482 
483 	if (stm32mp1_ram_intersect_pager_ram(ram_base, ram_size) &&
484 	    attr != ETZPC_DECPROT_S_RW) {
485 		EMSG("Internal RAM %#"PRIxPA"..%#"PRIxPA" is used by pager, must be secure",
486 		     ram_base, ram_base + ram_size);
487 		return false;
488 	}
489 
490 	return true;
491 }
492 #endif /* CFG_STM32MP15 */
493 
494 static bool decprot_id_is_internal_ram(uint32_t id)
495 {
496 	switch (id) {
497 	case STM32MP1_ETZPC_SRAM1_ID:
498 	case STM32MP1_ETZPC_SRAM2_ID:
499 	case STM32MP1_ETZPC_SRAM3_ID:
500 #ifdef CFG_STM32MP15
501 	case STM32MP1_ETZPC_SRAM4_ID:
502 	case STM32MP1_ETZPC_RETRAM_ID:
503 #endif
504 		return true;
505 	default:
506 		return false;
507 	}
508 }
509 
510 static TEE_Result stm32_etzpc_configure_memory(struct firewall_query *firewall,
511 					       paddr_t paddr, size_t size)
512 {
513 	enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX;
514 	bool lock = false;
515 	uint32_t mode = 0;
516 	uint32_t id = 0;
517 
518 	if (firewall->arg_count != 1)
519 		return TEE_ERROR_BAD_PARAMETERS;
520 
521 	id = firewall->args[0] & ETZPC_ID_MASK;
522 	mode = (firewall->args[0] & ETZPC_MODE_MASK) >> ETZPC_MODE_SHIFT;
523 	attr = etzpc_binding2decprot(mode);
524 	lock = firewall->args[0] & ETZPC_LOCK_MASK;
525 
526 	if (decprot_id_is_internal_ram(id)) {
527 		/* Use OP-TEE SRAM addresses, not the alias one */
528 		paddr = stm32mp1_pa_or_sram_alias_pa(paddr);
529 
530 		/* Target address range must match the full SRAM range */
531 		switch (id) {
532 		case STM32MP1_ETZPC_SRAM1_ID:
533 			if (paddr != SRAM1_BASE || size != SRAM1_SIZE)
534 				return TEE_ERROR_BAD_PARAMETERS;
535 			break;
536 		case STM32MP1_ETZPC_SRAM2_ID:
537 			if (paddr != SRAM2_BASE || size != SRAM2_SIZE)
538 				return TEE_ERROR_BAD_PARAMETERS;
539 			break;
540 		case STM32MP1_ETZPC_SRAM3_ID:
541 			if (paddr != SRAM3_BASE || size != SRAM3_SIZE)
542 				return TEE_ERROR_BAD_PARAMETERS;
543 			break;
544 #ifdef CFG_STM32MP15
545 		case STM32MP1_ETZPC_SRAM4_ID:
546 			if (paddr != SRAM4_BASE || size != SRAM4_SIZE)
547 				return TEE_ERROR_BAD_PARAMETERS;
548 			break;
549 		case STM32MP1_ETZPC_RETRAM_ID:
550 			if (paddr != RETRAM_BASE || size != RETRAM_SIZE)
551 				return TEE_ERROR_BAD_PARAMETERS;
552 			break;
553 #endif /*CFG_STM32MP15*/
554 		default:
555 			panic();
556 		}
557 
558 		if (decprot_is_locked(id)) {
559 			if (etzpc_get_decprot(id) != attr) {
560 				EMSG("Internal RAM configuration locked");
561 				return TEE_ERROR_ACCESS_DENIED;
562 			}
563 
564 			return TEE_SUCCESS;
565 		}
566 
567 #ifdef CFG_STM32MP15
568 		if (!pager_permits_decprot_config(id, attr))
569 			return TEE_ERROR_ACCESS_DENIED;
570 #endif
571 
572 		etzpc_configure_decprot(id, attr);
573 		if (lock)
574 			etzpc_lock_decprot(id);
575 	} else if (id == ETZPC_TZMA0_ID || id == ETZPC_TZMA1_ID) {
576 		unsigned int tzma_id = 0;
577 		uint16_t tzma_r0size = 0;
578 		paddr_t ram_base = 0;
579 		size_t ram_size = 0;
580 
581 		switch (id) {
582 		case ETZPC_TZMA0_ID:
583 			ram_base = ROM_BASE;
584 			ram_size = ROM_SIZE;
585 			tzma_id = 0;
586 			break;
587 		case ETZPC_TZMA1_ID:
588 			ram_base = SYSRAM_BASE;
589 			ram_size = SYSRAM_SIZE;
590 			tzma_id = 1;
591 			break;
592 		default:
593 			return TEE_ERROR_BAD_PARAMETERS;
594 		}
595 
596 		/* TZMA configuration supports only page aligned sizes */
597 		if (!IS_ALIGNED(paddr, SMALL_PAGE_SIZE) ||
598 		    !IS_ALIGNED(size, SMALL_PAGE_SIZE))
599 			return TEE_ERROR_BAD_PARAMETERS;
600 
601 		/*
602 		 * TZMA supports only 2 access rights configuration
603 		 * for RAM ranges: secure or non-secure.
604 		 * Secure RAM range must start from RAM base address
605 		 * and non-secure RAM range must end at RAM top address.
606 		 */
607 		switch (attr) {
608 		case ETZPC_DECPROT_S_RW:
609 			if (paddr != ram_base || size > ram_size)
610 				return TEE_ERROR_BAD_PARAMETERS;
611 			tzma_r0size = ram_size / SMALL_PAGE_SIZE;
612 			break;
613 		case ETZPC_DECPROT_NS_RW:
614 			if (paddr < ram_base ||
615 			    paddr + size != ram_base + ram_size)
616 				return TEE_ERROR_BAD_PARAMETERS;
617 			tzma_r0size = (paddr - ram_base) / SMALL_PAGE_SIZE;
618 			break;
619 		default:
620 			EMSG("Invalid TZMA mode %"PRIu32, mode);
621 			return TEE_ERROR_BAD_PARAMETERS;
622 		}
623 
624 #ifdef CFG_STM32MP15
625 		if (!pager_permits_decprot_config(id, attr))
626 			return TEE_ERROR_ACCESS_DENIED;
627 #endif
628 
629 		if (tzma_is_locked(tzma_id)) {
630 			if (etzpc_get_tzma(tzma_id) != tzma_r0size) {
631 				EMSG("TZMA configuration locked");
632 				return TEE_ERROR_ACCESS_DENIED;
633 			}
634 
635 			return TEE_SUCCESS;
636 		}
637 
638 		etzpc_configure_tzma(tzma_id, tzma_r0size);
639 		if (lock)
640 			etzpc_lock_tzma(tzma_id);
641 	} else {
642 		EMSG("Unknown firewall ID: %"PRIu32, id);
643 
644 		return TEE_ERROR_BAD_PARAMETERS;
645 	}
646 
647 	return TEE_SUCCESS;
648 }
649 
650 static TEE_Result stm32_etzpc_configure(struct firewall_query *firewall)
651 {
652 	enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX;
653 	uint32_t id = 0;
654 
655 	if (firewall->arg_count != 1)
656 		return TEE_ERROR_BAD_PARAMETERS;
657 
658 	id = firewall->args[0] & ETZPC_ID_MASK;
659 
660 	if (id < etzpc_device->ddata.num_per_sec) {
661 		uint32_t mode = 0;
662 
663 		/*
664 		 * Peripheral configuration, we assume the configuration is as
665 		 * follows:
666 		 * firewall->args[0]: Firewall configuration to apply
667 		 */
668 
669 		mode = (firewall->args[0] & ETZPC_MODE_MASK) >>
670 		       ETZPC_MODE_SHIFT;
671 		attr = etzpc_binding2decprot(mode);
672 
673 		if (decprot_is_locked(id)) {
674 			if (etzpc_get_decprot(id) != attr) {
675 				EMSG("Peripheral configuration locked");
676 				return TEE_ERROR_ACCESS_DENIED;
677 			}
678 
679 			DMSG("Compliant locked config for periph %"PRIu32" - attr %s",
680 			     id, etzpc_decprot_strings[attr]);
681 
682 			return TEE_SUCCESS;
683 		}
684 
685 #ifdef CFG_STM32MP15
686 		if (!pager_permits_decprot_config(id, attr))
687 			return TEE_ERROR_ACCESS_DENIED;
688 #endif
689 
690 		DMSG("Setting access config for periph %"PRIu32" - attr %s", id,
691 		     etzpc_decprot_strings[attr]);
692 
693 		etzpc_configure_decprot(id, attr);
694 		if (firewall->args[0] & ETZPC_LOCK_MASK)
695 			etzpc_lock_decprot(id);
696 
697 		return TEE_SUCCESS;
698 	}
699 	EMSG("Unknown firewall ID: %"PRIu32, id);
700 
701 	return TEE_ERROR_BAD_PARAMETERS;
702 }
703 
704 static void stm32_etzpc_set_driverdata(void)
705 {
706 	struct stm32_etzpc_driver_data *ddata = &etzpc_device->ddata;
707 	vaddr_t base = etzpc_device->pdata.base.va;
708 	uint32_t reg = io_read32(base + ETZPC_HWCFGR);
709 
710 	ddata->num_tzma = (reg & ETZPC_HWCFGR_NUM_TZMA_MASK) >>
711 			   ETZPC_HWCFGR_NUM_TZMA_SHIFT;
712 	ddata->num_per_sec = (reg & ETZPC_HWCFGR_NUM_PER_SEC_MASK) >>
713 			      ETZPC_HWCFGR_NUM_PER_SEC_SHIFT;
714 	ddata->num_ahb_sec = (reg & ETZPC_HWCFGR_NUM_AHB_SEC_MASK) >>
715 			      ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT;
716 
717 	DMSG("ETZPC revision 0x%02"PRIx8", per_sec %u, ahb_sec %u, tzma %u",
718 	     io_read8(base + ETZPC_VERR),
719 	     ddata->num_per_sec, ddata->num_ahb_sec, ddata->num_tzma);
720 }
721 
722 static void fdt_etzpc_conf_decprot(const void *fdt, int node)
723 {
724 	const fdt32_t *cuint = NULL;
725 	size_t i = 0;
726 	int len = 0;
727 
728 	cuint = fdt_getprop(fdt, node, "st,decprot", &len);
729 	if (!cuint) {
730 		DMSG("No ETZPC DECPROT configuration in DT");
731 		return;
732 	}
733 
734 	clk_enable(etzpc_device->pdata.clk);
735 
736 	for (i = 0; i < len / sizeof(uint32_t); i++) {
737 		uint32_t value = fdt32_to_cpu(cuint[i]);
738 		uint32_t id = value & ETZPC_ID_MASK;
739 		uint32_t mode = (value & ETZPC_MODE_MASK) >> ETZPC_MODE_SHIFT;
740 		bool lock = value & ETZPC_LOCK_MASK;
741 		enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX;
742 
743 		if (!valid_decprot_id(id)) {
744 			DMSG("Invalid DECPROT %"PRIu32, id);
745 			panic();
746 		}
747 
748 		attr = etzpc_binding2decprot(mode);
749 
750 #ifdef CFG_STM32MP15
751 		if (!pager_permits_decprot_config(id, attr))
752 			panic();
753 #endif
754 
755 		etzpc_configure_decprot(id, attr);
756 
757 		if (lock)
758 			etzpc_lock_decprot(id);
759 	}
760 
761 	clk_disable(etzpc_device->pdata.clk);
762 }
763 
764 static TEE_Result
765 stm32_etzpc_dt_probe_bus(const void *fdt, int node,
766 			 struct firewall_controller *ctrl __maybe_unused)
767 {
768 	TEE_Result res = TEE_ERROR_GENERIC;
769 	struct firewall_query *fw = NULL;
770 	int subnode = 0;
771 
772 	DMSG("Populating %s firewall bus", ctrl->name);
773 
774 	fdt_for_each_subnode(subnode, fdt, node) {
775 		unsigned int i = 0;
776 
777 		if (fdt_get_status(fdt, subnode) == DT_STATUS_DISABLED)
778 			continue;
779 
780 		if (IS_ENABLED(CFG_INSECURE) &&
781 		    stm32mp_allow_probe_shared_device(fdt, subnode)) {
782 			DMSG("Skipping firewall attributes check for %s",
783 			     fdt_get_name(fdt, subnode, NULL));
784 			goto skip_check;
785 		}
786 
787 		DMSG("Acquiring firewall access for %s when probing bus",
788 		     fdt_get_name(fdt, subnode, NULL));
789 
790 		do {
791 			/*
792 			 * The access-controllers property is mandatory for
793 			 * firewall bus devices
794 			 */
795 			res = firewall_dt_get_by_index(fdt, subnode, i, &fw);
796 			if (res == TEE_ERROR_ITEM_NOT_FOUND) {
797 				/* Stop when nothing more to parse */
798 				break;
799 			} else if (res) {
800 				EMSG("%s: Error on node %s: %#"PRIx32,
801 				     ctrl->name,
802 				     fdt_get_name(fdt, subnode, NULL), res);
803 				panic();
804 			}
805 
806 			res = firewall_acquire_access(fw);
807 			if (res) {
808 				EMSG("%s: %s not accessible: %#"PRIx32,
809 				     ctrl->name,
810 				     fdt_get_name(fdt, subnode, NULL), res);
811 				panic();
812 			}
813 
814 			firewall_put(fw);
815 			i++;
816 		} while (true);
817 
818 skip_check:
819 		res = dt_driver_maybe_add_probe_node(fdt, subnode);
820 		if (res) {
821 			EMSG("Failed on node %s with %#"PRIx32,
822 			     fdt_get_name(fdt, subnode, NULL), res);
823 			panic();
824 		}
825 	}
826 
827 	return TEE_SUCCESS;
828 }
829 
830 static TEE_Result init_etzpc_from_dt(const void *fdt, int node)
831 {
832 	TEE_Result res = TEE_ERROR_GENERIC;
833 	struct dt_node_info etzpc_info = { };
834 	int len = 0;
835 
836 	fdt_fill_device_info(fdt, &etzpc_info, node);
837 	if (etzpc_info.reg == DT_INFO_INVALID_REG ||
838 	    etzpc_info.reg_size == DT_INFO_INVALID_REG_SIZE)
839 		return TEE_ERROR_ITEM_NOT_FOUND;
840 
841 	etzpc_device->pdata.base.pa = etzpc_info.reg;
842 	etzpc_device->pdata.name = strdup(fdt_get_name(fdt, node, &len));
843 	io_pa_or_va_secure(&etzpc_device->pdata.base, etzpc_info.reg_size);
844 	res = clk_dt_get_by_index(fdt, node, 0, &etzpc_device->pdata.clk);
845 	if (res)
846 		return res;
847 
848 	stm32_etzpc_set_driverdata();
849 
850 	etzpc_device->pdata.periph_cfg =
851 		calloc(etzpc_device->ddata.num_per_sec,
852 		       sizeof(*etzpc_device->pdata.periph_cfg));
853 	if (!etzpc_device->pdata.periph_cfg)
854 		return TEE_ERROR_OUT_OF_MEMORY;
855 
856 	etzpc_device->pdata.tzma_cfg =
857 		calloc(etzpc_device->ddata.num_tzma,
858 		       sizeof(*etzpc_device->pdata.tzma_cfg));
859 	if (!etzpc_device->pdata.tzma_cfg) {
860 		free(etzpc_device->pdata.periph_cfg);
861 		return TEE_ERROR_OUT_OF_MEMORY;
862 	}
863 
864 	return TEE_SUCCESS;
865 }
866 
867 static const struct firewall_controller_ops firewall_ops = {
868 	.set_conf = stm32_etzpc_configure,
869 	.set_memory_conf = stm32_etzpc_configure_memory,
870 	.check_access = stm32_etzpc_check_access,
871 	.acquire_access = stm32_etzpc_acquire_access,
872 	.acquire_memory_access = stm32_etzpc_acquire_memory_access,
873 };
874 
875 static TEE_Result stm32_etzpc_probe(const void *fdt, int node,
876 				    const void *compat_data __unused)
877 {
878 	TEE_Result res = TEE_ERROR_GENERIC;
879 	struct firewall_controller *controller = NULL;
880 
881 	etzpc_device = calloc(1, sizeof(*etzpc_device));
882 	if (!etzpc_device)
883 		panic();
884 
885 	res = init_etzpc_from_dt(fdt, node);
886 	if (res) {
887 		free(etzpc_device->pdata.periph_cfg);
888 		free(etzpc_device->pdata.tzma_cfg);
889 		free(etzpc_device->pdata.name);
890 		free(etzpc_device);
891 		free(controller);
892 		return res;
893 	}
894 
895 	controller = calloc(1, sizeof(*controller));
896 	if (!controller)
897 		panic();
898 
899 	controller->base = &etzpc_device->pdata.base;
900 	controller->name = etzpc_device->pdata.name;
901 	controller->priv = etzpc_device;
902 	controller->ops = &firewall_ops;
903 
904 	res = firewall_dt_controller_register(fdt, node, controller);
905 	if (res)
906 		panic("Cannot register ETZPC as a firewall controller");
907 
908 	fdt_etzpc_conf_decprot(fdt, node);
909 
910 	res = stm32_etzpc_dt_probe_bus(fdt, node, controller);
911 	if (res)
912 		panic("Cannot populate bus");
913 
914 	register_pm_core_service_cb(etzpc_pm, NULL, "stm32-etzpc");
915 
916 	return TEE_SUCCESS;
917 }
918 
919 static const struct dt_device_match etzpc_match_table[] = {
920 	{ .compatible = "st,stm32-etzpc" },
921 	{ }
922 };
923 
924 DEFINE_DT_DRIVER(etzpc_dt_driver) = {
925 	.name = "stm32-etzpc",
926 	.match_table = etzpc_match_table,
927 	.probe = stm32_etzpc_probe,
928 };
929