blob: eec7b44eb214c7cb752524c1cf9941e9f6b889c1 [file] [log] [blame]
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +01001/*
2 * SPDX-FileCopyrightText: Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use _this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#pragma once
20
21/*****************************************************************************
22 * Includes
23 *****************************************************************************/
24
25#include <FreeRTOS.h>
26#include <queue.h>
27#include <semphr.h>
28
29#include <metal/alloc.h>
30#include <openamp/open_amp.h>
31#include <openamp/remoteproc.h>
32
33#include <mailbox.hpp>
34
35/*****************************************************************************
36 * Resource table
37 *****************************************************************************/
38
39struct ResourceTable {
Ledion Dajab00e4ed2023-05-22 10:45:31 +020040 static constexpr uint32_t VERSION = 1;
41#if defined(REMOTEPROC_TRACE_BUFFER)
42 static constexpr uint32_t NUM_RESOURCES = 3;
43#else
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +010044 static constexpr uint32_t NUM_RESOURCES = 2;
Ledion Dajab00e4ed2023-05-22 10:45:31 +020045#endif
46 static constexpr uint32_t NUM_VRINGS = 2;
47 static constexpr uint32_t VRING_ALIGN = 0x100;
48 static constexpr uint32_t VRING_SIZE = 0x08;
49 static constexpr uint32_t RESERVED = 0;
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +010050
51 resource_table table;
52 uint32_t offset[NUM_RESOURCES];
Ledion Dajab00e4ed2023-05-22 10:45:31 +020053#if defined(REMOTEPROC_TRACE_BUFFER)
54 fw_rsc_trace trace;
55#endif
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +010056 fw_rsc_vdev vdev;
57 fw_rsc_vdev_vring vring[NUM_VRINGS];
58 fw_rsc_carveout carveout;
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +010059} __attribute__((packed));
60
61/*****************************************************************************
62 * MetalIO
63 *****************************************************************************/
64
65class MetalIO {
66public:
67 MetalIO();
68
69 remoteproc_mem *operator&();
70
71private:
72 static metal_phys_addr_t offsetToPhys(metal_io_region *io, unsigned long offset);
73 static unsigned long physToOffset(metal_io_region *io, metal_phys_addr_t phys);
74
75 metal_io_ops ops;
76 metal_io_region region;
77 remoteproc_mem mem;
78};
79
80/*****************************************************************************
81 * RProc
82 *****************************************************************************/
83
84class RProc {
85public:
86 RProc(Mailbox::Mailbox &_mailbox, resource_table &table, size_t tableSize, MetalIO &_mem);
87 ~RProc();
88
89 remoteproc *getRProc();
90 virtio_device *getVDev();
91
92private:
93 // IRQ notification callback
94 static void mailboxCallback(void *userArg);
95
96 // Notification task handling virtio messages
97 static void notifyTask(void *param);
98
99 // Remote proc ops
100 static struct remoteproc *init(remoteproc *rproc, const remoteproc_ops *ops, void *arg);
101 static void remove(remoteproc *rproc);
102 static void *mmap(remoteproc *rproc,
103 metal_phys_addr_t *pa,
104 metal_phys_addr_t *da,
105 size_t size,
106 unsigned int attribute,
107 metal_io_region **io);
108 static int notify(remoteproc *rproc, uint32_t id);
109 static struct remoteproc_mem *getMem(remoteproc *rproc,
110 const char *name,
111 metal_phys_addr_t pa,
112 metal_phys_addr_t da,
113 void *va,
114 size_t size,
115 remoteproc_mem *buf);
116
117 // IRQ notification
118 Mailbox::Mailbox &mailbox;
119
120 // Remoteproc
121 MetalIO &mem;
122 remoteproc rproc;
123 remoteproc_ops ops;
124 virtio_device *vdev;
125
126 // FreeRTOS
127 SemaphoreHandle_t notifySemaphore;
128 TaskHandle_t notifyHandle;
129};
130
131/*****************************************************************************
132 * Rpmsg
133 *****************************************************************************/
134
135class Rpmsg {
136public:
137 Rpmsg(RProc &rproc, const char *const name);
138
139 int send(void *data, size_t len, uint32_t dst = 0);
140 void *physicalToVirtual(metal_phys_addr_t pa);
141
142protected:
143 virtual int handleMessage(void *data, size_t len, uint32_t src);
144
145private:
146 // RPMsg ops
147 static void rpmsgNsBind(rpmsg_device *rdev, const char *name, uint32_t dest);
148 static void nsUnbindCallback(rpmsg_endpoint *ept);
149 static int endpointCallback(rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv);
150
151 // RPMsg
152 rpmsg_virtio_device rvdev;
153 rpmsg_device *rdev;
154 rpmsg_endpoint endpoint;
155};