# 06 — Accuracy: what the risc-v-gsp-rm-debugger test bed does and does not prove > Status: implemented, documented and tested (audit: docs/27-TOOL-AUDIT.md; value demos: docs/25-VALUE-VALIDATION.md). > This document is deliberately conservative. Treat every claim without a > recorded A/B as unverified. ## 1. Purpose risc-v-gsp-rm-debugger exists to measure how accurately Open-IOV's GSP emulation (`vgsp` and the in-kernel emulation) reproduces the behaviour of the real GSP firmware, and to make the firmware itself analysable. That makes accuracy a first-class deliverable, not an assumption. This document defines the fidelity levels, the measurement contract, and the rules for honest conclusions. ## 2. Fidelity levels | Level | Property | risc-v-gsp-rm-debugger today | |---|---|---| | **L0 — instruction semantics** | RV64IMAC executes as on the device core | high (QEMU TCG, same ISA family) | | **L1 — memory behaviour** | reads/writes/ordering as firmware expects | high for RAM-resident code, *conditional* on mapping the same physical layout | | **L2 — time/concurrency** | cycle counts, DMA latency, interrupt timing | **not modelled** (do not claim) | | **L3 — device environment** | falcon windows, WPR2, CSB/TRANSCOM, PMU, timers, FB DMA, IRQ routing | **absent** (roadmap) | The practical reading: risc-v-gsp-rm-debugger is an **execution and memory** microscope, not a timing or silicon model. Conclusions of the form "the firmware writes X before Y" are in scope; "the firmware takes N µs" is not. ## 3. The real boot chain vs a bare QEMU VM The physical path the project already proved is: ``` FWSEC (falcon) -> WPR2 carve -> Booter Load (SEC2) -> RISC-V start -> bootloader/appMain -> GSP-RM init -> RPC server ``` The GSP application's own entry supports this model: `_start` receives bootargs from the bootloader in `a0`–`a5` (bootargs PA/VA, ELF PA/size, load base PA, write-protected-region id), sets `stvec`, sets its stack, and calls `appMain` (see `uproc/gsp/src/kernel/start.S`). It expects falcon/CSB register windows, a TCM/MPU layout and a PMU-provided environment that `qemu virt` does not have. **Therefore:** loading the raw `.fwimage` into `qemu virt` cannot boot it. The `./risc-v-gsp-rm-debugger.sh probe` command is designed for exactly this: it loads the segments, runs bounded, and reports the first divergence (`guest_errors,unimp,int` log + stopped PC + symbol). That report is a *memory and control-flow map* of what the firmware tries to touch first — useful data, but not a boot. **Measured first-touch (2026-10-02, TU104 570.144 image).** The firmware enters at relocated `0x84009000`, executes six instructions, and faults at firmware vaddr `0x4009014` on a 4-byte read of `0x2000000000000A00` (load access fault), after which it falls into an `mtvec=0` fetch loop. That address is the first entry for the R1 device model's register map. ## 4. Re-hosting the uproc components (the higher-fidelity path) The GSP firmware contains the uproc components (`gsp`, `os/libos`, `nvriscv`, `sec2*`, `soe*`, `pmu_sw`, `conf_compute`, …). Re-hosting them means compiling a *subset* against a QEMU-virt platform shim: | Area | Can be faithful | Cannot be faithful | |---|---|---| | task/RPC logic, parsers, state machines | yes — this is ordinary code | — | | memory layout of app-owned structures | yes, if schemas/addresses are pinned | TCM/MPU protections | | libos scheduler semantics | approximated (round-robin, timers) | real interrupt latencies, partition switching | | register/CSB access, falcon windows | stubbed with recorded behaviour | true device semantics | | PMU/SEC2/ACR/Booter interactions | modelled as messages | boot ROM, secure state machines | Re-host fidelity must be stated per module in the session metadata, and every "this is what the firmware does" claim should be cross-checked against the physical RPC traces (PLAN B) before it is used to change the emulation. ## 5. Measurement contract for `vgsp` accuracy Define these metrics once and use them everywhere: | # | Metric | How it is measured | |---|---|---| | M1 | **Inventory coverage** | set of controls/RPCs observed in a real run vs the emulation's handled set (and risc-v-gsp-rm-debugger's observed set) | | M2 | **Reply agreement** | field-by-field diff of replies (real vs emulated); canonical-size and consumed-field checks included | | M3 | **Ordering agreement** | sequence alignment of the control/event stream (edit distance / LCS) | | M4 | **State agreement** | state-machine transitions observed in the firmware vs the emulation's internal state model | | M5 | **Error-path agreement** | injected faults produce the same status/notifier path | | M6 | **Memory side-effects** | read/write map agreement against the emulation's shadow state; snapshot hashes for fixed points | | M7 | **Timing** | *not claimed*; only order-of-events budgets (e.g. "reply before the 4 s poll") | Reference capture: * real hardware/backend: the project's existing RPC logs (module trace, `gsp-phys-log-dump`, status-queue drains) and the static-config oracle; * risc-v-gsp-rm-debugger: `events.jsonl` + snapshots, symbol-annotated. Comparison: `./risc-v-gsp-rm-debugger.sh compare dumps/real- dumps/greeneye- --symbols`, then a short table of M1–M6 with counts. Never publish a single "accuracy %" number without the metric breakdown. ## 6. Adversarial interoperability use risc-v-gsp-rm-debugger is also a safe place to be adversarial: corrupt a reply, flip a capability bit, truncate a control payload, or inject a fault at a chosen firmware PC, then observe whether the emulation and the firmware agree on the failure path. The rules: 1. The simulator's reaction is *evidence about the firmware*, not about silicon. Confirm any conclusion against a physical cycle before it changes the product. 2. Keep the injected fault and the observed path in the session recording. 3. Do not use simulator timing as a security proof (side-channel claims need physical measurement). ## 7. Validating the tool itself Before trusting a risc-v-gsp-rm-debugger session: * the demo firmware self-test must pass (`./risc-v-gsp-rm-debugger.sh demo`, `make test`); * the session must contain the expected `hook`/`watch` registrations and a coherent `bp_hit` sequence (the analyzer highlights empty sessions); * the UART banner and control-block magic are cheap liveness checks; * golden sessions (checked-in expectations) for the demo detect regressions in the toolchain itself. ## 8. Known accuracy gaps (living list) 1. No TU104 device model: no boot beyond the first unmapped access. 2. No time/concurrency model; multi-core and partition-switch behaviour is approximated. 3. PMU/SEC2/ACR/Booter behaviour is message-level only. 4. Re-hosted uproc code is compiled for `qemu virt`, so compiler/layout differences with the shipped image must be accounted for when comparing control flow. 5. Interrupt delivery and MSI semantics differ; error-path M5 is the weakest metric until the device model exists (08). Each gap maps to a roadmap item; do not silently ignore them in reports.