aboutsummaryrefslogtreecommitdiff
path: root/applications/message_handler_openamp/remoteproc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'applications/message_handler_openamp/remoteproc.cpp')
-rw-r--r--applications/message_handler_openamp/remoteproc.cpp107
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, &region);
-
- metal_io_init(&region,
- 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 &region) {
-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, &region);
+ metal_io_init(&region, (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();
}