blob: 090a3eaf7861afa6852dc671e8a5ee1371f2be2a [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>
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +01003 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the License); you may
6 * not use _this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#pragma once
19
20/*****************************************************************************
21 * Includes
22 *****************************************************************************/
23
24#include <FreeRTOS.h>
25#include <queue.h>
26#include <semphr.h>
27
28#include <metal/alloc.h>
29#include <openamp/open_amp.h>
30#include <openamp/remoteproc.h>
31
32#include <mailbox.hpp>
33
34/*****************************************************************************
35 * Resource table
36 *****************************************************************************/
37
Mikael Olsson67add212023-05-31 19:00:48 +020038static constexpr uint32_t RSC_MAPPING = RSC_VENDOR_START + 1;
39
40/**
41 * struct fw_rsc_map_range - memory map range
42 * @da: Start device address of the memory address range
43 * @pa: Start physical address of the memory address range
44 * @len: length of memory address range
45 *
46 * Memory range to translate between physical and device addresses.
47 */
48METAL_PACKED_BEGIN
49struct fw_rsc_map_range {
50 uint32_t da;
51 uint32_t pa;
52 uint32_t len;
53} METAL_PACKED_END;
54
55/**
56 * struct fw_rsc_mapping - memory map for address translation
57 * @type: RSC_MAPPING
58 * @num_ranges: Number of ranges in the memory map
59 * @range: Array of the ranges in the memory map
60 *
61 * This resource entry requests the host to provide information for how to
62 * translate between physical and device addresses.
63 */
64METAL_PACKED_BEGIN
65struct fw_rsc_mapping {
66 uint32_t type;
67 uint8_t num_ranges;
68 struct fw_rsc_map_range range[0];
69} METAL_PACKED_END;
70
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +010071struct ResourceTable {
Ledion Dajab00e4ed2023-05-22 10:45:31 +020072 static constexpr uint32_t VERSION = 1;
73#if defined(REMOTEPROC_TRACE_BUFFER)
Mikael Olsson67add212023-05-31 19:00:48 +020074 static constexpr uint32_t NUM_RESOURCES = 4;
Ledion Dajab00e4ed2023-05-22 10:45:31 +020075#else
Mikael Olsson67add212023-05-31 19:00:48 +020076 static constexpr uint32_t NUM_RESOURCES = 3;
Ledion Dajab00e4ed2023-05-22 10:45:31 +020077#endif
Mikael Olsson67add212023-05-31 19:00:48 +020078 static constexpr uint32_t NUM_RANGES = 2;
Ledion Dajab00e4ed2023-05-22 10:45:31 +020079 static constexpr uint32_t NUM_VRINGS = 2;
80 static constexpr uint32_t VRING_ALIGN = 0x100;
81 static constexpr uint32_t VRING_SIZE = 0x08;
82 static constexpr uint32_t RESERVED = 0;
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +010083
84 resource_table table;
85 uint32_t offset[NUM_RESOURCES];
Mikael Olsson67add212023-05-31 19:00:48 +020086 fw_rsc_mapping mapping;
87 fw_rsc_map_range range[NUM_RANGES];
Ledion Dajab00e4ed2023-05-22 10:45:31 +020088#if defined(REMOTEPROC_TRACE_BUFFER)
89 fw_rsc_trace trace;
90#endif
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +010091 fw_rsc_vdev vdev;
92 fw_rsc_vdev_vring vring[NUM_VRINGS];
93 fw_rsc_carveout carveout;
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +010094} __attribute__((packed));
95
96/*****************************************************************************
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +010097 * RProc
98 *****************************************************************************/
99
100class RProc {
101public:
Mikael Olsson67add212023-05-31 19:00:48 +0200102 RProc(Mailbox::Mailbox &_mailbox, resource_table &table, size_t tableSize);
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +0100103 ~RProc();
104
105 remoteproc *getRProc();
106 virtio_device *getVDev();
107
108private:
109 // IRQ notification callback
110 static void mailboxCallback(void *userArg);
111
112 // Notification task handling virtio messages
113 static void notifyTask(void *param);
114
115 // Remote proc ops
116 static struct remoteproc *init(remoteproc *rproc, const remoteproc_ops *ops, void *arg);
117 static void remove(remoteproc *rproc);
Mikael Olsson67add212023-05-31 19:00:48 +0200118 static int handle_rsc(struct remoteproc *rproc, void *rsc, size_t len);
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +0100119 static int notify(remoteproc *rproc, uint32_t id);
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +0100120
121 // IRQ notification
122 Mailbox::Mailbox &mailbox;
123
124 // Remoteproc
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +0100125 remoteproc rproc;
126 remoteproc_ops ops;
127 virtio_device *vdev;
128
Mikael Olsson67add212023-05-31 19:00:48 +0200129 // Resource table memory region
130 remoteproc_mem rsc_mem;
131 metal_io_region rsc_region;
132
133 // Host provided memory regions
134 remoteproc_mem mems[ResourceTable::NUM_RANGES];
135 metal_io_region regions[ResourceTable::NUM_RANGES];
136
Kristofer Jonsson3f5510f2023-02-08 14:23:00 +0100137 // FreeRTOS
138 SemaphoreHandle_t notifySemaphore;
139 TaskHandle_t notifyHandle;
140};
141
142/*****************************************************************************
143 * Rpmsg
144 *****************************************************************************/
145
146class Rpmsg {
147public:
148 Rpmsg(RProc &rproc, const char *const name);
149
150 int send(void *data, size_t len, uint32_t dst = 0);
151 void *physicalToVirtual(metal_phys_addr_t pa);
152
153protected:
154 virtual int handleMessage(void *data, size_t len, uint32_t src);
155
156private:
157 // RPMsg ops
158 static void rpmsgNsBind(rpmsg_device *rdev, const char *name, uint32_t dest);
159 static void nsUnbindCallback(rpmsg_endpoint *ept);
160 static int endpointCallback(rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv);
161
162 // RPMsg
163 rpmsg_virtio_device rvdev;
164 rpmsg_device *rdev;
165 rpmsg_endpoint endpoint;
166};