1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2023, STMicroelectronics 4 */ 5 6 #include <assert.h> 7 #include <config.h> 8 #include <drivers/rstctrl.h> 9 #include <drivers/stm32_remoteproc.h> 10 #ifdef CFG_STM32MP15 11 #include <drivers/stm32mp1_rcc.h> 12 #endif 13 #include <kernel/cache_helpers.h> 14 #include <kernel/dt_driver.h> 15 #include <kernel/tee_misc.h> 16 #include <libfdt.h> 17 #include <mm/core_memprot.h> 18 #include <mm/core_mmu.h> 19 #include <stm32_util.h> 20 21 #define TIMEOUT_US_1MS U(1000) 22 23 /** 24 * struct stm32_rproc_mem - Memory regions used by the remote processor 25 * 26 * @addr: physical base address from the CPU space perspective 27 * @da: device address corresponding to the physical base address 28 * from remote processor space perspective 29 * @size: size of the region 30 */ 31 struct stm32_rproc_mem { 32 paddr_t addr; 33 paddr_t da; 34 size_t size; 35 }; 36 37 /** 38 * struct stm32_rproc_instance - rproc instance context 39 * 40 * @cdata: pointer to the device compatible data 41 * @link: the node in the rproc_list 42 * @n_regions: number of memory regions 43 * @regions: memory regions used 44 * @mcu_rst: remote processor reset control 45 * @hold_boot: remote processor hold boot control 46 * @ns_loading: True if supports non-secure firmware loading, false otherwise 47 */ 48 struct stm32_rproc_instance { 49 const struct stm32_rproc_compat_data *cdata; 50 SLIST_ENTRY(stm32_rproc_instance) link; 51 size_t n_regions; 52 struct stm32_rproc_mem *regions; 53 struct rstctrl *mcu_rst; 54 struct rstctrl *hold_boot; 55 bool ns_loading; 56 }; 57 58 /** 59 * struct stm32_rproc_compat_data - rproc associated data for compatible list 60 * 61 * @rproc_id: identifies the remote processor 62 */ 63 struct stm32_rproc_compat_data { 64 uint32_t rproc_id; 65 }; 66 67 static SLIST_HEAD(, stm32_rproc_instance) rproc_list = 68 SLIST_HEAD_INITIALIZER(rproc_list); 69 70 void *stm32_rproc_get(uint32_t rproc_id) 71 { 72 struct stm32_rproc_instance *rproc = NULL; 73 74 SLIST_FOREACH(rproc, &rproc_list, link) 75 if (rproc->cdata->rproc_id == rproc_id) 76 break; 77 78 return rproc; 79 } 80 81 bool stm32_rproc_is_secure(uint32_t rproc_id) 82 { 83 struct stm32_rproc_instance *rproc = stm32_rproc_get(rproc_id); 84 85 if (rproc) 86 return !rproc->cdata->ns_loading; 87 88 return false; 89 } 90 91 TEE_Result stm32_rproc_start(uint32_t rproc_id) 92 { 93 struct stm32_rproc_instance *rproc = stm32_rproc_get(rproc_id); 94 TEE_Result res = TEE_ERROR_GENERIC; 95 96 if (!rproc || !rproc->hold_boot) 97 return TEE_ERROR_GENERIC; 98 99 /* 100 * The firmware is started by de-asserting the hold boot and 101 * asserting it back to avoid auto restart on a crash. 102 * No need to release the MCU reset as it is automatically released by 103 * the hardware. 104 */ 105 res = rstctrl_deassert_to(rproc->hold_boot, TIMEOUT_US_1MS); 106 if (!res) 107 res = rstctrl_assert_to(rproc->hold_boot, TIMEOUT_US_1MS); 108 109 return res; 110 } 111 112 static TEE_Result rproc_stop(struct stm32_rproc_instance *rproc) 113 { 114 TEE_Result res = TEE_ERROR_GENERIC; 115 116 if (!rproc->hold_boot || !rproc->mcu_rst) 117 return TEE_ERROR_GENERIC; 118 119 res = rstctrl_assert_to(rproc->hold_boot, TIMEOUT_US_1MS); 120 if (!res) 121 res = rstctrl_assert_to(rproc->mcu_rst, TIMEOUT_US_1MS); 122 123 return res; 124 } 125 126 TEE_Result stm32_rproc_stop(uint32_t rproc_id) 127 { 128 struct stm32_rproc_instance *rproc = stm32_rproc_get(rproc_id); 129 130 if (!rproc) 131 return TEE_ERROR_BAD_PARAMETERS; 132 133 return rproc_stop(rproc); 134 } 135 136 TEE_Result stm32_rproc_da_to_pa(uint32_t rproc_id, paddr_t da, size_t size, 137 paddr_t *pa) 138 { 139 struct stm32_rproc_instance *rproc = stm32_rproc_get(rproc_id); 140 struct stm32_rproc_mem *mems = NULL; 141 unsigned int i = 0; 142 143 if (!rproc) 144 return TEE_ERROR_BAD_PARAMETERS; 145 146 mems = rproc->regions; 147 148 for (i = 0; i < rproc->n_regions; i++) { 149 if (core_is_buffer_inside(da, size, mems[i].da, mems[i].size)) { 150 /* 151 * A match between the requested DA memory area and the 152 * registered regions has been found. 153 * The PA is the reserved-memory PA address plus the 154 * delta between the requested DA and the 155 * reserved-memory DA address. 156 */ 157 *pa = mems[i].addr + da - mems[i].da; 158 return TEE_SUCCESS; 159 } 160 } 161 162 return TEE_ERROR_ACCESS_DENIED; 163 } 164 165 TEE_Result stm32_rproc_map(uint32_t rproc_id, paddr_t pa, size_t size, 166 void **va) 167 { 168 struct stm32_rproc_instance *rproc = stm32_rproc_get(rproc_id); 169 struct stm32_rproc_mem *mems = NULL; 170 unsigned int i = 0; 171 172 if (!rproc) 173 return TEE_ERROR_BAD_PARAMETERS; 174 175 mems = rproc->regions; 176 177 for (i = 0; i < rproc->n_regions; i++) { 178 if (!core_is_buffer_inside(pa, size, mems[i].addr, 179 mems[i].size)) 180 continue; 181 *va = core_mmu_add_mapping(MEM_AREA_RAM_NSEC, pa, size); 182 if (!*va) { 183 EMSG("Can't map region %#"PRIxPA" size %zu", pa, size); 184 return TEE_ERROR_GENERIC; 185 } 186 187 return TEE_SUCCESS; 188 } 189 190 return TEE_ERROR_ACCESS_DENIED; 191 } 192 193 TEE_Result stm32_rproc_unmap(uint32_t rproc_id, void *va, size_t size) 194 { 195 struct stm32_rproc_instance *rproc = stm32_rproc_get(rproc_id); 196 struct stm32_rproc_mem *mems = NULL; 197 paddr_t pa = virt_to_phys(va); 198 unsigned int i = 0; 199 200 if (!rproc || !pa) 201 return TEE_ERROR_BAD_PARAMETERS; 202 203 mems = rproc->regions; 204 205 for (i = 0; i < rproc->n_regions; i++) { 206 if (!core_is_buffer_inside(pa, size, mems[i].addr, 207 mems[i].size)) 208 continue; 209 210 /* Flush the cache before unmapping the memory */ 211 dcache_clean_range(va, size); 212 213 if (core_mmu_remove_mapping(MEM_AREA_RAM_NSEC, va, size)) { 214 EMSG("Can't unmap region %#"PRIxPA" size %zu", 215 pa, size); 216 return TEE_ERROR_GENERIC; 217 } 218 219 return TEE_SUCCESS; 220 } 221 222 return TEE_ERROR_ACCESS_DENIED; 223 } 224 225 static TEE_Result stm32_rproc_get_dma_range(struct stm32_rproc_mem *region, 226 const void *fdt, int node) 227 { 228 const fdt32_t *list = NULL; 229 int ahb_node = 0; 230 int len = 0; 231 int nranges = 0; 232 int i = 0; 233 234 /* 235 * The match between local and remote processor memory mapping is 236 * described in the dma-ranges defined by the bus parent node. 237 */ 238 ahb_node = fdt_parent_offset(fdt, node); 239 240 list = fdt_getprop(fdt, ahb_node, "dma-ranges", &len); 241 if (!list) { 242 if (len != -FDT_ERR_NOTFOUND) 243 return TEE_ERROR_GENERIC; 244 /* Same memory mapping */ 245 DMSG("No dma-ranges found in DT"); 246 region->da = region->addr; 247 return TEE_SUCCESS; 248 } 249 250 if ((len % (sizeof(uint32_t) * 3))) 251 return TEE_ERROR_GENERIC; 252 253 nranges = len / sizeof(uint32_t); 254 255 for (i = 0; i < nranges; i += 3) { 256 uint32_t da = fdt32_to_cpu(list[i]); 257 uint32_t pa = fdt32_to_cpu(list[i + 1]); 258 uint32_t size = fdt32_to_cpu(list[i + 2]); 259 260 if (core_is_buffer_inside(region->addr, region->size, 261 pa, size)) { 262 region->da = da + (region->addr - pa); 263 return TEE_SUCCESS; 264 } 265 } 266 267 return TEE_ERROR_BAD_PARAMETERS; 268 } 269 270 /* Get device tree memory regions reserved for the Cortex-M and the IPC */ 271 static TEE_Result stm32_rproc_parse_mems(struct stm32_rproc_instance *rproc, 272 const void *fdt, int node) 273 { 274 const fdt32_t *list = NULL; 275 TEE_Result res = TEE_ERROR_GENERIC; 276 struct stm32_rproc_mem *regions = NULL; 277 int len = 0; 278 int n_regions = 0; 279 int i = 0; 280 281 list = fdt_getprop(fdt, node, "memory-region", &len); 282 if (!list) { 283 EMSG("No memory regions found in DT"); 284 return TEE_ERROR_GENERIC; 285 } 286 287 n_regions = len / sizeof(uint32_t); 288 289 regions = calloc(n_regions, sizeof(*regions)); 290 if (!regions) 291 return TEE_ERROR_OUT_OF_MEMORY; 292 293 for (i = 0; i < n_regions; i++) { 294 int pnode = 0; 295 296 pnode = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(list[i])); 297 if (pnode < 0) { 298 res = TEE_ERROR_GENERIC; 299 goto err; 300 } 301 302 if (fdt_reg_info(fdt, pnode, ®ions[i].addr, 303 ®ions[i].size)) { 304 res = TEE_ERROR_GENERIC; 305 goto err; 306 } 307 308 #if defined(CFG_STM32MP15) 309 if (stm32mp1_ram_intersect_pager_ram(regions[i].addr, 310 regions[i].size)) { 311 EMSG("Region %#"PRIxPA"..%#"PRIxPA" intersects pager secure memory", 312 regions[i].addr, 313 regions[i].addr + regions[i].size); 314 return TEE_ERROR_GENERIC; 315 } 316 #endif 317 318 res = stm32_rproc_get_dma_range(®ions[i], fdt, node); 319 if (res) 320 goto err; 321 322 if (!regions[i].addr || !regions[i].size) { 323 res = TEE_ERROR_BAD_PARAMETERS; 324 goto err; 325 } 326 327 DMSG("register region %#"PRIxPA" size %#zx", 328 regions[i].addr, regions[i].size); 329 } 330 331 rproc->n_regions = n_regions; 332 rproc->regions = regions; 333 334 return TEE_SUCCESS; 335 336 err: 337 free(regions); 338 339 return res; 340 } 341 342 TEE_Result stm32_rproc_clean_up_memories(uint32_t rproc_id) 343 { 344 struct stm32_rproc_instance *rproc = stm32_rproc_get(rproc_id); 345 struct stm32_rproc_mem *mems = NULL; 346 TEE_Result res = TEE_ERROR_GENERIC; 347 unsigned int i = 0; 348 void *va = NULL; 349 size_t size = 0; 350 paddr_t pa = 0; 351 352 if (!rproc) 353 return TEE_ERROR_BAD_PARAMETERS; 354 355 mems = rproc->regions; 356 for (i = 0; i < rproc->n_regions; i++) { 357 pa = mems[i].addr; 358 size = mems[i].size; 359 res = stm32_rproc_map(rproc_id, pa, size, &va); 360 if (res) 361 break; 362 memset(va, 0, size); 363 res = stm32_rproc_unmap(rproc_id, va, size); 364 if (res) 365 break; 366 } 367 368 return res; 369 } 370 371 static void stm32_rproc_cleanup(struct stm32_rproc_instance *rproc) 372 { 373 free(rproc->regions); 374 free(rproc); 375 } 376 377 static TEE_Result stm32_rproc_probe(const void *fdt, int node, 378 const void *comp_data) 379 { 380 struct stm32_rproc_instance *rproc = NULL; 381 TEE_Result res = TEE_ERROR_GENERIC; 382 383 rproc = calloc(1, sizeof(*rproc)); 384 if (!rproc) 385 return TEE_ERROR_OUT_OF_MEMORY; 386 387 rproc->cdata = comp_data; 388 389 res = stm32_rproc_parse_mems(rproc, fdt, node); 390 if (res) 391 goto err; 392 393 res = rstctrl_dt_get_by_name(fdt, node, "mcu_rst", &rproc->mcu_rst); 394 if (res) 395 goto err; 396 397 res = rstctrl_dt_get_by_name(fdt, node, "hold_boot", &rproc->hold_boot); 398 if (res) 399 goto err; 400 401 /* Ensure that the MCU is HOLD */ 402 if (rproc->mcu_rst) { 403 res = rproc_stop(rproc); 404 if (res) 405 goto err; 406 } 407 408 if (!stm32_rcc_is_secure()) { 409 IMSG("WARNING: insecure rproc isolation, RCC is not secure"); 410 if (!IS_ENABLED(CFG_INSECURE)) 411 panic(); 412 } else { 413 stm32_rcc_set_mckprot(true); 414 } 415 416 /* 417 * The memory management should be enhance with firewall 418 * mechanism to map the memory in secure area for the firmware 419 * loading and then to give exclusive access right to the 420 * coprocessor (except for the shared memory). 421 */ 422 IMSG("Warning: the remoteproc memories are not protected by firewall"); 423 424 SLIST_INSERT_HEAD(&rproc_list, rproc, link); 425 426 return TEE_SUCCESS; 427 428 err: 429 stm32_rproc_cleanup(rproc); 430 return res; 431 } 432 433 static const struct stm32_rproc_compat_data stm32_rproc_m4_compat = { 434 .rproc_id = STM32_M4_RPROC_ID, 435 .ns_loading = false, 436 }; 437 438 static const struct dt_device_match stm32_rproc_match_table[] = { 439 { 440 .compatible = "st,stm32mp1-m4-tee", 441 .compat_data = &stm32_rproc_m4_compat, 442 }, 443 { } 444 }; 445 446 DEFINE_DT_DRIVER(stm32_rproc_dt_driver) = { 447 .name = "stm32-rproc", 448 .match_table = stm32_rproc_match_table, 449 .probe = &stm32_rproc_probe, 450 }; 451