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