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 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) == _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 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 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