OpenAMP Library  353
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 #ifdef VIRTIO_DRIVER_ONLY
74 #warning "VIRTIO_DRIVER_ONLY is deprecated, please use VIRTIO_DEVICE_SUPPORT=0"
75 #define VIRTIO_DRIVER_SUPPORT 1
76 #define VIRTIO_DEVICE_SUPPORT 0
77 #endif /* VIRTIO_DRIVER_ONLY */
78 
79 #ifdef VIRTIO_DEVICE_ONLY
80 #warning "VIRTIO_DEVICE_ONLY is deprecated, please use VIRTIO_DRIVER_SUPPORT=0"
81 #define VIRTIO_DRIVER_SUPPORT 0
82 #define VIRTIO_DEVICE_SUPPORT 1
83 #endif /* VIRTIO_DEVICE_ONLY */
84 
85 #define VIRTIO_ENABLED(option) (option == 1)
86 
87 #ifdef VIRTIO_DRIVER_SUPPORT
88 #define VIRTIO_ROLE_IS_DRIVER(vdev) \
89  (VIRTIO_ENABLED(VIRTIO_DRIVER_SUPPORT) && ((vdev)->role) == VIRTIO_DEV_DRIVER)
90 #else
91 /* Default definition without code size optimization */
92 #define VIRTIO_ROLE_IS_DRIVER(vdev) ((vdev)->role == VIRTIO_DEV_DRIVER)
93 #endif
94 
95 #ifdef VIRTIO_DEVICE_SUPPORT
96 #define VIRTIO_ROLE_IS_DEVICE(vdev) \
97  (VIRTIO_ENABLED(VIRTIO_DEVICE_SUPPORT) && ((vdev)->role) == VIRTIO_DEV_DEVICE)
98 #else
99 /* Default definition without code size optimization */
100 #define VIRTIO_ROLE_IS_DEVICE(vdev) ((vdev)->role == VIRTIO_DEV_DEVICE)
101 #endif
102 
106  uint32_t device;
107 
109  uint32_t vendor;
110 
112  uint32_t version;
113 };
114 
115 /*
116  * Generate interrupt when the virtqueue ring is
117  * completely used, even if we've suppressed them.
118  */
119 #define VIRTIO_F_NOTIFY_ON_EMPTY (1 << 24)
120 
121 /*
122  * This feature indicates that the device accepts arbitrary
123  * descriptor layouts.
124  */
125 #define VIRTIO_F_ANY_LAYOUT (1 << 27)
126 
127 /*
128  * The guest should never negotiate this feature; it
129  * is used to detect faulty drivers.
130  */
131 #define VIRTIO_F_BAD_FEATURE (1 << 30)
132 
133 /*
134  * Some VirtIO feature bits (currently bits 28 through 31) are
135  * reserved for the transport being used (eg. virtio_ring), the
136  * rest are per-device feature bits.
137  */
138 #define VIRTIO_TRANSPORT_F_START 28
139 #define VIRTIO_TRANSPORT_F_END 32
140 
141 #ifdef VIRTIO_DEBUG
142 #include <metal/log.h>
143 
144 #define VIRTIO_ASSERT(_exp, _msg) do { \
145  int exp = (_exp); \
146  if (!(exp)) { \
147  metal_log(METAL_LOG_EMERGENCY, \
148  "FATAL: %s - " _msg, __func__); \
149  metal_assert(exp); \
150  } \
151  } while (0)
152 #else
153 #define VIRTIO_ASSERT(_exp, _msg) metal_assert(_exp)
154 #endif /* VIRTIO_DEBUG */
155 
156 #define VIRTIO_MMIO_VRING_ALIGNMENT 4096
157 
158 typedef void (*virtio_dev_reset_cb)(struct virtio_device *vdev);
159 
160 struct virtio_dispatch;
161 struct virtio_memory_ops;
162 
166  uint32_t vfd_val;
167 
169  const char *vfd_str;
170 };
171 
175  struct virtqueue *vq;
176 
178  struct vring_alloc_info info;
179 
181  uint32_t notifyid;
182 
184  struct metal_io_region *io;
185 };
186 
190  uint32_t notifyid;
191 
193  struct virtio_device_id id;
194 
196  uint64_t features;
197 
199  unsigned int role;
200 
203 
205  const struct virtio_dispatch *func;
206 
208  const struct virtio_memory_ops *mmops;
209 
211  void *priv;
212 
214  unsigned int vrings_num;
215 
218 };
219 
220 /*
221  * Helper functions.
222  */
223 
233  int (*create_virtqueues)(struct virtio_device *vdev,
234  unsigned int flags,
235  unsigned int nvqs, const char *names[],
236  vq_callback callbacks[],
237  void *callback_args[]);
238 
240  void (*delete_virtqueues)(struct virtio_device *vdev);
241 
243  uint8_t (*get_status)(struct virtio_device *dev);
244 
246  void (*set_status)(struct virtio_device *dev, uint8_t status);
247 
249  uint32_t (*get_features)(struct virtio_device *dev);
250 
252  void (*set_features)(struct virtio_device *dev, uint32_t feature);
253 
258  uint32_t (*negotiate_features)(struct virtio_device *dev,
259  uint32_t features);
260 
265  void (*read_config)(struct virtio_device *dev, uint32_t offset,
266  void *dst, int length);
267 
272  void (*write_config)(struct virtio_device *dev, uint32_t offset,
273  void *src, int length);
274 
276  void (*reset_device)(struct virtio_device *dev);
277 
279  void (*notify)(struct virtqueue *vq);
280 };
281 
284  void *(*alloc)(struct virtio_device *dev, size_t size, size_t align);
285 
287  void (*free)(struct virtio_device *dev, void *buf);
288 };
289 
302 int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
303  unsigned int nvqs, const char *names[],
304  vq_callback callbacks[], void *callback_args[]);
305 
312 static inline void virtio_delete_virtqueues(struct virtio_device *vdev)
313 {
314  if (!vdev || !vdev->func || !vdev->func->delete_virtqueues)
315  return;
316 
317  vdev->func->delete_virtqueues(vdev);
318 }
319 
327 static inline uint32_t virtio_get_devid(const struct virtio_device *vdev)
328 {
329  if (!vdev)
330  return 0;
331  return vdev->id.device;
332 }
333 
342 static inline int virtio_get_status(struct virtio_device *vdev, uint8_t *status)
343 {
344  if (!vdev || !status)
345  return -EINVAL;
346 
347  if (!vdev->func || !vdev->func->get_status)
348  return -ENXIO;
349 
350  *status = vdev->func->get_status(vdev);
351  return 0;
352 }
353 
362 static inline int virtio_set_status(struct virtio_device *vdev, uint8_t status)
363 {
364  if (!vdev)
365  return -EINVAL;
366 
367  if (!vdev->func || !vdev->func->set_status)
368  return -ENXIO;
369 
370  vdev->func->set_status(vdev, status);
371  return 0;
372 }
373 
384 static inline int virtio_read_config(struct virtio_device *vdev,
385  uint32_t offset, void *dst, int len)
386 {
387  if (!vdev || !dst)
388  return -EINVAL;
389 
390  if (!vdev->func || !vdev->func->read_config)
391  return -ENXIO;
392 
393  vdev->func->read_config(vdev, offset, dst, len);
394  return 0;
395 }
396 
407 static inline int virtio_write_config(struct virtio_device *vdev,
408  uint32_t offset, void *src, int len)
409 {
410  if (!vdev || !src)
411  return -EINVAL;
412 
413  if (!vdev->func || !vdev->func->write_config)
414  return -ENXIO;
415 
416  vdev->func->write_config(vdev, offset, src, len);
417  return 0;
418 }
419 
429 static inline int virtio_get_features(struct virtio_device *vdev,
430  uint32_t *features)
431 {
432  if (!vdev || !features)
433  return -EINVAL;
434 
435  if (!vdev->func || !vdev->func->get_features)
436  return -ENXIO;
437 
438  *features = vdev->func->get_features(vdev);
439  if (VIRTIO_ROLE_IS_DEVICE(vdev))
440  vdev->features = *features;
441 
442  return 0;
443 }
444 
453 static inline int virtio_set_features(struct virtio_device *vdev,
454  uint32_t features)
455 {
456  if (!vdev)
457  return -EINVAL;
458 
459  if (!vdev->func || !vdev->func->set_features)
460  return -ENXIO;
461 
462  vdev->func->set_features(vdev, features);
463  return 0;
464 }
465 
475 static inline int virtio_negotiate_features(struct virtio_device *vdev,
476  uint32_t features,
477  uint32_t *final_features)
478 {
479  if (!vdev)
480  return -EINVAL;
481 
482  if (!vdev->func || !vdev->func->negotiate_features)
483  return -ENXIO;
484 
485  vdev->features = vdev->func->negotiate_features(vdev, features);
486  if (final_features)
487  *final_features = vdev->features;
488  return 0;
489 }
490 
498 static inline int virtio_reset_device(struct virtio_device *vdev)
499 {
500  if (!vdev)
501  return -EINVAL;
502 
503  if (!vdev->func || !vdev->func->reset_device)
504  return -ENXIO;
505 
506  vdev->func->reset_device(vdev);
507  return 0;
508 }
509 
520 static inline int virtio_alloc_buf(struct virtio_device *vdev, void **buf,
521  size_t size, size_t align)
522 {
523  if (!vdev || !buf)
524  return -EINVAL;
525 
526  if (!vdev->mmops || !vdev->mmops->alloc)
527  return -ENXIO;
528 
529  *buf = vdev->mmops->alloc(vdev, size, align);
530  if (!*buf)
531  return -ENOMEM;
532 
533  return 0;
534 }
535 
545 static inline int virtio_free_buf(struct virtio_device *vdev, void *buf)
546 {
547  if (!vdev)
548  return -EINVAL;
549 
550  if (!vdev->mmops || !vdev->mmops->free)
551  return -ENXIO;
552 
553  vdev->mmops->free(vdev, buf);
554 
555  return 0;
556 }
557 
566 static inline bool virtio_has_feature(struct virtio_device *vdev,
567  unsigned int feature_bit)
568 {
569  uint32_t features;
570 
571  if (!vdev && feature_bit >= sizeof(features) * 8)
572  return false;
573 
574  if (!vdev->features)
576 
577  return (vdev->features & (1UL << feature_bit)) != 0;
578 }
579 
580 #if defined __cplusplus
581 }
582 #endif
583 
584 #endif /* _VIRTIO_H_ */
Virtio device identifier.
Definition: virtio.h:104
uint32_t device
Virtio subsystem device ID.
Definition: virtio.h:106
uint32_t version
Virtio subsystem device version.
Definition: virtio.h:112
uint32_t vendor
Virtio subsystem vendor ID.
Definition: virtio.h:109
Structure definition for virtio devices for use by the applications/drivers.
Definition: virtio.h:188
unsigned int role
If it is virtio backend or front end.
Definition: virtio.h:199
virtio_dev_reset_cb reset_cb
User-registered device callback.
Definition: virtio.h:202
void * priv
Private data.
Definition: virtio.h:211
const struct virtio_memory_ops * mmops
Definition: virtio.h:208
struct virtio_vring_info * vrings_info
Pointer to the virtio vring structure.
Definition: virtio.h:217
struct virtio_device_id id
The device type identification used to match it with a driver.
Definition: virtio.h:193
uint32_t notifyid
Unique position on the virtio bus.
Definition: virtio.h:190
const struct virtio_dispatch * func
Virtio dispatch table.
Definition: virtio.h:205
unsigned int vrings_num
Number of vrings.
Definition: virtio.h:214
uint64_t features
The features supported by both ends.
Definition: virtio.h:196
Virtio device dispatcher functions.
Definition: virtio.h:231
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:265
void(* reset_device)(struct virtio_device *dev)
Request a reset of the virtio device.
Definition: virtio.h:276
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:233
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:258
void(* delete_virtqueues)(struct virtio_device *vdev)
Delete virtio queue instances.
Definition: virtio.h:240
void(* notify)(struct virtqueue *vq)
Notify the other side that a virtio vring as been updated.
Definition: virtio.h:279
uint8_t(* get_status)(struct virtio_device *dev)
Get the status of the virtio device.
Definition: virtio.h:243
void(* set_features)(struct virtio_device *dev, uint32_t feature)
Set the supported feature (virtio driver only).
Definition: virtio.h:252
uint32_t(* get_features)(struct virtio_device *dev)
Get the feature exposed by the virtio device.
Definition: virtio.h:249
void(* set_status)(struct virtio_device *dev, uint8_t status)
Set the status of the virtio device.
Definition: virtio.h:246
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:272
Device features.
Definition: virtio.h:164
const char * vfd_str
Name of the feature (for debug).
Definition: virtio.h:169
uint32_t vfd_val
Unique feature ID, defined in the virtio specification.
Definition: virtio.h:166
Definition: virtio.h:282
void *(* alloc)(struct virtio_device *dev, size_t size, size_t align)
Allocate memory from the virtio device.
Definition: virtio.h:284
void(* free)(struct virtio_device *dev, void *buf)
Free memory allocated from the virtio device.
Definition: virtio.h:287
Virtio vring data structure.
Definition: virtio.h:173
struct vring_alloc_info info
Vring alloc info.
Definition: virtio.h:178
uint32_t notifyid
Vring notify id.
Definition: virtio.h:181
struct virtqueue * vq
Virtio queue.
Definition: virtio.h:175
struct metal_io_region * io
Metal I/O region of the vring memory, can be NULL.
Definition: virtio.h:184
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:100
void(* virtio_dev_reset_cb)(struct virtio_device *vdev)
Definition: virtio.h:158
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:407
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:384
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:566
static int virtio_reset_device(struct virtio_device *vdev)
Reset virtio device.
Definition: virtio.h:498
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:475
static void virtio_delete_virtqueues(struct virtio_device *vdev)
Delete the virtio device virtqueue.
Definition: virtio.h:312
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:520
static int virtio_get_features(struct virtio_device *vdev, uint32_t *features)
Get the virtio device features.
Definition: virtio.h:429
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:342
static int virtio_set_features(struct virtio_device *vdev, uint32_t features)
Set features supported by the VIRTIO driver.
Definition: virtio.h:453
static int virtio_set_status(struct virtio_device *vdev, uint8_t status)
Set device status.
Definition: virtio.h:362
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:545
static uint32_t virtio_get_devid(const struct virtio_device *vdev)
Get device ID.
Definition: virtio.h:327
void(* vq_callback)(struct virtqueue *)
Definition: virtqueue.h:154