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 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 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 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 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 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 checktests are run in Travis and they should all pass.
- The RISC-V ISA compatibility tests from the
riscv-testsrepository 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
virtmachine. 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
- Linux 4.15.0 with bbl and busybox are used for forward compatibility testing
- HiFive1 binaries from the
freedom-u-sdkare used for testing the
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
- Make changes in your branch.
Signed-off-by: <email@example.com> My Nameto all of your commits.
- Add add
Cc:lines using information from
qemu/MAINTAINERSbased on the changed areas of the codebase.
- Tag your branch for every patch series you intend to send out.
git format-patch -v 1 --numbered --cover-letter -M master -o outgoingto create a patch series, then edit the cover letter to summarize your changes.
scripts/checkpatch.plon all of the patches to check that they comply with the QEMU coding conventions.
git send-emailto send patches to the qemu-devel mailing list (requires configuration in
git rebaseto add
Reviewed-by:lines to commits after reviews on the qemu-devel mailing list.
- When your changes are tested and ready, use
git request-pullto 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: