diff options
Diffstat (limited to 'applications/message_handler_openamp/remoteproc.hpp')
-rw-r--r-- | applications/message_handler_openamp/remoteproc.hpp | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/applications/message_handler_openamp/remoteproc.hpp b/applications/message_handler_openamp/remoteproc.hpp new file mode 100644 index 0000000..2f16e24 --- /dev/null +++ b/applications/message_handler_openamp/remoteproc.hpp @@ -0,0 +1,200 @@ +/* + * 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 + * not use _this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +/***************************************************************************** + * Includes + *****************************************************************************/ + +#include <FreeRTOS.h> +#include <queue.h> +#include <semphr.h> + +#include <metal/alloc.h> +#include <openamp/open_amp.h> +#include <openamp/remoteproc.h> + +#include <mailbox.hpp> + +/***************************************************************************** + * Resource table + *****************************************************************************/ + +struct ResourceTable { + static constexpr uint32_t VERSION = 1; + static constexpr uint32_t NUM_RESOURCES = 2; + static constexpr uint32_t NUM_VRINGS = 2; + static constexpr uint32_t VRING_ALIGN = 0x100; + // static constexpr uint32_t VRING_SIZE = 0x10; + static constexpr uint32_t RESERVED = 0; + + resource_table table; + uint32_t offset[NUM_RESOURCES]; + fw_rsc_vdev vdev; + fw_rsc_vdev_vring vring[NUM_VRINGS]; + fw_rsc_carveout carveout; + + // clang-format off + constexpr ResourceTable(const uint32_t vringSize = 0x100, const uint32_t carveoutSize = 0) : + table { + VERSION, + NUM_RESOURCES, + { RESERVED, RESERVED }, + {} + }, + offset { + offsetof(ResourceTable, vdev), + offsetof(ResourceTable, carveout), + }, + vdev { + RSC_VDEV, + VIRTIO_ID_RPMSG, + 2, // Notify ID + 1 << VIRTIO_RPMSG_F_NS, + 0, + 0, + 0, + NUM_VRINGS, + { 0, RESERVED }, + {} + }, + vring { + { + FW_RSC_U32_ADDR_ANY, + VRING_ALIGN, + vringSize, + 1, + RESERVED + }, + { + FW_RSC_U32_ADDR_ANY, + VRING_ALIGN, + vringSize, + 2, + RESERVED + } + }, + carveout { + RSC_CARVEOUT, + FW_RSC_U32_ADDR_ANY, + FW_RSC_U32_ADDR_ANY, + carveoutSize, + 0, + RESERVED, + "TFLM arena" + } + {} + // clang-format off +} __attribute__((packed)); + +/***************************************************************************** + * MetalIO + *****************************************************************************/ + +class MetalIO { +public: + MetalIO(); + + remoteproc_mem *operator&(); + +private: + static metal_phys_addr_t offsetToPhys(metal_io_region *io, unsigned long offset); + static unsigned long physToOffset(metal_io_region *io, metal_phys_addr_t phys); + + metal_io_ops ops; + metal_io_region region; + remoteproc_mem mem; +}; + +/***************************************************************************** + * RProc + *****************************************************************************/ + +class RProc { +public: + RProc(Mailbox::Mailbox &_mailbox, resource_table &table, size_t tableSize, MetalIO &_mem); + ~RProc(); + + remoteproc *getRProc(); + virtio_device *getVDev(); + +private: + // IRQ notification callback + static void mailboxCallback(void *userArg); + + // Notification task handling virtio messages + static void notifyTask(void *param); + + // Remote proc ops + static struct remoteproc *init(remoteproc *rproc, const remoteproc_ops *ops, void *arg); + static void remove(remoteproc *rproc); + static void *mmap(remoteproc *rproc, + metal_phys_addr_t *pa, + metal_phys_addr_t *da, + size_t size, + unsigned int attribute, + metal_io_region **io); + static int notify(remoteproc *rproc, uint32_t id); + static struct remoteproc_mem *getMem(remoteproc *rproc, + const char *name, + metal_phys_addr_t pa, + metal_phys_addr_t da, + void *va, + size_t size, + remoteproc_mem *buf); + + // IRQ notification + Mailbox::Mailbox &mailbox; + + // Remoteproc + MetalIO &mem; + remoteproc rproc; + remoteproc_ops ops; + virtio_device *vdev; + + // FreeRTOS + SemaphoreHandle_t notifySemaphore; + TaskHandle_t notifyHandle; +}; + +/***************************************************************************** + * Rpmsg + *****************************************************************************/ + +class Rpmsg { +public: + Rpmsg(RProc &rproc, const char *const name); + + int send(void *data, size_t len, uint32_t dst = 0); + void *physicalToVirtual(metal_phys_addr_t pa); + +protected: + virtual int handleMessage(void *data, size_t len, uint32_t src); + +private: + // RPMsg ops + static void rpmsgNsBind(rpmsg_device *rdev, const char *name, uint32_t dest); + static void nsUnbindCallback(rpmsg_endpoint *ept); + static int endpointCallback(rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv); + + // RPMsg + rpmsg_virtio_device rvdev; + rpmsg_device *rdev; + rpmsg_endpoint endpoint; +}; |