diff options
Diffstat (limited to 'applications/message_handler_openamp/remoteproc.cpp')
-rw-r--r-- | applications/message_handler_openamp/remoteproc.cpp | 107 |
1 files changed, 52 insertions, 55 deletions
diff --git a/applications/message_handler_openamp/remoteproc.cpp b/applications/message_handler_openamp/remoteproc.cpp index f355634..8fda69b 100644 --- a/applications/message_handler_openamp/remoteproc.cpp +++ b/applications/message_handler_openamp/remoteproc.cpp @@ -1,6 +1,5 @@ /* * SPDX-FileCopyrightText: Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> - * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may @@ -26,66 +25,39 @@ #include <ethosu_log.h> -/***************************************************************************** - * MetalIO - *****************************************************************************/ - -extern "C" { - -__attribute__((weak)) void *ethosu_phys_to_virt(const uint64_t pa) { - return reinterpret_cast<void *>(pa); -} -} - -MetalIO::MetalIO() : - ops{.read = nullptr, - .write = nullptr, - .block_read = nullptr, - .block_write = nullptr, - .block_set = nullptr, - .close = nullptr, - .offset_to_phys = nullptr, - .phys_to_offset = physToOffset} { - remoteproc_init_mem(&mem, "shm", 0, 0, 0xffffffff, ®ion); - - metal_io_init(®ion, - reinterpret_cast<void *>(0), /* virt */ - &mem.pa, /* physmap */ - 0xffffffff, /* size */ - -1L, /* pagemask */ - 0, /* attributes */ - &ops); /* ops */ -} - -remoteproc_mem *MetalIO::operator&() { - return &mem; -} +namespace { +void setupRProcMem(remoteproc &rproc, + metal_phys_addr_t pa, + metal_phys_addr_t da, + size_t size, + remoteproc_mem &mem, + metal_io_region ®ion) { -unsigned long MetalIO::physToOffset(metal_io_region *io, metal_phys_addr_t pa) { - auto offset = reinterpret_cast<unsigned long>(ethosu_phys_to_virt(pa)); - LOG_DEBUG("Translate PA to offset. pa=%lx, offset=%lx", pa, offset); - return offset; + remoteproc_init_mem(&mem, nullptr, pa, da, size, ®ion); + metal_io_init(®ion, (void *)da, &mem.pa, size, -1, 0, nullptr); + remoteproc_add_mem(&rproc, &mem); } +}; // namespace /***************************************************************************** * RProc *****************************************************************************/ -RProc::RProc(Mailbox::Mailbox &_mailbox, resource_table &table, size_t tableSize, MetalIO &_mem) : - mailbox(_mailbox), mem(_mem), +RProc::RProc(Mailbox::Mailbox &_mailbox, resource_table &table, size_t tableSize) : + mailbox(_mailbox), ops{ - .init = init, // initialize the remoteproc instance - .remove = remove, // remove the remoteproc instance - .mmap = nullptr, // memory mapped the memory with physical address as input - .handle_rsc = nullptr, // handle the vendor specific resource - .config = nullptr, // configure the remoteproc to make it ready to load and run executable - .start = nullptr, // kick the remoteproc to run application + .init = init, // initialize the remoteproc instance + .remove = remove, // remove the remoteproc instance + .mmap = nullptr, // memory mapped the memory with physical address as input + .handle_rsc = handle_rsc, // handle the vendor specific resource + .config = nullptr, // configure the remoteproc to make it ready to load and run executable + .start = nullptr, // kick the remoteproc to run application .stop = nullptr, // stop the remoteproc from running application, the resource such as memory may not be off. .shutdown = nullptr, // shutdown the remoteproc and release its resources. .notify = notify, // notify the remote .get_mem = nullptr, // get remoteproc memory I/O region. }, - vdev(nullptr), notifySemaphore(xSemaphoreCreateBinary()) { + vdev(nullptr), mems(), regions(), notifySemaphore(xSemaphoreCreateBinary()) { mailbox.registerCallback(mailboxCallback, static_cast<void *>(this)); if (!remoteproc_init(&rproc, &ops, this)) { @@ -93,6 +65,12 @@ RProc::RProc(Mailbox::Mailbox &_mailbox, resource_table &table, size_t tableSize abort(); } + // Setup memory region for resource table + const metal_phys_addr_t rsc_addr = reinterpret_cast<metal_phys_addr_t>(&table); + // No translation is needed for rsc_addr because it already contains the DA + // so PA is set to DA + setupRProcMem(rproc, rsc_addr, rsc_addr, tableSize, rsc_mem, rsc_region); + int ret = remoteproc_set_rsc_table(&rproc, &table, tableSize); if (ret) { LOG_ERR("Failed to set resource table. ret=%d", ret); @@ -148,15 +126,33 @@ void RProc::notifyTask(void *param) { struct remoteproc *RProc::init(remoteproc *rproc, const remoteproc_ops *ops, void *arg) { LOG_DEBUG(""); - auto _this = static_cast<RProc *>(arg); - rproc->ops = ops; rproc->priv = arg; - remoteproc_add_mem(rproc, &_this->mem); return rproc; } +int RProc::handle_rsc(remoteproc *rproc, void *rsc, size_t len) { + auto _this = static_cast<RProc *>(rproc->priv); + struct fw_rsc_mapping *mapping = static_cast<fw_rsc_mapping *>(rsc); + + if (mapping->type != RSC_MAPPING) { + LOG_ERR("Unknown resource type %" PRIu32, mapping->type); + return -RPROC_ERR_RSC_TAB_NS; + } + + for (uint32_t i = 0; i < mapping->num_ranges; ++i) { + const fw_rsc_map_range *range = &mapping->range[i]; + if (range->len == 0) { + LOG_DEBUG("Ignored zero length memory map range[%" PRIu32 "]", i); + continue; + } + setupRProcMem(*rproc, range->pa, range->da, range->len, _this->mems[i], _this->regions[i]); + } + + return 0; +} + void RProc::remove(remoteproc *rproc) { LOG_DEBUG(""); } @@ -174,14 +170,15 @@ int RProc::notify(remoteproc *rproc, uint32_t id) { *****************************************************************************/ Rpmsg::Rpmsg(RProc &rproc, const char *const name) { + struct virtio_device *vdev = rproc.getVDev(); - metal_io_region *region = remoteproc_get_io_with_name(rproc.getRProc(), "shm"); - if (!region) { - LOG_ERR("Failed to get shared mem region"); + if (vdev->vrings_num != ResourceTable::NUM_VRINGS) { + LOG_ERR("Invalid number of vrings"); abort(); } - if (rpmsg_init_vdev(&rvdev, rproc.getVDev(), nullptr, region, nullptr)) { + // Vdev can use the same IO region for translations as the vring + if (rpmsg_init_vdev(&rvdev, vdev, nullptr, vdev->vrings_info[0].io, nullptr)) { LOG_ERR("Failed to initialize rpmsg vdev"); abort(); } |