OpenAMP Library  latest
Loading...
Searching...
No Matches
virtio.h
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * $FreeBSD$
5 */
6
7#ifndef _VIRTIO_H_
8#define _VIRTIO_H_
9
10#include <openamp/virtqueue.h>
11#include <metal/errno.h>
12#include <metal/spinlock.h>
13
14#if defined __cplusplus
15extern "C" {
16#endif
17
18/* VirtIO device IDs. */
19#define VIRTIO_ID_NETWORK 1UL
20#define VIRTIO_ID_BLOCK 2UL
21#define VIRTIO_ID_CONSOLE 3UL
22#define VIRTIO_ID_ENTROPY 4UL
23#define VIRTIO_ID_BALLOON 5UL
24#define VIRTIO_ID_IOMEMORY 6UL
25#define VIRTIO_ID_RPMSG 7UL /* remote processor messaging */
26#define VIRTIO_ID_SCSI 8UL
27#define VIRTIO_ID_9P 9UL
28#define VIRTIO_ID_MAC80211_WLAN 10UL
29#define VIRTIO_ID_RPROC_SERIAL 11UL
30#define VIRTIO_ID_CAIF 12UL
31#define VIRTIO_ID_MEMORY_BALLOON 13UL
32#define VIRTIO_ID_GPU 16UL
33#define VIRTIO_ID_CLOCK 17UL
34#define VIRTIO_ID_INPUT 18UL
35#define VIRTIO_ID_VSOCK 19UL
36#define VIRTIO_ID_CRYPTO 20UL
37#define VIRTIO_ID_SIGNAL_DIST 21UL
38#define VIRTIO_ID_PSTORE 22UL
39#define VIRTIO_ID_IOMMU 23UL
40#define VIRTIO_ID_MEM 24UL
41#define VIRTIO_ID_SOUND 25UL
42#define VIRTIO_ID_FS 26UL
43#define VIRTIO_ID_PMEM 27UL
44#define VIRTIO_ID_RPMB 28UL
45#define VIRTIO_ID_MAC80211_HWSIM 29UL
46#define VIRTIO_ID_VIDEO_ENCODER 30UL
47#define VIRTIO_ID_VIDEO_DECODER 31UL
48#define VIRTIO_ID_SCMI 32UL
49#define VIRTIO_ID_NITRO_SEC_MOD 33UL
50#define VIRTIO_ID_I2C_ADAPTER 34UL
51#define VIRTIO_ID_WATCHDOG 35UL
52#define VIRTIO_ID_CAN 36UL
53#define VIRTIO_ID_PARAM_SERV 38UL
54#define VIRTIO_ID_AUDIO_POLICY 39UL
55#define VIRTIO_ID_BT 40UL
56#define VIRTIO_ID_GPIO 41UL
57#define VIRTIO_ID_RDMA 42UL
58#define VIRTIO_DEV_ANY_ID -1UL
59
60/* Status byte for guest to report progress. */
61#define VIRTIO_CONFIG_STATUS_RESET 0x00
62#define VIRTIO_CONFIG_STATUS_ACK 0x01
63#define VIRTIO_CONFIG_STATUS_DRIVER 0x02
64#define VIRTIO_CONFIG_STATUS_DRIVER_OK 0x04
65#define VIRTIO_CONFIG_FEATURES_OK 0x08
66#define VIRTIO_CONFIG_STATUS_NEEDS_RESET 0x40
67#define VIRTIO_CONFIG_STATUS_FAILED 0x80
68
69/* Virtio device role */
70#define VIRTIO_DEV_DRIVER 0UL
71#define VIRTIO_DEV_DEVICE 1UL
72
73#define VIRTIO_ENABLED(option) (option == 1)
74
75#ifdef VIRTIO_DRIVER_SUPPORT
76#define VIRTIO_ROLE_IS_DRIVER(vdev) \
77 (VIRTIO_ENABLED(VIRTIO_DRIVER_SUPPORT) && ((vdev)->role) == VIRTIO_DEV_DRIVER)
78#else
79/* Default definition without code size optimization */
80#define VIRTIO_ROLE_IS_DRIVER(vdev) ((vdev)->role == VIRTIO_DEV_DRIVER)
81#endif
82
83#ifdef VIRTIO_DEVICE_SUPPORT
84#define VIRTIO_ROLE_IS_DEVICE(vdev) \
85 (VIRTIO_ENABLED(VIRTIO_DEVICE_SUPPORT) && ((vdev)->role) == VIRTIO_DEV_DEVICE)
86#else
87/* Default definition without code size optimization */
88#define VIRTIO_ROLE_IS_DEVICE(vdev) ((vdev)->role == VIRTIO_DEV_DEVICE)
89#endif
90
94 uint32_t device;
95
97 uint32_t vendor;
98
100 uint32_t version;
101};
102
103/*
104 * Generate interrupt when the virtqueue ring is
105 * completely used, even if we've suppressed them.
106 */
107#define VIRTIO_F_NOTIFY_ON_EMPTY (1 << 24)
108
109/*
110 * This feature indicates that the device accepts arbitrary
111 * descriptor layouts.
112 */
113#define VIRTIO_F_ANY_LAYOUT (1 << 27)
114
115/*
116 * The guest should never negotiate this feature; it
117 * is used to detect faulty drivers.
118 */
119#define VIRTIO_F_BAD_FEATURE (1 << 30)
120
121/*
122 * Some VirtIO feature bits (currently bits 28 through 31) are
123 * reserved for the transport being used (eg. virtio_ring), the
124 * rest are per-device feature bits.
125 */
126#define VIRTIO_TRANSPORT_F_START 28
127#define VIRTIO_TRANSPORT_F_END 32
128
129#ifdef VIRTIO_DEBUG
130#include <metal/log.h>
131
132#define VIRTIO_ASSERT(_exp, _msg) do { \
133 int exp = (_exp); \
134 if (!(exp)) { \
135 metal_log(METAL_LOG_EMERGENCY, \
136 "FATAL: %s - " _msg, __func__); \
137 metal_assert(exp); \
138 } \
139 } while (0)
140#else
141#define VIRTIO_ASSERT(_exp, _msg) metal_assert(_exp)
142#endif /* VIRTIO_DEBUG */
143
144#define VIRTIO_MMIO_VRING_ALIGNMENT 4096
145
146typedef void (*virtio_dev_reset_cb)(struct virtio_device *vdev);
147
148struct virtio_dispatch;
149struct virtio_memory_ops;
150
154 uint32_t vfd_val;
155
157 const char *vfd_str;
158};
159
163 struct virtqueue *vq;
164
167
169 uint32_t notifyid;
170
172 struct metal_io_region *io;
173};
174
178 uint32_t notifyid;
179
182
184 uint64_t features;
185
187 unsigned int role;
188
191
193 const struct virtio_dispatch *func;
194
197
199 void *priv;
200
202 unsigned int vrings_num;
203
206};
207
208/*
209 * Helper functions.
210 */
211
218
221 int (*create_virtqueues)(struct virtio_device *vdev,
222 unsigned int flags,
223 unsigned int nvqs, const char *names[],
224 vq_callback callbacks[],
225 void *callback_args[]);
226
228 void (*delete_virtqueues)(struct virtio_device *vdev);
229
231 uint8_t (*get_status)(struct virtio_device *dev);
232
234 void (*set_status)(struct virtio_device *dev, uint8_t status);
235
237 uint32_t (*get_features)(struct virtio_device *dev);
238
240 void (*set_features)(struct virtio_device *dev, uint32_t feature);
241
246 uint32_t (*negotiate_features)(struct virtio_device *dev,
247 uint32_t features);
248
253 void (*read_config)(struct virtio_device *dev, uint32_t offset,
254 void *dst, int length);
255
260 void (*write_config)(struct virtio_device *dev, uint32_t offset,
261 void *src, int length);
262
264 void (*reset_device)(struct virtio_device *dev);
265
267 void (*notify)(struct virtqueue *vq);
268};
269
272 void *(*alloc)(struct virtio_device *dev, size_t size, size_t align);
273
275 void (*free)(struct virtio_device *dev, void *buf);
276};
277
290int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
291 unsigned int nvqs, const char *names[],
292 vq_callback callbacks[], void *callback_args[]);
293
300static inline void virtio_delete_virtqueues(struct virtio_device *vdev)
301{
302 if (!vdev || !vdev->func || !vdev->func->delete_virtqueues)
303 return;
304
305 vdev->func->delete_virtqueues(vdev);
306}
307
315static inline uint32_t virtio_get_devid(const struct virtio_device *vdev)
316{
317 if (!vdev)
318 return 0;
319 return vdev->id.device;
320}
321
330static inline int virtio_get_status(struct virtio_device *vdev, uint8_t *status)
331{
332 if (!vdev || !status)
333 return -EINVAL;
334
335 if (!vdev->func || !vdev->func->get_status)
336 return -ENXIO;
337
338 *status = vdev->func->get_status(vdev);
339 return 0;
340}
341
350static inline int virtio_set_status(struct virtio_device *vdev, uint8_t status)
351{
352 if (!vdev)
353 return -EINVAL;
354
355 if (!vdev->func || !vdev->func->set_status)
356 return -ENXIO;
357
358 vdev->func->set_status(vdev, status);
359 return 0;
360}
361
372static inline int virtio_read_config(struct virtio_device *vdev,
373 uint32_t offset, void *dst, int len)
374{
375 if (!vdev || !dst)
376 return -EINVAL;
377
378 if (!vdev->func || !vdev->func->read_config)
379 return -ENXIO;
380
381 vdev->func->read_config(vdev, offset, dst, len);
382 return 0;
383}
384
395static inline int virtio_write_config(struct virtio_device *vdev,
396 uint32_t offset, void *src, int len)
397{
398 if (!vdev || !src)
399 return -EINVAL;
400
401 if (!vdev->func || !vdev->func->write_config)
402 return -ENXIO;
403
404 vdev->func->write_config(vdev, offset, src, len);
405 return 0;
406}
407
417static inline int virtio_get_features(struct virtio_device *vdev,
418 uint32_t *features)
419{
420 if (!vdev || !features)
421 return -EINVAL;
422
423 if (!vdev->func || !vdev->func->get_features)
424 return -ENXIO;
425
426 *features = vdev->func->get_features(vdev);
427 if (VIRTIO_ROLE_IS_DEVICE(vdev))
428 vdev->features = *features;
429
430 return 0;
431}
432
441static inline int virtio_set_features(struct virtio_device *vdev,
442 uint32_t features)
443{
444 if (!vdev)
445 return -EINVAL;
446
447 if (!vdev->func || !vdev->func->set_features)
448 return -ENXIO;
449
450 vdev->func->set_features(vdev, features);
451 return 0;
452}
453
463static inline int virtio_negotiate_features(struct virtio_device *vdev,
464 uint32_t features,
465 uint32_t *final_features)
466{
467 if (!vdev)
468 return -EINVAL;
469
470 if (!vdev->func || !vdev->func->negotiate_features)
471 return -ENXIO;
472
473 vdev->features = vdev->func->negotiate_features(vdev, features);
474 if (final_features)
475 *final_features = vdev->features;
476 return 0;
477}
478
486static inline int virtio_reset_device(struct virtio_device *vdev)
487{
488 if (!vdev)
489 return -EINVAL;
490
491 if (!vdev->func || !vdev->func->reset_device)
492 return -ENXIO;
493
494 vdev->func->reset_device(vdev);
495 return 0;
496}
497
508static inline int virtio_alloc_buf(struct virtio_device *vdev, void **buf,
509 size_t size, size_t align)
510{
511 if (!vdev || !buf)
512 return -EINVAL;
513
514 if (!vdev->mmops || !vdev->mmops->alloc)
515 return -ENXIO;
516
517 *buf = vdev->mmops->alloc(vdev, size, align);
518 if (!*buf)
519 return -ENOMEM;
520
521 return 0;
522}
523
533static inline int virtio_free_buf(struct virtio_device *vdev, void *buf)
534{
535 if (!vdev)
536 return -EINVAL;
537
538 if (!vdev->mmops || !vdev->mmops->free)
539 return -ENXIO;
540
541 vdev->mmops->free(vdev, buf);
542
543 return 0;
544}
545
554static inline bool virtio_has_feature(struct virtio_device *vdev,
555 unsigned int feature_bit)
556{
557 uint32_t features;
558
559 if (!vdev && feature_bit >= sizeof(features) * 8)
560 return false;
561
562 if (!vdev->features)
564
565 return (vdev->features & (1UL << feature_bit)) != 0;
566}
567
568#if defined __cplusplus
569}
570#endif
571
572#endif /* _VIRTIO_H_ */
Virtio device identifier.
Definition virtio.h:92
uint32_t device
Virtio subsystem device ID.
Definition virtio.h:94
uint32_t version
Virtio subsystem device version.
Definition virtio.h:100
uint32_t vendor
Virtio subsystem vendor ID.
Definition virtio.h:97
Structure definition for virtio devices for use by the applications/drivers.
Definition virtio.h:176
unsigned int role
If it is virtio backend or front end.
Definition virtio.h:187
virtio_dev_reset_cb reset_cb
User-registered device callback.
Definition virtio.h:190
void * priv
Private data.
Definition virtio.h:199
const struct virtio_memory_ops * mmops
Definition virtio.h:196
struct virtio_vring_info * vrings_info
Pointer to the virtio vring structure.
Definition virtio.h:205
struct virtio_device_id id
The device type identification used to match it with a driver.
Definition virtio.h:181
uint32_t notifyid
Unique position on the virtio bus.
Definition virtio.h:178
const struct virtio_dispatch * func
Virtio dispatch table.
Definition virtio.h:193
unsigned int vrings_num
Number of vrings.
Definition virtio.h:202
uint64_t features
The features supported by both ends.
Definition virtio.h:184
Virtio device dispatcher functions.
Definition virtio.h:219
void(* read_config)(struct virtio_device *dev, uint32_t offset, void *dst, int length)
Read a variable amount from the device specific (ie, network) configuration region.
Definition virtio.h:253
void(* reset_device)(struct virtio_device *dev)
Request a reset of the virtio device.
Definition virtio.h:264
int(* create_virtqueues)(struct virtio_device *vdev, unsigned int flags, unsigned int nvqs, const char *names[], vq_callback callbacks[], void *callback_args[])
Create virtio queue instances.
Definition virtio.h:221
uint32_t(* negotiate_features)(struct virtio_device *dev, uint32_t features)
Set the supported features negotiate between the features parameter and features supported by the dev...
Definition virtio.h:246
void(* delete_virtqueues)(struct virtio_device *vdev)
Delete virtio queue instances.
Definition virtio.h:228
void(* notify)(struct virtqueue *vq)
Notify the other side that a virtio vring as been updated.
Definition virtio.h:267
uint8_t(* get_status)(struct virtio_device *dev)
Get the status of the virtio device.
Definition virtio.h:231
void(* set_features)(struct virtio_device *dev, uint32_t feature)
Set the supported feature (virtio driver only).
Definition virtio.h:240
uint32_t(* get_features)(struct virtio_device *dev)
Get the feature exposed by the virtio device.
Definition virtio.h:237
void(* set_status)(struct virtio_device *dev, uint8_t status)
Set the status of the virtio device.
Definition virtio.h:234
void(* write_config)(struct virtio_device *dev, uint32_t offset, void *src, int length)
Write a variable amount from the device specific (ie, network) configuration region.
Definition virtio.h:260
Device features.
Definition virtio.h:152
const char * vfd_str
Name of the feature (for debug).
Definition virtio.h:157
uint32_t vfd_val
Unique feature ID, defined in the virtio specification.
Definition virtio.h:154
Definition virtio.h:270
void *(* alloc)(struct virtio_device *dev, size_t size, size_t align)
Allocate memory from the virtio device.
Definition virtio.h:272
void(* free)(struct virtio_device *dev, void *buf)
Free memory allocated from the virtio device.
Definition virtio.h:275
Virtio vring data structure.
Definition virtio.h:161
struct vring_alloc_info info
Vring alloc info.
Definition virtio.h:166
uint32_t notifyid
Vring notify id.
Definition virtio.h:169
struct virtqueue * vq
Virtio queue.
Definition virtio.h:163
struct metal_io_region * io
Metal I/O region of the vring memory, can be NULL.
Definition virtio.h:172
Local virtio queue to manage a virtio ring for sending or receiving.
Definition virtqueue.h:78
Virtio ring specific information.
Definition virtqueue.h:140
#define VIRTIO_ROLE_IS_DEVICE(vdev)
Definition virtio.h:88
void(* virtio_dev_reset_cb)(struct virtio_device *vdev)
Definition virtio.h:146
static int virtio_write_config(struct virtio_device *vdev, uint32_t offset, void *src, int len)
Write configuration data to the device.
Definition virtio.h:395
static int virtio_read_config(struct virtio_device *vdev, uint32_t offset, void *dst, int len)
Retrieve configuration data from the device.
Definition virtio.h:372
static bool virtio_has_feature(struct virtio_device *vdev, unsigned int feature_bit)
Check if the virtio device support a specific feature.
Definition virtio.h:554
static int virtio_reset_device(struct virtio_device *vdev)
Reset virtio device.
Definition virtio.h:486
static int virtio_negotiate_features(struct virtio_device *vdev, uint32_t features, uint32_t *final_features)
Negotiate features between virtio device and driver.
Definition virtio.h:463
static void virtio_delete_virtqueues(struct virtio_device *vdev)
Delete the virtio device virtqueue.
Definition virtio.h:300
static int virtio_alloc_buf(struct virtio_device *vdev, void **buf, size_t size, size_t align)
Allocate buffer from the virtio device.
Definition virtio.h:508
static int virtio_get_features(struct virtio_device *vdev, uint32_t *features)
Get the virtio device features.
Definition virtio.h:417
int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags, unsigned int nvqs, const char *names[], vq_callback callbacks[], void *callback_args[])
Create the virtio device virtqueue.
Definition virtio.c:53
static int virtio_get_status(struct virtio_device *vdev, uint8_t *status)
Retrieve device status.
Definition virtio.h:330
static int virtio_set_features(struct virtio_device *vdev, uint32_t features)
Set features supported by the VIRTIO driver.
Definition virtio.h:441
static int virtio_set_status(struct virtio_device *vdev, uint8_t status)
Set device status.
Definition virtio.h:350
static int virtio_free_buf(struct virtio_device *vdev, void *buf)
Free the buffer allocated by virtio_alloc_buf from the virtio device.
Definition virtio.h:533
static uint32_t virtio_get_devid(const struct virtio_device *vdev)
Get device ID.
Definition virtio.h:315
void(* vq_callback)(struct virtqueue *)
Definition virtqueue.h:154