xref: /openbmc/qemu/docs/system/riscv/virt.rst (revision 92ec7805190313c9e628f8fc4eb4f932c15247bd)
185198f18SBin Meng'virt' Generic Virtual Platform (``virt``)
285198f18SBin Meng==========================================
385198f18SBin Meng
46df743dcSPeter MaydellThe ``virt`` board is a platform which does not correspond to any real hardware;
585198f18SBin Mengit is designed for use in virtual machines. It is the recommended board type
685198f18SBin Mengif you simply want to run a guest such as Linux and do not care about
785198f18SBin Mengreproducing the idiosyncrasies and limitations of a particular bit of
885198f18SBin Mengreal-world hardware.
985198f18SBin Meng
1085198f18SBin MengSupported devices
1185198f18SBin Meng-----------------
1285198f18SBin Meng
1385198f18SBin MengThe ``virt`` machine supports the following devices:
1485198f18SBin Meng
15257cfaedSDaniel Henrique Barboza* Up to 512 generic RV32GC/RV64GC cores, with optional extensions
1685198f18SBin Meng* Core Local Interruptor (CLINT)
1785198f18SBin Meng* Platform-Level Interrupt Controller (PLIC)
1885198f18SBin Meng* CFI parallel NOR flash memory
1985198f18SBin Meng* 1 NS16550 compatible UART
2085198f18SBin Meng* 1 Google Goldfish RTC
2185198f18SBin Meng* 1 SiFive Test device
2285198f18SBin Meng* 8 virtio-mmio transport devices
2385198f18SBin Meng* 1 generic PCIe host bridge
2485198f18SBin Meng* The fw_cfg device that allows a guest to obtain data from QEMU
2585198f18SBin Meng
267035b842SYu LiThe hypervisor extension has been enabled for the default CPU, so virtual
277035b842SYu Limachines with hypervisor extension can simply be used without explicitly
287035b842SYu Lideclaring.
2985198f18SBin Meng
3085198f18SBin MengHardware configuration information
3185198f18SBin Meng----------------------------------
3285198f18SBin Meng
3385198f18SBin MengThe ``virt`` machine automatically generates a device tree blob ("dtb")
3485198f18SBin Mengwhich it passes to the guest, if there is no ``-dtb`` option. This provides
3585198f18SBin Menginformation about the addresses, interrupt lines and other configuration of
3685198f18SBin Mengthe various devices in the system. Guest software should discover the devices
3785198f18SBin Mengthat are present in the generated DTB.
3885198f18SBin Meng
3985198f18SBin MengIf users want to provide their own DTB, they can use the ``-dtb`` option.
4085198f18SBin MengThese DTBs should have the following requirements:
4185198f18SBin Meng
4285198f18SBin Meng* The number of subnodes of the /cpus node should match QEMU's ``-smp`` option
4385198f18SBin Meng* The /memory reg size should match QEMU’s selected ram_size via ``-m``
4485198f18SBin Meng* Should contain a node for the CLINT device with a compatible string
4585198f18SBin Meng  "riscv,clint0" if using with OpenSBI BIOS images
4685198f18SBin Meng
4785198f18SBin MengBoot options
4885198f18SBin Meng------------
4985198f18SBin Meng
5085198f18SBin MengThe ``virt`` machine can start using the standard -kernel functionality
5185198f18SBin Mengfor loading a Linux kernel, a VxWorks kernel, an S-mode U-Boot bootloader
5285198f18SBin Mengwith the default OpenSBI firmware image as the -bios. It also supports
5385198f18SBin Mengthe recommended RISC-V bootflow: U-Boot SPL (M-mode) loads OpenSBI fw_dynamic
5485198f18SBin Mengfirmware and U-Boot proper (S-mode), using the standard -bios functionality.
5585198f18SBin Meng
56e158a652SSunil V LUsing flash devices
57e158a652SSunil V L-------------------
58e158a652SSunil V L
59e158a652SSunil V LBy default, the first flash device (pflash0) is expected to contain
60e158a652SSunil V LS-mode firmware code. It can be configured as read-only, with the
61e158a652SSunil V Lsecond flash device (pflash1) available to store configuration data.
62e158a652SSunil V L
63e158a652SSunil V LFor example, booting edk2 looks like
64e158a652SSunil V L
65e158a652SSunil V L.. code-block:: bash
66e158a652SSunil V L
67e158a652SSunil V L  $ qemu-system-riscv64 \
68e158a652SSunil V L     -blockdev node-name=pflash0,driver=file,read-only=on,filename=<edk2_code> \
69e158a652SSunil V L     -blockdev node-name=pflash1,driver=file,filename=<edk2_vars> \
70e158a652SSunil V L     -M virt,pflash0=pflash0,pflash1=pflash1 \
71e158a652SSunil V L     ... other args ....
72e158a652SSunil V L
73e158a652SSunil V LFor TCG guests only, it is also possible to boot M-mode firmware from
74e158a652SSunil V Lthe first flash device (pflash0) by additionally passing ``-bios
75e158a652SSunil V Lnone``, as in
76e158a652SSunil V L
77e158a652SSunil V L.. code-block:: bash
78e158a652SSunil V L
79e158a652SSunil V L  $ qemu-system-riscv64 \
80e158a652SSunil V L     -bios none \
81e158a652SSunil V L     -blockdev node-name=pflash0,driver=file,read-only=on,filename=<m_mode_code> \
82e158a652SSunil V L     -M virt,pflash0=pflash0 \
83e158a652SSunil V L     ... other args ....
84e158a652SSunil V L
85e158a652SSunil V LFirmware images used for pflash must be exactly 32 MiB in size.
86e158a652SSunil V L
87*77cfbf5dSDaniel Henrique Barbozariscv-iommu support
88*77cfbf5dSDaniel Henrique Barboza-------------------
89*77cfbf5dSDaniel Henrique Barboza
90*77cfbf5dSDaniel Henrique BarbozaThe board has support for the riscv-iommu-pci device by using the following
91*77cfbf5dSDaniel Henrique Barbozacommand line:
92*77cfbf5dSDaniel Henrique Barboza
93*77cfbf5dSDaniel Henrique Barboza.. code-block:: bash
94*77cfbf5dSDaniel Henrique Barboza
95*77cfbf5dSDaniel Henrique Barboza  $ qemu-system-riscv64 -M virt -device riscv-iommu-pci (...)
96*77cfbf5dSDaniel Henrique Barboza
97*77cfbf5dSDaniel Henrique BarbozaRefer to :ref:`riscv-iommu` for more information on how the RISC-V IOMMU support
98*77cfbf5dSDaniel Henrique Barbozaworks.
99*77cfbf5dSDaniel Henrique Barboza
100954886eaSAnup PatelMachine-specific options
101954886eaSAnup Patel------------------------
102954886eaSAnup Patel
103954886eaSAnup PatelThe following machine-specific options are supported:
104954886eaSAnup Patel
105954886eaSAnup Patel- aclint=[on|off]
106954886eaSAnup Patel
107954886eaSAnup Patel  When this option is "on", ACLINT devices will be emulated instead of
108954886eaSAnup Patel  SiFive CLINT. When not specified, this option is assumed to be "off".
109c0716c81SPhilippe Mathieu-Daudé  This option is restricted to the TCG accelerator.
110954886eaSAnup Patel
11160db7a03SHeinrich Schuchardt- acpi=[on|off|auto]
11260db7a03SHeinrich Schuchardt
11360db7a03SHeinrich Schuchardt  When this option is "on" (which is the default), ACPI tables are generated and
11460db7a03SHeinrich Schuchardt  exposed as firmware tables etc/acpi/rsdp and etc/acpi/tables.
11560db7a03SHeinrich Schuchardt
116c65bc383SAnup Patel- aia=[none|aplic|aplic-imsic]
117c65bc383SAnup Patel
118c65bc383SAnup Patel  This option allows selecting interrupt controller defined by the AIA
119c65bc383SAnup Patel  (advanced interrupt architecture) specification. The "aia=aplic" selects
120c65bc383SAnup Patel  APLIC (advanced platform level interrupt controller) to handle wired
121c65bc383SAnup Patel  interrupts whereas the "aia=aplic-imsic" selects APLIC and IMSIC (incoming
122c65bc383SAnup Patel  message signaled interrupt controller) to handle both wired interrupts and
123c65bc383SAnup Patel  MSIs. When not specified, this option is assumed to be "none" which selects
124c65bc383SAnup Patel  SiFive PLIC to handle wired interrupts.
125c65bc383SAnup Patel
126c65bc383SAnup Patel- aia-guests=nnn
127c65bc383SAnup Patel
128c65bc383SAnup Patel  The number of per-HART VS-level AIA IMSIC pages to be emulated for a guest
129c65bc383SAnup Patel  having AIA IMSIC (i.e. "aia=aplic-imsic" selected). When not specified,
130c65bc383SAnup Patel  the default number of per-HART VS-level AIA IMSIC pages is 0.
131c65bc383SAnup Patel
13285198f18SBin MengRunning Linux kernel
13385198f18SBin Meng--------------------
13485198f18SBin Meng
13585198f18SBin MengLinux mainline v5.12 release is tested at the time of writing. To build a
13685198f18SBin MengLinux mainline kernel that can be booted by the ``virt`` machine in
13785198f18SBin Meng64-bit mode, simply configure the kernel using the defconfig configuration:
13885198f18SBin Meng
13985198f18SBin Meng.. code-block:: bash
14085198f18SBin Meng
14185198f18SBin Meng  $ export ARCH=riscv
14285198f18SBin Meng  $ export CROSS_COMPILE=riscv64-linux-
14385198f18SBin Meng  $ make defconfig
14485198f18SBin Meng  $ make
14585198f18SBin Meng
14685198f18SBin MengTo boot the newly built Linux kernel in QEMU with the ``virt`` machine:
14785198f18SBin Meng
14885198f18SBin Meng.. code-block:: bash
14985198f18SBin Meng
15085198f18SBin Meng  $ qemu-system-riscv64 -M virt -smp 4 -m 2G \
15185198f18SBin Meng      -display none -serial stdio \
15285198f18SBin Meng      -kernel arch/riscv/boot/Image \
15385198f18SBin Meng      -initrd /path/to/rootfs.cpio \
15485198f18SBin Meng      -append "root=/dev/ram"
15585198f18SBin Meng
15685198f18SBin MengTo build a Linux mainline kernel that can be booted by the ``virt`` machine
15785198f18SBin Mengin 32-bit mode, use the rv32_defconfig configuration. A patch is required to
15885198f18SBin Mengfix the 32-bit boot issue for Linux kernel v5.12.
15985198f18SBin Meng
16085198f18SBin Meng.. code-block:: bash
16185198f18SBin Meng
16285198f18SBin Meng  $ export ARCH=riscv
16385198f18SBin Meng  $ export CROSS_COMPILE=riscv64-linux-
16485198f18SBin Meng  $ curl https://patchwork.kernel.org/project/linux-riscv/patch/20210627135117.28641-1-bmeng.cn@gmail.com/mbox/ > riscv.patch
16585198f18SBin Meng  $ git am riscv.patch
16685198f18SBin Meng  $ make rv32_defconfig
16785198f18SBin Meng  $ make
16885198f18SBin Meng
16985198f18SBin MengReplace ``qemu-system-riscv64`` with ``qemu-system-riscv32`` in the command
17085198f18SBin Mengline above to boot the 32-bit Linux kernel. A rootfs image containing 32-bit
17185198f18SBin Mengapplications shall be used in order for kernel to boot to user space.
17285198f18SBin Meng
17385198f18SBin MengRunning U-Boot
17485198f18SBin Meng--------------
17585198f18SBin Meng
17685198f18SBin MengU-Boot mainline v2021.04 release is tested at the time of writing. To build an
17785198f18SBin MengS-mode U-Boot bootloader that can be booted by the ``virt`` machine, use
17885198f18SBin Mengthe qemu-riscv64_smode_defconfig with similar commands as described above for Linux:
17985198f18SBin Meng
18085198f18SBin Meng.. code-block:: bash
18185198f18SBin Meng
18285198f18SBin Meng  $ export CROSS_COMPILE=riscv64-linux-
18385198f18SBin Meng  $ make qemu-riscv64_smode_defconfig
18485198f18SBin Meng
18585198f18SBin MengBoot the 64-bit U-Boot S-mode image directly:
18685198f18SBin Meng
18785198f18SBin Meng.. code-block:: bash
18885198f18SBin Meng
18985198f18SBin Meng  $ qemu-system-riscv64 -M virt -smp 4 -m 2G \
19085198f18SBin Meng      -display none -serial stdio \
19185198f18SBin Meng      -kernel /path/to/u-boot.bin
19285198f18SBin Meng
19385198f18SBin MengTo test booting U-Boot SPL which in M-mode, which in turn loads a FIT image
19485198f18SBin Mengthat bundles OpenSBI fw_dynamic firmware and U-Boot proper (S-mode) together,
19585198f18SBin Mengbuild the U-Boot images using riscv64_spl_defconfig:
19685198f18SBin Meng
19785198f18SBin Meng.. code-block:: bash
19885198f18SBin Meng
19985198f18SBin Meng  $ export CROSS_COMPILE=riscv64-linux-
20085198f18SBin Meng  $ export OPENSBI=/path/to/opensbi-riscv64-generic-fw_dynamic.bin
20185198f18SBin Meng  $ make qemu-riscv64_spl_defconfig
20285198f18SBin Meng
20385198f18SBin MengThe minimal QEMU commands to run U-Boot SPL are:
20485198f18SBin Meng
20585198f18SBin Meng.. code-block:: bash
20685198f18SBin Meng
20785198f18SBin Meng  $ qemu-system-riscv64 -M virt -smp 4 -m 2G \
20885198f18SBin Meng      -display none -serial stdio \
20985198f18SBin Meng      -bios /path/to/u-boot-spl \
21085198f18SBin Meng      -device loader,file=/path/to/u-boot.itb,addr=0x80200000
21185198f18SBin Meng
21285198f18SBin MengTo test 32-bit U-Boot images, switch to use qemu-riscv32_smode_defconfig and
21385198f18SBin Mengriscv32_spl_defconfig builds, and replace ``qemu-system-riscv64`` with
21485198f18SBin Meng``qemu-system-riscv32`` in the command lines above to boot the 32-bit U-Boot.
215325b7c4eSAlistair Francis
216325b7c4eSAlistair FrancisEnabling TPM
217325b7c4eSAlistair Francis------------
218325b7c4eSAlistair Francis
219325b7c4eSAlistair FrancisA TPM device can be connected to the virt board by following the steps below.
220325b7c4eSAlistair Francis
2210c2d4671SAlex BennéeFirst launch the TPM emulator:
222325b7c4eSAlistair Francis
2230c2d4671SAlex Bennée.. code-block:: bash
2240c2d4671SAlex Bennée
2250c2d4671SAlex Bennée  $ swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm \
226325b7c4eSAlistair Francis        --ctrl type=unixio,path=swtpm-sock
227325b7c4eSAlistair Francis
2280c2d4671SAlex BennéeThen launch QEMU with some additional arguments to link a TPM device to the backend:
229325b7c4eSAlistair Francis
2300c2d4671SAlex Bennée.. code-block:: bash
2310c2d4671SAlex Bennée
2320c2d4671SAlex Bennée  $ qemu-system-riscv64 \
2330c2d4671SAlex Bennée    ... other args .... \
234325b7c4eSAlistair Francis    -chardev socket,id=chrtpm,path=swtpm-sock \
235325b7c4eSAlistair Francis    -tpmdev emulator,id=tpm0,chardev=chrtpm \
236325b7c4eSAlistair Francis    -device tpm-tis-device,tpmdev=tpm0
237325b7c4eSAlistair Francis
238325b7c4eSAlistair FrancisThe TPM device can be seen in the memory tree and the generated device
239325b7c4eSAlistair Francistree and should be accessible from the guest software.
240