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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
# 37 — Simulator vs the QEMU line: evaluation harness + real RE proof
> **Status: in development (2026-10-03).** This document is the S4 (value
> validation) record for the standalone GSP simulator workstream. It defines
> the evaluation harness, freezes the thresholds used, reports the first
> measured A/B run on the real TU104 570.144 image, and records the U51
> real-reverse-engineering demonstration. Nothing here is a product claim:
> simulator evidence is L0/L1 (docs/06).
>
> **Update (2026-10-03, later):** S1 (device model + profiles + boot shim)
> landed and the harness was wired to it; §4.3 records the re-measured A/B
> where the native side is the S1 `sim.gsp_boot` path (verdict `above` on the
> frozen checks). §4.1/§4.2 remain the pre-S1 measured record, and §7's
> "S1 not landed" limit applies only to those sections.
>
> **Artifacts:** `harness/sim_qemu_line.py` (A/B harness),
> `tests/test_sim_qemu_line.py` (shape + determinism + QEMU regression),
> `harness/re_demo.py` + `harness/re-demo-report.md` (real RE proof).
> **Line definition source:** docs/35-GREENEYE-SIMULATOR-DESIGN.md §1.1 and
> the boot ladder in §3.3.
---
## 1. The line being evaluated
The QEMU line (docs/35 §1.1) is the v0.1/v0.2 tool behaviour on the real
image: hooks/watchpoints, memory/struct/snapshot tooling, sessions, symbols
and analyze/compare, probes/plugins, Ghidra bridges, trace, injection SDK and
`Session.call`/`run_until`, plus the documented first fault at firmware vaddr
`0x4009014` (4-byte read of `0x2000000000000A00`).
The boot ladder (docs/35 §3.3) is `pre-B0` (image loads, first MMIO observed
*as a fault*) < `B0` (first MMIO observed; lenient) < `B1` (first fault past
the QEMU point, explained by device semantics) < `B2` (boot-stage progress) <
`B3` (first mailbox poll) < `B4` (message loop) < `B5` (one scripted message
served).
**"Above the QEMU line"** requires *all* of the frozen checks in §3,
including the docs/35 §1.1 requirement that the milestone be reached "with
the device model and shims documented". Lenient MMIO is an observation
mechanism, not a device model, so it cannot satisfy the contract by itself.
## 2. Method
Everything is stdlib-only, bounded (`<= 2,000,000` native instructions,
`<= 10 s` QEMU), and touches no hardware, GPU, mdev, module, guest or network.
```bash
cd open-iov/debug/risc-v-gsp-rm-vm
python3 harness/sim_qemu_line.py # A/B harness -> harness/qemu_line/
python3 -m unittest tests.test_sim_qemu_line -v
python3 harness/re_demo.py # U51 proof -> harness/re-demo-report.md
```
* **QEMU side** — `harness.common.open_flat_session` (the same relocation and
`guest_errors,unimp,int` logging as `greeneye probe`), bounded run, first
exception parsed from the bounded head of the log (trap loops flood it),
first-touch device map harvested, session recorded with the log blob.
* **Native side** — a discovered S1 profile runs `sim.gsp_boot` (device model
+ recorded boot shim) twice and reports the observed rung; without one, the
lenient `sim.gsp_profile.run_profile` baseline (deterministic RV64IMAC,
modeled cycles) runs twice with `greeneye.device_map` for MMIO. S1's
profile is discovered defensively (`sim.devices` Python entry points, then
`sim/profiles/*.json` matched by firmware sha / `sim/devices/*.json`); when
absent the run is the lenient `B0` baseline and the report says so.
* **Feature matrix** — exercised on the bundled demo firmware
(`firmware/uproc_demo`): hooks, breakpoints, watchpoints, memory, struct
decode, sessions, analyze/compare, exec trace, injection SDK. MCP is
recorded `not_run` here to keep this harness independent of the MCP surface
(the native MCP tools are tested in `tests/test_mcp.py`; docs/20).
## 3. Frozen thresholds (2026-10-03, before the first measurement)
Stored in `harness/sim_qemu_line.py:FROZEN_THRESHOLDS` and
`harness/re_demo.py:FROZEN_THRESHOLDS`; they are never moved silently.
| check | threshold | why |
|---|---|---|
| `qemu_first_fault_reproduced` | QEMU reproduces fw `0x4009014` / `0x2000000000000A00` | otherwise the two sides are not comparable |
| `native_above_qemu` | native rung >= QEMU rung + 1 | the line's rung rule |
| `identical_runs` | 2 identical native runs (key fields) | determinism is a docs/35 §1.1 requirement |
| `native_pair_wall_s` | <= 20 s for the two native runs | keeps the harness usable |
| `device_model_documented` | a discovered S1 device map/profile is used | docs/35 §1.1 "with the device model and shims documented" |
`re_demo.py` additionally freezes: emulator wall <= 120 s, 5 answers present,
2 identical lenient runs, milestone past the QEMU point; the manual static
baseline is a documented **floor estimate** of 600 s (method note in the
script: ~90 instructions across three sections read by hand and correlated
with the QEMU fault report; not measured).
## 4. Measured results (2026-10-03)
### 4.1 A/B harness on the real image
Firmware `gsp-570.144.fwimage.bin`, sha256 `2d1bb5c60b208cfd…`; S1 absent at
run time (`sim/devices/` and `sim/profiles/` not present), so the native side
ran lenient.
| side | ran | rung | instructions | cycles (modeled) | stop | wall s | evidence |
|---|---|---|---:|---:|---|---:|---|
| QEMU probe | yes | `pre-B0` | – | – | `fault_load` fw `0x4009014` -> `0x2000000000000A00` | 0.95 | `harness/qemu_line/sessions/qemu-probe` |
| native run 1 | yes | `B0` | 200,000 | 200,012 | `budget@0x4009070` | 0.21 | `harness/qemu_line/sessions/native-1` |
| native run 2 | yes | `B0` | 200,000 | 200,012 | `budget@0x4009070` | 0.22 | `harness/qemu_line/sessions/native-2` |
Wall figures are from one measured run (host-load dependent); re-run the
command for current numbers. Session hashes for the record are in
`harness/qemu_line/sim-qemu-line.json`.
* first-touch match with the documented reference: **true** (same address,
same 4-byte read, same fw PC);
* identical across the two runs: **true**; session compare ran (breakpoint,
watchpoint and written-page deltas);
* verdict: **`above_lenient_only`** — rung progress exists (`B0` is one past
`pre-B0`) but the device-model check fails, so `above_qemu_line = false`.
This is the honest underclaim: the native run observes and continues past
the QEMU fault, but lenient MMIO is not device semantics.
* native feature matrix (demo firmware): `hooks`, `breakpoints`, `watch`,
`memory`, `struct`, `sessions`, `analyze_compare`, `trace`, `injection` all
**pass**; `mcp` **not_run** (S3-owned).
* session hashes for every side/session are in
`harness/qemu_line/sim-qemu-line.json` and rendered in `.md`.
Expected delta when S1 landed (realised; see §4.3): `device_model_used = true`,
rung `B2` because the model serves the QEMU first touch and the shim reaches
the relocation stage, and `verdict = above` because the run stays deterministic
and within the wall bound. S1's profile is picked up automatically from
`sim/profiles/*.json` when its `firmware.sha256` matches (or pass
`--device-map FILE` for an observational map).
### 4.2 Real RE proof (U51)
Scenario: *what happens on the real GSP image between entry and the first
fault/milestone, and what does the state tell us about boot?*
| side | method | wall s | answers |
|---|---|---:|---|
| baseline | QEMU probe (measured, 0.5 s bound) | 0.99 | first fault only |
| baseline | manual static reading (floor estimate) | 600 | entry->fault path by hand |
| baseline | **total** | **600.99** | full question |
| emulator | 3 recorded native sessions (`harness/re_demo.py`) | **0.13** | full question + evidence |
Frozen threshold: emulator wall <= 120 s, 5/5 answers present, two identical
lenient runs, milestone past the QEMU point. Result: **PASS** (all checks
true). Session hashes and the JSON answers are in `harness/re_demo/result.json`
and `harness/re-demo-report.md`.
Answer (evidence-backed; simulator L0/L1, no silicon claim):
1. **First touch:** a 4-byte read of PA `0x2000000000000A00` at fw PC
`0x4009014`; it is exactly the QEMU-documented first fault.
2. **Path:** the entry state is all-zero (no bootloader handoff is modelled);
`.bootstrap` materialises the device PA with five arithmetic instructions,
reads it, then runs a chip-ID comparison chain — 25 executed instructions
from entry to the halt (exec trace).
3. **Field:** the read value's bits `[28:20]` are extracted (`srli 20`,
`andi 0x1ff`) and compared against `354..360` (Turing IDs) and `368`
(Ampere ID).
4. **Dispatch:** `354..360` jumps to `.tu10x_text` at `0x4007000`; `368`
jumps to `.ga100_text` at `0x4005000`; any other value (including the
lenient zero) falls into the fail-closed `j .` loop at `0x4009070`.
5. **Next blocker (B1 candidate):** with a Turing ID served from a one-entry
device map, `.tu10x_text` programs CSRs `0x7c8–0x7cc` (region
descriptors), enables `mstatus` FP/SIMD state, builds the **absolute**
link-time address `0x40070f8` and jumps to it. Because the loader
relocates segments but not absolute immediates, that jump lands outside
RAM and faults (first fault past the QEMU point, 74 instructions). The
next rung therefore needs a chip-ID device model **plus** load-at-link
address (or alias/translation of absolute immediates); the modeled ID
value itself is an assumption (the QEMU baseline faults before reading
it), while the field position and the compared IDs are firmware evidence.
### 4.3 Re-measurement after S1 landed (2026-10-03, later)
The harness now discovers the S1 `greeneye-sim-profile/1` document
(`sim/profiles/*.json`, matched by `firmware.sha256`) and runs the native side
through `sim.gsp_boot` (device model + recorded boot shim) instead of lenient
MMIO. Frozen thresholds unchanged. Measured run on the same image
(sha256 `2d1bb5c60b208cfd…`):
| side | ran | rung | instructions | cycles (modeled) | stop | wall s | evidence |
|---|---|---|---:|---:|---|---:|---|
| QEMU probe | yes | `pre-B0` | – | – | `fault_load` fw `0x4009014` -> `0x2000000000000A00` | 0.98 | `harness/qemu_line/sessions/qemu-probe` |
| native run 1 | yes | `B2` | 14,682 | 27,294 | `fault@0x400EA0C` (DMEM runspace unknown) | 0.16 | `harness/qemu_line/sessions/native-1` |
| native run 2 | yes | `B2` | 14,682 | 27,294 | `fault@0x400EA0C` | 0.17 | `harness/qemu_line/sessions/native-2` |
* `device_model_used = true`, `device_model_documented = true`,
`identical_runs = true` (device-state sha256
`3fa264b9f81081e8…` on both runs), `native_pair_wall_s = 0.33`,
`native_above_qemu = true`; **verdict `above`** on all five frozen checks.
* milestones observed: `bootargs_consumer`, `relocation_copy`;
`unknown MMIO = 0`, `device_unhandled = 0`.
* What this does **not** claim: B3/B4 are not reached (the run stops at the
documented DMEM-runspace unknown); the shim values are declared assumptions;
cycles are modeled (docs/32); no timing/device-environment claim.
* Command: `python3 harness/sim_qemu_line.py` (regenerates
`harness/qemu_line/sim-qemu-line.json|.md`). Wall figures are host-load
dependent.
## 5. Failure signals (when to disable, per U48/U56)
* Any frozen check false **with QEMU available and the firmware present**:
keep `above_qemu_line = false`, do not claim the line.
* `device_model_documented` still false at the Phase S pause review: the S1
work package has not met its acceptance; the harness keeps reporting
`above_lenient_only`.
* A feature matrix entry `fail`: disable that feature flag and record it as a
failed experiment; an entry silently stuck at `not_run` blocks the S4 exit.
* `re_demo.py` pass false: U51 is not satisfied; fix the tool chain before
any Phase G design work.
* Thresholds change only with a dated entry in this document; a moved
threshold without a measurement is a review failure.
## 6. Re-running / reproducing
```bash
cd open-iov/debug/risc-v-gsp-rm-vm
python3 harness/sim_qemu_line.py # full A/B + feature matrix
python3 harness/sim_qemu_line.py --no-qemu # native only, no baseline claim
python3 -m unittest tests.test_sim_qemu_line -v # shape/determinism/QEMU gate
python3 harness/re_demo.py # real RE proof
```
Without the 570.144 image the commands skip cleanly (exit 2 for the CLIs,
skipped tests), because the tool tree is used on machines without the
firmware. The QEMU side also needs `qemu-system-riscv64`; without it the
report is emitted with `unverified_qemu_absent`.
## 7. Honest limits
* **S1 partial** — the device model reaches B2 (relocation copy) with the
recorded boot shim; B3/B4 (CSB poll, message loop) are not reached and the
DMEM-runspace unknown is the documented ceiling (docs/36 §6). The §4.1
lenient record predates S1; §4.3 is the post-S1 measurement.
* **L2/L3 partial** — cycles are modeled (`rv64imac-modeled/1`, docs/32), not
measured; the device model is partial and carries per-register evidence
(docs/36). No timing or full device-environment claim is made.
* **MCP native surface not exercised here** — the A/B feature matrix records
it `not_run`; the native MCP tools have their own suite (docs/20 §9).
* **Modeled chip-ID value is an assumption** — only the field extraction and
the compared ID set come from the image; in the S1 profile the `0x164`
value is declared by the profile, and the boot shim values are declared
assumptions recorded in the session.
* **Relocation artifact** — the B1-candidate fault at `0x40070f8` is a
property of the bias-relocated harness, not of silicon; it is labelled as
such and not counted as a device milestone. (The S1 path loads at the link
addresses and does not use that relocation.)
* **Manual baseline is an estimate** — labelled a floor with its method; the
measured parts of the baseline (QEMU probe) are reproducible with the
harness.
|