OpenAMP Library  v2026.04.0
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
15 extern "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 
146 typedef void (*virtio_dev_reset_cb)(struct virtio_device *vdev);
147 
148 struct virtio_dispatch;
149 struct virtio_memory_ops;
150 
154  uint32_t vfd_val;
155 
157  const char *vfd_str;
158 };
159 
163  struct virtqueue *vq;
164 
166  struct vring_alloc_info info;
167 
169  uint32_t notifyid;
170 
172  struct metal_io_region *io;
173 };
174 
178  uint32_t notifyid;
179 
181  struct virtio_device_id id;
182 
184  uint64_t features;
185 
187  unsigned int role;
188 
191 
193  const struct virtio_dispatch *func;
194 
196  const struct virtio_memory_ops *mmops;
197 
199  void *priv;
200 
202  unsigned int vrings_num;
203 
206 };
207 
208 /*
209  * Helper functions.
210  */
211 
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 
290 int 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 
300 static 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 
315 static 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 
330 static 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 
350 static 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 
372 static 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 
395 static 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 
417 static 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 
441 static 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 
463 static 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 
486 static 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 
508 static 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 
533 static 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 
554 static 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