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