xref: /optee_os/core/drivers/firewall/stm32_risab.c (revision 6b1c18580069a7c71e32deb57f609031fffb6e68)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2022-2024, STMicroelectronics
4  */
5 
6 #include <assert.h>
7 #include <drivers/clk.h>
8 #include <drivers/clk_dt.h>
9 #include <drivers/firewall.h>
10 #include <drivers/stm32_rif.h>
11 #include <drivers/stm32_risab.h>
12 #include <dt-bindings/firewall/stm32mp25-risab.h>
13 #include <io.h>
14 #include <kernel/boot.h>
15 #include <kernel/dt.h>
16 #include <kernel/pm.h>
17 #include <kernel/spinlock.h>
18 #include <kernel/tee_misc.h>
19 #include <libfdt.h>
20 #include <mm/core_memprot.h>
21 #include <platform_config.h>
22 #include <stdint.h>
23 #include <string_ext.h>
24 #include <stm32_sysconf.h>
25 #include <util.h>
26 
27 #define _RISAB_CR				U(0x0)
28 #define _RISAB_IASR				U(0x8)
29 #define _RISAB_IACR				U(0xC)
30 #define _RISAB_RCFGLOCKR			U(0x10)
31 #define _RISAB_IAESR				U(0x20)
32 #define _RISAB_IADDR				U(0x24)
33 #define _RISAB_PGy_SECCFGR(y)			(U(0x100) + (0x4 * (y)))
34 #define _RISAB_PGy_PRIVCFGR(y)			(U(0x200) + (0x4 * (y)))
35 #define _RISAB_RISAB_PGy_C2PRIVCFGR(y)		(U(0x600) + (0x4 * (y)))
36 #define _RISAB_CIDxPRIVCFGR(x)			(U(0x800) + (0x20 * (x)))
37 #define _RISAB_CIDxRDCFGR(x)			(U(0x808) + (0x20 * (x)))
38 #define _RISAB_CIDxWRCFGR(x)			(U(0x810) + (0x20 * (x)))
39 #define _RISAB_PGy_CIDCFGR(y)			(U(0xA00) + (0x4 * (y)))
40 #define _RISAB_HWCFGR3				U(0xFE8)
41 #define _RISAB_HWCFGR2				U(0xFEC)
42 #define _RISAB_HWCFGR1				U(0xFF0)
43 #define _RISAB_VERR				U(0xFF4)
44 #define _RISAB_IPIDR				U(0xFF8)
45 #define _RISAB_SIDR				U(0xFFC)
46 
47 /* RISAB_CR bitfields */
48 #define _RISAB_CR_SRWIAD			BIT(31)
49 
50 /* RISAB_IACR bitfields */
51 #define _RISAB_IACR_CAEF			BIT(0)
52 #define _RISAB_IACR_IAEF			BIT(1)
53 #define _RISAB_IACR_MASK			(_RISAB_IACR_CAEF | \
54 						 _RISAB_IACR_IAEF)
55 
56 /* Define RISAB_PG_SECCFGR bitfields */
57 #define _RISAB_PG_SECCFGR_MASK			GENMASK_32(7, 0)
58 
59 /* Define RISAB_PG_PRIVCFGR bitfields */
60 #define _RISAB_PG_PRIVCFGR_MASK			GENMASK_32(7, 0)
61 
62 /* CIDCFGR bitfields */
63 #define _RISAB_PG_CIDCFGR_CFEN			BIT(0)
64 #define _RISAB_PG_CIDCFGR_DCEN			BIT(2)
65 #define _RISAB_PG_CIDCFGR_DDCID_SHIFT		U(4)
66 #define _RISAB_PG_CIDCFGR_DDCID_MASK		GENMASK_32(6, 4)
67 #define _RISAB_PG_CIDCFGR_CONF_MASK		(_RISAB_PG_CIDCFGR_CFEN | \
68 						 _RISAB_PG_CIDCFGR_DCEN | \
69 						 _RISAB_PG_CIDCFGR_DDCID_MASK)
70 
71 /* Miscellaneous */
72 #define _RISAB_NB_PAGES_MAX			U(32)
73 #define _RISAB_PAGE_SIZE			U(0x1000)
74 #define _RISAB_NB_MAX_CID_SUPPORTED		U(7)
75 
76 #define RISAB_NAME_LEN_MAX			U(20)
77 
78 struct mem_region {
79 	paddr_t base;
80 	size_t size;
81 };
82 
83 struct stm32_risab_rif_conf {
84 	unsigned int first_page;
85 	unsigned int nb_pages_cfged;
86 	uint32_t plist[_RISAB_NB_MAX_CID_SUPPORTED];
87 	uint32_t rlist[_RISAB_NB_MAX_CID_SUPPORTED];
88 	uint32_t wlist[_RISAB_NB_MAX_CID_SUPPORTED];
89 	uint32_t cidcfgr;
90 	uint32_t dprivcfgr;
91 	uint32_t seccfgr;
92 };
93 
94 struct stm32_risab_pdata {
95 	unsigned int nb_regions_cfged;
96 	struct clk *clock;
97 	struct mem_region region_cfged;
98 	struct stm32_risab_rif_conf *subr_cfg;
99 	struct io_pa_va base;
100 	unsigned int conf_lock;
101 	char risab_name[RISAB_NAME_LEN_MAX];
102 	uint32_t pages_configured;
103 	bool srwiad;
104 
105 	SLIST_ENTRY(stm32_risab_pdata) link;
106 };
107 
108 static SLIST_HEAD(, stm32_risab_pdata) risab_list =
109 		SLIST_HEAD_INITIALIZER(risab_list);
110 
111 static bool is_tdcid;
112 
113 static vaddr_t risab_base(struct stm32_risab_pdata *risab)
114 {
115 	return io_pa_or_va_secure(&risab->base, 1);
116 }
117 
118 void stm32_risab_clear_illegal_access_flags(void)
119 {
120 	struct stm32_risab_pdata *risab = NULL;
121 
122 	SLIST_FOREACH(risab, &risab_list, link) {
123 		vaddr_t base = risab_base(risab);
124 
125 		if (!io_read32(base + _RISAB_IASR))
126 			continue;
127 
128 		io_write32(base + _RISAB_IACR, _RISAB_IACR_CAEF |
129 			   _RISAB_IACR_IAEF);
130 	}
131 }
132 
133 #ifdef CFG_TEE_CORE_DEBUG
134 void stm32_risab_print_erroneous_data(void)
135 {
136 	struct stm32_risab_pdata *risab = NULL;
137 
138 	SLIST_FOREACH(risab, &risab_list, link) {
139 		vaddr_t base = risab_base(risab);
140 
141 		/* Check if faulty address on this RISAB */
142 		if (!io_read32(base + _RISAB_IASR))
143 			continue;
144 
145 		EMSG("\n\nDUMPING DATA FOR %s\n\n", risab->risab_name);
146 		EMSG("=====================================================");
147 		EMSG("Status register (IAESR): %#"PRIx32,
148 		     io_read32(base + _RISAB_IAESR));
149 		EMSG("-----------------------------------------------------");
150 		EMSG("Faulty address (IADDR): %#"PRIx32,
151 		     io_read32(base + _RISAB_IADDR));
152 		EMSG("=====================================================\n");
153 	};
154 }
155 #endif /* CFG_TEE_CORE_DEBUG */
156 
157 static bool regs_access_granted(struct stm32_risab_pdata *risab_d,
158 				unsigned int reg_idx)
159 {
160 	unsigned int first_page = risab_d->subr_cfg[reg_idx].first_page;
161 	uint32_t cidcfgr = io_read32(risab_base(risab_d) +
162 				     _RISAB_PGy_CIDCFGR(first_page));
163 
164 	if (virt_to_phys((void *)risab_base(risab_d)) == RISAB1_BASE ||
165 	    virt_to_phys((void *)risab_base(risab_d)) == RISAB2_BASE)
166 		return true;
167 
168 	/* No CID filtering */
169 	if (!(cidcfgr & _RISAB_PG_CIDCFGR_CFEN))
170 		return true;
171 
172 	/* Trusted CID access */
173 	if (is_tdcid && !(cidcfgr & _RISAB_PG_CIDCFGR_DCEN))
174 		return true;
175 
176 	/* Delegated CID access check */
177 	if (cidcfgr & _RISAB_PG_CIDCFGR_DCEN &&
178 	    ((cidcfgr & _RISAB_PG_CIDCFGR_DDCID_MASK) >>
179 	     _RISAB_PG_CIDCFGR_DDCID_SHIFT) == RIF_CID1)
180 		return true;
181 
182 	return false;
183 }
184 
185 static void set_block_seccfgr(struct stm32_risab_pdata *risab_d,
186 			      struct stm32_risab_rif_conf *subr_cfg)
187 {
188 	vaddr_t base = risab_base(risab_d);
189 	unsigned int i = 0;
190 	unsigned int last_page = subr_cfg->first_page +
191 				 subr_cfg->nb_pages_cfged - 1;
192 
193 	for (i = subr_cfg->first_page; i <= last_page; i++)
194 		io_clrsetbits32(base + _RISAB_PGy_SECCFGR(i),
195 				_RISAB_PG_SECCFGR_MASK, subr_cfg->seccfgr);
196 }
197 
198 static void set_block_dprivcfgr(struct stm32_risab_pdata *risab_d,
199 				struct stm32_risab_rif_conf *subr_cfg)
200 {
201 	vaddr_t base = risab_base(risab_d);
202 	unsigned int i = 0;
203 	unsigned int last_page = subr_cfg->first_page +
204 				 subr_cfg->nb_pages_cfged - 1;
205 
206 	for (i = subr_cfg->first_page; i <= last_page; i++)
207 		io_clrsetbits32(base + _RISAB_PGy_PRIVCFGR(i),
208 				_RISAB_PG_PRIVCFGR_MASK,
209 				subr_cfg->dprivcfgr);
210 }
211 
212 static void set_cidcfgr(struct stm32_risab_pdata *risab_d,
213 			struct stm32_risab_rif_conf *subr_cfg)
214 {
215 	vaddr_t base = risab_base(risab_d);
216 	unsigned int i = 0;
217 	unsigned int last_page = subr_cfg->first_page +
218 				 subr_cfg->nb_pages_cfged - 1;
219 
220 	for (i = subr_cfg->first_page; i <= last_page; i++) {
221 		/*
222 		 * When TDCID, OP-TEE should be the one to set the CID filtering
223 		 * configuration. Clearing previous configuration prevents
224 		 * undesired events during the only legitimate configuration.
225 		 */
226 		io_clrsetbits32(base + _RISAB_PGy_CIDCFGR(i),
227 				_RISAB_PG_CIDCFGR_CONF_MASK,
228 				subr_cfg->cidcfgr);
229 	}
230 }
231 
232 static void set_read_conf(struct stm32_risab_pdata *risab_d,
233 			  struct stm32_risab_rif_conf *subr_cfg)
234 {
235 	vaddr_t base = risab_base(risab_d);
236 	unsigned int i = 0;
237 	unsigned int last_page = subr_cfg->first_page +
238 				 subr_cfg->nb_pages_cfged - 1;
239 	uint32_t mask = GENMASK_32(last_page, subr_cfg->first_page);
240 
241 	for (i = 0; i < _RISAB_NB_MAX_CID_SUPPORTED; i++) {
242 		if (subr_cfg->rlist[i])
243 			io_setbits32(base + _RISAB_CIDxRDCFGR(i), mask);
244 	}
245 }
246 
247 static void set_write_conf(struct stm32_risab_pdata *risab_d,
248 			   struct stm32_risab_rif_conf *subr_cfg)
249 {
250 	vaddr_t base = risab_base(risab_d);
251 	unsigned int i = 0;
252 	unsigned int last_page = subr_cfg->first_page +
253 				 subr_cfg->nb_pages_cfged - 1;
254 	uint32_t mask = GENMASK_32(last_page, subr_cfg->first_page);
255 
256 	for (i = 0; i < _RISAB_NB_MAX_CID_SUPPORTED; i++) {
257 		if (subr_cfg->wlist[i])
258 			io_setbits32(base + _RISAB_CIDxWRCFGR(i), mask);
259 	}
260 }
261 
262 static void set_cid_priv_conf(struct stm32_risab_pdata *risab_d,
263 			      struct stm32_risab_rif_conf *subr_cfg)
264 {
265 	vaddr_t base = risab_base(risab_d);
266 	unsigned int i = 0;
267 	unsigned int last_page = subr_cfg->first_page +
268 				 subr_cfg->nb_pages_cfged - 1;
269 	uint32_t mask = GENMASK_32(last_page, subr_cfg->first_page);
270 
271 	for (i = 0; i < _RISAB_NB_MAX_CID_SUPPORTED; i++) {
272 		if (subr_cfg->plist[i])
273 			io_clrsetbits32(base + _RISAB_CIDxPRIVCFGR(i), mask,
274 					subr_cfg->plist[i]);
275 	}
276 }
277 
278 static TEE_Result set_rif_registers(struct stm32_risab_pdata *risab,
279 				    unsigned int reg_idx)
280 {
281 	struct stm32_risab_rif_conf *subr_cfg = NULL;
282 
283 	assert(&risab->subr_cfg[reg_idx]);
284 
285 	subr_cfg = &risab->subr_cfg[reg_idx];
286 
287 	/*
288 	 * This sequence will generate an IAC if the CID filtering
289 	 * configuration is inconsistent with these desired rights
290 	 * to apply.
291 	 */
292 	if (!regs_access_granted(risab, reg_idx))
293 		return TEE_ERROR_ACCESS_DENIED;
294 
295 	set_block_dprivcfgr(risab, subr_cfg);
296 	set_block_seccfgr(risab, subr_cfg);
297 
298 	/*
299 	 * Grant page access to some CIDs, in read and/or write, and the
300 	 * necessary privilege level.
301 	 */
302 	set_read_conf(risab, subr_cfg);
303 	set_write_conf(risab, subr_cfg);
304 	set_cid_priv_conf(risab, subr_cfg);
305 
306 	if (virt_to_phys((void *)risab_base(risab)) != RISAB1_BASE &&
307 	    virt_to_phys((void *)risab_base(risab)) != RISAB2_BASE) {
308 		/* Delegate RIF configuration or not */
309 		if (!is_tdcid)
310 			DMSG("Cannot set %s CID config for region %u",
311 			     risab->risab_name, reg_idx);
312 		else
313 			set_cidcfgr(risab, subr_cfg);
314 	} else {
315 		set_cidcfgr(risab, subr_cfg);
316 	}
317 
318 	dsb();
319 
320 	return TEE_SUCCESS;
321 }
322 
323 static void apply_rif_config(struct stm32_risab_pdata *risab_d)
324 {
325 	vaddr_t base = risab_base(risab_d);
326 	unsigned int i = 0;
327 
328 	/* If TDCID, we expect to restore default RISAB configuration */
329 	if (is_tdcid) {
330 		for (i = 0; i < _RISAB_NB_PAGES_MAX; i++) {
331 			io_clrbits32(base + _RISAB_PGy_CIDCFGR(i),
332 				     _RISAB_PG_CIDCFGR_CONF_MASK);
333 			io_clrbits32(base + _RISAB_PGy_SECCFGR(i),
334 				     _RISAB_PG_SECCFGR_MASK);
335 			io_clrbits32(base + _RISAB_PGy_PRIVCFGR(i),
336 				     _RISAB_PG_PRIVCFGR_MASK);
337 		}
338 		for (i = 0; i < _RISAB_NB_MAX_CID_SUPPORTED; i++) {
339 			io_clrbits32(base + _RISAB_CIDxRDCFGR(i), UINT32_MAX);
340 			io_clrbits32(base + _RISAB_CIDxWRCFGR(i), UINT32_MAX);
341 			io_clrbits32(base + _RISAB_CIDxPRIVCFGR(i), UINT32_MAX);
342 		}
343 	}
344 
345 	for (i = 0; i < risab_d->nb_regions_cfged; i++) {
346 		if (set_rif_registers(risab_d, i))
347 			panic();
348 	}
349 }
350 
351 static void parse_risab_rif_conf(struct stm32_risab_pdata *risab_d,
352 				 struct stm32_risab_rif_conf *subr_cfg,
353 				 uint32_t rif_conf, bool check_overlap)
354 {
355 	unsigned int first_page = subr_cfg->first_page;
356 	unsigned int last_page = first_page + subr_cfg->nb_pages_cfged - 1;
357 	uint32_t reg_pages_cfged = GENMASK_32(last_page, first_page);
358 	unsigned int i = 0;
359 
360 	assert(last_page <= _RISAB_NB_PAGES_MAX);
361 
362 	DMSG("Configuring pages %u to %u", first_page, last_page);
363 
364 	/* Parse secure configuration */
365 	if (rif_conf & BIT(RISAB_SEC_SHIFT)) {
366 		subr_cfg->seccfgr = _RISAB_PG_SECCFGR_MASK;
367 		/*
368 		 * Memory region overlapping should only be checked at platform
369 		 * setup when memory mapping is first applied. A region's
370 		 * attributes can later be dynamically modified but not its
371 		 * bounds.
372 		 */
373 		if (check_overlap &&
374 		    reg_pages_cfged & risab_d->pages_configured)
375 			panic("Memory region overlap detected");
376 	} else {
377 		subr_cfg->seccfgr = 0;
378 	}
379 
380 	/* Parse default privilege configuration */
381 	if (rif_conf & BIT(RISAB_DPRIV_SHIFT)) {
382 		subr_cfg->dprivcfgr = _RISAB_PG_PRIVCFGR_MASK;
383 		if (check_overlap &&
384 		    reg_pages_cfged & risab_d->pages_configured)
385 			panic("Memory region overlap detected");
386 	} else {
387 		subr_cfg->dprivcfgr = 0;
388 	}
389 
390 	if (check_overlap)
391 		risab_d->pages_configured |= reg_pages_cfged;
392 
393 	for (i = 0; i < _RISAB_NB_MAX_CID_SUPPORTED; i++) {
394 		/* RISAB compartment priv configuration */
395 		if (rif_conf & BIT(i))
396 			subr_cfg->plist[i] |= GENMASK_32(last_page, first_page);
397 
398 		/* RISAB compartment read configuration */
399 		if (rif_conf & BIT(i + RISAB_READ_LIST_SHIFT))
400 			subr_cfg->rlist[i] |= GENMASK_32(last_page, first_page);
401 
402 		/* RISAB compartment write configuration */
403 		if (rif_conf & BIT(i + RISAB_WRITE_LIST_SHIFT))
404 			subr_cfg->wlist[i] |= GENMASK_32(last_page, first_page);
405 	}
406 
407 	/* CID filtering configuration */
408 	if (rif_conf & BIT(RISAB_CFEN_SHIFT))
409 		subr_cfg->cidcfgr |= _RISAB_PG_CIDCFGR_CFEN;
410 
411 	if (rif_conf & BIT(RISAB_DCEN_SHIFT))
412 		subr_cfg->cidcfgr |= _RISAB_PG_CIDCFGR_DCEN;
413 
414 	if (rif_conf & RISAB_DCCID_MASK) {
415 		uint32_t ddcid = SHIFT_U32((rif_conf & RISAB_DCCID_MASK) >>
416 					   RISAB_DCCID_SHIFT,
417 					   _RISAB_PG_CIDCFGR_DDCID_SHIFT);
418 
419 		assert(((rif_conf & RISAB_DCCID_MASK) >> RISAB_DCCID_SHIFT) <
420 		       _RISAB_NB_MAX_CID_SUPPORTED);
421 
422 		subr_cfg->cidcfgr |= ddcid;
423 	}
424 }
425 
426 static TEE_Result parse_dt(const void *fdt, int node,
427 			   struct stm32_risab_pdata *risab_d)
428 {
429 	TEE_Result res = TEE_ERROR_GENERIC;
430 	const fdt32_t *mem_regions = NULL;
431 	struct dt_node_info info = { };
432 	const fdt32_t *cuint = NULL;
433 	int mem_reg_node = 0;
434 	unsigned int i = 0;
435 	int lenp = 0;
436 
437 	fdt_fill_device_info(fdt, &info, node);
438 	assert(info.reg != DT_INFO_INVALID_REG &&
439 	       info.reg_size != DT_INFO_INVALID_REG_SIZE);
440 
441 	risab_d->base.pa = info.reg;
442 
443 	/* Gate the IP */
444 	res = clk_dt_get_by_index(fdt, node, 0, &risab_d->clock);
445 	if (res)
446 		return res;
447 
448 	strlcpy(risab_d->risab_name, fdt_get_name(fdt, node, NULL),
449 		sizeof(risab_d->risab_name));
450 
451 	cuint = fdt_getprop(fdt, node, "st,srwiad", NULL);
452 	if (cuint)
453 		risab_d->srwiad = true;
454 
455 	/* Get the memory region being configured */
456 	cuint = fdt_getprop(fdt, node, "st,mem-map", &lenp);
457 	if (!cuint)
458 		panic("Missing st,mem-map property in configure memory region");
459 
460 	assert((unsigned int)(lenp / sizeof(uint32_t)) == 2);
461 
462 	risab_d->region_cfged.base = fdt32_to_cpu(cuint[0]);
463 	risab_d->region_cfged.size = fdt32_to_cpu(cuint[1]);
464 
465 	/* Get the memory regions to configure */
466 	mem_regions = fdt_getprop(fdt, node, "memory-region", &lenp);
467 	if (!mem_regions)
468 		panic("No memory region to configure");
469 
470 	risab_d->nb_regions_cfged = (unsigned int)(lenp / sizeof(uint32_t));
471 	assert(risab_d->nb_regions_cfged < _RISAB_NB_PAGES_MAX);
472 
473 	risab_d->subr_cfg = calloc(risab_d->nb_regions_cfged,
474 				   sizeof(*risab_d->subr_cfg));
475 	if (!risab_d->subr_cfg)
476 		return TEE_ERROR_OUT_OF_MEMORY;
477 
478 	for (i = 0; i < risab_d->nb_regions_cfged; i++) {
479 		uint32_t phandle = fdt32_to_cpu(mem_regions[i]);
480 		size_t sub_region_offset = 0;
481 		paddr_t address = 0;
482 		size_t length = 0;
483 
484 		mem_reg_node = fdt_node_offset_by_phandle(fdt, phandle);
485 		if (mem_reg_node < 0)
486 			return TEE_ERROR_ITEM_NOT_FOUND;
487 
488 		/*
489 		 * Get the reg property to determine the number of pages
490 		 * to configure
491 		 */
492 		address = fdt_reg_base_address(fdt, mem_reg_node);
493 		length = fdt_reg_size(fdt, mem_reg_node);
494 
495 		assert(IS_ALIGNED(address, _RISAB_PAGE_SIZE) &&
496 		       IS_ALIGNED(length, _RISAB_PAGE_SIZE));
497 
498 		/*
499 		 * Get the sub region offset and check if it is not out
500 		 * of bonds
501 		 */
502 		sub_region_offset = address - risab_d->region_cfged.base;
503 
504 		if (!core_is_buffer_inside(address, length,
505 					   risab_d->region_cfged.base,
506 					   risab_d->region_cfged.size)) {
507 			EMSG("Region %#"PRIxPA"..%#"PRIxPA" outside RISAB area %#"PRIxPA"...%#"PRIxPA,
508 			     address, address + length,
509 			     risab_d->region_cfged.base,
510 			     risab_d->region_cfged.base +
511 			     risab_d->region_cfged.size);
512 			return TEE_ERROR_BAD_PARAMETERS;
513 		}
514 
515 		risab_d->subr_cfg[i].first_page = sub_region_offset /
516 						  _RISAB_PAGE_SIZE;
517 		risab_d->subr_cfg[i].nb_pages_cfged = length /
518 						      _RISAB_PAGE_SIZE;
519 		if (!risab_d->subr_cfg[i].nb_pages_cfged)
520 			panic("Range to configure is < to the size of a page");
521 
522 		/* Get the RIF configuration for this region */
523 		cuint = fdt_getprop(fdt, mem_reg_node, "st,protreg", &lenp);
524 		if (!cuint)
525 			panic("No RIF configuration available");
526 
527 		/* There should be only one configuration for this region */
528 		assert((unsigned int)(lenp / sizeof(uint32_t)) == 1);
529 
530 		parse_risab_rif_conf(risab_d, &risab_d->subr_cfg[i],
531 				     fdt32_to_cpu(cuint[0]),
532 				     true /*check_overlap*/);
533 	}
534 
535 	return TEE_SUCCESS;
536 }
537 
538 static void enable_srwiad_if_set(struct stm32_risab_pdata *risab_d)
539 {
540 	if (is_tdcid && risab_d->srwiad)
541 		io_setbits32(risab_base(risab_d), _RISAB_CR_SRWIAD);
542 };
543 
544 static void disable_srwiad_if_unset(struct stm32_risab_pdata *risab_d)
545 {
546 	if (is_tdcid && !risab_d->srwiad)
547 		io_clrbits32(risab_base(risab_d), _RISAB_CR_SRWIAD);
548 };
549 
550 static void clear_iac_regs(struct stm32_risab_pdata *risab_d)
551 {
552 	io_setbits32(risab_base(risab_d) + _RISAB_IACR, _RISAB_IACR_MASK);
553 }
554 
555 static void set_vderam_syscfg(struct stm32_risab_pdata *risab_d)
556 {
557 	/*
558 	 * Set the VDERAMCR_VDERAM_EN bit if the VDERAM should be accessed by
559 	 * the system. Else, clear it so that VDEC/VENC can access it.
560 	 */
561 	if (risab_d->nb_regions_cfged)
562 		stm32mp_syscfg_write(SYSCFG_VDERAMCR, VDERAMCR_VDERAM_EN,
563 				     VDERAMCR_MASK);
564 	else
565 		stm32mp_syscfg_write(SYSCFG_VDERAMCR, 0, VDERAMCR_MASK);
566 }
567 
568 static struct stm32_risab_rif_conf *
569 get_subreg_by_range(struct stm32_risab_pdata *risab, paddr_t paddr, size_t size)
570 {
571 	unsigned int nb_page = size / _RISAB_PAGE_SIZE;
572 	unsigned int i = 0;
573 
574 	for (i = 0; i < risab->nb_regions_cfged; i++) {
575 		unsigned int first_page = (paddr - risab->region_cfged.base) /
576 					  _RISAB_PAGE_SIZE;
577 
578 		if (first_page == risab->subr_cfg[i].first_page &&
579 		    nb_page == risab->subr_cfg[i].nb_pages_cfged)
580 			return risab->subr_cfg + i;
581 	}
582 
583 	return NULL;
584 }
585 
586 static TEE_Result stm32_risab_check_access(struct firewall_query *fw,
587 					   paddr_t paddr, size_t size,
588 					   bool read, bool write)
589 {
590 	struct stm32_risab_rif_conf *reg_conf = NULL;
591 	struct stm32_risab_pdata *risab = NULL;
592 	unsigned int first_page = 0;
593 	uint32_t write_cids = 0;
594 	uint32_t read_cids = 0;
595 	uint32_t priv_cids = 0;
596 	uint32_t dprivcfgr = 0;
597 	uint32_t seccfgr = 0;
598 	uint32_t cidcfgr = 0;
599 	uint32_t q_conf = 0;
600 	unsigned int i = 0;
601 	vaddr_t base = 0;
602 
603 	assert(fw->ctrl->priv && (read || write));
604 
605 	risab = fw->ctrl->priv;
606 	base = risab_base(risab);
607 
608 	if (!IS_ALIGNED(paddr, _RISAB_PAGE_SIZE) ||
609 	    !IS_ALIGNED(size, _RISAB_PAGE_SIZE)) {
610 		EMSG("Physical address %"PRIxPA" or size:%#zx misaligned with RISAB page boundaries",
611 		     paddr, size);
612 		return TEE_ERROR_BAD_PARAMETERS;
613 	}
614 
615 	if (fw->arg_count != 1)
616 		return TEE_ERROR_BAD_PARAMETERS;
617 
618 	/*
619 	 * RISAF region configuration, we assume the query is as
620 	 * follows:
621 	 * fw->args[0]: Configuration of the region
622 	 */
623 	q_conf = fw->args[0];
624 
625 	reg_conf = get_subreg_by_range(risab, paddr, size);
626 	if (!reg_conf)
627 		return TEE_ERROR_BAD_PARAMETERS;
628 
629 	first_page = reg_conf->first_page;
630 
631 	seccfgr = io_read32(base + _RISAB_PGy_SECCFGR(first_page));
632 	/* Security level is exclusive on memories */
633 	if (!!(q_conf & BIT(RISAB_SEC_SHIFT)) ^ !!(seccfgr & BIT(first_page))) {
634 		if (!(q_conf & BIT(RISAB_SEC_SHIFT) &&
635 		      (io_read32(base + _RISAB_CR) & _RISAB_CR_SRWIAD)))
636 			return TEE_ERROR_ACCESS_DENIED;
637 	}
638 
639 	dprivcfgr = io_read32(base + _RISAB_PGy_PRIVCFGR(first_page));
640 	cidcfgr = io_read32(base + _RISAB_PGy_CIDCFGR(first_page));
641 
642 	if (!(cidcfgr & _RISAB_PG_CIDCFGR_CFEN)) {
643 		if (dprivcfgr && !(q_conf & BIT(RISAB_DPRIV_SHIFT)))
644 			return TEE_ERROR_ACCESS_DENIED;
645 		else
646 			return TEE_SUCCESS;
647 	}
648 
649 	read_cids = SHIFT_U32(q_conf & RISAB_RLIST_MASK, RISAB_READ_LIST_SHIFT);
650 	write_cids = SHIFT_U32(q_conf & RISAB_WLIST_MASK,
651 			       RISAB_WRITE_LIST_SHIFT);
652 	priv_cids = q_conf & RISAB_PLIST_MASK;
653 
654 	for (i = 0; i < _RISAB_NB_MAX_CID_SUPPORTED; i++) {
655 		uint32_t read_list = io_read32(base + _RISAB_CIDxRDCFGR(i));
656 		uint32_t write_list = io_read32(base + _RISAB_CIDxWRCFGR(i));
657 		uint32_t priv_list = io_read32(base + _RISAB_CIDxPRIVCFGR(i));
658 
659 		if (read && (read_cids & BIT(i)) &&
660 		    !(read_list & BIT(first_page)))
661 			return TEE_ERROR_ACCESS_DENIED;
662 
663 		if (write && (write_cids & BIT(i)) &&
664 		    !(write_list & BIT(first_page)))
665 			return TEE_ERROR_ACCESS_DENIED;
666 
667 		if ((priv_list & BIT(first_page)) && !(priv_cids & BIT(i)))
668 			return TEE_ERROR_ACCESS_DENIED;
669 	}
670 
671 	return TEE_SUCCESS;
672 }
673 
674 static TEE_Result stm32_risab_reconfigure_region(struct firewall_query *fw,
675 						 paddr_t paddr, size_t size)
676 {
677 	struct stm32_risab_pdata *risab = NULL;
678 	TEE_Result res = TEE_ERROR_GENERIC;
679 	paddr_t sub_region_offset = 0;
680 	uint32_t exceptions = 0;
681 	unsigned int i = 0;
682 
683 	assert(fw->ctrl->priv);
684 
685 	risab = fw->ctrl->priv;
686 
687 	if (!IS_ALIGNED(paddr, _RISAB_PAGE_SIZE) ||
688 	    !IS_ALIGNED(size, _RISAB_PAGE_SIZE)) {
689 		EMSG("Unaligned region: pa %#"PRIxPA" size %zx", paddr, size);
690 		return TEE_ERROR_BAD_PARAMETERS;
691 	}
692 
693 	if (fw->arg_count != 1)
694 		return TEE_ERROR_BAD_PARAMETERS;
695 
696 	/*
697 	 * Get the sub region offset and check if it is not out
698 	 * of bounds
699 	 */
700 	sub_region_offset = paddr - risab->region_cfged.base;
701 	if (!core_is_buffer_inside(paddr, size, risab->region_cfged.base,
702 				   risab->region_cfged.size))
703 		return TEE_ERROR_BAD_PARAMETERS;
704 
705 	/*
706 	 * RISAF region configuration, we assume the query is as
707 	 * follows:
708 	 * fw->args[0]: Configuration of the region
709 	 */
710 	for (i = 0; i < risab->nb_regions_cfged; i++) {
711 		if (sub_region_offset / _RISAB_PAGE_SIZE !=
712 		    risab->subr_cfg[i].first_page ||
713 		    (size / _RISAB_PAGE_SIZE) !=
714 		    risab->subr_cfg[i].nb_pages_cfged)
715 			continue;
716 
717 		parse_risab_rif_conf(risab, &risab->subr_cfg[i], fw->args[0],
718 				     false /*!check_overlap*/);
719 
720 		break;
721 	}
722 
723 	if (i == risab->nb_regions_cfged)
724 		return TEE_ERROR_BAD_PARAMETERS;
725 
726 	DMSG("Reconfiguring %s pages %u-%u: %s, %s, CID attributes: %#"PRIx32", R:%#"PRIx32", W:%#"PRIx32", P:%#"PRIx32"",
727 	     risab->risab_name, risab->subr_cfg[i].first_page,
728 	     risab->subr_cfg[i].first_page +
729 	     risab->subr_cfg[i].nb_pages_cfged - 1,
730 	     risab->subr_cfg[i].seccfgr ? "Secure" : "Non secure",
731 	     risab->subr_cfg[i].dprivcfgr ? "Default priv" : "Default unpriv",
732 	     risab->subr_cfg[i].cidcfgr,
733 	     fw->args[0] & RISAB_RLIST_MASK,
734 	     fw->args[0] & RISAB_WLIST_MASK,
735 	     fw->args[0] & RISAB_PLIST_MASK);
736 
737 	exceptions = cpu_spin_lock_xsave(&risab->conf_lock);
738 
739 	res = set_rif_registers(risab, i);
740 
741 	cpu_spin_unlock_xrestore(&risab->conf_lock, exceptions);
742 
743 	return res;
744 }
745 
746 static TEE_Result stm32_risab_pm_resume(struct stm32_risab_pdata *risab)
747 {
748 	unsigned int i = 0;
749 
750 	if (risab->base.pa == RISAB6_BASE)
751 		set_vderam_syscfg(risab);
752 	enable_srwiad_if_set(risab);
753 	clear_iac_regs(risab);
754 
755 	for (i = 0; i < risab->nb_regions_cfged; i++) {
756 		if (set_rif_registers(risab, i))
757 			panic();
758 	}
759 
760 	disable_srwiad_if_unset(risab);
761 
762 	return TEE_SUCCESS;
763 }
764 
765 static TEE_Result stm32_risab_pm_suspend(struct stm32_risab_pdata *risab)
766 {
767 	vaddr_t base = risab_base(risab);
768 	size_t i = 0;
769 
770 	for (i = 0; i < risab->nb_regions_cfged; i++) {
771 		size_t j = 0;
772 		unsigned int first_page = risab->subr_cfg[i].first_page;
773 
774 		/* Save all configuration fields that need to be restored */
775 		risab->subr_cfg[i].seccfgr =
776 			io_read32(base + _RISAB_PGy_SECCFGR(first_page));
777 		risab->subr_cfg[i].dprivcfgr =
778 			io_read32(base + _RISAB_PGy_PRIVCFGR(first_page));
779 		risab->subr_cfg[i].cidcfgr =
780 			io_read32(base + _RISAB_PGy_CIDCFGR(first_page));
781 
782 		for (j = 0; j < _RISAB_NB_MAX_CID_SUPPORTED; j++) {
783 			risab->subr_cfg[i].rlist[j] =
784 				io_read32(base + _RISAB_CIDxRDCFGR(j));
785 			risab->subr_cfg[i].wlist[j] =
786 				io_read32(base + _RISAB_CIDxWRCFGR(j));
787 			risab->subr_cfg[i].plist[j] =
788 				io_read32(base + _RISAB_CIDxPRIVCFGR(j));
789 		}
790 	}
791 
792 	return TEE_SUCCESS;
793 }
794 
795 static TEE_Result
796 stm32_risab_pm(enum pm_op op, unsigned int pm_hint,
797 	       const struct pm_callback_handle *pm_handle)
798 {
799 	struct stm32_risab_pdata *risab = pm_handle->handle;
800 	TEE_Result res = TEE_ERROR_GENERIC;
801 
802 	if (!PM_HINT_IS_STATE(pm_hint, CONTEXT) || !is_tdcid)
803 		return TEE_SUCCESS;
804 
805 	if (op == PM_OP_RESUME)
806 		res = stm32_risab_pm_resume(risab);
807 	else
808 		res = stm32_risab_pm_suspend(risab);
809 
810 	return res;
811 }
812 
813 static const struct firewall_controller_ops firewall_ops = {
814 	.check_memory_access = stm32_risab_check_access,
815 	.set_memory_conf = stm32_risab_reconfigure_region,
816 };
817 
818 static TEE_Result stm32_risab_probe(const void *fdt, int node,
819 				    const void *compat_data __maybe_unused)
820 {
821 	struct firewall_controller *controller = NULL;
822 	struct stm32_risab_pdata *risab_d = NULL;
823 	TEE_Result res = TEE_ERROR_GENERIC;
824 
825 	res = stm32_rifsc_check_tdcid(&is_tdcid);
826 	if (res)
827 		return res;
828 
829 	risab_d = calloc(1, sizeof(*risab_d));
830 	if (!risab_d)
831 		return TEE_ERROR_OUT_OF_MEMORY;
832 
833 	res = parse_dt(fdt, node, risab_d);
834 	if (res)
835 		goto err;
836 
837 	if (clk_enable(risab_d->clock))
838 		panic("Can't enable RISAB clock");
839 
840 	if (is_tdcid) {
841 		if (risab_d->base.pa == RISAB6_BASE)
842 			set_vderam_syscfg(risab_d);
843 		clear_iac_regs(risab_d);
844 		enable_srwiad_if_set(risab_d);
845 	}
846 
847 	apply_rif_config(risab_d);
848 
849 	disable_srwiad_if_unset(risab_d);
850 
851 	controller = calloc(1, sizeof(*controller));
852 	if (!controller) {
853 		res = TEE_ERROR_OUT_OF_MEMORY;
854 		goto err;
855 	}
856 
857 	controller->base = &risab_d->base;
858 	controller->name = risab_d->risab_name;
859 	controller->priv = risab_d;
860 	controller->ops = &firewall_ops;
861 
862 	SLIST_INSERT_HEAD(&risab_list, risab_d, link);
863 
864 	res = firewall_dt_controller_register(fdt, node, controller);
865 	if (res)
866 		panic();
867 
868 	register_pm_core_service_cb(stm32_risab_pm, risab_d, "stm32-risab");
869 
870 	return TEE_SUCCESS;
871 
872 err:
873 	clk_disable(risab_d->clock);
874 	free(risab_d->subr_cfg);
875 	free(risab_d);
876 
877 	return res;
878 }
879 
880 static const struct dt_device_match risab_match_table[] = {
881 	{ .compatible = "st,stm32mp25-risab" },
882 	{ }
883 };
884 
885 DEFINE_DT_DRIVER(risab_dt_driver) = {
886 	.name = "stm32-risab",
887 	.match_table = risab_match_table,
888 	.probe = stm32_risab_probe,
889 };
890