1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #pragma once
26 #include <arch/io-mem.h>
27 #include <arch/virtio-base.h>
28 #include <stdbool.h>
29 #include <sys/types.h>
30 #include <trusty/sysdeps.h>
31 
32 struct virtio_config;
33 
34 /*
35  * Size of virtual queues. This can be dynamic, but since we do not have
36  * memory allocation, supporting dynamic allocation seems like overkill.
37  *
38  * Maximum number of ports we support in multiport of virtual serial console
39  * device is 16. To support 16 ports, vqueue size should be double size of
40  * maximum ports supported, since host would sent port add control event for
41  * all ports in one sequence.
42  */
43 #define VQ_SIZE 32
44 
45 /**
46  * struct virtq_desc - VirtIO buffer descriptor
47  * @addr:  Physical address of the buffer
48  * @len:   Size of the buffer
49  * @flags: Buffer flags, see VIRTQ_DESC_* constants
50  * @next:  Used to indicate a chained buffer (not used in our code)
51  *
52  * Buffer descriptor, stored in a descriptor table and referenced in rings
53  */
54 struct virtq_desc {
55     uint64_t addr;
56     uint32_t len;
57     uint16_t flags;
58     uint16_t next;
59 };
60 
61 /* Used to indicate a chained descriptor. We aren't doing this */
62 #define VIRTQ_DESC_F_NEXT (1 << 0)
63 
64 /* This buffer may be written by the host */
65 #define VIRTQ_DESC_F_WRITE (1 << 1)
66 
67 /* This descriptor contains other descriptor ids. We aren't doing this */
68 #define VIRTQ_DESC_F_INDIRECT (1 << 2)
69 
70 /**
71  * struct virtq_avail - VirtIO ring of buffers for use by the device
72  * @flags:      Features for the ring. We zero this.
73  * @idx:        Location we would insert the next buffer, mod VQ_SIZE
74  * @ring:       Ring of indexes into the descriptor table.
75  * @used_event: Delay interrupts until idx > used_event if
76  *              VIRTIO_F_EVENT_IDX was negotiated.
77  */
78 struct virtq_avail {
79     uint16_t flags;
80     uint16_t idx;
81     uint16_t ring[VQ_SIZE];
82     uint16_t used_event;
83 };
84 
85 /**
86  * struct virtq_used_elem - What the device did with a buffer
87  * @id:  Descriptor index of the buffer used.
88  * @len: How much of the buffer was used.
89  *       NOTE: On Legacy MMIO devices (e.g. our serial ports), this field
90  *       may be inaccurate for send requests (and is for our QEMU version).
91  */
92 struct virtq_used_elem {
93     uint32_t id;
94     uint32_t len;
95 };
96 
97 /**
98  * struct virtq_used - Ring of buffers used by the device
99  * @flags:       Features for the ring. We zero this.
100  * @idx:         Location the device would insert the next buffer, mod VQ_SIZE
101  * @ring:        Ring of virtq_used_elem, saying what the device has done.
102  * @avail_event: Delay interrupt until idx > avail_event if
103  *               VIRTIO_F_EVENT_IDX was negotiated.
104  *
105  * While virtq_used has weaker alignment requirements (4) than PAGE_SIZE in
106  * the current spec, the Legacy spec requires that it be aligned to PAGE_SIZE.
107  */
108 struct virtq_used {
109     uint16_t flags;
110     uint16_t idx;
111     struct virtq_used_elem ring[VQ_SIZE];
112     uint16_t avail_event;
113 } __attribute__((aligned(PAGE_SIZE)));
114 
115 /**
116  * struct virtq_raw - Legacy VirtIO layout container
117  * @desc:  Table of bufferdescriptors. Indexes/IDs mentioned elsewhere are
118  *         indexes into this table.
119  * @avail: Ring of buffers made available to the device
120  * @used:  Ring of buffers the device is done processing
121  *
122  * The virtq_raw struct itself must be page aligned because a page frame is
123  * passed to the VirtIO driver to identify the region rather than an address.
124  *
125  * Further, the Legacy spec requires that @avail immediately follow the
126  * descriptor table, and that @used must be at the first page boundary
127  * afterwards.
128  */
129 struct virtq_raw {
130     struct virtq_desc desc[VQ_SIZE];
131     struct virtq_avail avail;
132     struct virtq_used used;
133 } __attribute__((aligned(PAGE_SIZE)));
134 ;
135 
136 /* VirtIO Device IDs */
137 #define VIRTIO_DEVICE_ID_RESERVED (0)
138 #define VIRTIO_DEVICE_ID_BLOCK_DEVICE (2)
139 #define VIRTIO_DEVICE_ID_CONSOLE (3)
140 
141 /* Flags for the status field of a VirtIO device */
142 
143 /* Guest->Host: I have seen this device */
144 #define VIRTIO_STATUS_ACKNOWLEDGE (1)
145 
146 /* Guest->Host: I have a driver for this device */
147 #define VIRTIO_STATUS_DRIVER (2)
148 
149 /* Guest->Host: Driver is ready to drive the device */
150 #define VIRTIO_STATUS_DRIVER_OK (4)
151 
152 /* Guest->Host: Feature negotiation is complete */
153 #define VIRTIO_STATUS_FEATURES_OK (8)
154 
155 /* Host->Guest: The device has encountered an error; a reset may recover */
156 #define VIRTIO_STATUS_DEVICE_NEEDS_RESET (64)
157 
158 /* Guest->Host: The driver can no longer drive the device */
159 #define VIRTIO_STATUS_FAILED (128)
160 
161 /**
162  * struct virtq - VirtIO Queue + bookkeeping information
163  * @num_bufs:     How many buffers are in the queue. For now, this is always
164  *                VQ_NUM_BUFS.
165  * @queue_id:     Which ID this queue has on the device.
166  * @raw:          The actual legacy MMIO ring.
167  * @old_used_idx: Last seen value of the used index.
168  *                This value is used to track whether there are new buffers to
169  *                process.
170  * @vio:          Pointer to the MMIO space this virtq is used by.
171  */
172 struct virtq {
173     size_t num_bufs;
174     size_t queue_id;
175     struct virtq_raw* raw;
176     uint16_t old_used_idx;
177     struct virtio_config* vio;
178 };
179 
180 /**
181  * virtio_set_features() - Sets the provided features on a VirtIO device
182  * @vio:      The device to set the features on
183  * @features: The features to set
184  */
185 void virtio_set_features(struct virtio_config* vio, uint64_t features);
186 
187 /**
188  * virtio_get_features() - Gets the possible features on a VirtIO device
189  * @vio:   The device to query
190  *
191  * Return: The feature vector supported by the device
192  */
193 uint64_t virtio_get_features(struct virtio_config* vio);
194 
195 /**
196  * vq_init() - Initialize a virtq for the provided VirtIO device and sense.
197  * @vq:       The uninitialized virtq
198  * @vq_raw:   The uninitialized legacy-compatible VirtIO queue
199  * @vio:      The VirtIO device the queue is for
200  * @is_input: Whether buffers moving through the queue should be
201  *            host->guest (input) or guest->host (output).
202  *
203  * It is reccomended that virtq_raw be statically allocated to avoid alignment
204  * considerations.
205  */
206 void vq_init(struct virtq* vq,
207              struct virtq_raw* raw,
208              struct virtio_config* vio,
209              bool is_input);
210 
211 /**
212  * vq_attach() - Attaches an initialized virtq to the specified queue ID
213  * @vq:  The virtq to attach
214  * @idx: Which id to attach it on
215  */
216 void vq_attach(struct virtq* vq, uint16_t idx);
217 
218 /**
219  * vq_make_avail - Adds the specified descriptor to the available ring
220  * @vq:      The virtq we are operating on
221  * @desc_id: Which descriptor to make available to the device
222  */
223 void vq_make_avail(struct virtq* vq, uint16_t desc_id);
224 
225 /**
226  * vq_kick - Alerts the device that this virtq has been updated
227  * @vq: The virtq to tell the device about.
228  */
229 void vq_kick(struct virtq* vq);
230 
231 /**
232  * vq_ready() - Checks whether the device has processed another buffer.
233  * @vq: The queue to check
234  */
vq_ready(struct virtq * vq)235 static inline bool vq_ready(struct virtq* vq) {
236     return io_read_16(&vq->raw->used.idx) != vq->old_used_idx;
237 }
238 
239 /**
240  * vq_wait() - Performs a blocking wait for the device to process a buffer.
241  * @vq: The queue to wait for processing on.
242  */
243 void vq_wait(struct virtq* vq);
244 
245 /**
246  * vq_adv() - Acknowledge that the host processed a buffer
247  * @vq:    The queue we are acknowledging
248  * Return: The processed buffer's length.
249  *         This may be inaccurate for output buffers when in Legacy mode.
250  */
251 uint32_t vq_adv(struct virtq* vq);
252 
253 /**
254  * send_vq() - Send a buffer via a virtq.
255  * @vq:    The VirtIO queue to send on
256  * @data:  The buffer to send
257  * @len:   The size of the buffer
258  * Return: Negative on error, size sent on success.
259  */
260 ssize_t send_vq(struct virtq* vq, const char* data, size_t len);
261 
262 /**
263  * recv_vq() - Receive data from a VirtIO queue.
264  * @vq:    The queue to receive on.
265  * @data:  The buffer to write to.
266  * @len:   The size of the buffer.
267  * Return: Negative value on error, size received on success.
268  *
269  * Will receive *exactly* one packet (since this is not truly a stream
270  * protocol).
271  */
272 ssize_t recv_vq(struct virtq* vq, char* data, size_t len);
273 
274 /**
275  * vq_set_buf_w() - Set a descriptor's buffer, host writable
276  * @vq:      The queue to operate on
277  * @desc_id: Which descriptor to set
278  * @data:    The buffer to set it to
279  * @len:     How big the buffer is
280  */
281 void vq_set_buf_w(struct virtq* vq, uint16_t desc_id, void* data, size_t len);
282 
283 /**
284  * vq_set_buf_r() - Set a descriptor's buffer, host readable
285  * @vq:      The queue to operate on
286  * @desc_id: Which descriptor to set
287  * @data:    The buffer to set it to
288  * @len:     How big the buffer is
289  */
290 void vq_set_buf_r(struct virtq* vq,
291                   uint16_t desc_id,
292                   const void* data,
293                   size_t len);
294