Skip to main content

riscv_emulator/
lib.rs

1//! # riscv-emulator — A RISC-V RV32IMA Emulator
2//!
3//! A cycle-accurate emulator for the RISC-V 32-bit base integer ISA with the
4//! **M** (multiply/divide), **A** (atomics), and machine-level privileged
5//! extensions. It runs real Linux kernels and FreeRTOS images, and compiles
6//! to WebAssembly for in-browser execution.
7//!
8//! ## Architecture overview
9//!
10//! The emulator is split into focused modules:
11//!
12//! | Module | Responsibility |
13//! |--------|---------------|
14//! | [`cpu`] | CPU state, trap handling, timer |
15//! | [`emulator`] | Main execution loop, image loading |
16//! | [`mmio`] | Memory-mapped I/O (UART, CLINT, SYSCON) |
17//! | [`platform`] | OS abstraction (time, keyboard, sleep) |
18//! | [`elf`] | ELF32 parser and symbol table |
19//! | [`disasm`] | RV32IMA disassembler |
20//! | [`dtb`] | Embedded device tree blob |
21//! | wasm | WebAssembly bindings (wasm32 only) |
22//!
23//! ## Memory map
24//!
25//! ```text
26//! 0x1000_0000  UART 16550  TX/RX + LSR
27//! 0x1100_4000  CLINT       mtimecmp low
28//! 0x1100_4004  CLINT       mtimecmp high
29//! 0x1100_BFF8  CLINT       mtime low  (read-only)
30//! 0x1100_BFFC  CLINT       mtime high (read-only)
31//! 0x1110_0000  SYSCON      0x5555 = poweroff, 0x7777 = restart
32//! 0x8000_0000  RAM start   (default 64 MB)
33//! ```
34//!
35//! ## Execution model
36//!
37//! Each call to [`emulator::Emulator::step`] executes up to `count`
38//! instructions in a tight loop and returns a [`cpu::StepResult`] indicating
39//! why it stopped. The caller is responsible for advancing wall-clock time and
40//! passing `elapsed_us` (microseconds since the last call) so the CLINT timer
41//! stays accurate.
42//!
43//! The high-level [`emulator::Emulator::run`] method wraps this loop with
44//! timing, WFI sleep, and instruction-count limiting.
45//!
46//! ## Trap handling
47//!
48//! Traps (exceptions and interrupts) follow the RISC-V privileged spec 1.11.
49//! When a trap is detected inside `step`, [`cpu::CpuState::commit_trap`] saves
50//! the machine context into the CSRs and redirects the PC to `mtvec`. The
51//! kernel's trap handler is then responsible for dispatching and returning via
52//! `mret`.
53//!
54//! ## Extending the emulator
55//!
56//! - **New peripherals**: add address ranges to [`mmio`] and handle them in
57//!   `handle_store` / `handle_load`.
58//! - **New instructions**: add opcode arms to the `match ir & 0x7f` block in
59//!   [`emulator::Emulator::step`].
60//! - **New platforms**: implement the [`platform::Platform`] trait.
61
62#![allow(non_snake_case)]
63
64pub mod cpu;
65pub mod disasm;
66pub mod dtb;
67pub mod elf;
68pub mod emulator;
69pub mod mmio;
70pub mod platform;
71
72/// WebAssembly bindings — only compiled when targeting `wasm32`.
73#[cfg(target_arch = "wasm32")]
74pub mod wasm;