blob: 2f16e2453a53ef81e4140e12490bb724b1725da8 [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 {
40 static constexpr uint32_t VERSION = 1;
41 static constexpr uint32_t NUM_RESOURCES = 2;
42 static constexpr uint32_t NUM_VRINGS = 2;
43 static constexpr uint32_t VRING_ALIGN = 0x100;
44 // static constexpr uint32_t VRING_SIZE = 0x10;
45 static constexpr uint32_t RESERVED = 0;
46
47 resource_table table;
48 uint32_t offset[NUM_RESOURCES];
49 fw_rsc_vdev vdev;
50 fw_rsc_vdev_vring vring[NUM_VRINGS];
51 fw_rsc_carveout carveout;
52
53 // clang-format off
54 constexpr ResourceTable(const uint32_t vringSize = 0x100, const uint32_t carveoutSize = 0) :
55 table {
56 VERSION,
57 NUM_RESOURCES,
58 { RESERVED, RESERVED },
59 {}
60 },
61 offset {
62 offsetof(ResourceTable, vdev),
63 offsetof(ResourceTable, carveout),
64 },
65 vdev {
66 RSC_VDEV,
67 VIRTIO_ID_RPMSG,
68 2, // Notify ID
69 1 << VIRTIO_RPMSG_F_NS,
70 0,
71 0,
72 0,
73 NUM_VRINGS,
74 { 0, RESERVED },
75 {}
76 },
77 vring {
78 {
79 FW_RSC_U32_ADDR_ANY,
80 VRING_ALIGN,
81 vringSize,
82 1,
83 RESERVED
84 },
85 {
86 FW_RSC_U32_ADDR_ANY,
87 VRING_ALIGN,
88 vringSize,
89 2,
90 RESERVED
91 }
92 },
93 carveout {
94 RSC_CARVEOUT,
95 FW_RSC_U32_ADDR_ANY,
96 FW_RSC_U32_ADDR_ANY,
97 carveoutSize,
98 0,
99 RESERVED,
100 "TFLM arena"
101 }
102 {}
103 // clang-format off
104} __attribute__((packed));
105
106/*****************************************************************************
107 * MetalIO
108 *****************************************************************************/
109
110class MetalIO {
111public:
112 MetalIO();
113
114 remoteproc_mem *operator&();
115
116private:
117 static metal_phys_addr_t offsetToPhys(metal_io_region *io, unsigned long offset);
118 static unsigned long physToOffset(metal_io_region *io, metal_phys_addr_t phys);
119
120 metal_io_ops ops;
121 metal_io_region region;
122 remoteproc_mem mem;
123};
124
125/*****************************************************************************
126 * RProc
127 *****************************************************************************/
128
129class RProc {
130public:
131 RProc(Mailbox::Mailbox &_mailbox, resource_table &table, size_t tableSize, MetalIO &_mem);
132 ~RProc();
133
134 remoteproc *getRProc();
135 virtio_device *getVDev();
136
137private:
138 // IRQ notification callback
139 static void mailboxCallback(void *userArg);
140
141 // Notification task handling virtio messages
142 static void notifyTask(void *param);
143
144 // Remote proc ops
145 static struct remoteproc *init(remoteproc *rproc, const remoteproc_ops *ops, void *arg);
146 static void remove(remoteproc *rproc);
147 static void *mmap(remoteproc *rproc,
148 metal_phys_addr_t *pa,
149 metal_phys_addr_t *da,
150 size_t size,
151 unsigned int attribute,
152 metal_io_region **io);
153 static int notify(remoteproc *rproc, uint32_t id);
154 static struct remoteproc_mem *getMem(remoteproc *rproc,
155 const char *name,
156 metal_phys_addr_t pa,
157 metal_phys_addr_t da,
158 void *va,
159 size_t size,
160 remoteproc_mem *buf);
161
162 // IRQ notification
163 Mailbox::Mailbox &mailbox;
164
165 // Remoteproc
166 MetalIO &mem;
167 remoteproc rproc;
168 remoteproc_ops ops;
169 virtio_device *vdev;
170
171 // FreeRTOS
172 SemaphoreHandle_t notifySemaphore;
173 TaskHandle_t notifyHandle;
174};
175
176/*****************************************************************************
177 * Rpmsg
178 *****************************************************************************/
179
180class Rpmsg {
181public:
182 Rpmsg(RProc &rproc, const char *const name);
183
184 int send(void *data, size_t len, uint32_t dst = 0);
185 void *physicalToVirtual(metal_phys_addr_t pa);
186
187protected:
188 virtual int handleMessage(void *data, size_t len, uint32_t src);
189
190private:
191 // RPMsg ops
192 static void rpmsgNsBind(rpmsg_device *rdev, const char *name, uint32_t dest);
193 static void nsUnbindCallback(rpmsg_endpoint *ept);
194 static int endpointCallback(rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv);
195
196 // RPMsg
197 rpmsg_virtio_device rvdev;
198 rpmsg_device *rdev;
199 rpmsg_endpoint endpoint;
200};