1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2018, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
4 * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
6 * VirtIO is a virtualization standard for network and disk device drivers
7 * where just the guest's device driver "knows" it is running in a virtual
8 * environment, and cooperates with the hypervisor. This enables guests to
9 * get high performance network and disk operations, and gives most of the
10 * performance benefits of paravirtualization. In the U-Boot case, the guest
11 * is U-Boot itself, while the virtual environment are normally QEMU targets
12 * like ARM, RISC-V and x86.
14 * See http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf for
15 * the VirtIO specification v1.0.
21 #include <virtio_types.h>
25 static const char *const virtio_drv_name
[VIRTIO_ID_MAX_NUM
] = {
26 [VIRTIO_ID_NET
] = VIRTIO_NET_DRV_NAME
,
27 [VIRTIO_ID_BLOCK
] = VIRTIO_BLK_DRV_NAME
,
28 [VIRTIO_ID_RNG
] = VIRTIO_RNG_DRV_NAME
,
31 int virtio_get_config(struct udevice
*vdev
, unsigned int offset
,
32 void *buf
, unsigned int len
)
34 struct dm_virtio_ops
*ops
;
36 ops
= virtio_get_ops(vdev
->parent
);
38 return ops
->get_config(vdev
->parent
, offset
, buf
, len
);
41 int virtio_set_config(struct udevice
*vdev
, unsigned int offset
,
42 void *buf
, unsigned int len
)
44 struct dm_virtio_ops
*ops
;
46 ops
= virtio_get_ops(vdev
->parent
);
48 return ops
->set_config(vdev
->parent
, offset
, buf
, len
);
51 int virtio_generation(struct udevice
*vdev
, u32
*counter
)
53 struct dm_virtio_ops
*ops
;
55 ops
= virtio_get_ops(vdev
->parent
);
59 return ops
->generation(vdev
->parent
, counter
);
62 int virtio_get_status(struct udevice
*vdev
, u8
*status
)
64 struct dm_virtio_ops
*ops
;
66 ops
= virtio_get_ops(vdev
->parent
);
68 return ops
->get_status(vdev
->parent
, status
);
71 int virtio_set_status(struct udevice
*vdev
, u8 status
)
73 struct dm_virtio_ops
*ops
;
75 ops
= virtio_get_ops(vdev
->parent
);
77 return ops
->set_status(vdev
->parent
, status
);
80 int virtio_reset(struct udevice
*vdev
)
82 struct dm_virtio_ops
*ops
;
84 ops
= virtio_get_ops(vdev
->parent
);
86 return ops
->reset(vdev
->parent
);
89 int virtio_get_features(struct udevice
*vdev
, u64
*features
)
91 struct dm_virtio_ops
*ops
;
93 ops
= virtio_get_ops(vdev
->parent
);
95 return ops
->get_features(vdev
->parent
, features
);
98 int virtio_set_features(struct udevice
*vdev
)
100 struct dm_virtio_ops
*ops
;
102 ops
= virtio_get_ops(vdev
->parent
);
104 return ops
->set_features(vdev
->parent
);
107 int virtio_find_vqs(struct udevice
*vdev
, unsigned int nvqs
,
108 struct virtqueue
*vqs
[])
110 struct dm_virtio_ops
*ops
;
112 ops
= virtio_get_ops(vdev
->parent
);
114 return ops
->find_vqs(vdev
->parent
, nvqs
, vqs
);
117 int virtio_del_vqs(struct udevice
*vdev
)
119 struct dm_virtio_ops
*ops
;
121 ops
= virtio_get_ops(vdev
->parent
);
123 return ops
->del_vqs(vdev
->parent
);
126 int virtio_notify(struct udevice
*vdev
, struct virtqueue
*vq
)
128 struct dm_virtio_ops
*ops
;
130 ops
= virtio_get_ops(vdev
->parent
);
132 return ops
->notify(vdev
->parent
, vq
);
135 void virtio_add_status(struct udevice
*vdev
, u8 status
)
139 if (!virtio_get_status(vdev
, &old
))
140 virtio_set_status(vdev
, old
| status
);
143 int virtio_finalize_features(struct udevice
*vdev
)
145 struct virtio_dev_priv
*uc_priv
= dev_get_uclass_priv(vdev
->parent
);
149 ret
= virtio_set_features(vdev
);
156 virtio_add_status(vdev
, VIRTIO_CONFIG_S_FEATURES_OK
);
157 ret
= virtio_get_status(vdev
, &status
);
160 if (!(status
& VIRTIO_CONFIG_S_FEATURES_OK
)) {
161 debug("(%s): device refuses features %x\n", vdev
->name
, status
);
168 void virtio_driver_features_init(struct virtio_dev_priv
*priv
,
171 const u32
*feature_legacy
,
172 u32 feature_legacy_size
)
174 priv
->feature_table
= feature
;
175 priv
->feature_table_size
= feature_size
;
176 priv
->feature_table_legacy
= feature_legacy
;
177 priv
->feature_table_size_legacy
= feature_legacy_size
;
180 int virtio_init(void)
185 /* Enumerate all known virtio devices */
186 ret
= uclass_first_device(UCLASS_VIRTIO
, &bus
);
191 ret
= uclass_next_device(&bus
);
199 static int virtio_uclass_pre_probe(struct udevice
*udev
)
201 struct dm_virtio_ops
*ops
;
203 ops
= (struct dm_virtio_ops
*)(udev
->driver
->ops
);
206 * Check virtio transport driver ops here so that we don't need
207 * check these ops each time when the virtio_xxx APIs are called.
209 * Only generation op is optional. All other ops are must-have.
211 if (!ops
->get_config
|| !ops
->set_config
||
212 !ops
->get_status
|| !ops
->set_status
||
213 !ops
->get_features
|| !ops
->set_features
||
214 !ops
->find_vqs
|| !ops
->del_vqs
||
215 !ops
->reset
|| !ops
->notify
)
221 static int virtio_uclass_post_probe(struct udevice
*udev
)
223 struct virtio_dev_priv
*uc_priv
= dev_get_uclass_priv(udev
);
224 char dev_name
[30], *str
;
225 struct udevice
*vdev
;
228 if (uc_priv
->device
> VIRTIO_ID_MAX_NUM
) {
229 debug("(%s): virtio device ID %d exceeds maximum num\n",
230 udev
->name
, uc_priv
->device
);
234 if (!virtio_drv_name
[uc_priv
->device
]) {
235 debug("(%s): underlying virtio device driver unavailable\n",
240 snprintf(dev_name
, sizeof(dev_name
), "%s#%d",
241 virtio_drv_name
[uc_priv
->device
], udev
->seq
);
242 str
= strdup(dev_name
);
246 ret
= device_bind_driver(udev
, virtio_drv_name
[uc_priv
->device
],
248 if (ret
== -ENOENT
) {
249 debug("(%s): no driver configured\n", udev
->name
);
256 device_set_name_alloced(vdev
);
258 INIT_LIST_HEAD(&uc_priv
->vqs
);
263 static int virtio_uclass_child_post_bind(struct udevice
*vdev
)
265 /* Acknowledge that we've seen the device */
266 virtio_add_status(vdev
, VIRTIO_CONFIG_S_ACKNOWLEDGE
);
271 static int virtio_uclass_child_pre_probe(struct udevice
*vdev
)
273 struct virtio_dev_priv
*uc_priv
= dev_get_uclass_priv(vdev
->parent
);
276 u64 driver_features_legacy
;
281 * Save the real virtio device (eg: virtio-net, virtio-blk) to
282 * the transport (parent) device's uclass priv for future use.
284 uc_priv
->vdev
= vdev
;
287 * We always start by resetting the device, in case a previous driver
288 * messed it up. This also tests that code path a little.
290 ret
= virtio_reset(vdev
);
294 /* We have a driver! */
295 virtio_add_status(vdev
, VIRTIO_CONFIG_S_DRIVER
);
297 /* Figure out what features the device supports */
298 virtio_get_features(vdev
, &device_features
);
299 debug("(%s) plain device features supported %016llx\n",
300 vdev
->name
, device_features
);
301 if (!(device_features
& (1ULL << VIRTIO_F_VERSION_1
)))
302 uc_priv
->legacy
= true;
304 /* Figure out what features the driver supports */
306 for (i
= 0; i
< uc_priv
->feature_table_size
; i
++) {
307 unsigned int f
= uc_priv
->feature_table
[i
];
310 driver_features
|= (1ULL << f
);
313 /* Some drivers have a separate feature table for virtio v1.0 */
314 if (uc_priv
->feature_table_legacy
) {
315 driver_features_legacy
= 0;
316 for (i
= 0; i
< uc_priv
->feature_table_size_legacy
; i
++) {
317 unsigned int f
= uc_priv
->feature_table_legacy
[i
];
320 driver_features_legacy
|= (1ULL << f
);
323 driver_features_legacy
= driver_features
;
326 if (uc_priv
->legacy
) {
327 debug("(%s): legacy virtio device\n", vdev
->name
);
328 uc_priv
->features
= driver_features_legacy
& device_features
;
330 debug("(%s): v1.0 complaint virtio device\n", vdev
->name
);
331 uc_priv
->features
= driver_features
& device_features
;
334 /* Transport features always preserved to pass to finalize_features */
335 for (i
= VIRTIO_TRANSPORT_F_START
; i
< VIRTIO_TRANSPORT_F_END
; i
++)
336 if ((device_features
& (1ULL << i
)) &&
337 (i
== VIRTIO_F_VERSION_1
))
338 __virtio_set_bit(vdev
->parent
, i
);
340 debug("(%s) final negotiated features supported %016llx\n",
341 vdev
->name
, uc_priv
->features
);
342 ret
= virtio_finalize_features(vdev
);
349 virtio_add_status(vdev
, VIRTIO_CONFIG_S_FAILED
);
353 static int virtio_uclass_child_post_probe(struct udevice
*vdev
)
355 /* Indicates that the driver is set up and ready to drive the device */
356 virtio_add_status(vdev
, VIRTIO_CONFIG_S_DRIVER_OK
);
361 UCLASS_DRIVER(virtio
) = {
364 .flags
= DM_UC_FLAG_SEQ_ALIAS
,
365 .pre_probe
= virtio_uclass_pre_probe
,
366 .post_probe
= virtio_uclass_post_probe
,
367 .child_post_bind
= virtio_uclass_child_post_bind
,
368 .child_pre_probe
= virtio_uclass_child_pre_probe
,
369 .child_post_probe
= virtio_uclass_child_post_probe
,
370 .per_device_auto_alloc_size
= sizeof(struct virtio_dev_priv
),