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