dev — Device Models
The dev module provides device models that connect to gem5's memory system through PIO and DMA ports. It implements PCI bus infrastructure, Ethernet NICs, storage controllers, VirtIO Device Framework | gem5 Wiki" href="virtio/index.html">VirtIO paravirtualized devices, AArch32, AArch64, TrustZone security extensions, SVE/SVE2 vector processing, PMU, and hardware transactional memory." href="../arch_doc/arm/index.html">ARM interrupt controllers, serial ports, and platform-specific peripherals needed for full-system simulation.
PCI Bus Ethernet NICs ARM GIC VirtIO Storage
📜 Table of Contents
Module Overview
📚 What is this & why does it exist?
The dev module is gem5's hardware peripheral layer. In a real computer, the CPU communicates with devices (network cards, disks, GPUs) through memory-mapped I/O (MMIO) and DMA. The dev module models these interactions so that a full operating system can boot, discover hardware, load drivers, and run I/O workloads inside the simulator.
💡 Real-world analogy
Think of the dev module as a collection of virtual appliances plugged into a simulated motherboard. Just as your physical PC has a network card in a PCIe slot, a SATA disk, and a USB controller — each with its own registers and DMA engine — gem5's device models present the same register interfaces and transfer mechanisms. The OS running inside gem5 sees "real" hardware and uses its normal drivers, even though everything is happening in software.
Device Architecture
All devices in gem5 inherit from a hierarchy rooted in ClockedObject. The base device classes provide the port infrastructure to communicate with the memory bus:
flowchart LR
subgraph BaseClasses["Base Device Classes"]
CO["ClockedObject"]
PIO["PioDevice\n<i>PioPort for MMIO</i>"]
BPIO["BasicPioDevice\n<i>fixed addr + size</i>"]
DMA["DmaDevice\n<i>+ DmaPort for DMA</i>"]
end
subgraph PCIStack["PCI Stack"]
PCID["PciDevice\n<i>config space, BARs</i>"]
PCIE["PciEndpoint\n<i>Type 0 header</i>"]
PCIB["PciType1Device\n<i>Bridge / Type 1</i>"]
HOST["PciHost\n<i>root complex</i>"]
BUS["PciBus\n<i>non-coherent xbar</i>"]
end
subgraph NetDevices["Network"]
ELINK["EtherLink\n<i>point-to-point</i>"]
EBUS["EtherBus\n<i>shared medium</i>"]
ESWITCH["EtherSwitch"]
NIC["NsGigE / IGbE / Sinic"]
end
subgraph StorageDevices["Storage"]
IDEC["IdeController"]
IDED["IdeDisk"]
DIMG["DiskImage"]
end
subgraph VirtIODevices["VirtIO"]
VDB["VirtIODeviceBase"]
VQ["VirtQueue"]
VBK["VirtIOBlock"]
VCN["VirtIOConsole"]
end
subgraph Platform["Platform & Interrupts"]
PLAT["Platform\n<i>interrupt routing</i>"]
end
CO --> PIO
PIO --> BPIO
PIO --> DMA
DMA --> PCID
PCID --> PCIE
PCID --> PCIB
HOST --> BUS
PCIE --> NIC
BPIO --> IDEC
PLAT --> HOST
DMA -.->|"DmaPort"| MEMBUS["Memory Bus"]
PIO -.->|"PioPort"| MEMBUS
NIC --> ELINK
ELINK --> EBUS
IDEC --> IDED
IDED --> DIMG
VDB --> VQ
VDB --> VBK
VDB --> VCN
Data Flow
Devices communicate with the CPU and memory through two fundamental mechanisms: Programmed I/O (PIO) and Direct Memory Access (DMA).
sequenceDiagram
participant CPU as CPU Core
participant BUS as Memory Bus
participant NIC as NIC Device
participant DMAPORT as DMA Port
participant RAM as System Memory
Note over CPU,RAM: PIO Read — CPU reads a device register
CPU->>BUS: ReadReq (device MMIO addr)
BUS->>NIC: PioPort.recvAtomic(pkt)
NIC->>NIC: read(pkt) — decode register
NIC-->>BUS: Response with data
BUS-->>CPU: Data returned
Note over CPU,RAM: DMA Write — Device writes to host memory
NIC->>DMAPORT: dmaWrite(addr, size, data)
DMAPORT->>DMAPORT: ChunkGenerator splits request
DMAPORT->>BUS: WriteReq (chunk 1)
BUS->>RAM: Store data
RAM-->>BUS: WriteResp
BUS-->>DMAPORT: Response
DMAPORT->>BUS: WriteReq (chunk 2)
BUS->>RAM: Store data
RAM-->>DMAPORT: Response
DMAPORT->>NIC: completionEvent fired
Note over CPU,RAM: Interrupt — Device signals CPU
NIC->>NIC: intrPost()
NIC-->>CPU: Interrupt delivered via Platform
Narrated Walkthrough: Network Packet Reception
Follow the journey of an Ethernet frame arriving at a simulated NIC, being DMA'd to memory, and triggering an interrupt for the guest OS to process:
EtherLink::Link models a fixed-bandwidth wire. The packet is queued with a propagation delay calculated from ticksPerByte * pkt.length + linkDelay.EtherInt interface calls recvPacket() on the NIC model (e.g., IGbE or NsGigE). The NIC stores the packet in an internal FIFO.DmaPort::dmaAction(ReadReq, descAddr, ...) issues a memory read. The ChunkGenerator splits the request into Cache Hierarchy | gem5 Wiki" href="../mem_doc/cache/index.html">cache-line-sized chunks.dmaWrite(bufferAddr, pkt.length, data) initiates a DMA transfer. Each chunk travels through the memory bus to DRAM.completionEvent fires, telling the NIC the transfer is done.intrPost() which routes through the PCI host and Platform to deliver an interrupt to the CPU model.Key Components
| Class | Header | Role |
|---|---|---|
PioDevice | dev/io_device.hh | Base class for all programmed I/O devices; provides PioPort |
BasicPioDevice | dev/io_device.hh | Simplified PioDevice with fixed address and size parameters |
DmaDevice | dev/dma_device.hh | Extends PioDevice with DmaPort for DMA read/write capability |
DmaPort | dev/dma_device.hh | Request port that manages chunked DMA transfers with completion events |
DmaReadFifo | dev/dma_device.hh | Buffered DMA engine helper with FIFO for streaming reads |
Platform | dev/platform.hh | System-level I/O controller; routes PCI and console interrupts |
PciDevice | dev/pci/device.hh | Base PCI device with config space, BARs, MSI/MSI-X support |
PciHost | dev/pci/host.hh | PCI host bridge; maps config/IO/memory spaces and routes interrupts |
PciBus | dev/pci/bus.hh | Non-coherent crossbar implementing PCI bus topology |
EtherLink | dev/net/etherlink.hh | Fixed-bandwidth full-duplex Ethernet link model |
NsGigE | dev/net/ns_gige.hh | National Semiconductor DP83820 Gigabit Ethernet NIC model |
IGbE | dev/net/i8254xGBe.hh | Intel 8254x Gigabit Ethernet NIC model |
IdeDisk | dev/storage/ide_disk.hh | IDE disk device with PIO/DMA transfer modes and state machine |
IdeController | dev/storage/ide_ctrl.hh | IDE controller managing up to two disk channels |
VirtIODeviceBase | dev/virtio/base.hh | Base class for VirtIO paravirtualized devices with VirtQueue support |
Sub-Module Deep Dives
Core Device Infrastructure
pci
Complete PCI subsystem: host bridge with CAM/ECAM config space, PCI bus crossbar, BAR management (IO/Memory/64-bit), MSI/MSI-X interrupts, and the PciEndpoint/PciType1Device hierarchy for endpoint and bridge devices.
net
Ethernet simulation layer: NIC models (NsGigE, IGbE, Sinic), link/bus/switch topologies, packet FIFOs, distributed simulation interfaces, and EtherDump packet capture. Supports both local and multi-process simulation.
storage
IDE disk controller and disk models with full ATA command set, PIO/DMA transfer modes, and disk image backends (raw and copy-on-write). Provides block-level storage for full-system simulation.
virtio
Paravirtualized device framework using VirtQueues for efficient guest-host communication. Includes block device, serial console, RNG, and 9P filesystem sharing — all usable with standard VirtIO guest drivers.
Architecture-Specific Devices
arm
ARM-specific devices: GIC (Generic Interrupt Controller) v2/v3/v4, GPU (NoMali), timers, SMMU v3, AMBA bus, HDLcd display, RealView/VExpress platforms, flash memory, energy controllers.
x86
x86 platform devices: i8254 PIT, i8259 PIC, i82094 IOAPIC, ACPI PM timer, SMBios, Intel 8237 DMA, i8042 keyboard controller, speaker, CMOS, South/North bridge stubs.
riscv
RISC-V devices: PLIC (Platform Level Interrupt Controller), CLINT (Core Local Interruptor), HiFive platform, RTC.
serial
UART and terminal models: UART8250 (16550A-compatible), Atomic and Timing Simple CPUs — gem5 Wiki" href="../cpu_doc/simple/index.html">simple UART, terminal emulation for console I/O.
Other Sub-Modules
amdgpu
AMD GPU device models for HSA and ROCm support.
hsa
HSA (Heterogeneous System Architecture) packet processor and signal handling.
i2c
I2C bus and device models for low-speed peripheral communication.
lupio
LupIO educational devices for RISC-V: timer, PIC, block, console, RNG, IPI, TTY, system.
mips
MIPS-specific platform devices: Malta board, interrupt controller.
sparc
SPARC T1000 platform: IOB, DTOD, memory-mapped disk.
ps2
PS/2 keyboard and mouse interface models.
qemu
QEMU firmware configuration (fw_cfg) device for passing boot parameters.
Directory Map
Source tree
src/dev/
├── io_device.hh/cc ← PioDevice, BasicPioDevice, PioPort
├── dma_device.hh/cc ← DmaDevice, DmaPort, DmaReadFifo, DmaCallback
├── platform.hh/cc ← Platform base — interrupt routing
├── baddev.hh/cc ← BadDevice — catches invalid accesses
├── isa_fake.hh/cc ← IsaFake — stub device for unmapped ranges
├── intel_8254_timer.hh/cc ← Intel 8254 PIT timer model
├── mc146818.hh/cc ← MC146818 RTC (real-time clock) model
├── pixelpump.hh/cc ← Pixel pump for display timing
├── reg_bank.hh ← Register bank template for device registers
├── intpin.hh ← Interrupt pin interface
├── pci/ ← PCI host, bus, device, BARs, copy engine
├── net/ ← Ethernet NICs, links, switches, dist. sim
├── storage/ ← IDE controller, disk, disk images
├── virtio/ ← VirtIO base, block, console, RNG, 9P
├── arm/ ← ARM GIC, SMMU, timers, AMBA, platforms
├── x86/ ← x86 PIC, PIT, IOAPIC, ACPI devices
├── riscv/ ← RISC-V PLIC, CLINT, HiFive board
├── serial/ ← UART, terminal models
├── amdgpu/ ← AMD GPU device models
├── hsa/ ← HSA packet processor
├── i2c/ ← I2C bus and device
├── lupio/ ← LupIO educational RISC-V devices
├── mips/ ← MIPS Malta platform
├── sparc/ ← SPARC T1000 platform
├── ps2/ ← PS/2 keyboard and mouse
└── qemu/ ← QEMU fw_cfg device
Configuration Reference
| Parameter | Python Class | Default | Description |
|---|---|---|---|
pio_addr | BasicPioDevice | 0x0 | Base address for the device's PIO range in physical memory |
pio_latency | BasicPioDevice | '100ns' | Latency for PIO accesses to the device |
system | PioDevice | — | Reference to the System object (required for all devices) |
pci_bus | PciDevice | 0 | PCI bus number |
pci_dev | PciDevice | 0 | PCI device number |
pci_func | PciDevice | 0 | PCI function number |
InterruptLine | PciDevice | 0x1f | PCI interrupt line (legacy INTx) |
speed | EtherLink | '1Gbps' | Link bandwidth |
delay | EtherLink | '0us' | Propagation delay |
image | IdeDisk | — | DiskImage object backing the IDE disk |
Cross-Module Connections
flowchart TD
subgraph dev["dev Module"]
PIO["PioDevice"]
DMA["DmaDevice"]
PLAT["Platform"]
end
subgraph mem["mem Module"]
MBUS["MemBus / CoherentXBar"]
PORT["Port (Request/Response)"]
DRAM["DRAM Controller"]
end
subgraph cpu["cpu Module"]
CPUCORE["CPU Core"]
INT["Interrupt Handler"]
end
subgraph sim["sim Module"]
SYS["System"]
EVTQ["EventQueue"]
end
PIO -->|"PioPort"| PORT
DMA -->|"DmaPort"| PORT
PORT --> MBUS
MBUS --> DRAM
PLAT -->|"postInt / clearInt"| INT
INT --> CPUCORE
SYS -->|"owns"| PIO
SYS -->|"owns"| DMA
EVTQ -->|"schedules"| DMA
Key insight: Thedevmodule depends onmemfor its port infrastructure (SimpleTimingPort,RequestPort), onsimforClockedObjectand event scheduling, and oncpu/archfor interrupt delivery. Device models never directly access CPU state — all communication is through the memory bus and interrupt lines.
Glossary
| Term | Definition |
|---|---|
| PIO | Programmed I/O — CPU directly reads/writes device registers via memory-mapped addresses |
| DMA | Direct Memory Access — device reads/writes system memory without CPU intervention |
| BAR | Base Address Register — PCI config space register that maps a device's memory/IO region |
| MSI/MSI-X | Message Signaled Interrupts — PCI interrupt mechanism using memory writes instead of dedicated lines |
| VirtQueue | Shared memory ring buffer used by VirtIO for guest-host data exchange |
| MMIO | Memory-Mapped I/O — device registers accessible at physical memory addresses |
| ECAM | Enhanced Configuration Access Mechanism — PCIe standard for config space addressing |