diff options
Diffstat (limited to 'debug/risc-v-gsp-rm-vm/docs/43-GMMU-PTE-DECODER.md')
| -rw-r--r-- | debug/risc-v-gsp-rm-vm/docs/43-GMMU-PTE-DECODER.md | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/debug/risc-v-gsp-rm-vm/docs/43-GMMU-PTE-DECODER.md b/debug/risc-v-gsp-rm-vm/docs/43-GMMU-PTE-DECODER.md new file mode 100644 index 0000000..ea6d3d4 --- /dev/null +++ b/debug/risc-v-gsp-rm-vm/docs/43-GMMU-PTE-DECODER.md @@ -0,0 +1,206 @@ +# 43 — GMMU PTE/PDE decoder for TU104 (in development) + +> **Status: in development (2026-10-03, G2 work package).** This page +> documents `sim/gmmu_pte.py`: a clean-room decoder for captured Turing +> (TU104) GMMU page-table entries. It is decode-only tooling — no hardware, +> no kernel module, no mdev, no guest, no RM 610. Development-only, never +> shipped. +> +> **Rule: decode captured data only; validate against a capture before +> trusting.** Every field position below is a reverse-engineering result; +> none of it is a silicon-accuracy or timing claim (`06-ACCURACY.md` +> fidelity levels apply). + + +## 1. What this is — and is not + +`sim/gmmu_pte.py` turns a captured page-table value or blob into named +fields with exact bit positions. It is **not** a page-table walker: it never +dereferences a decoded address, never reads a target table, and never fills +a gap with a guess. Unsupported encodings and levels raise `E_UNSUPPORTED`; +set bits that no named field covers are reported (`reserved_bits` / +`reserved_mask`) and never dropped. + +The evidence base is the Turing GMMU entry-format definitions (field names, +bit ranges, aperture/KIND numeric IDs) together with the driver's own +page-table encoder/decoder behaviour, which is what proves which of the +several described encodings Turing actually uses (VER2) and how the +page-tree geometry maps to virtual-address bits. + +## 2. Encodings shipped + +| Encoding | Size | Used for | +|---|---|---| +| `ver2` | 8 bytes | VER2 leaf PTE and directory PDE — the encoding the Turing driver's page-tree path programs | +| `ver2_dual` | 16 bytes | VER2 dual PDE0 slot for mixed 64K/4K page tables: BIG half (low 64 bits) + SMALL half (high 64 bits) | + +Known-but-unsupported encodings (explicit `E_UNSUPPORTED`): the older +non-VER2 PTE/PDE encoding and the "NEW"/VER1 encodings also described by the +same register definitions. They are not shipped because the Turing driver's +page-tree path uses VER2; adding them without a capture to validate against +would be unverified surface. See §8. + +## 3. VER2 leaf PTE (8 bytes) + +| Field (our name) | Bits | Meaning | +|---|---|---| +| `valid` | 0 | entry is present | +| `aperture` / `aperture_name` | 2:1 | 0 video, 1 peer, 2 system coherent, 3 system non-coherent | +| `volatile` | 3 | cache/volatility bit: 0 = cached, 1 = volatile (the format's cache-related field) | +| `encrypted` | 4 | encrypted memory | +| `privilege` | 5 | privileged access | +| `read_only` (`writable`) | 6 | write protection | +| `atomic_disable` | 7 | atomics disabled | +| `address_sys` | 53:8 | system-aperture address bits (PA 53:12) | +| `address_vid` | 32:8 | video/peer address bits (PA 36:12) | +| `peer_id` | 35:33 | peer/fabric id (peer aperture) | +| `comptagline` | 55:36 | compression tag; overloaded as high address bits for the documented 47-bit peer case | +| `kind` / `kind_name` | 63:56 | memory kind id (see §6); unknown ids are reported, not guessed | + +## 4. VER2 directory PDE (8 bytes) + +| Field (our name) | Bits | Meaning | +|---|---|---| +| `is_pde_pointer` / `is_leaf` | 0 | 0 = pointer to a lower table, 1 = 2 MB leaf PTE stored at PDE0 | +| `aperture` / `aperture_name` | 2:1 | 0 invalid, 1 video, 2 system coherent, 3 system non-coherent | +| `volatile` | 3 | as PTE | +| `no_ats` | 5 | skip the ATS lookup for the covered range (driver sets it at depth 2) | +| `address_sys` | 53:8 | next-table address bits (system aperture) | +| `address_vid` | 32:8 | next-table address bits (video aperture) | +| `peer_id` | 35:33 | peer/fabric id | + +Note the aperture-id difference: for a leaf PTE aperture 0 is video memory; +for a directory PDE aperture 0 is invalid. + +## 5. VER2 dual PDE0 (16 bytes) + +The BIG half is the low 64 bits, the SMALL half the high 64 bits. Bit 0 +applies to the whole slot. + +| Field (our name) | Bits | Meaning | +|---|---|---| +| `is_pde_pointer` / `is_leaf` | 0 | whole-slot discriminator | +| `aperture_big` | 2:1 | 0 invalid, 1 video, 2 system coherent, 3 system non-coherent | +| `volatile_big` | 3 | as PTE | +| `no_ats` | 5 | ATS skip; lies inside the BIG address field (see §7) | +| `address_big_sys` | 53:4 | BIG target address; stores address >> 8 (PA 57:8) | +| `address_big_vid` | 32:4 | BIG target address, video aperture | +| `peer_id_big` | 35:33 | BIG peer/fabric id | +| `aperture_small` | 66:65 | as `aperture_big` | +| `volatile_small` | 67 | as PTE | +| `address_small_sys` | 117:72 | SMALL target address; stores address >> 12 (PA 57:12) | +| `address_small_vid` | 96:72 | SMALL target address, video aperture | +| `peer_id_small` | 99:97 | SMALL peer/fabric id | + +Bits 54–64, 68–71 and 118–127 are unnamed by the format definitions and are +reported as reserved when set. + +## 6. Page-tree geometry and KIND ids + +Turing's page-tree path inherits the Pascal/Volta geometry and uses the VER2 +entry encoding. Depths are root (0) to leaf (4): + +| Depth | HW level | VA bits | Index bits | Entry size | Role | +|---|---|---|---|---|---| +| 0 | PDE3 | 48:47 | 2 | 8 | pointer PDE | +| 1 | PDE2 | 46:38 | 9 | 8 | pointer PDE | +| 2 | PDE1 | 37:29 | 9 | 8 | pointer PDE (NO_ATS here) | +| 3 | PDE0 | 28:21 | 8 | 16 (dual) / 8 (2 MB leaf) | dual 64K/4K PDE, or a 2 MB leaf PTE | +| 4 | PTE | 20:12 (4 KB) / 20:16 (64 KB) | 9 (4 KB) / 5 (64 KB) | 8 | leaf PTE | + +Supported page sizes: 2 MB (depth 3), 64 KB and 4 KB (depth 4); VA width 49 +bits. A leaf entry alone does not tell 4 KB from 64 KB — the table's depth +and page-size context do, so the decoder reports `page_size` as +`4k_or_64k` when the depth is pinned to 4. + +The PTE `kind` field carries numeric ids (243 named values re-derived from +the format definitions). Common compute values: `0x00 PITCH`, +`0x06 GENERIC_MEMORY`, `0x07 INVALID`, `0x0F SMSKED_MESSAGE`, +`0xFE GENERIC_16BX2`. Unknown ids decode as `kind_name: null`, +`kind_known: false` with the raw value preserved. + +## 7. Address decode and uncertainty + +* System apertures (`system_coherent_memory`, `system_non_coherent_memory`): + the reconstructed `address` is complete (`address_complete: true`). +* Video/peer apertures: only the low address bits are unambiguous + (`address_complete: false`). `comptagline` is a compression tag in the + normal case and is documented as overloaded for 47-bit peer addresses; the + decoder therefore does not claim a complete video address. +* Dual BIG address: the field stores `address >> 8`, so `address` is + reconstructed as `field << 8`. Bit 5 of the slot is named `no_ats` and also + lies inside the BIG address field (address bit 9). The decoder reports the + flag from bit 5 and excludes that bit from the reconstructed BIG address; + the raw `address_big_sys` / `address_big_vid` fields keep the bit visible. + This assumes the target table is 4 KB aligned, which is the normal GPU + allocation granularity — if a capture shows a non-aligned target, treat + that entry as an unexplained case, not as proof of a different format. +* Reserved-bit policy: `reserved_bits` lists every set bit not covered by a + named field; `reserved_mask` is the same set as a mask. Nothing is + silently dropped. +* The VER2 PTE has no separate cache field: `volatile` (bit 3) is the only + cache-related bit the format defines, so no cache encoding is invented. +* `decode_table` is little-endian and never follows pointers; a blob whose + length is not a multiple of `entry_size` raises `E_TRUNCATED`, an empty + blob decodes to `[]`. + +## 8. Supported levels and explicit gaps + +`levels` may pin the page-tree depth (0–4) or a sequence of acceptable +depths. `None` (default) uses the full supported set and lets each entry's +bit-0 discriminator choose between the leaf-PTE and directory-PDE views, +reporting `level: null` plus `level_candidates` instead of guessing a single +depth. Any depth outside 0–4 raises `E_UNSUPPORTED`. + +Explicit gaps (never guessed): + +1. Pre-VER2 and "NEW"/VER1 encodings are not decoded (`E_UNSUPPORTED`). +2. The decoder does not walk tables, resolve virtual addresses, or infer a + 4 KB vs 64 KB leaf page size from the entry alone. +3. No capture has been validated yet: the golden vectors are constructed + field-by-field from the format definitions, not sampled from silicon. + **Validate against a real capture before trusting a decode.** +4. No timing, device-environment, isolation or security claim is made; the + simulator fidelity levels in `06-ACCURACY.md` apply. + +## 9. Usage + +Python: + +```python +from sim.gmmu_pte import decode_pte, decode_table + +pte = decode_pte(0x0600000000123456, pte_kind="ver2") +entries = decode_table(blob, base_pa=0x2000, entry_size=8, levels=4) +dual = decode_table(blob16, base_pa=0x2000, entry_size=16, kind="ver2_dual", + levels=3) +``` + +CLI: + +```bash +# one entry (default role "auto": bit 0 picks leaf vs directory) +python3 -m sim.gmmu_pte --value 0x0600000000123456 --role pte +python3 -m sim.gmmu_pte --value 0x0600000000123456 --json + +# a captured table blob, with the blob's GPU physical base address +python3 -m sim.gmmu_pte --blob table.bin --base-pa 0x2000 +python3 -m sim.gmmu_pte --blob table.bin --base-pa 0x2000 --levels 4 --json + +# a dual PDE0 slot +python3 -m sim.gmmu_pte --blob dual.bin --base-pa 0x2000 \ + --kind ver2_dual --entry-size 16 --levels 3 --json +``` + +Exit code 0 on success; 2 with an `E_*` code on stderr for unsupported +kinds/levels, truncated blobs or bad values. JSON output is sorted-key and +deterministic. + +## 10. Tests + +`tests/test_gmmu_pte.py` builds every vector field-by-field from the tables +above, asserts field round-trips, reserved-bit reporting (including the +unnamed dual bit 64 and the unnamed PDE bits 4, 6, 7, 54–63), the NO_ATS +overlap behaviour, unknown-kind reporting, unsupported kind/level/entry-size +errors, empty and truncated blobs, deterministic output, and CLI success and +error paths. 44 constructed golden entry vectors across 43 tests. |
