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