summaryrefslogtreecommitdiffstats
path: root/debug/risc-v-gsp-rm-vm/docs/06-ACCURACY.md
blob: e55162d417e93f45758b786f2ec8011ec613809e (plain)
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

> 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
(`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 `./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 `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: `./risc-v-gsp-rm-debugger.sh 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 (`./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.