xref: /rk3399_ARM-atf/drivers/st/rif/stm32mp2_risaf.c (revision 7f690c3786224d000ff53f459f1bdb6ad05dc1d1)
1 /*
2  * Copyright (c) 2025, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <errno.h>
9 
10 #include <arch_helpers.h>
11 #include <common/debug.h>
12 #include <drivers/clk.h>
13 #include <drivers/delay_timer.h>
14 #include <drivers/st/stm32mp2_risaf.h>
15 #include <dt-bindings/soc/rif.h>
16 #include <lib/mmio.h>
17 #include <libfdt.h>
18 #include <plat/common/platform.h>
19 
20 #include <platform_def.h>
21 #include <stm32mp_fconf_getter.h>
22 
23 static struct stm32mp2_risaf_platdata stm32mp2_risaf;
24 static int region_per_instance[RISAF_MAX_INSTANCE];
25 
26 #if ENABLE_ASSERTIONS
valid_protreg_id(int instance,uint32_t id)27 static bool valid_protreg_id(int instance, uint32_t id)
28 {
29 	uint32_t max_id;
30 
31 	max_id = mmio_read_32(stm32mp2_risaf.base[instance] + _RISAF_HWCFGR);
32 	max_id = (max_id & _RISAF_HWCFGR_CFG1_MASK) >> _RISAF_HWCFGR_CFG1_SHIFT;
33 
34 	return id < max_id;
35 }
36 
valid_instance(int instance)37 static bool valid_instance(int instance)
38 {
39 	return (instance < RISAF_MAX_INSTANCE) && (stm32mp2_risaf.base[instance] != 0U);
40 }
41 #endif
42 
risaf_is_hw_encryption_functional(int instance)43 static bool risaf_is_hw_encryption_functional(int instance)
44 {
45 	return (mmio_read_32(stm32mp2_risaf.base[instance] + _RISAF_SR) & _RISAF_SR_ENCDIS) !=
46 	       _RISAF_SR_ENCDIS;
47 }
48 
check_region_boundaries(int instance,uintptr_t addr,size_t len)49 static int check_region_boundaries(int instance, uintptr_t addr, size_t len)
50 {
51 	uintptr_t end_address;
52 	uintptr_t mem_base = stm32_risaf_get_memory_base(instance);
53 
54 	if ((addr < mem_base) || (len == 0U)) {
55 		return -EINVAL;
56 	}
57 
58 	/* Get physical end address */
59 	end_address = mem_base + stm32_risaf_get_memory_size(instance) - 1U;
60 	if ((addr > end_address) || ((addr - 1U + len) > end_address)) {
61 		return -EINVAL;
62 	}
63 
64 	if ((stm32mp2_risaf.granularity[instance] == 0U) ||
65 	    ((addr % stm32mp2_risaf.granularity[instance]) != 0U) ||
66 	    ((len % stm32mp2_risaf.granularity[instance]) != 0U)) {
67 		return -EINVAL;
68 	}
69 
70 	return 0;
71 }
72 
do_regions_overlap(uintptr_t addr1,size_t len1,uintptr_t addr2,size_t len2)73 static bool do_regions_overlap(uintptr_t addr1, size_t len1, uintptr_t addr2, size_t len2)
74 {
75 	return !((addr1 >= (addr2 + len2)) || (addr2 >= (addr1 + len1)));
76 }
77 
check_region_overlap(void)78 static int check_region_overlap(void)
79 {
80 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
81 	int i;
82 	uintptr_t addr;
83 	size_t length;
84 	int instance;
85 	int region_id;
86 
87 	if (pdata->nregions <= 1) {
88 		/*
89 		 * No region found, or first region found.
90 		 * No need to check overlap with previous ones.
91 		 */
92 		return 0;
93 	}
94 
95 	region_id = pdata->nregions - 1;
96 	addr = pdata->region[region_id].addr;
97 	length = pdata->region[region_id].len;
98 	instance = pdata->region[region_id].instance;
99 
100 	for (i = 0; i < region_id; i++) {
101 		if (pdata->region[i].instance != instance) {
102 			continue;
103 		}
104 
105 		if (do_regions_overlap(addr, length,
106 				       pdata->region[i].addr, pdata->region[i].len)) {
107 			ERROR("RISAF%d: Regions %d and %d overlap\n", instance + 1, region_id, i);
108 			return -EINVAL;
109 		}
110 	}
111 
112 	return 0;
113 }
114 
risaf_configure_region(int instance,uint32_t region_id,uint32_t cfg,uint32_t cid_cfg,uintptr_t saddr,uintptr_t eaddr)115 static int risaf_configure_region(int instance, uint32_t region_id, uint32_t cfg,
116 				  uint32_t cid_cfg, uintptr_t saddr, uintptr_t eaddr)
117 {
118 	uintptr_t base = stm32mp2_risaf.base[instance];
119 	uint32_t hwcfgr;
120 	uint32_t mask_lsb;
121 	uint32_t mask_msb;
122 	uint32_t mask;
123 
124 	assert(valid_instance(instance));
125 	assert(valid_protreg_id(instance, region_id));
126 
127 	mmio_clrbits_32(base + _RISAF_REG_CFGR(region_id), _RISAF_REG_CFGR_BREN);
128 
129 	/* Get address mask depending on RISAF instance HW configuration */
130 	hwcfgr =  mmio_read_32(base + _RISAF_HWCFGR);
131 	mask_lsb = (hwcfgr & _RISAF_HWCFGR_CFG3_MASK) >> _RISAF_HWCFGR_CFG3_SHIFT;
132 	mask_msb = mask_lsb + ((hwcfgr & _RISAF_HWCFGR_CFG4_MASK) >> _RISAF_HWCFGR_CFG4_SHIFT) - 1U;
133 	mask = GENMASK_32(mask_msb, mask_lsb);
134 
135 	mmio_clrsetbits_32(base + _RISAF_REG_STARTR(region_id), mask,
136 			   (saddr - stm32_risaf_get_memory_base(instance)) & mask);
137 	mmio_clrsetbits_32(base + _RISAF_REG_ENDR(region_id), mask,
138 			   (eaddr - stm32_risaf_get_memory_base(instance)) & mask);
139 
140 	mmio_clrsetbits_32(base + _RISAF_REG_CIDCFGR(region_id), _RISAF_REG_CIDCFGR_ALL_MASK,
141 			   cid_cfg & _RISAF_REG_CIDCFGR_ALL_MASK);
142 
143 	mmio_clrsetbits_32(base + _RISAF_REG_CFGR(region_id),
144 			   _RISAF_REG_CFGR_ALL_MASK, cfg & _RISAF_REG_CFGR_ALL_MASK);
145 
146 	if ((cfg & _RISAF_REG_CFGR_ENC) == _RISAF_REG_CFGR_ENC) {
147 		if (!risaf_is_hw_encryption_functional(instance)) {
148 			ERROR("RISAF%d: encryption disabled\n", instance + 1);
149 			return -EIO;
150 		}
151 
152 		if ((cfg & _RISAF_REG_CFGR_SEC) != _RISAF_REG_CFGR_SEC) {
153 			ERROR("RISAF%d: encryption on non secure area\n", instance + 1);
154 			return -EIO;
155 		}
156 	}
157 
158 	return 0;
159 }
160 
risaf_conf_protreg(void)161 static void risaf_conf_protreg(void)
162 {
163 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
164 	int idx;
165 
166 	for (idx = 0; idx < RISAF_MAX_INSTANCE; idx++) {
167 		int n;
168 
169 		if (pdata->base[idx] == 0) {
170 			continue;
171 		}
172 
173 		if (clk_enable(pdata->clock[idx]) != 0) {
174 			ERROR("%s: RISAF@%lx clock failed\n", __func__, pdata->base[idx]);
175 			panic();
176 		}
177 
178 		for (n = 0; n < pdata->nregions; n++) {
179 			uint32_t id;
180 			uint32_t value;
181 			uint32_t cfg;
182 			uint32_t cid_cfg;
183 			uintptr_t start_addr;
184 			uintptr_t end_addr;
185 
186 			if (pdata->region[n].instance != idx) {
187 				continue;
188 			}
189 
190 			value = pdata->region[n].cfg;
191 			id = (value & DT_RISAF_REG_ID_MASK);
192 			assert(valid_protreg_id(idx, id));
193 
194 			cfg = (((value & DT_RISAF_EN_MASK) >> DT_RISAF_EN_SHIFT) <<
195 			       _RISAF_REG_CFGR_BREN_SHIFT) |
196 			      (((value & DT_RISAF_SEC_MASK) >> DT_RISAF_SEC_SHIFT) <<
197 			       _RISAF_REG_CFGR_SEC_SHIFT) |
198 			      (((value & DT_RISAF_ENC_MASK) >> DT_RISAF_ENC_SHIFT) <<
199 			       _RISAF_REG_CFGR_ENC_SHIFT) |
200 			      (((value & DT_RISAF_PRIV_MASK) >> DT_RISAF_PRIV_SHIFT) <<
201 			       _RISAF_REG_CFGR_PRIVC_SHIFT);
202 
203 			cid_cfg = (((value & DT_RISAF_WRITE_MASK) >> DT_RISAF_WRITE_SHIFT) <<
204 				   _RISAF_REG_CIDCFGR_WRENC_SHIFT) |
205 				  (((value & DT_RISAF_READ_MASK) >> DT_RISAF_READ_SHIFT) <<
206 				   _RISAF_REG_CIDCFGR_RDENC_SHIFT);
207 
208 			start_addr = pdata->region[n].addr;
209 			end_addr = (start_addr - 1U) + pdata->region[n].len;
210 
211 			if (risaf_configure_region(idx, id, cfg, cid_cfg,
212 						   start_addr, end_addr) < 0) {
213 				ERROR("%s: failed to configure region %u of RISAF@%lx\n",
214 				      __func__, id, pdata->base[idx]);
215 				panic();
216 			}
217 		}
218 
219 		clk_disable(pdata->clock[idx]);
220 	}
221 }
222 
risaf_get_dt_node(struct dt_node_info * info,int offset)223 static int risaf_get_dt_node(struct dt_node_info *info, int offset)
224 {
225 	return dt_get_node(info, offset, DT_RISAF_COMPAT);
226 }
227 
risaf_get_instance_from_region(uintptr_t address,size_t length)228 static int risaf_get_instance_from_region(uintptr_t address, size_t length)
229 {
230 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
231 	unsigned int idx;
232 	int instance = -1;
233 
234 	for (idx = 0U; idx < RISAF_MAX_INSTANCE; idx++) {
235 		if (pdata->base[idx] == 0U) {
236 			continue;
237 		}
238 
239 		if (check_region_boundaries(idx, address, length) == 0) {
240 			instance = idx;
241 		}
242 	}
243 
244 	return instance;
245 }
246 
247 /*
248  * Register region in platfoirm data structure if parameters are valid.
249  * If instance is known, related entry parameter is filled, else it is equal to -1.
250  */
risaf_register_region(void * fdt,int node,int instance)251 static int risaf_register_region(void *fdt, int node, int instance)
252 {
253 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
254 	const fdt32_t *cuint;
255 	int len = 0;
256 	int inst;
257 	uintptr_t address;
258 	size_t length;
259 	uint32_t protreg;
260 
261 	/*  Get address and length */
262 	cuint = fdt_getprop(fdt, node, "reg", &len);
263 	if ((cuint == NULL) || (len != RISAF_REGION_REG_SIZE)) {
264 		ERROR("RISAF: No or bad reg entry in DT\n");
265 		return -EINVAL;
266 	}
267 
268 	address = (uintptr_t)fdt32_to_cpu(cuint[0]) << 32;
269 	address |= fdt32_to_cpu(cuint[1]);
270 	length = (size_t)fdt32_to_cpu(cuint[2]) << 32;
271 	length |= fdt32_to_cpu(cuint[3]);
272 
273 	/* Get instance */
274 	inst = risaf_get_instance_from_region(address, length);
275 	if (inst < 0) {
276 		ERROR("RISAF: No instance found in DT\n");
277 		return -EINVAL;
278 	}
279 
280 	if ((instance != -1) && (inst != instance)) {
281 		ERROR("RISAF%d: Region not located in expected address space\n", instance + 1);
282 		return -EINVAL;
283 	}
284 
285 	/* Get protreg configuration */
286 	cuint = fdt_getprop(fdt, node, "st,protreg", &len);
287 	if ((cuint == NULL) || (len != RISAF_REGION_PROTREG_SIZE)) {
288 		ERROR("RISAF%d: No or bad st,protreg entry in DT\n", inst + 1);
289 		return -EINVAL;
290 	}
291 
292 	protreg = fdt32_to_cpu(*cuint);
293 
294 	/* Check if region max is reached for the current instance */
295 	region_per_instance[inst]++;
296 	if (region_per_instance[inst] > stm32_risaf_get_max_region(inst)) {
297 		ERROR("RISAF%d: Too many entries in DT\n", inst + 1);
298 		return -EINVAL;
299 	}
300 
301 	if (check_region_boundaries(inst, address, length) != 0) {
302 		ERROR("RISAF%d: Region %d exceeds limits\n", inst + 1, pdata->nregions);
303 		return -EINVAL;
304 	}
305 
306 	/* Register region configuration */
307 	pdata->region[pdata->nregions].instance = inst;
308 	pdata->region[pdata->nregions].cfg = protreg;
309 	pdata->region[pdata->nregions].addr = address;
310 	pdata->region[pdata->nregions].len = length;
311 	pdata->nregions++;
312 
313 	if (check_region_overlap() != 0) {
314 		return -EINVAL;
315 	}
316 
317 	return 0;
318 }
319 
320 /*
321  * From DT, retrieve base address, clock ID and all region information for each RISAF instance.
322  * Check boundaries for each region and overlap for each instance.
323  */
risaf_parse_fdt(void)324 static int risaf_parse_fdt(void)
325 {
326 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
327 	struct dt_node_info risaf_info;
328 	int node = -1;
329 	void *fdt;
330 
331 	if (fdt_get_address(&fdt) == 0) {
332 		return -ENOENT;
333 	}
334 
335 	for (node = risaf_get_dt_node(&risaf_info, node); node >= 0;
336 	     node = risaf_get_dt_node(&risaf_info, node)) {
337 		int idx;
338 		int nregions;
339 		int inst_maxregions;
340 		int i;
341 		int len = 0;
342 		const fdt32_t *conf_list;
343 		uint32_t granularity;
344 
345 		idx = stm32_risaf_get_instance(risaf_info.base);
346 		if ((idx < 0) || (risaf_info.clock < 0)) {
347 			continue;
348 		}
349 
350 		pdata->base[idx] = risaf_info.base;
351 		pdata->clock[idx] = (unsigned long)risaf_info.clock;
352 
353 		/* Get IP region granularity */
354 		if (clk_enable(pdata->clock[idx]) != 0) {
355 			ERROR("%s: clock enable failed.\n", __func__);
356 			panic();
357 		}
358 
359 		granularity = mmio_read_32(pdata->base[idx] + _RISAF_HWCFGR);
360 		clk_disable(pdata->clock[idx]);
361 		granularity = BIT_32((granularity & _RISAF_HWCFGR_CFG3_MASK) >>
362 				  _RISAF_HWCFGR_CFG3_SHIFT);
363 		pdata->granularity[idx] = granularity;
364 
365 		conf_list = fdt_getprop(fdt, node, "memory-region", &len);
366 		if (conf_list == NULL) {
367 			len = 0;
368 		}
369 
370 		nregions = (unsigned int)len / sizeof(uint32_t);
371 
372 		inst_maxregions = stm32_risaf_get_max_region(idx);
373 		if (inst_maxregions <= 0) {
374 			continue;
375 		}
376 
377 		if ((nregions > inst_maxregions) ||
378 		    ((pdata->nregions + nregions) > RISAF_MAX_REGION)) {
379 			ERROR("RISAF%d: Too many entries in DT\n", idx + 1);
380 			return -EINVAL;
381 		}
382 
383 		for (i = 0; i < nregions; i++) {
384 			int pnode = 0;
385 
386 			pnode = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(conf_list[i]));
387 			if (pnode < 0) {
388 				continue;
389 			}
390 
391 			if (risaf_register_region(fdt, pnode, idx) != 0) {
392 				ERROR("RISAF%d: Region %d error\n", idx + 1, pdata->nregions);
393 				return -EINVAL;
394 			}
395 		}
396 	}
397 
398 	return 0;
399 }
400 
401 static uintptr_t risaf_base[RISAF_MAX_INSTANCE];
402 static unsigned long risaf_clock[RISAF_MAX_INSTANCE];
403 static uint32_t risaf_granularity[RISAF_MAX_INSTANCE];
404 static struct stm32mp2_risaf_region risaf_region[RISAF_MAX_REGION];
405 
406 /* Construct platform data structure */
risaf_get_platdata(struct stm32mp2_risaf_platdata * pdata)407 static int risaf_get_platdata(struct stm32mp2_risaf_platdata *pdata)
408 {
409 	pdata->base = risaf_base;
410 	pdata->clock = risaf_clock;
411 	pdata->granularity = risaf_granularity;
412 	pdata->region = risaf_region;
413 
414 	return 0;
415 }
416 
417 /*
418  * @brief  Write the encryption key for a given instance.
419  * @param  instance: RISAF instance ID.
420  *         key: Pointer to the encryption key buffer.
421  * @retval 0 if OK, negative value else.
422  */
stm32mp2_risaf_write_encryption_key(int instance,uint8_t * key)423 int stm32mp2_risaf_write_encryption_key(int instance, uint8_t *key)
424 {
425 	uint64_t timeout_ref;
426 	uint32_t i;
427 	uintptr_t base = stm32mp2_risaf.base[instance];
428 
429 	if (base == 0U) {
430 		return -EINVAL;
431 	}
432 
433 	if (key == NULL) {
434 		return -EINVAL;
435 	}
436 
437 	for (i = 0U; i < RISAF_ENCRYPTION_KEY_SIZE_IN_BYTES; i += sizeof(uint32_t)) {
438 		uint32_t key_val = 0U;
439 
440 		memcpy(&key_val, key + i, sizeof(uint32_t));
441 
442 		mmio_write_32(base + _RISAF_KEYR + i, key_val);
443 	}
444 
445 	timeout_ref = timeout_init_us(RISAF_TIMEOUT_1MS_IN_US);
446 
447 	while (((mmio_read_32(base + _RISAF_SR) & _RISAF_SR_KEYVALID) != _RISAF_SR_KEYVALID) ||
448 	       ((mmio_read_32(base + _RISAF_SR) & _RISAF_SR_KEYRDY) != _RISAF_SR_KEYRDY)) {
449 		if (timeout_elapsed(timeout_ref)) {
450 			return -EIO;
451 		}
452 	}
453 
454 	return 0;
455 }
456 
457 /*
458  * @brief  Lock the RISAF IP registers for a given instance.
459  * @param  instance: RISAF instance ID.
460  * @retval 0 if OK, negative value else.
461  */
stm32mp2_risaf_lock(int instance)462 int stm32mp2_risaf_lock(int instance)
463 {
464 	uintptr_t base = stm32mp2_risaf.base[instance];
465 
466 	if (base == 0U) {
467 		return -EINVAL;
468 	}
469 
470 	mmio_setbits_32(base + _RISAF_CR, _RISAF_CR_GLOCK);
471 
472 	return 0;
473 }
474 
475 /*
476  * @brief  Get the RISAF lock state for a given instance.
477  * @param  instance: RISAF instance ID.
478  *         state: lock state, true if locked, false else.
479  * @retval 0 if OK, negative value else.
480  */
stm32mp2_risaf_is_locked(int instance,bool * state)481 int stm32mp2_risaf_is_locked(int instance, bool *state)
482 {
483 	uintptr_t base = stm32mp2_risaf.base[instance];
484 
485 	if (base == 0U) {
486 		return -EINVAL;
487 	}
488 
489 	*state = (mmio_read_32(base + _RISAF_CR) & _RISAF_CR_GLOCK) == _RISAF_CR_GLOCK;
490 
491 	return 0;
492 }
493 
stm32mp2_risaf_init(void)494 int stm32mp2_risaf_init(void)
495 {
496 	int err;
497 
498 	err = risaf_get_platdata(&stm32mp2_risaf);
499 	if (err != 0) {
500 		return err;
501 	}
502 
503 	err = risaf_parse_fdt();
504 	if (err != 0) {
505 		return err;
506 	}
507 
508 	risaf_conf_protreg();
509 
510 	return err;
511 }
512 
risaf_parse_fwconfig(uintptr_t config)513 static int risaf_parse_fwconfig(uintptr_t config)
514 {
515 	struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf;
516 	unsigned int i;
517 	int node = -1;
518 	int subnode;
519 	const void *fdt = (const void *)config;
520 	const char *compatible_str = "st,stm32mp2-mem-firewall";
521 
522 	node = fdt_node_offset_by_compatible(fdt, -1, compatible_str);
523 	if (node < 0) {
524 		ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
525 		return node;
526 	}
527 
528 	fdt_for_each_subnode(subnode, fdt, node) {
529 		if (risaf_register_region((void *)fdt, subnode, -1) != 0) {
530 			ERROR("RISAF: Region %d error\n", pdata->nregions);
531 			return -EINVAL;
532 		}
533 	}
534 
535 	for (i = 0U; i < RISAF_MAX_INSTANCE; i++) {
536 		if ((region_per_instance[i] == 0) && (stm32_risaf_get_max_region(i) != 0)) {
537 			INFO("RISAF%u: No configuration in DT, use default\n", i + 1);
538 		}
539 	}
540 
541 	return 0;
542 }
543 
fconf_populate_risaf(uintptr_t config)544 static int fconf_populate_risaf(uintptr_t config)
545 {
546 	int err;
547 
548 	err = risaf_parse_fwconfig(config);
549 	if (err != 0) {
550 		return err;
551 	}
552 
553 	risaf_conf_protreg();
554 
555 	return err;
556 }
557 
558 FCONF_REGISTER_POPULATOR(FW_CONFIG, risaf_config, fconf_populate_risaf);
559