1 /* 2 * Copyright (c) 2025-2026, 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 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 37 static bool valid_instance(int instance) 38 { 39 return (instance < RISAF_MAX_INSTANCE) && (stm32mp2_risaf.base[instance] != 0U); 40 } 41 #endif 42 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 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 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 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 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) != 0U) { 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 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 #if STM32MP21 199 (((value & DT_RISAF_ENC_MASK) >> DT_RISAF_ENC_SHIFT) << 200 _RISAF_REG_CFGR_ENC_SHIFT) | 201 #else /* !STM32MP21 */ 202 (((value & DT_RISAF_ENC_MASK) >> (DT_RISAF_ENC_SHIFT + 1)) << 203 _RISAF_REG_CFGR_ENC_SHIFT) | 204 #endif /* STM32MP21 */ 205 (((value & DT_RISAF_PRIV_MASK) >> DT_RISAF_PRIV_SHIFT) << 206 _RISAF_REG_CFGR_PRIVC_SHIFT); 207 208 cid_cfg = (((value & DT_RISAF_WRITE_MASK) >> DT_RISAF_WRITE_SHIFT) << 209 _RISAF_REG_CIDCFGR_WRENC_SHIFT) | 210 (((value & DT_RISAF_READ_MASK) >> DT_RISAF_READ_SHIFT) << 211 _RISAF_REG_CIDCFGR_RDENC_SHIFT); 212 213 start_addr = pdata->region[n].addr; 214 end_addr = (start_addr - 1U) + pdata->region[n].len; 215 216 if (risaf_configure_region(idx, id, cfg, cid_cfg, 217 start_addr, end_addr) < 0) { 218 ERROR("%s: failed to configure region %u of RISAF@%lx\n", 219 __func__, id, pdata->base[idx]); 220 panic(); 221 } 222 } 223 224 clk_disable(pdata->clock[idx]); 225 } 226 } 227 228 static int risaf_get_dt_node(struct dt_node_info *info, int offset) 229 { 230 return dt_get_node(info, offset, DT_RISAF_COMPAT); 231 } 232 233 static int risaf_get_instance_from_region(uintptr_t address, size_t length) 234 { 235 struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf; 236 unsigned int idx; 237 int instance = -1; 238 239 for (idx = 0U; idx < RISAF_MAX_INSTANCE; idx++) { 240 if (pdata->base[idx] == 0U) { 241 continue; 242 } 243 244 if (check_region_boundaries(idx, address, length) == 0) { 245 instance = idx; 246 } 247 } 248 249 return instance; 250 } 251 252 /* 253 * Register region in platfoirm data structure if parameters are valid. 254 * If instance is known, related entry parameter is filled, else it is equal to -1. 255 */ 256 static int risaf_register_region(void *fdt, int node, int instance) 257 { 258 struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf; 259 const fdt32_t *cuint; 260 int len = 0; 261 int inst; 262 uintptr_t address; 263 size_t length; 264 uint32_t protreg; 265 266 /* Get address and length */ 267 cuint = fdt_getprop(fdt, node, "reg", &len); 268 if ((cuint == NULL) || (len != RISAF_REGION_REG_SIZE)) { 269 ERROR("RISAF: No or bad reg entry in DT\n"); 270 return -EINVAL; 271 } 272 273 address = (uintptr_t)fdt32_to_cpu(cuint[0]) << 32; 274 address |= fdt32_to_cpu(cuint[1]); 275 length = (size_t)fdt32_to_cpu(cuint[2]) << 32; 276 length |= fdt32_to_cpu(cuint[3]); 277 278 /* Get instance */ 279 inst = risaf_get_instance_from_region(address, length); 280 if (inst < 0) { 281 ERROR("RISAF: No instance found in DT\n"); 282 return -EINVAL; 283 } 284 285 if ((instance != -1) && (inst != instance)) { 286 ERROR("RISAF%d: Region not located in expected address space\n", instance + 1); 287 return -EINVAL; 288 } 289 290 /* Get protreg configuration */ 291 cuint = fdt_getprop(fdt, node, "st,protreg", &len); 292 if ((cuint == NULL) || (len != RISAF_REGION_PROTREG_SIZE)) { 293 ERROR("RISAF%d: No or bad st,protreg entry in DT\n", inst + 1); 294 return -EINVAL; 295 } 296 297 protreg = fdt32_to_cpu(*cuint); 298 299 /* Check if region max is reached for the current instance */ 300 region_per_instance[inst]++; 301 if (region_per_instance[inst] > stm32_risaf_get_max_region(inst)) { 302 ERROR("RISAF%d: Too many entries in DT\n", inst + 1); 303 return -EINVAL; 304 } 305 306 if (check_region_boundaries(inst, address, length) != 0) { 307 ERROR("RISAF%d: Region %d exceeds limits\n", inst + 1, pdata->nregions); 308 return -EINVAL; 309 } 310 311 /* Register region configuration */ 312 pdata->region[pdata->nregions].instance = inst; 313 pdata->region[pdata->nregions].cfg = protreg; 314 pdata->region[pdata->nregions].addr = address; 315 pdata->region[pdata->nregions].len = length; 316 pdata->nregions++; 317 318 if (check_region_overlap() != 0) { 319 return -EINVAL; 320 } 321 322 return 0; 323 } 324 325 /* 326 * From DT, retrieve base address, clock ID and all region information for each RISAF instance. 327 * Check boundaries for each region and overlap for each instance. 328 */ 329 static int risaf_parse_fdt(void) 330 { 331 struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf; 332 struct dt_node_info risaf_info; 333 int node = -1; 334 void *fdt; 335 336 if (fdt_get_address(&fdt) == 0) { 337 return -ENOENT; 338 } 339 340 for (node = risaf_get_dt_node(&risaf_info, node); node >= 0; 341 node = risaf_get_dt_node(&risaf_info, node)) { 342 int idx; 343 int nregions; 344 int inst_maxregions; 345 int i; 346 int len = 0; 347 const fdt32_t *conf_list; 348 uint32_t granularity; 349 350 idx = stm32_risaf_get_instance(risaf_info.base); 351 if ((idx < 0) || (risaf_info.clock < 0)) { 352 continue; 353 } 354 355 pdata->base[idx] = risaf_info.base; 356 pdata->clock[idx] = (unsigned long)risaf_info.clock; 357 358 /* Get IP region granularity */ 359 if (clk_enable(pdata->clock[idx]) != 0) { 360 ERROR("%s: clock enable failed.\n", __func__); 361 panic(); 362 } 363 364 granularity = mmio_read_32(pdata->base[idx] + _RISAF_HWCFGR); 365 clk_disable(pdata->clock[idx]); 366 granularity = BIT_32((granularity & _RISAF_HWCFGR_CFG3_MASK) >> 367 _RISAF_HWCFGR_CFG3_SHIFT); 368 pdata->granularity[idx] = granularity; 369 370 conf_list = fdt_getprop(fdt, node, "memory-region", &len); 371 if (conf_list == NULL) { 372 len = 0; 373 } 374 375 nregions = (unsigned int)len / sizeof(uint32_t); 376 377 inst_maxregions = stm32_risaf_get_max_region(idx); 378 if (inst_maxregions <= 0) { 379 continue; 380 } 381 382 if ((nregions > inst_maxregions) || 383 ((pdata->nregions + nregions) > RISAF_MAX_REGION)) { 384 ERROR("RISAF%d: Too many entries in DT\n", idx + 1); 385 return -EINVAL; 386 } 387 388 for (i = 0; i < nregions; i++) { 389 int pnode = 0; 390 391 pnode = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(conf_list[i])); 392 if (pnode < 0) { 393 continue; 394 } 395 396 if (risaf_register_region(fdt, pnode, idx) != 0) { 397 ERROR("RISAF%d: Region %d error\n", idx + 1, pdata->nregions); 398 return -EINVAL; 399 } 400 } 401 } 402 403 return 0; 404 } 405 406 static uintptr_t risaf_base[RISAF_MAX_INSTANCE]; 407 static unsigned long risaf_clock[RISAF_MAX_INSTANCE]; 408 static uint32_t risaf_granularity[RISAF_MAX_INSTANCE]; 409 static struct stm32mp2_risaf_region risaf_region[RISAF_MAX_REGION]; 410 411 /* Construct platform data structure */ 412 static int risaf_get_platdata(struct stm32mp2_risaf_platdata *pdata) 413 { 414 pdata->base = risaf_base; 415 pdata->clock = risaf_clock; 416 pdata->granularity = risaf_granularity; 417 pdata->region = risaf_region; 418 419 return 0; 420 } 421 422 /* 423 * @brief Write the encryption key for a given instance. 424 * @param instance: RISAF instance ID. 425 * key: Pointer to the encryption key buffer. 426 * @retval 0 if OK, negative value else. 427 */ 428 int stm32mp2_risaf_write_encryption_key(int instance, uint8_t *key) 429 { 430 uint64_t timeout_ref; 431 uint32_t i; 432 uintptr_t base = stm32mp2_risaf.base[instance]; 433 434 assert(key != NULL); 435 436 if (base == 0U) { 437 return -EINVAL; 438 } 439 440 for (i = 0U; i < RISAF_ENCRYPTION_KEY_SIZE_IN_BYTES; i += sizeof(uint32_t)) { 441 uint32_t key_val = 0U; 442 443 memcpy(&key_val, key + i, sizeof(uint32_t)); 444 445 mmio_write_32(base + _RISAF_KEYR + i, key_val); 446 } 447 448 timeout_ref = timeout_init_us(RISAF_TIMEOUT_1MS_IN_US); 449 450 while (((mmio_read_32(base + _RISAF_SR) & _RISAF_SR_KEYVALID) != _RISAF_SR_KEYVALID) || 451 ((mmio_read_32(base + _RISAF_SR) & _RISAF_SR_KEYRDY) != _RISAF_SR_KEYRDY)) { 452 if (timeout_elapsed(timeout_ref)) { 453 return -EIO; 454 } 455 } 456 457 return 0; 458 } 459 460 #if STM32MP21 461 static int risaf_get_mce_key_size(int instance, uint32_t *size) 462 { 463 struct dt_node_info risaf_info; 464 int node = -1; 465 void *fdt; 466 467 if (fdt_get_address(&fdt) == 0) { 468 return -ENOENT; 469 } 470 471 for (node = risaf_get_dt_node(&risaf_info, node); node >= 0; 472 node = risaf_get_dt_node(&risaf_info, node)) { 473 int idx; 474 const fdt32_t *cuint = NULL; 475 476 idx = stm32_risaf_get_instance(risaf_info.base); 477 if (idx != instance) { 478 continue; 479 } 480 481 cuint = fdt_getprop(fdt, node, "st,mce-keysize-bits", NULL); 482 if (cuint == NULL) { 483 /* Property not set, affect default value */ 484 *size = RISAF_MCE_KEY_128BITS_SIZE_IN_BYTES; 485 } else { 486 *size = (uint32_t)fdt32_to_cpu(*cuint) / 8; 487 } 488 489 return 0; 490 } 491 492 return -ENODEV; 493 } 494 495 /* 496 * @brief Write the MCE key for a given instance. 497 * @param instance: RISAF instance ID. 498 * key: Pointer to the MCE key buffer. 499 * size: MCE key size in bytes. 500 * @retval 0 if OK, negative value else. 501 */ 502 int stm32mp2_risaf_write_mce_key(int instance, uint8_t *key) 503 { 504 uint64_t timeout_ref; 505 uint32_t i; 506 uint32_t size; 507 uintptr_t base = stm32mp2_risaf.base[instance]; 508 509 assert(key != NULL); 510 511 if (base == 0U) { 512 return -EINVAL; 513 } 514 515 if (risaf_get_mce_key_size(instance, &size) != 0) { 516 return -EINVAL; 517 } 518 519 if (size == RISAF_MCE_KEY_128BITS_SIZE_IN_BYTES) { 520 mmio_write_32(base + _RISAF_XCR, 521 _RISAF_XCR_CIPHERSEL_AES128 << _RISAF_XCR_CIPHERSEL_SHIFT); 522 } else if (size == RISAF_MCE_KEY_256BITS_SIZE_IN_BYTES) { 523 mmio_write_32(base + _RISAF_XCR, 524 _RISAF_XCR_CIPHERSEL_AES256 << _RISAF_XCR_CIPHERSEL_SHIFT); 525 } else { 526 return -EINVAL; 527 } 528 529 for (i = 0U; i < size; i += sizeof(uint32_t)) { 530 uint32_t key_val = 0U; 531 532 memcpy(&key_val, key + i, sizeof(uint32_t)); 533 534 mmio_write_32(base + _RISAF_MKEYR + i, key_val); 535 } 536 537 timeout_ref = timeout_init_us(RISAF_TIMEOUT_1MS_IN_US); 538 539 while (((mmio_read_32(base + _RISAF_XSR) & _RISAF_XSR_MKVALID) != _RISAF_XSR_MKVALID)) { 540 if (timeout_elapsed(timeout_ref)) { 541 return -EIO; 542 } 543 } 544 545 return 0; 546 } 547 #endif /* STM32MP21 */ 548 549 /* 550 * @brief Lock the RISAF IP registers for a given instance. 551 * @param instance: RISAF instance ID. 552 * @retval 0 if OK, negative value else. 553 */ 554 int stm32mp2_risaf_lock(int instance) 555 { 556 uintptr_t base = stm32mp2_risaf.base[instance]; 557 558 if (base == 0U) { 559 return -EINVAL; 560 } 561 562 mmio_setbits_32(base + _RISAF_CR, _RISAF_CR_GLOCK); 563 564 return 0; 565 } 566 567 /* 568 * @brief Get the RISAF lock state for a given instance. 569 * @param instance: RISAF instance ID. 570 * state: lock state, true if locked, false else. 571 * @retval 0 if OK, negative value else. 572 */ 573 int stm32mp2_risaf_is_locked(int instance, bool *state) 574 { 575 uintptr_t base = stm32mp2_risaf.base[instance]; 576 577 if (base == 0U) { 578 return -EINVAL; 579 } 580 581 *state = (mmio_read_32(base + _RISAF_CR) & _RISAF_CR_GLOCK) == _RISAF_CR_GLOCK; 582 583 return 0; 584 } 585 586 int stm32mp2_risaf_init(void) 587 { 588 int err; 589 590 err = risaf_get_platdata(&stm32mp2_risaf); 591 if (err != 0) { 592 return err; 593 } 594 595 err = risaf_parse_fdt(); 596 if (err != 0) { 597 return err; 598 } 599 600 risaf_conf_protreg(); 601 602 return err; 603 } 604 605 static int risaf_parse_fwconfig(uintptr_t config) 606 { 607 struct stm32mp2_risaf_platdata *pdata = &stm32mp2_risaf; 608 unsigned int i; 609 int node; 610 int subnode; 611 const void *fdt = (const void *)config; 612 const char *compatible_str = "st,stm32mp2-mem-firewall"; 613 614 node = fdt_node_offset_by_compatible(fdt, -1, compatible_str); 615 if (node < 0) { 616 ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); 617 return node; 618 } 619 620 fdt_for_each_subnode(subnode, fdt, node) { 621 if (risaf_register_region((void *)fdt, subnode, -1) != 0) { 622 ERROR("RISAF: Region %d error\n", pdata->nregions); 623 return -EINVAL; 624 } 625 } 626 627 for (i = 0U; i < RISAF_MAX_INSTANCE; i++) { 628 if ((region_per_instance[i] == 0) && (stm32_risaf_get_max_region(i) != 0)) { 629 INFO("RISAF%u: No configuration in DT, use default\n", i + 1); 630 } 631 } 632 633 return 0; 634 } 635 636 static int fconf_populate_risaf(uintptr_t config) 637 { 638 int err; 639 640 err = risaf_parse_fwconfig(config); 641 if (err != 0) { 642 return err; 643 } 644 645 risaf_conf_protreg(); 646 647 return err; 648 } 649 650 FCONF_REGISTER_POPULATOR(FW_CONFIG, risaf_config, fconf_populate_risaf); 651