1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
# 06 — Accuracy: what the risc-v-gsp-rm-debugger test bed does and does not prove
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
> 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
(`gsp-rm-vfio` 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 `greeneye 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 `gsp-rm-vfio` 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: `greeneye compare dumps/real-<run> dumps/greeneye-<run>
--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 (`greeneye 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.
|