1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2015 4 * Texas Instruments Incorporated - https://www.ti.com/ 5 */ 6 7#define LOG_CATEGORY UCLASS_REMOTEPROC 8 9#define pr_fmt(fmt) "%s: " fmt, __func__ 10#include <common.h> 11#include <elf.h> 12#include <errno.h> 13#include <log.h> 14#include <malloc.h> 15#include <virtio_ring.h> 16#include <fs_loader.h> 17#include <remoteproc.h> 18#include <asm/io.h> 19#include <dm/device-internal.h> 20#include <dm.h> 21#include <dm/uclass.h> 22#include <dm/uclass-internal.h> 23#include <linux/compat.h> 24#include <linux/printk.h> 25 26DECLARE_GLOBAL_DATA_PTR; 27 28struct resource_table { 29 u32 ver; 30 u32 num; 31 u32 reserved[2]; 32 u32 offset[0]; 33} __packed; 34 35typedef int (*handle_resource_t) (struct udevice *, void *, int offset, int avail); 36 37static struct resource_table *rsc_table; 38 39/** 40 * for_each_remoteproc_device() - iterate through the list of rproc devices 41 * @fn: check function to call per match, if this function returns fail, 42 * iteration is aborted with the resultant error value 43 * @skip_dev: Device to skip calling the callback about. 44 * @data: Data to pass to the callback function 45 * 46 * Return: 0 if none of the callback returned a non 0 result, else returns the 47 * result from the callback function 48 */ 49static int for_each_remoteproc_device(int (*fn) (struct udevice *dev, 50 struct dm_rproc_uclass_pdata *uc_pdata, 51 const void *data), 52 struct udevice *skip_dev, 53 const void *data) 54{ 55 struct udevice *dev; 56 struct dm_rproc_uclass_pdata *uc_pdata; 57 int ret; 58 59 for (ret = uclass_find_first_device(UCLASS_REMOTEPROC, &dev); dev; 60 ret = uclass_find_next_device(&dev)) { 61 if (ret || dev == skip_dev) 62 continue; 63 uc_pdata = dev_get_uclass_plat(dev); 64 ret = fn(dev, uc_pdata, data); 65 if (ret) 66 return ret; 67 } 68 69 return 0; 70} 71 72/** 73 * _rproc_name_is_unique() - iteration helper to check if rproc name is unique 74 * @dev: device that we are checking name for 75 * @uc_pdata: uclass platform data 76 * @data: compare data (this is the name we want to ensure is unique) 77 * 78 * Return: 0 is there is no match(is unique); if there is a match(we dont 79 * have a unique name), return -EINVAL. 80 */ 81static int _rproc_name_is_unique(struct udevice *dev, 82 struct dm_rproc_uclass_pdata *uc_pdata, 83 const void *data) 84{ 85 const char *check_name = data; 86 87 /* devices not yet populated with data - so skip them */ 88 if (!uc_pdata->name || !check_name) 89 return 0; 90 91 /* Return 0 to search further if we dont match */ 92 if (strlen(uc_pdata->name) != strlen(check_name)) 93 return 0; 94 95 if (!strcmp(uc_pdata->name, check_name)) 96 return -EINVAL; 97 98 return 0; 99} 100 101/** 102 * rproc_name_is_unique() - Check if the rproc name is unique 103 * @check_dev: Device we are attempting to ensure is unique 104 * @check_name: Name we are trying to ensure is unique. 105 * 106 * Return: true if we have a unique name, false if name is not unique. 107 */ 108static bool rproc_name_is_unique(struct udevice *check_dev, 109 const char *check_name) 110{ 111 int ret; 112 113 ret = for_each_remoteproc_device(_rproc_name_is_unique, 114 check_dev, check_name); 115 return ret ? false : true; 116} 117 118/** 119 * rproc_pre_probe() - Pre probe accessor for the uclass 120 * @dev: device for which we are preprobing 121 * 122 * Parses and fills up the uclass pdata for use as needed by core and 123 * remote proc drivers. 124 * 125 * Return: 0 if all wernt ok, else appropriate error value. 126 */ 127static int rproc_pre_probe(struct udevice *dev) 128{ 129 struct dm_rproc_uclass_pdata *uc_pdata; 130 const struct dm_rproc_ops *ops; 131 132 uc_pdata = dev_get_uclass_plat(dev); 133 134 /* See if we need to populate via fdt */ 135 136 if (!dev_get_plat(dev)) { 137#if CONFIG_IS_ENABLED(OF_CONTROL) 138 bool tmp; 139 debug("'%s': using fdt\n", dev->name); 140 uc_pdata->name = dev_read_string(dev, "remoteproc-name"); 141 142 /* Default is internal memory mapped */ 143 uc_pdata->mem_type = RPROC_INTERNAL_MEMORY_MAPPED; 144 tmp = dev_read_bool(dev, "remoteproc-internal-memory-mapped"); 145 if (tmp) 146 uc_pdata->mem_type = RPROC_INTERNAL_MEMORY_MAPPED; 147#else 148 /* Nothing much we can do about this, can we? */ 149 return -EINVAL; 150#endif 151 152 } else { 153 struct dm_rproc_uclass_pdata *pdata = dev_get_plat(dev); 154 155 debug("'%s': using legacy data\n", dev->name); 156 if (pdata->name) 157 uc_pdata->name = pdata->name; 158 uc_pdata->mem_type = pdata->mem_type; 159 uc_pdata->driver_plat_data = pdata->driver_plat_data; 160 } 161 162 /* Else try using device Name */ 163 if (!uc_pdata->name) 164 uc_pdata->name = dev->name; 165 if (!uc_pdata->name) { 166 debug("Unnamed device!"); 167 return -EINVAL; 168 } 169 170 if (!rproc_name_is_unique(dev, uc_pdata->name)) { 171 debug("%s duplicate name '%s'\n", dev->name, uc_pdata->name); 172 return -EINVAL; 173 } 174 175 ops = rproc_get_ops(dev); 176 if (!ops) { 177 debug("%s driver has no ops?\n", dev->name); 178 return -EINVAL; 179 } 180 181 if (!ops->load || !ops->start) { 182 debug("%s driver has missing mandatory ops?\n", dev->name); 183 return -EINVAL; 184 } 185 186 return 0; 187} 188 189/** 190 * rproc_post_probe() - post probe accessor for the uclass 191 * @dev: deivce we finished probing 192 * 193 * initiate init function after the probe is completed. This allows 194 * the remote processor drivers to split up the initializations between 195 * probe and init as needed. 196 * 197 * Return: if the remote proc driver has a init routine, invokes it and 198 * hands over the return value. overall, 0 if all went well, else appropriate 199 * error value. 200 */ 201static int rproc_post_probe(struct udevice *dev) 202{ 203 const struct dm_rproc_ops *ops; 204 205 ops = rproc_get_ops(dev); 206 if (!ops) { 207 debug("%s driver has no ops?\n", dev->name); 208 return -EINVAL; 209 } 210 211 if (ops->init) 212 return ops->init(dev); 213 214 return 0; 215} 216 217/** 218 * rproc_add_res() - After parsing the resource table add the mappings 219 * @dev: device we finished probing 220 * @mapping: rproc_mem_entry for the resource 221 * 222 * Return: if the remote proc driver has a add_res routine, invokes it and 223 * hands over the return value. overall, 0 if all went well, else appropriate 224 * error value. 225 */ 226static int rproc_add_res(struct udevice *dev, struct rproc_mem_entry *mapping) 227{ 228 const struct dm_rproc_ops *ops = rproc_get_ops(dev); 229 230 if (!ops->add_res) 231 return -ENOSYS; 232 233 return ops->add_res(dev, mapping); 234} 235 236/** 237 * rproc_alloc_mem() - After parsing the resource table allocat mem 238 * @dev: device we finished probing 239 * @len: rproc_mem_entry for the resource 240 * @align: alignment for the resource 241 * 242 * Return: if the remote proc driver has a add_res routine, invokes it and 243 * hands over the return value. overall, 0 if all went well, else appropriate 244 * error value. 245 */ 246static void *rproc_alloc_mem(struct udevice *dev, unsigned long len, 247 unsigned long align) 248{ 249 const struct dm_rproc_ops *ops; 250 251 ops = rproc_get_ops(dev); 252 if (!ops) { 253 debug("%s driver has no ops?\n", dev->name); 254 return NULL; 255 } 256 257 if (ops->alloc_mem) 258 return ops->alloc_mem(dev, len, align); 259 260 return NULL; 261} 262 263/** 264 * rproc_config_pagetable() - Configure page table for remote processor 265 * @dev: device we finished probing 266 * @virt: Virtual address of the resource 267 * @phys: Physical address the resource 268 * @len: length the resource 269 * 270 * Return: if the remote proc driver has a add_res routine, invokes it and 271 * hands over the return value. overall, 0 if all went well, else appropriate 272 * error value. 273 */ 274static int rproc_config_pagetable(struct udevice *dev, unsigned int virt, 275 unsigned int phys, unsigned int len) 276{ 277 const struct dm_rproc_ops *ops; 278 279 ops = rproc_get_ops(dev); 280 if (!ops) { 281 debug("%s driver has no ops?\n", dev->name); 282 return -EINVAL; 283 } 284 285 if (ops->config_pagetable) 286 return ops->config_pagetable(dev, virt, phys, len); 287 288 return 0; 289} 290 291UCLASS_DRIVER(rproc) = { 292 .id = UCLASS_REMOTEPROC, 293 .name = "remoteproc", 294 .flags = DM_UC_FLAG_SEQ_ALIAS, 295 .pre_probe = rproc_pre_probe, 296 .post_probe = rproc_post_probe, 297 .per_device_plat_auto = sizeof(struct dm_rproc_uclass_pdata), 298}; 299 300/* Remoteproc subsystem access functions */ 301/** 302 * _rproc_probe_dev() - iteration helper to probe a rproc device 303 * @dev: device to probe 304 * @uc_pdata: uclass data allocated for the device 305 * @data: unused 306 * 307 * Return: 0 if all ok, else appropriate error value. 308 */ 309static int _rproc_probe_dev(struct udevice *dev, 310 struct dm_rproc_uclass_pdata *uc_pdata, 311 const void *data) 312{ 313 int ret; 314 315 ret = device_probe(dev); 316 317 if (ret) 318 debug("%s: Failed to initialize - %d\n", dev->name, ret); 319 return ret; 320} 321 322/** 323 * _rproc_dev_is_probed() - check if the device has been probed 324 * @dev: device to check 325 * @uc_pdata: unused 326 * @data: unused 327 * 328 * Return: -EAGAIN if not probed else return 0 329 */ 330static int _rproc_dev_is_probed(struct udevice *dev, 331 struct dm_rproc_uclass_pdata *uc_pdata, 332 const void *data) 333{ 334 if (dev_get_flags(dev) & DM_FLAG_ACTIVATED) 335 return 0; 336 337 return -EAGAIN; 338} 339 340bool rproc_is_initialized(void) 341{ 342 int ret = for_each_remoteproc_device(_rproc_dev_is_probed, NULL, NULL); 343 return ret ? false : true; 344} 345 346int rproc_init(void) 347{ 348 int ret; 349 350 if (rproc_is_initialized()) { 351 debug("Already initialized\n"); 352 return -EINVAL; 353 } 354 355 ret = for_each_remoteproc_device(_rproc_probe_dev, NULL, NULL); 356 return ret; 357} 358 359int rproc_dev_init(int id) 360{ 361 struct udevice *dev = NULL; 362 int ret; 363 364 ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev); 365 if (ret) { 366 debug("Unknown remote processor id '%d' requested(%d)\n", 367 id, ret); 368 return ret; 369 } 370 371 ret = device_probe(dev); 372 if (ret) 373 debug("%s: Failed to initialize - %d\n", dev->name, ret); 374 375 return ret; 376} 377 378int rproc_load(int id, ulong addr, ulong size) 379{ 380 struct udevice *dev = NULL; 381 struct dm_rproc_uclass_pdata *uc_pdata; 382 const struct dm_rproc_ops *ops; 383 int ret; 384 385 ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev); 386 if (ret) { 387 debug("Unknown remote processor id '%d' requested(%d)\n", 388 id, ret); 389 return ret; 390 } 391 392 uc_pdata = dev_get_uclass_plat(dev); 393 394 ops = rproc_get_ops(dev); 395 if (!ops) { 396 debug("%s driver has no ops?\n", dev->name); 397 return -EINVAL; 398 } 399 400 debug("Loading to '%s' from address 0x%08lX size of %lu bytes\n", 401 uc_pdata->name, addr, size); 402 if (ops->load) 403 return ops->load(dev, addr, size); 404 405 debug("%s: data corruption?? mandatory function is missing!\n", 406 dev->name); 407 408 return -EINVAL; 409}; 410 411/* 412 * Completely internal helper enums.. 413 * Keeping this isolated helps this code evolve independent of other 414 * parts.. 415 */ 416enum rproc_ops { 417 RPROC_START, 418 RPROC_STOP, 419 RPROC_RESET, 420 RPROC_PING, 421 RPROC_RUNNING, 422}; 423 424/** 425 * _rproc_ops_wrapper() - wrapper for invoking remote proc driver callback 426 * @id: id of the remote processor 427 * @op: one of rproc_ops that indicate what operation to invoke 428 * 429 * Most of the checks and verification for remoteproc operations are more 430 * or less same for almost all operations. This allows us to put a wrapper 431 * and use the common checks to allow the driver to function appropriately. 432 * 433 * Return: 0 if all ok, else appropriate error value. 434 */ 435static int _rproc_ops_wrapper(int id, enum rproc_ops op) 436{ 437 struct udevice *dev = NULL; 438 struct dm_rproc_uclass_pdata *uc_pdata; 439 const struct dm_rproc_ops *ops; 440 int (*fn)(struct udevice *dev); 441 bool mandatory = false; 442 char *op_str; 443 int ret; 444 445 ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev); 446 if (ret) { 447 debug("Unknown remote processor id '%d' requested(%d)\n", 448 id, ret); 449 return ret; 450 } 451 452 uc_pdata = dev_get_uclass_plat(dev); 453 454 ops = rproc_get_ops(dev); 455 if (!ops) { 456 debug("%s driver has no ops?\n", dev->name); 457 return -EINVAL; 458 } 459 switch (op) { 460 case RPROC_START: 461 fn = ops->start; 462 mandatory = true; 463 op_str = "Starting"; 464 break; 465 case RPROC_STOP: 466 fn = ops->stop; 467 op_str = "Stopping"; 468 break; 469 case RPROC_RESET: 470 fn = ops->reset; 471 op_str = "Resetting"; 472 break; 473 case RPROC_RUNNING: 474 fn = ops->is_running; 475 op_str = "Checking if running:"; 476 break; 477 case RPROC_PING: 478 fn = ops->ping; 479 op_str = "Pinging"; 480 break; 481 default: 482 debug("what is '%d' operation??\n", op); 483 return -EINVAL; 484 } 485 486 debug("%s %s...\n", op_str, uc_pdata->name); 487 if (fn) 488 return fn(dev); 489 490 if (mandatory) 491 debug("%s: data corruption?? mandatory function is missing!\n", 492 dev->name); 493 494 return -ENOSYS; 495} 496 497int rproc_start(int id) 498{ 499 return _rproc_ops_wrapper(id, RPROC_START); 500}; 501 502int rproc_stop(int id) 503{ 504 return _rproc_ops_wrapper(id, RPROC_STOP); 505}; 506 507int rproc_reset(int id) 508{ 509 return _rproc_ops_wrapper(id, RPROC_RESET); 510}; 511 512int rproc_ping(int id) 513{ 514 return _rproc_ops_wrapper(id, RPROC_PING); 515}; 516 517int rproc_is_running(int id) 518{ 519 return _rproc_ops_wrapper(id, RPROC_RUNNING); 520}; 521 522 523static int handle_trace(struct udevice *dev, struct fw_rsc_trace *rsc, 524 int offset, int avail) 525{ 526 if (sizeof(*rsc) > avail) { 527 debug("trace rsc is truncated\n"); 528 return -EINVAL; 529 } 530 531 /* 532 * make sure reserved bytes are zeroes 533 */ 534 if (rsc->reserved) { 535 debug("trace rsc has non zero reserved bytes\n"); 536 return -EINVAL; 537 } 538 539 debug("trace rsc: da 0x%x, len 0x%x\n", rsc->da, rsc->len); 540 541 return 0; 542} 543 544static int handle_devmem(struct udevice *dev, struct fw_rsc_devmem *rsc, 545 int offset, int avail) 546{ 547 struct rproc_mem_entry *mapping; 548 549 if (sizeof(*rsc) > avail) { 550 debug("devmem rsc is truncated\n"); 551 return -EINVAL; 552 } 553 554 /* 555 * make sure reserved bytes are zeroes 556 */ 557 if (rsc->reserved) { 558 debug("devmem rsc has non zero reserved bytes\n"); 559 return -EINVAL; 560 } 561 562 debug("devmem rsc: pa 0x%x, da 0x%x, len 0x%x\n", 563 rsc->pa, rsc->da, rsc->len); 564 565 rproc_config_pagetable(dev, rsc->da, rsc->pa, rsc->len); 566 567 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); 568 if (!mapping) 569 return -ENOMEM; 570 571 /* 572 * We'll need this info later when we'll want to unmap everything 573 * (e.g. on shutdown). 574 * 575 * We can't trust the remote processor not to change the resource 576 * table, so we must maintain this info independently. 577 */ 578 mapping->dma = rsc->pa; 579 mapping->da = rsc->da; 580 mapping->len = rsc->len; 581 rproc_add_res(dev, mapping); 582 583 debug("mapped devmem pa 0x%x, da 0x%x, len 0x%x\n", 584 rsc->pa, rsc->da, rsc->len); 585 586 return 0; 587} 588 589static int handle_carveout(struct udevice *dev, struct fw_rsc_carveout *rsc, 590 int offset, int avail) 591{ 592 struct rproc_mem_entry *mapping; 593 594 if (sizeof(*rsc) > avail) { 595 debug("carveout rsc is truncated\n"); 596 return -EINVAL; 597 } 598 599 /* 600 * make sure reserved bytes are zeroes 601 */ 602 if (rsc->reserved) { 603 debug("carveout rsc has non zero reserved bytes\n"); 604 return -EINVAL; 605 } 606 607 debug("carveout rsc: da %x, pa %x, len %x, flags %x\n", 608 rsc->da, rsc->pa, rsc->len, rsc->flags); 609 610 rsc->pa = (uintptr_t)rproc_alloc_mem(dev, rsc->len, 8); 611 if (!rsc->pa) { 612 debug 613 ("failed to allocate carveout rsc: da %x, pa %x, len %x, flags %x\n", 614 rsc->da, rsc->pa, rsc->len, rsc->flags); 615 return -ENOMEM; 616 } 617 rproc_config_pagetable(dev, rsc->da, rsc->pa, rsc->len); 618 619 /* 620 * Ok, this is non-standard. 621 * 622 * Sometimes we can't rely on the generic iommu-based DMA API 623 * to dynamically allocate the device address and then set the IOMMU 624 * tables accordingly, because some remote processors might 625 * _require_ us to use hard coded device addresses that their 626 * firmware was compiled with. 627 * 628 * In this case, we must use the IOMMU API directly and map 629 * the memory to the device address as expected by the remote 630 * processor. 631 * 632 * Obviously such remote processor devices should not be configured 633 * to use the iommu-based DMA API: we expect 'dma' to contain the 634 * physical address in this case. 635 */ 636 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); 637 if (!mapping) 638 return -ENOMEM; 639 640 /* 641 * We'll need this info later when we'll want to unmap 642 * everything (e.g. on shutdown). 643 * 644 * We can't trust the remote processor not to change the 645 * resource table, so we must maintain this info independently. 646 */ 647 mapping->dma = rsc->pa; 648 mapping->da = rsc->da; 649 mapping->len = rsc->len; 650 rproc_add_res(dev, mapping); 651 652 debug("carveout mapped 0x%x to 0x%x\n", rsc->da, rsc->pa); 653 654 return 0; 655} 656 657#define RPROC_PAGE_SHIFT 12 658#define RPROC_PAGE_SIZE BIT(RPROC_PAGE_SHIFT) 659#define RPROC_PAGE_ALIGN(x) (((x) + (RPROC_PAGE_SIZE - 1)) & ~(RPROC_PAGE_SIZE - 1)) 660 661static int alloc_vring(struct udevice *dev, struct fw_rsc_vdev *rsc, int i) 662{ 663 struct fw_rsc_vdev_vring *vring = &rsc->vring[i]; 664 int size; 665 int order; 666 void *pa; 667 668 debug("vdev rsc: vring%d: da %x, qsz %d, align %d\n", 669 i, vring->da, vring->num, vring->align); 670 671 /* 672 * verify queue size and vring alignment are sane 673 */ 674 if (!vring->num || !vring->align) { 675 debug("invalid qsz (%d) or alignment (%d)\n", vring->num, 676 vring->align); 677 return -EINVAL; 678 } 679 680 /* 681 * actual size of vring (in bytes) 682 */ 683 size = RPROC_PAGE_ALIGN(vring_size(vring->num, vring->align)); 684 order = vring->align >> RPROC_PAGE_SHIFT; 685 686 pa = rproc_alloc_mem(dev, size, order); 687 if (!pa) { 688 debug("failed to allocate vring rsc\n"); 689 return -ENOMEM; 690 } 691 debug("alloc_mem(%#x, %d): %p\n", size, order, pa); 692 vring->da = (uintptr_t)pa; 693 694 return 0; 695} 696 697static int handle_vdev(struct udevice *dev, struct fw_rsc_vdev *rsc, 698 int offset, int avail) 699{ 700 int i, ret; 701 void *pa; 702 703 /* 704 * make sure resource isn't truncated 705 */ 706 if (sizeof(*rsc) + rsc->num_of_vrings * sizeof(struct fw_rsc_vdev_vring) 707 + rsc->config_len > avail) { 708 debug("vdev rsc is truncated\n"); 709 return -EINVAL; 710 } 711 712 /* 713 * make sure reserved bytes are zeroes 714 */ 715 if (rsc->reserved[0] || rsc->reserved[1]) { 716 debug("vdev rsc has non zero reserved bytes\n"); 717 return -EINVAL; 718 } 719 720 debug("vdev rsc: id %d, dfeatures %x, cfg len %d, %d vrings\n", 721 rsc->id, rsc->dfeatures, rsc->config_len, rsc->num_of_vrings); 722 723 /* 724 * we currently support only two vrings per rvdev 725 */ 726 if (rsc->num_of_vrings > 2) { 727 debug("too many vrings: %d\n", rsc->num_of_vrings); 728 return -EINVAL; 729 } 730 731 /* 732 * allocate the vrings 733 */ 734 for (i = 0; i < rsc->num_of_vrings; i++) { 735 ret = alloc_vring(dev, rsc, i); 736 if (ret) 737 goto alloc_error; 738 } 739 740 pa = rproc_alloc_mem(dev, RPMSG_TOTAL_BUF_SPACE, 6); 741 if (!pa) { 742 debug("failed to allocate vdev rsc\n"); 743 return -ENOMEM; 744 } 745 debug("vring buffer alloc_mem(%#x, 6): %p\n", RPMSG_TOTAL_BUF_SPACE, 746 pa); 747 748 return 0; 749 750 alloc_error: 751 return ret; 752} 753 754/* 755 * A lookup table for resource handlers. The indices are defined in 756 * enum fw_resource_type. 757 */ 758static handle_resource_t loading_handlers[RSC_LAST] = { 759 [RSC_CARVEOUT] = (handle_resource_t)handle_carveout, 760 [RSC_DEVMEM] = (handle_resource_t)handle_devmem, 761 [RSC_TRACE] = (handle_resource_t)handle_trace, 762 [RSC_VDEV] = (handle_resource_t)handle_vdev, 763}; 764 765/* 766 * handle firmware resource entries before booting the remote processor 767 */ 768static int handle_resources(struct udevice *dev, int len, 769 handle_resource_t handlers[RSC_LAST]) 770{ 771 handle_resource_t handler; 772 int ret = 0, i; 773 774 for (i = 0; i < rsc_table->num; i++) { 775 int offset = rsc_table->offset[i]; 776 struct fw_rsc_hdr *hdr = (void *)rsc_table + offset; 777 int avail = len - offset - sizeof(*hdr); 778 void *rsc = (void *)hdr + sizeof(*hdr); 779 780 /* 781 * make sure table isn't truncated 782 */ 783 if (avail < 0) { 784 debug("rsc table is truncated\n"); 785 return -EINVAL; 786 } 787 788 debug("rsc: type %d\n", hdr->type); 789 790 if (hdr->type >= RSC_LAST) { 791 debug("unsupported resource %d\n", hdr->type); 792 continue; 793 } 794 795 handler = handlers[hdr->type]; 796 if (!handler) 797 continue; 798 799 ret = handler(dev, rsc, offset + sizeof(*hdr), avail); 800 if (ret) 801 break; 802 } 803 804 return ret; 805} 806 807static int 808handle_intmem_to_l3_mapping(struct udevice *dev, 809 struct rproc_intmem_to_l3_mapping *l3_mapping) 810{ 811 u32 i = 0; 812 813 for (i = 0; i < l3_mapping->num_entries; i++) { 814 struct l3_map *curr_map = &l3_mapping->mappings[i]; 815 struct rproc_mem_entry *mapping; 816 817 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); 818 if (!mapping) 819 return -ENOMEM; 820 821 mapping->dma = curr_map->l3_addr; 822 mapping->da = curr_map->priv_addr; 823 mapping->len = curr_map->len; 824 rproc_add_res(dev, mapping); 825 } 826 827 return 0; 828} 829 830static Elf32_Shdr *rproc_find_table(unsigned int addr) 831{ 832 Elf32_Ehdr *ehdr; /* Elf header structure pointer */ 833 Elf32_Shdr *shdr; /* Section header structure pointer */ 834 Elf32_Shdr sectionheader; 835 int i; 836 u8 *elf_data; 837 char *name_table; 838 struct resource_table *ptable; 839 840 ehdr = (Elf32_Ehdr *)(uintptr_t)addr; 841 elf_data = (u8 *)ehdr; 842 shdr = (Elf32_Shdr *)(elf_data + ehdr->e_shoff); 843 memcpy(§ionheader, &shdr[ehdr->e_shstrndx], sizeof(sectionheader)); 844 name_table = (char *)(elf_data + sectionheader.sh_offset); 845 846 for (i = 0; i < ehdr->e_shnum; i++, shdr++) { 847 memcpy(§ionheader, shdr, sizeof(sectionheader)); 848 u32 size = sectionheader.sh_size; 849 u32 offset = sectionheader.sh_offset; 850 851 if (strcmp 852 (name_table + sectionheader.sh_name, ".resource_table")) 853 continue; 854 855 ptable = (struct resource_table *)(elf_data + offset); 856 857 /* 858 * make sure table has at least the header 859 */ 860 if (sizeof(struct resource_table) > size) { 861 debug("header-less resource table\n"); 862 return NULL; 863 } 864 865 /* 866 * we don't support any version beyond the first 867 */ 868 if (ptable->ver != 1) { 869 debug("unsupported fw ver: %d\n", ptable->ver); 870 return NULL; 871 } 872 873 /* 874 * make sure reserved bytes are zeroes 875 */ 876 if (ptable->reserved[0] || ptable->reserved[1]) { 877 debug("non zero reserved bytes\n"); 878 return NULL; 879 } 880 881 /* 882 * make sure the offsets array isn't truncated 883 */ 884 if (ptable->num * sizeof(ptable->offset[0]) + 885 sizeof(struct resource_table) > size) { 886 debug("resource table incomplete\n"); 887 return NULL; 888 } 889 890 return shdr; 891 } 892 893 return NULL; 894} 895 896struct resource_table *rproc_find_resource_table(struct udevice *dev, 897 unsigned int addr, 898 int *tablesz) 899{ 900 Elf32_Shdr *shdr; 901 Elf32_Shdr sectionheader; 902 struct resource_table *ptable; 903 u8 *elf_data = (u8 *)(uintptr_t)addr; 904 905 shdr = rproc_find_table(addr); 906 if (!shdr) { 907 debug("%s: failed to get resource section header\n", __func__); 908 return NULL; 909 } 910 911 memcpy(§ionheader, shdr, sizeof(sectionheader)); 912 ptable = (struct resource_table *)(elf_data + sectionheader.sh_offset); 913 if (tablesz) 914 *tablesz = sectionheader.sh_size; 915 916 return ptable; 917} 918 919unsigned long rproc_parse_resource_table(struct udevice *dev, struct rproc *cfg) 920{ 921 struct resource_table *ptable = NULL; 922 int tablesz; 923 int ret; 924 unsigned long addr; 925 926 addr = cfg->load_addr; 927 928 ptable = rproc_find_resource_table(dev, addr, &tablesz); 929 if (!ptable) { 930 debug("%s : failed to find resource table\n", __func__); 931 return 0; 932 } 933 934 debug("%s : found resource table\n", __func__); 935 rsc_table = kzalloc(tablesz, GFP_KERNEL); 936 if (!rsc_table) { 937 debug("resource table alloc failed!\n"); 938 return 0; 939 } 940 941 /* 942 * Copy the resource table into a local buffer before handling the 943 * resource table. 944 */ 945 memcpy(rsc_table, ptable, tablesz); 946 if (cfg->intmem_to_l3_mapping) 947 handle_intmem_to_l3_mapping(dev, cfg->intmem_to_l3_mapping); 948 ret = handle_resources(dev, tablesz, loading_handlers); 949 if (ret) { 950 debug("handle_resources failed: %d\n", ret); 951 return 0; 952 } 953 954 /* 955 * Instead of trying to mimic the kernel flow of copying the 956 * processed resource table into its post ELF load location in DDR 957 * copying it into its original location. 958 */ 959 memcpy(ptable, rsc_table, tablesz); 960 free(rsc_table); 961 rsc_table = NULL; 962 963 return 1; 964} 965 966int rproc_set_firmware(struct udevice *rproc_dev, const char *fw_name) 967{ 968 struct dm_rproc_uclass_pdata *uc_pdata; 969 int len; 970 char *p; 971 972 if (!rproc_dev || !fw_name) 973 return -EINVAL; 974 975 uc_pdata = dev_get_uclass_plat(rproc_dev); 976 if (!uc_pdata) 977 return -EINVAL; 978 979 len = strcspn(fw_name, "\n"); 980 if (!len) { 981 debug("invalid firmware name\n"); 982 return -EINVAL; 983 } 984 985 if (uc_pdata->fw_name) 986 free(uc_pdata->fw_name); 987 988 p = strndup(fw_name, len); 989 if (!p) 990 return -ENOMEM; 991 992 uc_pdata->fw_name = p; 993 994 return 0; 995} 996 997#if CONFIG_IS_ENABLED(FS_LOADER) 998int rproc_boot(struct udevice *rproc_dev) 999{ 1000 struct dm_rproc_uclass_pdata *uc_pdata; 1001 struct udevice *fs_loader; 1002 int core_id, ret = 0; 1003 char *firmware; 1004 void *addr; 1005 1006 if (!rproc_dev) 1007 return -EINVAL; 1008 1009 uc_pdata = dev_get_uclass_plat(rproc_dev); 1010 if (!uc_pdata) 1011 return -EINVAL; 1012 1013 core_id = dev_seq(rproc_dev); 1014 firmware = uc_pdata->fw_name; 1015 if (!firmware) { 1016 debug("No firmware name set for rproc core %d\n", core_id); 1017 return -EINVAL; 1018 } 1019 1020 /* Initialize all rproc cores */ 1021 if (!rproc_is_initialized()) { 1022 ret = rproc_init(); 1023 if (ret) { 1024 debug("rproc_init() failed: %d\n", ret); 1025 return ret; 1026 } 1027 } 1028 1029 /* Loading firmware to a given address */ 1030 ret = get_fs_loader(&fs_loader); 1031 if (ret) { 1032 debug("could not get fs loader: %d\n", ret); 1033 return ret; 1034 } 1035 1036 if (CONFIG_REMOTEPROC_MAX_FW_SIZE) { 1037 addr = malloc(CONFIG_REMOTEPROC_MAX_FW_SIZE); 1038 if (!addr) 1039 return -ENOMEM; 1040 } else { 1041 debug("CONFIG_REMOTEPROC_MAX_FW_SIZE not defined\n"); 1042 return -EINVAL; 1043 } 1044 1045 ret = request_firmware_into_buf(fs_loader, firmware, addr, CONFIG_REMOTEPROC_MAX_FW_SIZE, 1046 0); 1047 if (ret < 0) { 1048 debug("could not request %s: %d\n", firmware, ret); 1049 goto free_buffer; 1050 } 1051 1052 ret = rproc_load(core_id, (ulong)addr, ret); 1053 if (ret) { 1054 debug("failed to load %s to rproc core %d from addr 0x%08lX err %d\n", 1055 uc_pdata->fw_name, core_id, (ulong)addr, ret); 1056 goto free_buffer; 1057 } 1058 1059 ret = rproc_start(core_id); 1060 if (ret) 1061 debug("failed to start rproc core %d\n", core_id); 1062 1063free_buffer: 1064 free(addr); 1065 return ret; 1066} 1067#endif 1068