As all the gem5 users probably know, researchers in computer architecture often need to build a full hardware system in order to, for example, experiment a novel micro-architectural approach. In such a scenario, creating I/O devices for the system is typically not the main goal but only a necessary step, and researchers will therefore look for the easiest hardware designs to implement. Unfortunately, they may still face multiple difficulties in the process.
First, even if many hardware designs are widely available in existing computing systems and therefore well-supported by software stacks, their specifications may still be difficult to implement: e.g., a 16550-compatible UART, an IDE disk storage, etc. Second, many hardware specifications are proprietary, which forces researchers to abide by their licensing terms. Last, even if they are able to find some open-source specifications that are easy to implement, it will only apply to a few devices within the designed full system.
Researchers in systems software face very similar challenges, but from the side of device drivers. When building novel operating systems, the development of a few device drivers is also a necessary step that researchers should optimize. However, developing drivers for typical devices can often be difficult (e.g., a 16550-compatible UART, an IDE disk storage, etc.).
Our LupIO's collection of devices aims to bridge that gap. By providing a comprehensive and open-source collection of I/O devices, that are powerful enough to build complex multicore systems and yet straightforward to implement, LupIO can help researchers in computer architecture and systems software perform exploratory research more easily. Additionally, LupIO can be used as a teaching asset, as it is accessible to students at the undergraduate and graduate level.
LupIO is a comprehensive and open-source collection of education-friendly I/O devices. This collection defines the interfaces of the most common devices found in modern RISC-based computers, and makes it possible to build complete systems using only LupIO devices, even complex symmetric multiprocessor (SMP) systems.
LupIO includes core devices (such as an interrupt controller or a timer) as well as general I/O devices (such as a block device, a real-time clock, or a terminal). LupIO devices are intended to be processor-agnostic, so they should be usable with any processor architecture supporting memory-mapped devices (e.g., RISC-V, ARM, MIPS, etc.).
Each device interface is designed to be simple and clear, with an optimal balance between features and complexity. The register maps exposed by the devices are neatly organized by type (e.g., data, control, and status) and arranged consistently across devices, in order to ease their programmability. Developing implementations of LupIO devices, as well as corresponding device drivers, is meant to be straightforward.
The full specifications of LupIO devices are available at https://gitlab.com/luplab/lupio/lupio-specs.
Following a proof-of-concept implementation in QEMU (https://gitlab.com/luplab/lupio/qemu), Jason Lowe-Power and I decided to join forces and have the LupIO collection be ported to gem5, where it would reach more of the comparch/systems research community.
Last summer, we hired two talented undergraduate students from UC Davis, Laura Hinman and Melissa Jost, to work on this implementation.
They successfully implemented all eight devices of the LupIO collection (https://gem5.googlesource.com/public/gem5/+/refs/tags/v22.214.171.124/src/dev/lupio/) and created an example board, called
LupV, based around a RISC-V processor (https://gem5.googlesource.com/public/gem5/+/refs/tags/v126.96.36.199/src/python/gem5/components/boards/experimental/lupv_board.py). This experimental board can boot Linux and even has SMP support! The source for the bootloader/kernel and disk image resources used in this example board can be found here.
While only a RISC-V based board was created, LupIO should technically be processor-agnostic. We are currently working to prove that by building other boards based on other processors and only embedding LupIO devices (e.g., currently trying with an ARM32).
You can also use any of the LupIO devices individually in your hardware system. The purely peripheral I/O devices, such as the real-time clock, the terminal, etc., should work in any MMIO-capable systems.