summaryrefslogtreecommitdiffstats
path: root/debug/risc-v-gsp-rm-vm/harness/value_demos/README.md
blob: e1a450c546a972eadb0cce13fd820f93792c52bf (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
# green-eye value-validation demos

Runnable demonstrations that tie green-eye tool capabilities to **real**
Open-IOV scenarios (cited from `Handoff-vGPU-IO.md` and the project docs) and
measure the time-to-value against the static/Ghidra-only baseline.

Each demo:

* names the real scenario (handoff PART/addendum + date) and what it cost;
* prints the question, the green-eye commands used, the answer, the evidence
  artifact and the elapsed wall-clock;
* writes a machine-readable `result.json` under `artifacts/<demo>/`;
* labels what is **measured on the analog** vs **projected for the real
  case**; device-model-blocked scenarios say so explicitly.

> green-eye is development-only tooling (docs/00); these demos never touch
> hardware, a guest or a kernel module. The real `.fwimage` cannot boot
> without the H2 device model (docs/06 §3), so every demo is honest about
> being a *shape* reproduction on the bundled `uproc_demo` firmware + native
> RV64 simulator / QEMU.

## Run

From the tool root (`open-iov/debug/risc-v-gsp-rm-vm`):

```bash
make demo                            # once: build firmware/uproc_demo/build/uproc_demo.elf
make sdk                             # optional (s06): builds sdk/build/injected_demo.elf

python3 harness/value_demos/run_all.py                     # all 10, results JSON
python3 harness/value_demos/run_all.py --only s01,s04,s05  # subset
python3 harness/value_demos/s01_reply_consumer.py          # one demo, verbose

VALUE_DEMO_BACKEND=qemu python3 harness/value_demos/run_all.py   # force QEMU
```

Defaults: native backend (deterministic, in-process) for s01–s08; QEMU for
s09/s10 (with a native fallback if QEMU is absent). `VALUE_DEMO_BACKEND`
overrides all of them. No hardware is required.

The aggregate lands in `artifacts/results.json`; each demo writes under
`artifacts/<name>/` (results, sessions, TSVs, reports). The runner enforces a
per-demo timeout and the full suite runs in ~18 s on the reference host
(budget: each demo < ~30 s, suite < ~3 min).

## Demos

| # | Script | Real scenario (source, date) | Static/Ghidra-only baseline | Analog answer |
|---|---|---|---|---|
| s01 | `s01_reply_consumer.py` | 0x59 RM-init chase; fn72/fn73 hidden error (PART 91 + ADDENDA 2–7, 2026-10-01) | cycles 2–13, ~5 h, 10+ supervised boots; reply was a generic `0x59` | hook dispatcher + watch `result`: every command consumed and its exact reply decoded (1.14 s) |
| s02 | `s02_counter_publication.py` | 20 GR per-channel counters; only 4/20 moved (PARTs 46–64, 2026-09-24…29) | ~5 days; slot layout re-derived per boot; ~2–3 s pin vs ~2 s deadline | 20/20 slots published, each store PC captured (1.34 s) |
| s03 | `s03_unknown_command.py` | unknown/new control discovery; injected slots 16–23 (docs/19, 2026-10-02) | read the indirect dispatch table per stripped image | 24 IDs swept + classified: 6 known, 8 injected-slot, 10 default (5.96 s) |
| s04 | `s04_run_until_function.py` | RM-client ladder reachability per rung (PART 91 ADDENDUM 9 cycles 18–25, 2026-10-01) | ~1 h 41 m / 8 supervised cycles | natural run / timeout / trigger / direct call in one session (0.24 s) |
| s05 | `s05_snapshot_diff.py` | fn72 identity fix + 1656-B static-config reply (PART 91 ADDENDUM 6/7, 2026-10-01) | malformed field suspected statically; a live boot per fix iteration | every changed byte attributed to a named schema field (0.50 s) |
| s06 | `s06_inject_service.py` | P6 service wiring / guest CE copies (PART 92 ADDENDA 5–11, 2026-10-02) | kernel rebuild + supervised cycle (~5–8 min) per rung | service blob loaded, registered, invoked both routes (0.63 s) |
| s07 | `s07_version_diff.py` | 570.144 vs 570.211 pairing disproof; semantic diff (PART 91 cycles 2–3, 2026-10-01) | one full boot per version + manual log compare | same stimulus on two builds; exactly one reply field moved (1.14 s) |
| s08 | `s08_mutation_triage.py` | error-path corpus / fail-closed rules (R5; docs/19 §3.4, docs/18 §2) | hand-derived asserts and NOCAT records across cycles | 7 seeded mutations classified ok/fault/no-progress (1.82 s) |
| s09 | `s09_grabbing_a_ghidra_address.py` | static/dynamic join; GPFIFO GET fault `0x40000` vs `0x101000` (PART 91 ADDENDUM 9 cycle 24) | hypothesis unproven until the decoded status-queue fault (8 cycles) | Ghidra addr + bias = runtime; hook hit + `greeneye_hits.tsv` (0.72 s) |
| s10 | `s10_full_session_evidence.py` | evidence pack for a milestone (docs/14 §6; cycles 11–13, 2026-10-01) | hashes/sessions/logs/compare gathered by hand per cycle | one run → analyze + compare + hits + manifest + M1–M6 (4.92 s) |

Times are the measured green-eye path on the reference host (native for
s01–s08, QEMU for s09/s10); see `artifacts/results.json` for a fresh run.

## Projected vs measured

* **Measured:** every analog result, elapsed time, session size, trace
  slowdown and slot/reply count in `result.json`.
* **Projected (labelled `projected` in each result):** the real-case time
  saving. No demo claims a real-GSP result the simulator cannot reach.
* **Blocked (`blocked_on_device_model: true`):** all real-firmware claims
  wait on the H2.2 device model; the workflow is demonstrated on the analog.

## Tests

```bash
python3 -m unittest tests.test_value_demos -v   # 5 tests, ~5 s
```

The suite runs the fastest demos end-to-end as subprocesses, asserts their
answers and checks `run_all.py` emits `artifacts/results.json`. It skips
cleanly when QEMU or the demo firmware is absent. See
[`docs/25-VALUE-VALIDATION.md`](../../docs/25-VALUE-VALIDATION.md) for the
methodology, overhead analysis and scenario representativeness argument.