summaryrefslogtreecommitdiffstats
path: root/debug/risc-v-gsp-rm-vm/docs/02-USAGE.md
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-02 08:36:35 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-02 08:36:35 -0400
commitba58dcdc5ad6ca021c723d279f33e3f14e1184df (patch)
tree47e43a2dad9a2d4bb40da46243654bff8b1302de /debug/risc-v-gsp-rm-vm/docs/02-USAGE.md
parentfe485080e159c983242d699f4a584659df159818 (diff)
downloadopen-iov-ba58dcdc5ad6ca021c723d279f33e3f14e1184df.tar.gz
open-iov-ba58dcdc5ad6ca021c723d279f33e3f14e1184df.zip
debug: add green-eye GSP/uproc RISC-V VM runtime analysis tooling
Adds open-iov/debug/risc-v-gsp-rm-vm: a GDB-free instrumentation stack that boots uproc/GSP firmware in qemu-system-riscv64 and provides Frida-like hooks, breakpoints, watchpoints, memory dumps, structure decoding, snapshot diffs, recorded sessions, declarative probes, a plugin API and a Ghidra symbol/hit bridge. Verified: 25 tests green (including a live QEMU smoke test); the demo uproc boots with correct hook/leave/watch/schema/snapshot/fault evidence; the optional TCG trace plugin builds and recorded 15M trace lines in 3 s; the TU104 570.144 fwimage probe reports its first exception (load access fault at firmware vaddr 0x4009014 reading 0x2000000000000A00). Documentation: lean tool docs under debug/risc-v-gsp-rm-vm/docs/00-10, a new docs/05-operations/03-risc-v-gsp-rm-vm.md debugging document, and '# TOOL IN DEVELOPMENT - NOT READY YET!' markers in docs/README.md, the onboarding tooling table and the debugging workflows doc. Vendors qemu-plugin.h from QEMU v8.2.2 (GPL-2.0-or-later), with its license header intact, so the optional TCG plugin builds without a QEMU source tree.
Diffstat (limited to 'debug/risc-v-gsp-rm-vm/docs/02-USAGE.md')
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/02-USAGE.md168
1 files changed, 168 insertions, 0 deletions
diff --git a/debug/risc-v-gsp-rm-vm/docs/02-USAGE.md b/debug/risc-v-gsp-rm-vm/docs/02-USAGE.md
new file mode 100644
index 0000000..53cf19f
--- /dev/null
+++ b/debug/risc-v-gsp-rm-vm/docs/02-USAGE.md
@@ -0,0 +1,168 @@
+# 02 — green-eye usage
+
+> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
+
+All commands are run from `open-iov/debug/risc-v-gsp-rm-vm/`.
+
+## 0. Requirements
+
+* `qemu-system-riscv64` (Ubuntu: `apt install qemu-system-misc`);
+* Python 3.10+ (stdlib only);
+* for the demo firmware: `clang` and `lld` (`apt install lld-18` provides
+ `/usr/lib/llvm-18/bin/ld.lld`).
+
+Check everything:
+
+```bash
+./greeneye.sh info
+make test # builds the demo then runs unit + QEMU smoke tests
+```
+
+## 1. The canned demo (fastest way to see it work)
+
+```bash
+make demo
+./greeneye.sh demo
+```
+
+It boots `firmware/uproc_demo/build/uproc_demo.elf`, installs hooks on all
+`rpc_*` handlers and a watchpoint on `rpc_count`, runs the firmware self-test,
+injects a `PING` from the host, decodes and diffs the control block, then
+injects `FAULT` to capture the `ebreak` trap. A session is recorded under
+`dumps/` and a `summary.md` is written.
+
+Options: `--no-build`, `--duration SECONDS`, `--kernel PATH`, `--record PATH`.
+
+## 2. Interactive REPL
+
+```bash
+./greeneye.sh attach --kernel firmware/uproc_demo/build/uproc_demo.elf
+```
+
+`attach` launches the target itself when `--port` is omitted. To share a
+target between terminals, launch it separately and attach by port:
+
+```bash
+./greeneye.sh launch --kernel <elf> # prints: gdbstub: 127.0.0.1:<port>
+./greeneye.sh attach --port <port> --kernel <elf>
+```
+
+REPL commands:
+
+| Command | Meaning |
+|---|---|
+| `regs` / `reg <name> [value]` | read/write registers |
+| `x <addr> [len]` | annotated hexdump |
+| `mem <addr> <len>` | raw bytes (hex) |
+| `w <addr> <hex>` / `wstr <addr> <text>` | write memory |
+| `bp <addr\|symbol> [sw\|hw]` | breakpoint that prints on hit |
+| `hook <addr\|symbol>` | enter/leave hook with printing |
+| `watch <addr\|symbol> [size] [w\|r\|a]` | watchpoint |
+| `s [n]` / `c [seconds]` | step n; continue for N seconds |
+| `snap <label> <addr> <len>` | snapshot a region into the session |
+| `sym <addr\|name>` | symbol resolution |
+| `events [n]` | tail the recorded event stream |
+| `note <text>` | annotate the session |
+| `quit` | close and exit |
+
+Plugin-provided commands appear automatically (e.g. `gehits` from the example
+plugin when loaded with `--plugin plugins/example_plugin.py`).
+
+## 3. Scripted sessions
+
+```bash
+./greeneye.sh run examples/scripts/trace_rpc.py
+./greeneye.sh run examples/scripts/dump_diff.py
+./greeneye.sh run my_script.py --kernel <elf> --plugin plugins/example_plugin.py
+```
+
+The script runs with `ge`, `s`/`session`, `memory`, `symbols`, `recorder` in
+scope and is recorded by default. See [03-SCRIPTING](03-SCRIPTING.md).
+
+## 4. Recording, analysis, comparison
+
+```bash
+./greeneye.sh record --duration 2.0 --watch gsp_ctrl+0x10:8 --snapshot gsp_ctrl:392
+./greeneye.sh analyze dumps/20261002-082721-demo
+./greeneye.sh analyze dumps/<a> --symbols symbols.json > a.md
+./greeneye.sh compare dumps/<run-a> dumps/<run-b> --symbols
+```
+
+`analyze` prints a markdown report: event counts, breakpoint hits by symbol,
+watchpoint hits, written pages, stepped coverage, snapshot inventory and a
+timeline. `compare` diffs two sessions symbolically (hit-count deltas, watch
+deltas, written-page deltas) — the A/B primitive for bare-metal vs
+vfio-mdev and old-firmware vs new-firmware runs.
+
+## 5. Probing an arbitrary firmware image
+
+```bash
+./greeneye.sh probe # the project's TU104 570.144 fwimage
+./greeneye.sh probe path/to/fw.elf --duration 0.5
+./greeneye.sh probe --instructions 2000 --no-relocate
+```
+
+Segments are flattened into a raw kernel loaded at `0x80000000`; because QEMU
+starts raw kernels at the load base, a tiny PC-relative trampoline at offset 0
+jumps to the image's real (relocated) entry. The run is bounded and the report
+shows the **first exception** (faulting instruction, access address/size,
+cause) plus the QEMU log tail. For the real GSP image expect an early
+load-access fault on an unmodelled GPU register — that is the honest result
+(see [06-ACCURACY](06-ACCURACY.md)).
+
+## 6. Symbol databases
+
+```bash
+./greeneye.sh symbols export \
+ --names ../../userspace/cuda/570.144/annotations/names.tsv \
+ --index <run>/analysis/decompiled/decompiled_index.tsv \
+ --callgraph <run>/analysis/elf-index/callgraph.tsv \
+ --bias 0x100000 -o symbols-570.json
+./greeneye.sh symbols resolve --db symbols-570.json 0x453ef0
+```
+
+`--bias` normalises file vaddrs to runtime addresses (`0x100000` is the
+libcuda Ghidra image base; use 0 for firmware linked at its load address).
+
+## 7. Plugins
+
+```bash
+./greeneye.sh plugins
+./greeneye.sh run examples/scripts/trace_rpc.py --plugin plugins/example_plugin.py
+GREENEYE_PLUGINS=/path/to/plugins ./greeneye.sh demo
+```
+
+See [04-PLUGINS](04-PLUGINS.md).
+
+## 8. Make targets
+
+| Target | Action |
+|---|---|
+| `make demo` | build the demo firmware |
+| `make test` | build + unit tests + live QEMU smoke |
+| `make demo-run` | `greeneye demo --no-build` |
+| `make probe-real` | run the TU104 fwimage probe |
+| `make plugin` | build the optional TCG plugin |
+| `make clean` | remove builds, dumps and `__pycache__` |
+
+## 9. Troubleshooting
+
+* **`qemu-system-riscv64 not found`** — install `qemu-system-misc` or set
+ `GREENEYE_QEMU`.
+* **`gdbstub port not ready`** — QEMU exited early; the error includes its
+ stderr. Check the ELF actually loads (`./greeneye.sh info`).
+* **A run seems stuck** — sessions never `pkill -f greeneye` (it matches the
+ invoking shell). Use `pkill -9 -f '[q]emu-system-riscv64'` to clean up
+ leftover emulators.
+* **Target stops immediately at `0x1000`** — the firmware was not passed to
+ QEMU; check the `-kernel` path (known historical bug, fixed).
+* **`Permission denied` on `/dev/kvm`** — not needed here; QEMU `virt` may
+ fall back to TCG. For speed, ensure the user can use KVM.
+
+## 10. Safety
+
+green-eye touches no GPU, no mdev, no kernel module and no host driver. It
+runs unprivileged QEMU instances on loopback gdbstub ports. The only host
+side effects are temporary directories under `/tmp` and `dumps/` under the
+tool tree. It is safe to run alongside the CUDA/PLAN-B work, but keep an eye
+on RAM/CPU if large snapshots are recorded.