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
103 /** @brief Virtio device identifier. */
104 struct virtio_device_id {
105 /** Virtio subsystem device ID. */
106 uint32_t device;
107
108 /** Virtio subsystem vendor ID. */
109 uint32_t vendor;
110
111 /** Virtio subsystem device version. */
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 * The guest should never negotiate this feature; it
123 * is used to detect faulty drivers.
124 */
125 #define VIRTIO_F_BAD_FEATURE (1 << 30)
126
127 /*
128 * Some VirtIO feature bits (currently bits 28 through 31) are
129 * reserved for the transport being used (eg. virtio_ring), the
130 * rest are per-device feature bits.
131 */
132 #define VIRTIO_TRANSPORT_F_START 28
133 #define VIRTIO_TRANSPORT_F_END 32
134
135 #ifdef VIRTIO_DEBUG
136 #include <metal/log.h>
137
138 #define VIRTIO_ASSERT(_exp, _msg) do { \
139 int exp = (_exp); \
140 if (!(exp)) { \
141 metal_log(METAL_LOG_EMERGENCY, \
142 "FATAL: %s - " _msg, __func__); \
143 metal_assert(exp); \
144 } \
145 } while (0)
146 #else
147 #define VIRTIO_ASSERT(_exp, _msg) metal_assert(_exp)
148 #endif /* VIRTIO_DEBUG */
149
150 #define VIRTIO_MMIO_VRING_ALIGNMENT 4096
151
152 typedef void (*virtio_dev_reset_cb)(struct virtio_device *vdev);
153
154 struct virtio_dispatch;
155
156 /** @brief Device features. */
157 struct virtio_feature_desc {
158 /** Unique feature ID, defined in the virtio specification. */
159 uint32_t vfd_val;
160
161 /** Name of the feature (for debug). */
162 const char *vfd_str;
163 };
164
165 /** @brief Virtio vring data structure */
166 struct virtio_vring_info {
167 /** Virtio queue */
168 struct virtqueue *vq;
169
170 /** Vring alloc info */
171 struct vring_alloc_info info;
172
173 /** Vring notify id */
174 uint32_t notifyid;
175
176 /** Metal I/O region of the vring memory, can be NULL */
177 struct metal_io_region *io;
178 };
179
180 /** @brief Structure definition for virtio devices for use by the applications/drivers */
181 struct virtio_device {
182 /** Unique position on the virtio bus */
183 uint32_t notifyid;
184
185 /** The device type identification used to match it with a driver */
186 struct virtio_device_id id;
187
188 /** The features supported by both ends. */
189 uint64_t features;
190
191 /** If it is virtio backend or front end. */
192 unsigned int role;
193
194 /** User-registered device callback */
195 virtio_dev_reset_cb reset_cb;
196
197 /** Virtio dispatch table */
198 const struct virtio_dispatch *func;
199
200 /** Private data */
201 void *priv;
202
203 /** Number of vrings */
204 unsigned int vrings_num;
205
206 /** Pointer to the virtio vring structure */
207 struct virtio_vring_info *vrings_info;
208 };
209
210 /*
211 * Helper functions.
212 */
213
214 /**
215 * @brief Get the name of a virtio device.
216 *
217 * @param devid Id of the device.
218 *
219 * @return pointer to the device name string if found, otherwise null.
220 */
221 const char *virtio_dev_name(uint16_t devid);
222
223 __deprecated void virtio_describe(struct virtio_device *dev, const char *msg,
224 uint32_t features,
225 struct virtio_feature_desc *feature_desc);
226
227 /**
228 * @brief Virtio device dispatcher functions.
229 *
230 * Functions for virtio device configuration as defined in Rusty Russell's paper.
231 * The virtio transport layers are expected to implement these functions in their respective codes.
232 */
233
234 struct virtio_dispatch {
235 /** Create virtio queue instances. */
236 int (*create_virtqueues)(struct virtio_device *vdev,
237 unsigned int flags,
238 unsigned int nvqs, const char *names[],
239 vq_callback callbacks[],
240 void *callback_args[]);
241
242 /** Delete virtio queue instances. */
243 void (*delete_virtqueues)(struct virtio_device *vdev);
244
245 /** Get the status of the virtio device. */
246 uint8_t (*get_status)(struct virtio_device *dev);
247
248 /** Set the status of the virtio device. */
249 void (*set_status)(struct virtio_device *dev, uint8_t status);
250
251 /** Get the feature exposed by the virtio device. */
252 uint32_t (*get_features)(struct virtio_device *dev);
253
254 /** Set the supported `feature` (virtio driver only). */
255 void (*set_features)(struct virtio_device *dev, uint32_t feature);
256
257 /**
258 * Set the supported features negotiate between the `features` parameter and features
259 * supported by the device (virtio driver only).
260 */
261 uint32_t (*negotiate_features)(struct virtio_device *dev,
262 uint32_t features);
263
264 /**
265 * Read a variable amount from the device specific (ie, network)
266 * configuration region.
267 */
268 void (*read_config)(struct virtio_device *dev, uint32_t offset,
269 void *dst, int length);
270
271 /**
272 * Write a variable amount from the device specific (ie, network)
273 * configuration region.
274 */
275 void (*write_config)(struct virtio_device *dev, uint32_t offset,
276 void *src, int length);
277
278 /** Request a reset of the virtio device. */
279 void (*reset_device)(struct virtio_device *dev);
280
281 /** Notify the other side that a virtio vring as been updated. */
282 void (*notify)(struct virtqueue *vq);
283 };
284
285 /**
286 * @brief Create the virtio device virtqueue.
287 *
288 * @param vdev Pointer to virtio device structure.
289 * @param flags Create flag.
290 * @param nvqs The virtqueue number.
291 * @param names Virtqueue names.
292 * @param callbacks Virtqueue callback functions.
293 * @param callback_args Virtqueue callback function arguments.
294 *
295 * @return 0 on success, otherwise error code.
296 */
297 int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
298 unsigned int nvqs, const char *names[],
299 vq_callback callbacks[], void *callback_args[]);
300
301 /**
302 * @brief Delete the virtio device virtqueue.
303 *
304 * @param vdev Pointer to virtio device structure.
305 *
306 */
virtio_delete_virtqueues(struct virtio_device * vdev)307 static inline void virtio_delete_virtqueues(struct virtio_device *vdev)
308 {
309 if (!vdev || !vdev->func || !vdev->func->delete_virtqueues)
310 return;
311
312 vdev->func->delete_virtqueues(vdev);
313 }
314
315 /**
316 * @brief Get device ID.
317 *
318 * @param vdev Pointer to device structure.
319 *
320 * @return Device ID value.
321 */
virtio_get_devid(const struct virtio_device * vdev)322 static inline uint32_t virtio_get_devid(const struct virtio_device *vdev)
323 {
324 if (!vdev)
325 return 0;
326 return vdev->id.device;
327 }
328
329 /**
330 * @brief Retrieve device status.
331 *
332 * @param vdev Pointer to device structure.
333 * @param status Pointer to the virtio device status.
334 *
335 * @return 0 on success, otherwise error code.
336 */
virtio_get_status(struct virtio_device * vdev,uint8_t * status)337 static inline int virtio_get_status(struct virtio_device *vdev, uint8_t *status)
338 {
339 if (!vdev || !status)
340 return -EINVAL;
341
342 if (!vdev->func || !vdev->func->get_status)
343 return -ENXIO;
344
345 *status = vdev->func->get_status(vdev);
346 return 0;
347 }
348
349 /**
350 * @brief Set device status.
351 *
352 * @param vdev Pointer to device structure.
353 * @param status Value to be set as device status.
354 *
355 * @return 0 on success, otherwise error code.
356 */
virtio_set_status(struct virtio_device * vdev,uint8_t status)357 static inline int virtio_set_status(struct virtio_device *vdev, uint8_t status)
358 {
359 if (!vdev)
360 return -EINVAL;
361
362 if (!vdev->func || !vdev->func->set_status)
363 return -ENXIO;
364
365 vdev->func->set_status(vdev, status);
366 return 0;
367 }
368
369 /**
370 * @brief Retrieve configuration data from the device.
371 *
372 * @param vdev Pointer to device structure.
373 * @param offset Offset of the data within the configuration area.
374 * @param dst Address of the buffer that will hold the data.
375 * @param len Length of the data to be retrieved.
376 *
377 * @return 0 on success, otherwise error code.
378 */
virtio_read_config(struct virtio_device * vdev,uint32_t offset,void * dst,int len)379 static inline int virtio_read_config(struct virtio_device *vdev,
380 uint32_t offset, void *dst, int len)
381 {
382 if (!vdev || !dst)
383 return -EINVAL;
384
385 if (!vdev->func || !vdev->func->read_config)
386 return -ENXIO;
387
388 vdev->func->read_config(vdev, offset, dst, len);
389 return 0;
390 }
391
392 /**
393 * @brief Write configuration data to the device.
394 *
395 * @param vdev Pointer to device structure.
396 * @param offset Offset of the data within the configuration area.
397 * @param src Address of the buffer that holds the data to write.
398 * @param len Length of the data to be written.
399 *
400 * @return 0 on success, otherwise error code.
401 */
virtio_write_config(struct virtio_device * vdev,uint32_t offset,void * src,int len)402 static inline int virtio_write_config(struct virtio_device *vdev,
403 uint32_t offset, void *src, int len)
404 {
405 if (!vdev || !src)
406 return -EINVAL;
407
408 if (!vdev->func || !vdev->func->write_config)
409 return -ENXIO;
410
411 vdev->func->write_config(vdev, offset, src, len);
412 return 0;
413 }
414
415 /**
416 * @brief Get the virtio device features.
417 *
418 * @param vdev Pointer to device structure.
419 * @param features Pointer to features supported by both the driver and
420 * the device as a bitfield.
421 *
422 * @return 0 on success, otherwise error code.
423 */
virtio_get_features(struct virtio_device * vdev,uint32_t * features)424 static inline int virtio_get_features(struct virtio_device *vdev,
425 uint32_t *features)
426 {
427 if (!vdev || !features)
428 return -EINVAL;
429
430 if (!vdev->func || !vdev->func->get_features)
431 return -ENXIO;
432
433 *features = vdev->func->get_features(vdev);
434 return 0;
435 }
436
437 /**
438 * @brief Set features supported by the VIRTIO driver.
439 *
440 * @param vdev Pointer to device structure.
441 * @param features Features supported by the driver as a bitfield.
442 *
443 * @return 0 on success, otherwise error code.
444 */
virtio_set_features(struct virtio_device * vdev,uint32_t features)445 static inline int virtio_set_features(struct virtio_device *vdev,
446 uint32_t features)
447 {
448 if (!vdev)
449 return -EINVAL;
450
451 if (!vdev->func || !vdev->func->set_features)
452 return -ENXIO;
453
454 vdev->func->set_features(vdev, features);
455 return 0;
456 }
457
458 /**
459 * @brief Negotiate features between virtio device and driver.
460 *
461 * @param vdev Pointer to device structure.
462 * @param features Supported features.
463 * @param final_features Pointer to the final features after negotiate.
464 *
465 * @return 0 on success, otherwise error code.
466 */
virtio_negotiate_features(struct virtio_device * vdev,uint32_t features,uint32_t * final_features)467 static inline int virtio_negotiate_features(struct virtio_device *vdev,
468 uint32_t features,
469 uint32_t *final_features)
470 {
471 if (!vdev)
472 return -EINVAL;
473
474 if (!vdev->func || !vdev->func->negotiate_features)
475 return -ENXIO;
476
477 vdev->features = vdev->func->negotiate_features(vdev, features);
478 if (final_features)
479 *final_features = vdev->features;
480 return 0;
481 }
482
483 /**
484 * @brief Reset virtio device.
485 *
486 * @param vdev Pointer to virtio_device structure.
487 *
488 * @return 0 on success, otherwise error code.
489 */
virtio_reset_device(struct virtio_device * vdev)490 static inline int virtio_reset_device(struct virtio_device *vdev)
491 {
492 if (!vdev)
493 return -EINVAL;
494
495 if (!vdev->func || !vdev->func->reset_device)
496 return -ENXIO;
497
498 vdev->func->reset_device(vdev);
499 return 0;
500 }
501
502 #if defined __cplusplus
503 }
504 #endif
505
506 #endif /* _VIRTIO_H_ */
507