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