SiFive - April 25, 2018

RISC-V QEMU Part 2: The RISC-V QEMU port is upstream

QEMU 2.12.0 was released on April 24th 2018 and this version is the first official QEMU version to contain the RISC-V port. This is yet another milestone towards the development of the Open Source RISC-V tools on top of the recent acceptance of RISC-V in Linux kernel 4.15 in December last year and GLIBC 2.27 this past February.

The QEMU RISC-V port was being developed and maintained out-of-tree for several years by Sagar Karandikar and Bastian Koppelmann. The RISC-V Privileged specification evolved substantially over this period and SiFive joined the porting effort and asked me to help prepare the RISC-V port for review upstream by the QEMU core developers. We submitted the first patch series in December 2017 and after many iterations of review the port was accepted into the upstream codebase in March 2018.

This is a significant step, as this enables the mainstream Linux distributors to include RISC-V emulation support along with cross-compilers and other tools that will aid development targeting RISC-V. This is one step further towards the mainstream adoption of RISC-V Instruction Set Architecture.

What does the RISC-V QEMU port contain

The RISC-V QEMU port implements the following specifications:

  • RISC-V Instruction Set Manual Volume I: User-Level ISA Version 2.2
  • RISC-V Instruction Set Manual Volume II: Privileged ISA Version 1.9.1
  • RISC-V Instruction Set Manual Volume II: Privileged ISA Version 1.10

The RISC-V QEMU port supports the following instruction set extensions:

  • RV32GC with Supervisor-mode and User-mode (RV32IMAFDCSU)
  • RV64GC with Supervisor-mode and User-mode (RV64IMAFDCSU)
  • Any legal subset of the above (ie, RV32I or RV64IMACSU), as defined by current RISC-V specification

The RISC-V QEMU port adds support for the following targets:

  • riscv32-softmmu (RV32 full-system emulator)
  • riscv64-softmmu (RV64 full-system emulator)
  • riscv32-linux-user (RV32 linux user-mode emulator)
  • riscv64-linux-user (RV64 linux user-mode emulator)

The RISC-V QEMU port supports the following hardware blocks and features:

  • HTIF Console (Host Target Interface) for Spike emulation
  • SiFive CLINT (Core Local Interruptor) for Timer interrupts and IPIs
  • SiFive PLIC (Platform Level Interrupt Controller) for multi-core interrupts
  • SiFive Test (Test Finisher) for exiting simulations in tests
  • SiFive UART for console on the SiFive U series and E series devices
  • SiFive PRCI, AON, PWM, QSPI mocks for SiFive E series devices
  • VirtIO MMIO for network and block device support
  • Generic 16550A UART emulation on the ‘virt’ board
  • SMP and MTTCG support for multi-core emulation

What machines are available in the RISC-V QEMU port

The RISC-V QEMU full system emulator supports 5 different machines:

spike_v1.10

The spike_v1.10 machine is an emulator that provides a similar environment to Spike, the official RISC-V Instruction Set Simulator. It implements Version 1.10 of the Privileged ISA which is the most recently published version. It has CLINT, PLIC and HTIF Console device and uses device-tree to pass configuration information to guest software.

spike_v1.9.1

The spike_v1.9.1 machine, similarly to spike_v.10 provides a similar environment to Spike however it models Version 1.9.1 or the Privileged ISA and has been kept to allow backward compatibility. It has a slightly different memory map and uses a different method to pass configuration to guest software than Spike, the official RISC-V Instruction Set Simulator.

sifive_e

The sifive_e machine models SiFive's E Series Freedom Everywhere cores. It models an embedded microcontroller with no MMU, Machine and User modes. It has CLINT, PLIC, and SiFive UART devices. It is compatible with HiFive1 binaries and emulates enough hardware for the board support packages to run, as well as the SiFive Core IP family of RISC-V implementations.

sifive_u

