# risc-v-gsp-rm-debugger > **Scope.** risc-v-gsp-rm-debugger runs GSP/uproc firmware off-hardware in a controllable RISC-V machine, instruments it with Frida-like primitives, and records durable sessions so firmware behaviour can be captured and compared with evidence instead of anecdotes. Canonical sources: [`../docs/05-operations/03-risc-v-gsp-rm-vm.md`](../docs/05-operations/03-risc-v-gsp-rm-vm.md) and [`../docs/05-operations/04-risc-v-gsp-rm-debugger-user-guide.md`](../docs/05-operations/04-risc-v-gsp-rm-debugger-user-guide.md); if this page and the docs tree disagree, the docs tree wins. > > **Development-only.** Host-side tooling that is never shipped, never a driver dependency and never present in a guest; interfaces and file formats may change without notice. > > Status: 2026-10-12, tree `master @ 2f066727`. Tags: `[live]` recorded QEMU sessions; `[design]` device model and custom simulator are roadmap. ## 1. What it is risc-v-gsp-rm-debugger makes the firmware's **runtime behaviour** inspectable. It boots GSP/uproc firmware in `qemu-system-riscv64` (or a deterministic native interpreter) and offers Frida-like primitives on top: * breakpoints and enter/leave hooks (RV64 ABI aware); watchpoints on firmware variables; * memory read/write/hexdump/search, structure decoding, snapshot diffing; * recorded sessions: a replayable event stream plus memory dumps; * remote calls and run-to-cursor (execute until a chosen address); * injection: build a position-independent RV64 service, load it into the running firmware and dispatch to it; * declarative probe specs, a plugin API, and a Ghidra bridge for symbol export, hit annotation and decompiler-driven execution. Its purpose is **capturing how the firmware server behaves, repeatably and safely**, so emulation changes can be measured against recorded evidence and can survive GSP version, device and architecture churn. The tooling lives under `open-iov/debug/risc-v-gsp-rm-vm/`, with its own documentation set (design, usage, scripting, plugins, bridges, accuracy, portability, roadmap). ## 2. What it is not * **Not a GSP boot environment.** QEMU `virt` has no falcon windows, WPR2, CSB/TRANSCOM, PMU, timers or FB DMA. `probe` reports exactly where the real image first diverges (for the TU104 570.144 image: a load-access fault at firmware vaddr `0x4009014` reading `0x2000000000000A00`) — expected data, not a boot. A device model is a roadmap item, not a claim. * **Not a timing model.** Do not infer latency, jitter or concurrency behaviour from it; its in-scope conclusions are execution flow and memory side effects. * **Not a replacement for Ghidra or the guest diagnostics.** Ghidra answers *what is the code*; risc-v-gsp-rm-debugger answers *what did it do*; the guest driver remains the oracle for guest-side behaviour. * **Not a hardware or security tool.** It never attaches to a real GPU, a guest, a kernel module or an mdev, and it is never a security or confidentiality boundary. ## 3. Where it fits | Layer | Tool | Question answered | |---|---|---| | Static | Ghidra and the decompilation corpus | what is the code? | | Guest driver | guest diagnostics, ptrace tracing | what did the driver request? | | **Firmware runtime** | **risc-v-gsp-rm-debugger** | **what does the firmware server do, repeatably and safely?** | | Physical backend | supervised hardware sessions, module logs | what did real silicon / the real GSP-RM do? | The intended measurement loop: capture the real backend's RPC behaviour, run the same stimulus in risc-v-gsp-rm-debugger, and compare the recorded sessions with the tool's accuracy metrics. A simulator observation is evidence about the firmware, not about silicon; anything that would change the product is reproduced on a physical reference first. ## 4. Quickstart Requirements: Linux, Python 3.10+ (standard library only), `qemu-system-riscv64` (Ubuntu package `qemu-system-misc`), `clang` and `lld`. No GPU, no driver and no kernel module are touched. From the repository root: ```bash cd debug/risc-v-gsp-rm-vm ./risc-v-gsp-rm-debugger.sh info # environment check: QEMU, toolchain, paths make demo && make sdk # build the bundled RV64 uproc demo and the injection SDK ./risc-v-gsp-rm-debugger.sh demo # canned run: boot, hooks, watchpoints, session ./risc-v-gsp-rm-debugger.sh analyze dumps/ ./risc-v-gsp-rm-debugger.sh probe # real GSP image: report the first divergence ./risc-v-gsp-rm-debugger.sh inject # load and invoke a position-independent service ``` What "good" looks like: `info` reports QEMU and the demo paths; `demo` prints hook/branch lines and a session directory under `dumps/`; `analyze` renders hook/watch/breakpoint events and a coherent summary; `probe` reports a bounded first divergence (expected data, not a boot); `inject` returns matching values on the direct and firmware-dispatched invocation paths. A large test suite (hundreds of tests) is run with `make test`, covering unit tests plus live-QEMU smoke runs. ## 5. The primitives | Primitive | Use it for | |---|---| | `breakpoint` / `hook` | did this function run? with what arguments and return value? | | `watch` (`w`/`r`/`a`) | when did this field change, and from which store PC? | | `run` / `run_until` | bounded observation; stop at a chosen address | | `call` | remote call to unit-test a function in isolation | | `step` / `note` | single-step with dispatch; annotate the event stream | | `Memory.read/write/hexdump/search/snapshot/diff` | inspect and diff memory regions | | `SymbolDB` | resolve file/program/runtime addresses across sources | | `Recorder` | write the durable session (events, snapshots, blobs) | | injection SDK | load, register and invoke your own position-independent RV64 service | Instructions between stops are invisible unless a trace is on (a TCG plugin on QEMU, or `--trace` on the native backend). Two backends — QEMU-RSP and the native interpreter — satisfy the same session API, so scripts, probes, plugins, recordings and comparisons survive a backend change. ## 6. Fidelity levels (what a result can mean) | Level | Property | risc-v-gsp-rm-debugger today | |---|---|---| | **L0** | instruction semantics | high (QEMU TCG, same ISA family) | | **L1** | memory behaviour | high for RAM-resident code, conditional on mapping | | **L2** | time / concurrency | **not modelled** — never claim | | **L3** | device environment (falcon, WPR2, CSB, PMU, timers, DMA, IRQ) | **absent** — device model is roadmap | A simulator observation is evidence about the firmware, not about silicon. Never quote a session for timing, interrupt, security or confidentiality claims; zero hits in a run are a coverage fact, not proof that code is dead. ## 7. Sessions as evidence Every run records a session directory (format `greeneye-session/1`): ```text dumps/--/ session.json format, name, counts, snapshot inventory, meta events.jsonl append-only event stream (hooks, watches, memory, notes) snapshots/*.bin.z zlib-compressed region captures with sha256 blobs/* QEMU logs, instruction/access traces, extra captures summary.md rendered analysis ``` Rules that make a session usable as evidence: 1. **Record with a fixed stimulus.** The same script, seed, budgets and image hash make runs comparable; a self-comparison must be empty. 2. **Annotate as you go.** Explain inside the session what was asked and what was changed; a chat log is not evidence. 3. **Attach the provenance.** Firmware SHA-256, version string, symbol DB source/hash/bias, and the exact command or script. 4. **Keep the directory together.** `session.json` + `events.jsonl` + `snapshots/` + blobs are one artifact; a copied event stream alone is not evidence. 5. **State the fidelity.** Say which of L0/L1 was exercised and name the reference capture; do not silently waive L2/L3 gaps. 6. **Report deltas honestly.** Every remaining delta between two runs is explained or listed as open; an empty unexplained-delta list is a claim that must be earned. 7. **Prefer an A/B pair.** Static reading is a hypothesis; a recorded session is evidence; at least two comparable runs are a conclusion. ## 8. Safety and status * **Simulator only.** The tools launch their own QEMU or native machine against the bundled demo or an explicitly allowed re-hosted ELF; they never attach to hardware, a guest, a kernel module, an mdev or an existing debugger stub. * **No guest, no hardware, no product.** Nothing runs in a guest; injected services are prototypes, not shipped code; product changes go through the host module and a supervised physical confirmation. * **Bounded everywhere.** Runs have durations and stop caps; reads and snapshots have size caps; a wedged target is left stopped and restarted clean rather than poked. * **Local only.** The Ghidra bridge is a localhost transport, unauthenticated by design; never expose it on a network interface. * **No confidentiality claims.** The tool is a study environment; never use injection to defeat a hardware security boundary. * **Status.** The audited v0.1 surfaces are the CLI and the session format. Working and live-verified: hooks/watchpoints, memory tools, sessions, declarative probes, plugins, remote calls, run-to-cursor, the injection SDK, the Ghidra bridges, the first-fault probe and the instruction/access trace. The device model, the custom simulator and serving full host message traffic remain roadmap; porting and packaging scaffolds are pilot-status. Treat interface changes as reviewed events. ## 9. Related documentation * [`../docs/05-operations/03-risc-v-gsp-rm-vm.md`](../docs/05-operations/03-risc-v-gsp-rm-vm.md) — project-level purpose, status and limits. * [`../docs/05-operations/04-risc-v-gsp-rm-debugger-user-guide.md`](../docs/05-operations/04-risc-v-gsp-rm-debugger-user-guide.md) — the single user front door. * [`../docs/05-operations/02-debugging-and-maintenance-workflows.md`](../docs/05-operations/02-debugging-and-maintenance-workflows.md) — captures, failure taxonomy and upgrade workflows. * [`GSP-570.144W-Firmware-Analysis.md`](GSP-570.144W-Firmware-Analysis.md) and [`GSP-and-GSP-RM.md`](GSP-and-GSP-RM.md) — the firmware image and architecture the sessions exercise. * [`CUDA-Userspace-Driver.md`](CUDA-Userspace-Driver.md) and [`Physical-GPU-Backend.md`](Physical-GPU-Backend.md) — the client side of the RPC traffic and the supervised backend the simulator complements. * [`Project-Status.md`](Project-Status.md) and [`../docs/README.md`](../docs/README.md) — honest overall status and the documentation front door.