summaryrefslogtreecommitdiffstats
path: root/debug/risc-v-gsp-rm-vm/docs/07-PORTABILITY-PLAYBOOKS.md
blob: 3c0f6583371c24644b4c13722ac5eb8f0ecde05a (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
# 07 — Portability playbooks: new GSP, new device, new architecture

> Status: implemented, documented and tested (audit: docs/27-TOOL-AUDIT.md; value demos: docs/25-VALUE-VALIDATION.md).

These playbooks cover the three churn axes the project expects: a new GSP
firmware version, the same firmware on a new device, and a new GPU
architecture (e.g. GB10 / DGX Spark / Surface-class). They reuse the
project's existing version discipline and add risc-v-gsp-rm-debugger's runtime layer.

## 0. Common setup

1. Acquire the firmware for the target (driver runfile or `linux-firmware`):
   extract the GSP boot image (`.fwimage`) and record its hash. For TU10x,
   `firmware/57X-GSP/<ver>/gsp-<ver>.fwimage.bin` is the extracted form.
2. Lay down a versioned directory; never overwrite a working version.
3. Build a symbol DB for the new image:
   * import the fwimage into the existing Ghidra project tooling
     (`tools/ghidra/analyze_fwimage.py`, `DecompileFunctions.java`),
   * `./risc-v-gsp-rm-debugger.sh symbols export --index <export.tsv> -o symbols-<ver>.json`.
4. Record a baseline session of the previous version (see P1.4) so the
   comparison has an anchor.

## P1. New GSP firmware version (same family)

**Goal:** know what changed in the firmware's runtime behaviour before the
emulation is adjusted.

1. **Static triage** — the project's existing flow: decompile the new
   fwimage, diff the RPC dispatcher, subcommands, message layouts and version
   strings against the previous version (`cudatool.py delta`-style discipline
   for firmware; `diff_corpus.py` for the corpus).
2. **Probe the new image** — `./risc-v-gsp-rm-debugger.sh probe <new.fwimage>`: record the
   first divergence and the first MMIO/read/write addresses. Compare with the
   previous version's probe; changed first-touch addresses are early
   structure-change signals.
3. **Re-host / demo run** — if uproc sources for the family are available,
   build the rehosted subset against the QEMU-virt shim and run the same
   scripted stimulus used for the previous version.
4. **Baseline + candidate sessions** — for each version capture:
   * `./risc-v-gsp-rm-debugger.sh record --kernel <rehosted elf> --duration N --snapshot <regions>`
     or the scripted harness (`run`),
   * the real-backend reference traces for the same workload.
5. **Compare** — `./risc-v-gsp-rm-debugger.sh compare dumps/<old> dumps/<new> --symbols`:
   hit-count deltas per function, watchpoint deltas, written-page deltas.
   Investigate every function whose call-count changed before touching the
   emulation.
6. **Metrics** — fill in M1–M6 from `06-ACCURACY.md` for the new version
   against the real backend. Attach the table to the version-bump PR.
7. **Acceptance** — no rung regression in the existing guest ladder, the
   control inventory diff is explained, and every new/changed control has a
   version-keyed handler or an explicit "not used" note.

## P2. Same GSP version, new device

**Goal:** prove device-profile portability (the project direction is
"configuration + verification, not new code").

1. Collect the device profile: PCI IDs, BAR layout/sizes, FB geometry,
   engine inventory, interrupt topology, VBIOS/ROM specifics.
2. Verify the firmware pairing: the image family (TU10x/GH100/LS10 …), FMC
   partition manifests, and the version string; a mismatched pairing presents
   as an emulation bug (the project learned this with 570.144 vs 570.211).
3. `./risc-v-gsp-rm-debugger.sh probe <device fwimage>` on the new device image; compare
   first-divergence maps with the reference device. Differences here usually
   point at profile data, not logic.
4. Re-run the P1.4/1.5 loop with the device profile applied; record probe +
   compare evidence in the portability matrix.
5. Validate on the physical device with the supervised harness before
   claiming support (`docs/06-portability/hardware-software-matrix.md`
   discipline: tested and documented, not "should work").

## P3. New architecture (GB10 / DGX Spark / Surface-class)

**Goal:** survive a new silicon generation (likely a newer NV-RISCV core,
newer PMU/SEC2 images and possibly RV64GC rather than RV64IMAC).

1. **Confirm the ISA and image shape** — `file`/`readelf` the new fwimage:
   ISA string, segments, entry, compressed/float extensions. Update the
   rehost build flags (`-march=…`) accordingly; note that QEMU supports
   RV64GC even if risc-v-gsp-rm-debugger's demo uses IMAC.
2. **Check the platform's boot variant** — newer platforms use FMC/manifest
   partition models (`uproc/*_riscv/fmc`, `safety/PMU-*`, `conf_compute`
   Init→ACR→RM flow). Record which partition model the image uses; the
   rehost shim needs a matching entry/return convention.
3. **PMU/SOE deltas** — diff the PMU/SOE headers and firmware
   (`pmu_sw`, `uproc/soe*`) because the GSP environment provisions identity
   and clock state through them. Any change here invalidates prior
   environment assumptions.
4. **Run the P1 loop** with the new architecture profile; expect the probe to
   show *different* first-touch addresses (new register windows). Update the
   device-model scope in `08-ROADMAP.md` with what the probe revealed.
5. **Host portability** — risc-v-gsp-rm-debugger itself is Python and QEMU; on aarch64
   hosts install `qemu-system-misc` there and the same commands run. Keep
   host-specific paths out of session metadata.

## P4. A/B: bare metal vs vfio-mdev (the core accuracy ritual)

**Goal:** quantify how closely the virtual function's emulation tracks the
real firmware for a chosen workload.

1. **Reference capture (real):**
   * hardware path: the supervised physical backend cycle, capturing RPC
     records/log dumps and the static-config oracle;
   * or the vfio-mdev path with the same workload.
   Save the reference event stream in a session-compatible form (or the
   vendor logs plus a conversion note).
2. **risc-v-gsp-rm-debugger capture:** run the same workload's firmware-side stimulus in
   the rehosted simulator; record hooks, watchpoints, snapshots.
3. **Compare:** `./risc-v-gsp-rm-debugger.sh compare` for hit/watch/write profiles; for RPC
   payloads use M2 field agreement and M3 ordering (a small script or a
   plugin can emit per-control events).
4. **Report:** metric table (M1–M6), changed-function list, and an explicit
   statement of L2/L3 limits from `06-ACCURACY.md`.
5. **Escalation:** a divergence that changes emulation behaviour must be
   reproduced on the physical backend before the fix lands; simulator-only
   divergence that cannot be reproduced is recorded as a fidelity gap.

## Evidence checklist (attach to any portability task)

* firmware hash + version string + pairing notes;
* `probe` output (first divergence, first-touch map);
* symbol DB hash and the Ghidra export provenance;
* session directories for baseline and candidate (or their sha256 list);
* `compare` report;
* M1–M6 table with the reference-capture method;
* unexplained diffs list (empty is a claim, not a default).