blob: 31b94d04675107462de099c15316a3f25444f707 [file] [log] [blame]
Bin Mengad48bd92021-04-29 17:40:07 +08001.. SPDX-License-Identifier: GPL-2.0+
2.. sectionauthor:: Bin Meng <bmeng.cn@gmail.com>
Bin Mengf170edf2018-10-15 02:21:27 -07003
4VirtIO Support
5==============
6
Bin Mengad48bd92021-04-29 17:40:07 +08007This document describes the information about U-Boot support for VirtIO_
Bin Mengf170edf2018-10-15 02:21:27 -07008devices, including supported boards, build instructions, driver details etc.
9
10What's VirtIO?
11--------------
12VirtIO is a virtualization standard for network and disk device drivers where
13just the guest's device driver "knows" it is running in a virtual environment,
14and cooperates with the hypervisor. This enables guests to get high performance
15network and disk operations, and gives most of the performance benefits of
16paravirtualization. In the U-Boot case, the guest is U-Boot itself, while the
Bin Mengad48bd92021-04-29 17:40:07 +080017virtual environment are normally QEMU_ targets like ARM, RISC-V and x86.
Bin Mengf170edf2018-10-15 02:21:27 -070018
19Status
20------
21VirtIO can use various different buses, aka transports as described in the
22spec. While VirtIO devices are commonly implemented as PCI devices on x86,
23embedded devices models like ARM/RISC-V, which does not normally come with
24PCI support might use simple memory mapped device (MMIO) instead of the PCI
25device. The memory mapped virtio device behaviour is based on the PCI device
26specification. Therefore most operations including device initialization,
27queues configuration and buffer transfers are nearly identical. Both MMIO
28and PCI transport options are supported in U-Boot.
29
30The VirtIO spec defines a lots of VirtIO device types, however at present only
31network and block device, the most two commonly used devices, are supported.
32
33The following QEMU targets are supported.
34
35 - qemu_arm_defconfig
36 - qemu_arm64_defconfig
Patrick Rudolphcb42bc82024-10-23 15:20:08 +020037 - qemu-arm-sbsa_defconfig
Bin Mengf170edf2018-10-15 02:21:27 -070038 - qemu-riscv32_defconfig
39 - qemu-riscv64_defconfig
40 - qemu-x86_defconfig
41 - qemu-x86_64_defconfig
42
43Note ARM and RISC-V targets are configured with VirtIO MMIO transport driver,
44and on x86 it's the PCI transport driver.
45
46Build Instructions
47------------------
48Building U-Boot for pre-configured QEMU targets is no different from others.
49For example, we can do the following with the CROSS_COMPILE environment
50variable being properly set to a working toolchain for ARM:
51
Bin Mengad48bd92021-04-29 17:40:07 +080052.. code-block:: bash
53
Bin Mengf170edf2018-10-15 02:21:27 -070054 $ make qemu_arm_defconfig
55 $ make
56
57You can even create a QEMU ARM target with VirtIO devices showing up on both
58MMIO and PCI buses. In this case, you can enable the PCI transport driver
59from 'make menuconfig':
60
Bin Mengad48bd92021-04-29 17:40:07 +080061.. code-block:: none
62
63 Device Drivers --->
64 ...
65 VirtIO Drivers --->
66 ...
67 [*] PCI driver for virtio devices
Bin Mengf170edf2018-10-15 02:21:27 -070068
69Other drivers are at the same location and can be tuned to suit the needs.
70
71Requirements
72------------
73It is required that QEMU v2.5.0+ should be used to test U-Boot VirtIO support
74on QEMU ARM and x86, and v2.12.0+ on QEMU RISC-V.
75
76Testing
77-------
78The following QEMU command line is used to get U-Boot up and running with
79VirtIO net and block devices on ARM.
80
Bin Mengad48bd92021-04-29 17:40:07 +080081.. code-block:: bash
82
Bin Mengf170edf2018-10-15 02:21:27 -070083 $ qemu-system-arm -nographic -machine virt -bios u-boot.bin \
84 -netdev tap,ifname=tap0,id=net0 \
85 -device virtio-net-device,netdev=net0 \
86 -drive if=none,file=test.img,format=raw,id=hd0 \
87 -device virtio-blk-device,drive=hd0
88
89On x86, command is slightly different to create PCI VirtIO devices.
90
Bin Mengad48bd92021-04-29 17:40:07 +080091.. code-block:: bash
92
Bin Mengf170edf2018-10-15 02:21:27 -070093 $ qemu-system-i386 -nographic -bios u-boot.rom \
94 -netdev tap,ifname=tap0,id=net0 \
95 -device virtio-net-pci,netdev=net0 \
96 -drive if=none,file=test.img,format=raw,id=hd0 \
97 -device virtio-blk-pci,drive=hd0
98
99Additional net and block devices can be created by appending more '-device'
100parameters. It is also possible to specify both MMIO and PCI VirtIO devices.
101For example, the following commnad creates 3 VirtIO devices, with 1 on MMIO
102and 2 on PCI bus.
103
Bin Mengad48bd92021-04-29 17:40:07 +0800104.. code-block:: bash
105
Bin Mengf170edf2018-10-15 02:21:27 -0700106 $ qemu-system-arm -nographic -machine virt -bios u-boot.bin \
107 -netdev tap,ifname=tap0,id=net0 \
108 -device virtio-net-pci,netdev=net0 \
109 -drive if=none,file=test0.img,format=raw,id=hd0 \
110 -device virtio-blk-device,drive=hd0 \
111 -drive if=none,file=test1.img,format=raw,id=hd1 \
112 -device virtio-blk-pci,drive=hd1
113
114By default QEMU creates VirtIO legacy devices by default. To create non-legacy
115(aka modern) devices, pass additional device property/value pairs like below:
116
Bin Mengad48bd92021-04-29 17:40:07 +0800117.. code-block:: bash
118
Bin Mengf170edf2018-10-15 02:21:27 -0700119 $ qemu-system-i386 -nographic -bios u-boot.rom \
120 -netdev tap,ifname=tap0,id=net0 \
121 -device virtio-net-pci,netdev=net0,disable-legacy=true,disable-modern=false \
122 -drive if=none,file=test.img,format=raw,id=hd0 \
123 -device virtio-blk-pci,drive=hd0,disable-legacy=true,disable-modern=false
124
125A 'virtio' command is provided in U-Boot shell.
126
Bin Mengad48bd92021-04-29 17:40:07 +0800127.. code-block:: none
128
Bin Mengf170edf2018-10-15 02:21:27 -0700129 => virtio
130 virtio - virtio block devices sub-system
131
132 Usage:
133 virtio scan - initialize virtio bus
134 virtio info - show all available virtio block devices
135 virtio device [dev] - show or set current virtio block device
136 virtio part [dev] - print partition table of one or all virtio block devices
137 virtio read addr blk# cnt - read `cnt' blocks starting at block
138 `blk#' to memory address `addr'
139 virtio write addr blk# cnt - write `cnt' blocks starting at block
140 `blk#' from memory address `addr'
141
142To probe all the VirtIO devices, type:
143
Bin Mengad48bd92021-04-29 17:40:07 +0800144.. code-block:: none
145
Bin Mengf170edf2018-10-15 02:21:27 -0700146 => virtio scan
147
148Then we can show the connected block device details by:
149
Bin Mengad48bd92021-04-29 17:40:07 +0800150.. code-block:: none
151
Bin Mengf170edf2018-10-15 02:21:27 -0700152 => virtio info
153 Device 0: QEMU VirtIO Block Device
154 Type: Hard Disk
155 Capacity: 4096.0 MB = 4.0 GB (8388608 x 512)
156
157And list the directories and files on the disk by:
158
Bin Mengad48bd92021-04-29 17:40:07 +0800159.. code-block:: none
160
Bin Mengf170edf2018-10-15 02:21:27 -0700161 => ls virtio 0 /
162 <DIR> 4096 .
163 <DIR> 4096 ..
164 <DIR> 16384 lost+found
165 <DIR> 4096 dev
166 <DIR> 4096 proc
167 <DIR> 4096 sys
168 <DIR> 4096 var
169 <DIR> 4096 etc
170 <DIR> 4096 usr
171 <SYM> 7 bin
172 <SYM> 8 sbin
173 <SYM> 7 lib
174 <SYM> 9 lib64
175 <DIR> 4096 run
176 <DIR> 4096 boot
177 <DIR> 4096 home
178 <DIR> 4096 media
179 <DIR> 4096 mnt
180 <DIR> 4096 opt
181 <DIR> 4096 root
182 <DIR> 4096 srv
183 <DIR> 4096 tmp
184 0 .autorelabel
185
186Driver Internals
187----------------
188There are 3 level of drivers in the VirtIO driver family.
189
Bin Mengad48bd92021-04-29 17:40:07 +0800190.. code-block:: none
191
Bin Mengf170edf2018-10-15 02:21:27 -0700192 +---------------------------------------+
193 | virtio device drivers |
194 | +-------------+ +------------+ |
195 | | virtio-net | | virtio-blk | |
196 | +-------------+ +------------+ |
197 +---------------------------------------+
198 +---------------------------------------+
199 | virtio transport drivers |
200 | +-------------+ +------------+ |
201 | | virtio-mmio | | virtio-pci | |
202 | +-------------+ +------------+ |
203 +---------------------------------------+
204 +----------------------+
205 | virtio uclass driver |
206 +----------------------+
207
208The root one is the virtio uclass driver (virtio-uclass.c), which does lots of
209common stuff for the transport drivers (virtio_mmio.c, virtio_pci.c). The real
210virtio device is discovered in the transport driver's probe() method, and its
211device ID is saved in the virtio uclass's private data of the transport device.
212Then in the virtio uclass's post_probe() method, the real virtio device driver
213(virtio_net.c, virtio_blk.c) is bound if there is a match on the device ID.
214
215The child_post_bind(), child_pre_probe() and child_post_probe() methods of the
216virtio uclass driver help bring the virtio device driver online. They do things
217like acknowledging device, feature negotiation, etc, which are really common
218for all virtio devices.
219
220The transport drivers provide a set of ops (struct dm_virtio_ops) for the real
221virtio device driver to call. These ops APIs's parameter is designed to remind
222the caller to pass the correct 'struct udevice' id of the virtio device, eg:
223
Bin Mengad48bd92021-04-29 17:40:07 +0800224.. code-block:: C
225
226 int virtio_get_status(struct udevice *vdev, u8 *status)
Bin Mengf170edf2018-10-15 02:21:27 -0700227
228So the parameter 'vdev' indicates the device should be the real virtio device.
229But we also have an API like:
230
Bin Mengad48bd92021-04-29 17:40:07 +0800231.. code-block:: C
232
233 struct virtqueue *vring_create_virtqueue(unsigned int index, unsigned int num,
234 unsigned int vring_align,
235 struct udevice *udev)
Bin Mengf170edf2018-10-15 02:21:27 -0700236
237Here the parameter 'udev' indicates the device should be the transport device.
238Similar naming is applied in other functions that are even not APIs, eg:
239
Bin Mengad48bd92021-04-29 17:40:07 +0800240.. code-block:: C
241
242 static int virtio_uclass_post_probe(struct udevice *udev)
243 static int virtio_uclass_child_pre_probe(struct udevice *vdev)
Bin Mengf170edf2018-10-15 02:21:27 -0700244
245So it's easy to tell which device these functions are operating on.
246
247Development Flow
248----------------
249At present only VirtIO network card (device ID 1) and block device (device
250ID 2) are supported. If you want to develop new driver for new devices,
251please follow the guideline below.
252
2531. add new device ID in virtio.h
Bin Mengad48bd92021-04-29 17:40:07 +0800254
255.. code-block:: C
256
257 #define VIRTIO_ID_XXX X
Bin Mengf170edf2018-10-15 02:21:27 -0700258
2592. update VIRTIO_ID_MAX_NUM to be the largest device ID plus 1
260
2613. add new driver name string in virtio.h
Bin Mengad48bd92021-04-29 17:40:07 +0800262
263.. code-block:: C
264
265 #define VIRTIO_XXX_DRV_NAME "virtio-xxx"
Bin Mengf170edf2018-10-15 02:21:27 -0700266
2674. create a new driver with name set to the name string above
Bin Mengad48bd92021-04-29 17:40:07 +0800268
269.. code-block:: C
270
271 U_BOOT_DRIVER(virtio_xxx) = {
272 .name = VIRTIO_XXX_DRV_NAME,
273 ...
274 .remove = virtio_reset,
275 .flags = DM_FLAG_ACTIVE_DMA,
276 }
Bin Mengf170edf2018-10-15 02:21:27 -0700277
278Note the driver needs to provide the remove method and normally this can be
279hooked to virtio_reset(). The driver flags should contain DM_FLAG_ACTIVE_DMA
280for the remove method to be called before jumping to OS.
281
2825. provide bind() method in the driver, where virtio_driver_features_init()
283 should be called for driver to negotiate feature support with the device.
284
2856. do funny stuff with the driver
286
Bin Mengad48bd92021-04-29 17:40:07 +0800287.. _VirtIO: http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf
288.. _QEMU: https://www.qemu.org