/* * SPDX-FileCopyrightText: Copyright 2022-2023 Arm Limited and/or its affiliates * * 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 #include #include #include #include #include #include /***************************************************************************** * Resource table *****************************************************************************/ struct ResourceTable { static constexpr uint32_t VERSION = 1; #if defined(REMOTEPROC_TRACE_BUFFER) static constexpr uint32_t NUM_RESOURCES = 3; #else static constexpr uint32_t NUM_RESOURCES = 2; #endif static constexpr uint32_t NUM_VRINGS = 2; static constexpr uint32_t VRING_ALIGN = 0x100; static constexpr uint32_t VRING_SIZE = 0x08; static constexpr uint32_t RESERVED = 0; resource_table table; uint32_t offset[NUM_RESOURCES]; #if defined(REMOTEPROC_TRACE_BUFFER) fw_rsc_trace trace; #endif fw_rsc_vdev vdev; fw_rsc_vdev_vring vring[NUM_VRINGS]; fw_rsc_carveout carveout; } __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; };