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_DEV_MASTER	deprecated_virtio_dev_master()
74 #define VIRTIO_DEV_SLAVE	deprecated_virtio_dev_slave()
75 
deprecated_virtio_dev_master(void)76 __deprecated static inline int deprecated_virtio_dev_master(void)
77 {
78 	/* "VIRTIO_DEV_MASTER is deprecated, please use VIRTIO_DEV_DRIVER" */
79 	return VIRTIO_DEV_DRIVER;
80 }
81 
deprecated_virtio_dev_slave(void)82 __deprecated static inline int deprecated_virtio_dev_slave(void)
83 {
84 	/* "VIRTIO_DEV_SLAVE is deprecated, please use VIRTIO_DEV_DEVICE" */
85 	return VIRTIO_DEV_DEVICE;
86 }
87 
88 #ifdef VIRTIO_MASTER_ONLY
89 #define VIRTIO_DRIVER_ONLY
90 #warning "VIRTIO_MASTER_ONLY is deprecated, please use VIRTIO_DRIVER_ONLY"
91 #endif
92 
93 #ifdef VIRTIO_SLAVE_ONLY
94 #define VIRTIO_DEVICE_ONLY
95 #warning "VIRTIO_SLAVE_ONLY is deprecated, please use VIRTIO_DEVICE_ONLY"
96 #endif
97 
98 struct virtio_device_id {
99 	uint32_t device;
100 	uint32_t vendor;
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  * The guest should never negotiate this feature; it
111  * is used to detect faulty drivers.
112  */
113 #define VIRTIO_F_BAD_FEATURE (1 << 30)
114 
115 /*
116  * Some VirtIO feature bits (currently bits 28 through 31) are
117  * reserved for the transport being used (eg. virtio_ring), the
118  * rest are per-device feature bits.
119  */
120 #define VIRTIO_TRANSPORT_F_START      28
121 #define VIRTIO_TRANSPORT_F_END        32
122 
123 typedef void (*virtio_dev_reset_cb)(struct virtio_device *vdev);
124 
125 struct virtio_dispatch;
126 
127 struct virtio_feature_desc {
128 	uint32_t vfd_val;
129 	const char *vfd_str;
130 };
131 
132 /**
133  * struct virtio_vring_info
134  * @vq virtio queue
135  * @info vring alloc info
136  * @notifyid vring notify id
137  * @io metal I/O region of the vring memory, can be NULL
138  */
139 struct virtio_vring_info {
140 	struct virtqueue *vq;
141 	struct vring_alloc_info info;
142 	uint32_t notifyid;
143 	struct metal_io_region *io;
144 };
145 
146 /*
147  * Structure definition for virtio devices for use by the
148  * applications/drivers
149  */
150 
151 struct virtio_device {
152 	uint32_t notifyid; /**< unique position on the virtio bus */
153 	struct virtio_device_id id; /**< the device type identification
154 				      *  (used to match it with a driver
155 				      */
156 	uint64_t features; /**< the features supported by both ends. */
157 	unsigned int role; /**< if it is virtio backend or front end. */
158 	virtio_dev_reset_cb reset_cb; /**< user registered device callback */
159 	const struct virtio_dispatch *func; /**< Virtio dispatch table */
160 	void *priv; /**< TODO: remove pointer to virtio_device private data */
161 	unsigned int vrings_num; /**< number of vrings */
162 	struct virtio_vring_info *vrings_info;
163 };
164 
165 /*
166  * Helper functions.
167  */
168 const char *virtio_dev_name(uint16_t devid);
169 void virtio_describe(struct virtio_device *dev, const char *msg,
170 		     uint32_t features,
171 		     struct virtio_feature_desc *feature_desc);
172 
173 /*
174  * Functions for virtio device configuration as defined in Rusty Russell's
175  * paper.
176  * Drivers are expected to implement these functions in their respective codes.
177  */
178 
179 struct virtio_dispatch {
180 	int (*create_virtqueues)(struct virtio_device *vdev,
181 				 unsigned int flags,
182 				 unsigned int nvqs, const char *names[],
183 				 vq_callback callbacks[]);
184 	void (*delete_virtqueues)(struct virtio_device *vdev);
185 	uint8_t (*get_status)(struct virtio_device *dev);
186 	void (*set_status)(struct virtio_device *dev, uint8_t status);
187 	uint32_t (*get_features)(struct virtio_device *dev);
188 	void (*set_features)(struct virtio_device *dev, uint32_t feature);
189 	uint32_t (*negotiate_features)(struct virtio_device *dev,
190 				       uint32_t features);
191 
192 	/*
193 	 * Read/write a variable amount from the device specific (ie, network)
194 	 * configuration region. This region is encoded in the same endian as
195 	 * the guest.
196 	 */
197 	void (*read_config)(struct virtio_device *dev, uint32_t offset,
198 			    void *dst, int length);
199 	void (*write_config)(struct virtio_device *dev, uint32_t offset,
200 			     void *src, int length);
201 	void (*reset_device)(struct virtio_device *dev);
202 	void (*notify)(struct virtqueue *vq);
203 };
204 
205 /**
206  * @brief Create the virtio device virtqueue.
207  *
208  * @param vdev		Pointer to virtio device structure.
209  * @param flags		Create flag.
210  * @param nvqs		The virtqueue number.
211  * @param names		Virtqueue names.
212  * @param callbacks	Virtqueue callback functions.
213  *
214  * @return 0 on success, otherwise error code.
215  */
216 int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
217 			     unsigned int nvqs, const char *names[],
218 			     vq_callback callbacks[]);
219 
220 /**
221  * @brief Delete the virtio device virtqueue.
222  *
223  * @param vdev	Pointer to virtio device structure.
224  *
225  * @return 0 on success, otherwise error code.
226  */
virtio_delete_virtqueues(struct virtio_device * vdev)227 static inline int virtio_delete_virtqueues(struct virtio_device *vdev)
228 {
229 	if (!vdev)
230 		return -EINVAL;
231 
232 	if (!vdev->func || !vdev->func->delete_virtqueues)
233 		return -ENXIO;
234 
235 	vdev->func->delete_virtqueues(vdev);
236 	return 0;
237 }
238 
239 /**
240  * @brief Retrieve device status.
241  *
242  * @param dev		Pointer to device structure.
243  * @param status	Pointer to the virtio device status.
244  *
245  * @return 0 on success, otherwise error code.
246  */
virtio_get_status(struct virtio_device * vdev,uint8_t * status)247 static inline int virtio_get_status(struct virtio_device *vdev, uint8_t *status)
248 {
249 	if (!vdev || !status)
250 		return -EINVAL;
251 
252 	if (!vdev->func || !vdev->func->get_status)
253 		return -ENXIO;
254 
255 	*status = vdev->func->get_status(vdev);
256 	return 0;
257 }
258 
259 /**
260  * @brief Set device status.
261  *
262  * @param dev		Pointer to device structure.
263  * @param status	Value to be set as device status.
264  *
265  * @return 0 on success, otherwise error code.
266  */
virtio_set_status(struct virtio_device * vdev,uint8_t status)267 static inline int virtio_set_status(struct virtio_device *vdev, uint8_t status)
268 {
269 	if (!vdev)
270 		return -EINVAL;
271 
272 	if (!vdev->func || !vdev->func->set_status)
273 		return -ENXIO;
274 
275 	vdev->func->set_status(vdev, status);
276 	return 0;
277 }
278 
279 /**
280  * @brief Retrieve configuration data from the device.
281  *
282  * @param dev		Pointer to device structure.
283  * @param offset	Offset of the data within the configuration area.
284  * @param dst		Address of the buffer that will hold the data.
285  * @param len		Length of the data to be retrieved.
286  *
287  * @return 0 on success, otherwise error code.
288  */
virtio_read_config(struct virtio_device * vdev,uint32_t offset,void * dst,int len)289 static inline int virtio_read_config(struct virtio_device *vdev,
290 				     uint32_t offset, void *dst, int len)
291 {
292 	if (!vdev || !dst)
293 		return -EINVAL;
294 
295 	if (!vdev->func || !vdev->func->read_config)
296 		return -ENXIO;
297 
298 	vdev->func->read_config(vdev, offset, dst, len);
299 	return 0;
300 }
301 
302 /**
303  * @brief Write configuration data to the device.
304  *
305  * @param dev		Pointer to device structure.
306  * @param offset	Offset of the data within the configuration area.
307  * @param src		Address of the buffer that holds the data to write.
308  * @param len		Length of the data to be written.
309  *
310  * @return 0 on success, otherwise error code.
311  */
virtio_write_config(struct virtio_device * vdev,uint32_t offset,void * src,int len)312 static inline int virtio_write_config(struct virtio_device *vdev,
313 				      uint32_t offset, void *src, int len)
314 {
315 	if (!vdev || !src)
316 		return -EINVAL;
317 
318 	if (!vdev->func || !vdev->func->write_config)
319 		return -ENXIO;
320 
321 	vdev->func->write_config(vdev, offset, src, len);
322 	return 0;
323 }
324 
325 /**
326  * @brief Get the virtio device features.
327  *
328  * @param dev		Pointer to device structure.
329  * @param features	Pointer to features supported by both the driver and
330  *			the device as a bitfield.
331  *
332  * @return 0 on success, otherwise error code.
333  */
virtio_get_features(struct virtio_device * vdev,uint32_t * features)334 static inline int virtio_get_features(struct virtio_device *vdev,
335 				      uint32_t *features)
336 {
337 	if (!vdev || !features)
338 		return -EINVAL;
339 
340 	if (!vdev->func || !vdev->func->get_features)
341 		return -ENXIO;
342 
343 	*features = vdev->func->get_features(vdev);
344 	return 0;
345 }
346 
347 /**
348  * @brief Set features supported by the VIRTIO driver.
349  *
350  * @param dev		Pointer to device structure.
351  * @param features	Features supported by the driver as a bitfield.
352  *
353  * @return 0 on success, otherwise error code.
354  */
virtio_set_features(struct virtio_device * vdev,uint32_t features)355 static inline int virtio_set_features(struct virtio_device *vdev,
356 				      uint32_t features)
357 {
358 	if (!vdev)
359 		return -EINVAL;
360 
361 	if (!vdev->func || !vdev->func->set_features)
362 		return -ENXIO;
363 
364 	vdev->func->set_features(vdev, features);
365 	return 0;
366 }
367 
368 /**
369  * @brief Negotiate features between virtio device and driver.
370  *
371  * @param dev			Pointer to device structure.
372  * @param features		Supported features.
373  * @param final_features	Pointer to the final features after negotiate.
374  *
375  * @return 0 on success, otherwise error code.
376  */
virtio_negotiate_features(struct virtio_device * vdev,uint32_t features,uint32_t * final_features)377 static inline int virtio_negotiate_features(struct virtio_device *vdev,
378 					    uint32_t features,
379 					    uint32_t *final_features)
380 {
381 	if (!vdev || !final_features)
382 		return -EINVAL;
383 
384 	if (!vdev->func || !vdev->func->negotiate_features)
385 		return -ENXIO;
386 
387 	*final_features = vdev->func->negotiate_features(vdev, features);
388 	return 0;
389 }
390 
391 /**
392  * @brief Reset virtio device.
393  *
394  * @param vdev	Pointer to virtio_device structure.
395  *
396  * @return 0 on success, otherwise error code.
397  */
virtio_reset_device(struct virtio_device * vdev)398 static inline int virtio_reset_device(struct virtio_device *vdev)
399 {
400 	if (!vdev)
401 		return -EINVAL;
402 
403 	if (!vdev->func || !vdev->func->reset_device)
404 		return -ENXIO;
405 
406 	vdev->func->reset_device(vdev);
407 	return 0;
408 }
409 
410 #if defined __cplusplus
411 }
412 #endif
413 
414 #endif				/* _VIRTIO_H_ */
415