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