The sifive_u machine models SiFive's U Series Freedom Unleashed cores. It models an application processor with MMU for paged virtual memory, Machine, Supervisor and User modes. It has CLINT, PLIC, and SiFive UART devices and uses device-tree to pass configuration information to guest software. This closely matches the execution environment provided by the FE540-C000 chip on the recently shipped HiFive Unleashed board.

virt

The virt machine models a Generic RISC-V Virtual machine with support for the VirtIO standard networking and block storage devices. It has CLINT, PLIC, 16550A UART devices in addition to VirtIO and it also uses device-tree to pass configuration information to guest software.

Binary Compatibility between QEMU and Hardware Implementations

One particularly interesting aspect of our QEMU port is the faithfulness to which it is capable of emulating SiFive's hardware implementations. Thanks to the well specified RISC-V ISA and well documented SiFive platform devices, QEMU is capable of running exactly the same binaries that can run on SiFive's hardware RISC-V implementations. This compatibility applies at all levels of the stack: QEMU can emulate Linux user-mode binaries (without running the RISC-V Linux port), supervisor-mode software like Linux, and bare-metal embedded applications running directly in machine mode.

Having a faithful software emulation platform affords RISC-V developers the opportunity to implement and debug their applications without the headaches of targeting a physical piece of hardware in the lab -- for example, nobody can accidentally detach a JTAG signal wire when there's no physical wire to disconnect. Thanks to the RISC-V ISA being well specified and SiFive's platform devices being well documented, it is possible to move software developed in QEMU directly to SiFive's hardware implementations without even recompiling that software.

What has been tested and what works in the RISC-V QEMU port

Before each patch series is submitted upstream for review, a series of tests are run to ensure there are no regressions.

  • QEMU upstream make check tests are run in Travis and they should all pass.
  • The RISC-V ISA compatibility tests from the riscv-tests repository are run and currently all of the tests pass.
  • Fedora Linux and Debian Linux are used for running self-hosted GCC bootstraps using the latest Linux kernel and GLIBC user-space in the virt machine. A parallel GCC bootstrap is used for stress testing MTTCG, SMP and the interrupt controllers in a multi-core RISC-V virtual machine.
  • Linux 4.6.2 with bbl and busybox are used for backward compatibility testing in the spike_v1.9.1 machine.
  • Linux 4.15.0 with bbl and busybox are used for forward compatibility testing in the spike_v1.10 machine.
  • HiFive1 binaries from the freedom-u-sdk are used for testing the sifive_e machine.

How can I contribute to RISC-V QEMU

If you would like to contribute to the RISC-V QEMU port, it is now possible to do so upstream. The QEMU project has contributor guidelines here:

The following is a brief overview of the steps required to submit a patch:

  • Create a branch from the latest QEMU master branch.
  • Make changes in your branch.
  • Add Signed-off-by: <myemail@example.com> My Name to all of your commits.
  • Add add Cc: lines using information from qemu/MAINTAINERS based on the changed areas of the codebase.
  • Tag your branch for every patch series you intend to send out.
  • Use git format-patch -v 1 --numbered --cover-letter -M master -o outgoing to create a patch series, then edit the cover letter to summarize your changes.
  • Run scripts/checkpatch.pl on all of the patches to check that they comply with the QEMU coding conventions.
  • Use git send-email to send patches to the qemu-devel mailing list (requires configuration in ~/.gitconfig).
  • Use git rebase to add Reviewed-by: lines to commits after reviews on the qemu-devel mailing list.
  • When your changes are tested and ready, use git request-pull to create a pull request and email it to the qemu-devel mailing list.

It takes a little bit of time to go through the process so please be patient. Alternatively you can submit pull requests to the RISC-V QEMU repository so that they can be included along with other changes intended for upstream:

Where I can find out more about using RISC-V and QEMU

Here are several pointers into the RISC-V software ecosystem including pages with links to where you can access RISC-V software images such as Fedora Linux and Debian Linux which can be run on RISC-V hardware or in the latest version of QEMU with RISC-V support: