summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-04 10:13:21 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-04 10:13:21 -0500
commit392d62f860a6d8250d4a7331693219deb54e3c07 (patch)
tree78663fd10c270684f2bb1eb8c4a7f6f1ec824333
parenta33490a4d18801c30fa42f91f39f9129c49ea3da (diff)
downloadopen-iov-392d62f860a6d8250d4a7331693219deb54e3c07.tar.gz
open-iov-392d62f860a6d8250d4a7331693219deb54e3c07.zip
vgsp-mme: golden-only completion + mme-audit tool - accept golden slot 0 (entry=0 valid) + sema_gl_mme_golden_only=1 force-blanks non-golden called slots (stub/drop their CALL runs), overlay logs inspected/blank/maxa; tools/mme-audit: stdlib overlay-sim + booter-grammar walk + operand map + cross-boot table (decodes the r1448 slot-57 stall: IR 899-900 emits PIPELINE_BINDING(2) @0x2090 rejected only when the program-address pairs are carried)
-rw-r--r--kernel/gsp_phys_booter.c123
-rw-r--r--tools/mme-audit/mme_audit.py570
2 files changed, 689 insertions, 4 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 073d7a3..fdeed09 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -18239,7 +18239,23 @@ module_param_named(sema_gl_mme_golden_force, gsp_phys_rmcall_gr_mme_golden_force
MODULE_PARM_DESC(sema_gl_mme_golden_force,
"Force the golden overlay over captured slots too (A/B for a stale capture; default 0 = fill uncovered only)");
+/*
+ * r1448 STRATEGY 3.3 (golden-completion): with golden_force on, a called
+ * slot the golden library cannot serve is stubbed (SA pair -> harmless
+ * end-noop) and its CALL runs are dropped, and its captured body is
+ * zeroed in the packed IR - only golden bodies can execute. This closes
+ * the r1447 residual (slot 0, entry 0, was the one executed non-golden
+ * body). 0 = pre-r1448 behavior (capture bodies of non-golden slots may
+ * execute).
+ */
+static bool gsp_phys_rmcall_gr_mme_golden_only = true;
+module_param_named(sema_gl_mme_golden_only, gsp_phys_rmcall_gr_mme_golden_only,
+ bool, 0644);
+MODULE_PARM_DESC(sema_gl_mme_golden_only,
+ "Golden-only completion: with golden_force on, blank the packed body and stub/drop CALL runs of every slot the golden library cannot serve (default 1; 0 = current behavior)");
+
static u32 gsp_phys_gr_golden_log;
+static u32 gsp_phys_gr_golden0_log;
static int gsp_phys_gr_golden_slot(u32 j, u32 *entry, const u32 **words,
u32 *nwords)
@@ -18251,10 +18267,23 @@ static int gsp_phys_gr_golden_slot(u32 j, u32 *entry, const u32 **words,
if (j >= GOLDEN_MME_TU104_SLOTS || j >= 64u)
return 0;
gs = &golden_mme_tu104_sa[j];
- if (!(gs->flags & GMME_F_PRESENT) || !gs->words || !gs->entry)
+ if (!(gs->flags & GMME_F_PRESENT) || !gs->words)
return 0;
if ((u64)gs->off + gs->words > GOLDEN_MME_TU104_WORDS)
return 0;
+ /*
+ * r1448 STRATEGY 3.3: entry 0 is a valid IR address - slot 0's
+ * SETUP_FIXED_CONST body begins at IR word 0, and the window calls
+ * slot 0 (CALL at win-off 56). The pre-r1448 `!gs->entry` reject
+ * left slot 0 as the only executed non-golden body (r1447 54/55
+ * overlay). Accept it and log the acceptance once so the coverage
+ * change is visible in dmesg.
+ */
+ if (!gs->entry && !READ_ONCE(gsp_phys_gr_golden0_log)) {
+ WRITE_ONCE(gsp_phys_gr_golden0_log, 1u);
+ pr_info("vgsp-gr: MME-GOLDEN slot 0 accepted (entry=0 valid; golden body %u words)\n",
+ gs->words);
+ }
*entry = gs->entry;
*words = &golden_mme_tu104_words[gs->off];
*nwords = gs->words;
@@ -18262,6 +18291,23 @@ static int gsp_phys_gr_golden_slot(u32 j, u32 *entry, const u32 **words,
}
/*
+ * r1448 STRATEGY 3.3 golden-only completion: with golden_force on and
+ * the golden_only knob on, a slot the golden library cannot serve must
+ * never execute. Returns true when the slot is outside the golden corpus
+ * and has to be blanked/stubbed (fail-closed).
+ */
+static bool gsp_phys_gr_slot_golden_blank(u32 j)
+{
+ u32 gent, gn;
+ const u32 *gw;
+
+ if (!READ_ONCE(gsp_phys_rmcall_gr_mme_golden_only) ||
+ !READ_ONCE(gsp_phys_rmcall_gr_mme_golden_force))
+ return false;
+ return !gsp_phys_gr_golden_slot(j, &gent, &gw, &gn);
+}
+
+/*
* SESSION 153-CONTINUED-79: per-launch method-block word cap + prelude drain.
* The r1172-r1175 A/B: every beef launch whose emitted block exceeded ~2000
* words (3083-word full-SA prelude + window, 3315-3484 words) NEVER STARTED
@@ -19071,6 +19117,12 @@ static bool gsp_phys_gr_slot_kept(u32 j, u64 sa_mask, const u32 *sa_ent)
return false;
if (READ_ONCE(gsp_phys_rmcall_gr_nop_drop) & (1ull << j))
return false;
+ /*
+ * r1448 STRATEGY 3.3: golden-only means the kept-slot exemption
+ * cannot resurrect a body outside the golden corpus (fail-closed).
+ */
+ if (gsp_phys_gr_slot_golden_blank(j))
+ return false;
if (!READ_ONCE(gsp_phys_rmcall_gr_keep_clamp))
return true;
if ((sa_mask & (1ull << j)) && gsp_sema_mme_ir_covered(sa_ent[j]))
@@ -19110,6 +19162,13 @@ static bool gsp_phys_gr_slot_stubbed(u32 j, u64 sa_mask, const u32 *sa_ent)
*/
if (READ_ONCE(gsp_phys_rmcall_gr_nop_drop) & (1ull << j))
return true;
+ /*
+ * r1448 STRATEGY 3.3: no golden body, no execution - force-stub the
+ * slot so its captured body can never run (its CALL runs are then
+ * dropped and its SA pair points at the end-noop).
+ */
+ if (gsp_phys_gr_slot_golden_blank(j))
+ return true;
if (gsp_phys_gr_slot_kept(j, sa_mask, sa_ent))
return false;
/*
@@ -19805,6 +19864,7 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
if (sa_mask & (1ull << j)) {
if (!READ_ONCE(gsp_phys_rmcall_gr_sa_stub_all) &&
gsp_sema_mme_ir_covered(sa_ent[j]) &&
+ !gsp_phys_gr_slot_golden_blank(j) &&
!(READ_ONCE(gsp_phys_rmcall_gr_nop_drop) &
(1ull << j))) {
for (t = 0; t < sa_ncov; t++)
@@ -20599,7 +20659,8 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
* in mode 1 (the overlay then only logs).
*/
if (READ_ONCE(gsp_phys_rmcall_gr_mme_golden)) {
- u32 gj, goldn = 0;
+ u32 gj, goldn = 0, ginsp = 0;
+ u32 gblank = 0;
for (gj = 0; gj < 64u; gj++) {
u32 gent, gn, q;
@@ -20609,6 +20670,7 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
gj, &gent, &gw,
&gn))
continue;
+ ginsp++;
if (!READ_ONCE(gsp_phys_rmcall_gr_mme_golden_force)) {
/*
* Mode 1: only slots the
@@ -20636,10 +20698,63 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
sa_ent[gj] = gent;
goldn++;
}
+ /*
+ * r1448 STRATEGY 3.3: force-blank
+ * the captured bodies of every slot
+ * the golden library cannot serve so
+ * no capture word can survive - only
+ * golden bodies may execute
+ * (fail-closed). The zero range is
+ * bounded by the next captured SA
+ * entry, exactly the bound the
+ * capture fill above applied.
+ * Clearing the local sa_mask/sa_ent
+ * pair also unpublishes the slot
+ * from the SA re-arm; its CALL runs
+ * are dropped via the stubbed-slot
+ * predicate (slot_stubbed ->
+ * golden_blank).
+ */
+ if (READ_ONCE(gsp_phys_rmcall_gr_mme_golden_force) &&
+ READ_ONCE(gsp_phys_rmcall_gr_mme_golden_only)) {
+ for (gj = 0; gj < 64u; gj++) {
+ u32 gent, gn, q, kk2;
+ const u32 *gw;
+ u32 bstart, bend;
+ u64 nmask;
+
+ if (!(sa_mask & (1ull << gj)) ||
+ !sa_ent[gj])
+ continue;
+ if (gsp_phys_gr_golden_slot(
+ gj, &gent, &gw,
+ &gn))
+ continue;
+ bstart = 3u * sa_ent[gj];
+ bend = 4096u;
+ nmask = sa_mask &
+ ~(1ull << gj);
+ for (kk2 = 0; kk2 < 64u; kk2++) {
+ if (!(nmask &
+ (1ull << kk2)) ||
+ !sa_ent[kk2])
+ continue;
+ if (3u * sa_ent[kk2] > bstart &&
+ 3u * sa_ent[kk2] < bend)
+ bend = 3u * sa_ent[kk2];
+ }
+ for (q = bstart; q < bend; q++)
+ gsp_phys_gr_mme_ir_pack[q] = 0;
+ sa_mask &= ~(1ull << gj);
+ sa_ent[gj] = 0;
+ gblank++;
+ }
+ }
if (goldn && gsp_phys_gr_golden_log < 8u) {
gsp_phys_gr_golden_log++;
- pr_info("vgsp-gr: MME-GOLDEN overlay %u slot(s) maxa=%u h=0x%x push=0x%llx\n",
- goldn, maxa,
+ pr_info("vgsp-gr: MME-GOLDEN overlay %u slot(s) inspected=%u blank=%u maxa=%u h=0x%x push=0x%llx\n",
+ goldn, ginsp, gblank,
+ maxa,
req->h_object,
req->push_va);
}
diff --git a/tools/mme-audit/mme_audit.py b/tools/mme-audit/mme_audit.py
new file mode 100644
index 0000000..8031f3c
--- /dev/null
+++ b/tools/mme-audit/mme_audit.py
@@ -0,0 +1,570 @@
+#!/usr/bin/env python3
+"""mme-audit: offline audit of the vgsp MME golden overlay and replay streams.
+
+Pure Python 3.10 stdlib. Inputs (all local, all public):
+ * kernel/golden-mme-tu104.h (golden slot library)
+ * dmesg_live_*.log captures (3D win / MME-WINRUN / MME-PRE)
+
+What it checks (r1448-strategy 3.1):
+ 1. overlay simulation: golden_slot() accept rules, old (!gs->entry) vs new
+ (entry 0 valid) under force=1 -> 54 before, 55 after
+ 2. grammar walk of every 3D win[...] / MME-WINRUN / MME-PRE[...] block:
+ op 1/3/5 span, 0x114 IR loads, SA pairs; walk-end == len assertion
+ 3. call census per window (slot, off, payload)
+ 4. operand map over the mission slots: decode MME64 groups, flag
+ LOAD-sourced method emissions and suspect method immediates
+ 5. cross-boot pair-emitted/elided/MISS/first-fault table
+ 6. slot-57 focus decode around the r1448b/c stall (IR 868..930)
+"""
+import argparse
+import os
+import re
+import sys
+
+# --------------------------------------------------------------------- golden
+
+GOLDEN_SLOT_RE = re.compile(
+ r"\[\s*(\d+)\]\s*=\s*\{\s*0x([0-9a-fA-F]+)u,\s*(\d+)u,\s*(\d+)u,\s*0x([0-9a-fA-F]+)u\s*\}")
+GOLDEN_WORDS_RE = re.compile(
+ r"golden_mme_tu104_words\[GOLDEN_MME_TU104_WORDS\]\s*=\s*\{(.*?)\n\};", re.S)
+
+MISSION_SLOTS = [0, 2, 34, 39, 40, 48, 51, 57, 58]
+SUSPECT_METHODS = [0x1614, 0x1618, 0x2054, 0x2058, 0x2094, 0x2098,
+ 0x2154, 0x2158, 0x0d74, 0x0d78]
+
+# MME64 layout (3-word groups), extracted from the observed disassembly
+# convention: bits[95:64]=w0, [63:32]=w1, [31:0]=w2.
+REG = ["R%d" % i for i in range(24)] + ["ZERO", "IMMED", "IMMEDPAIR",
+ "IMMED32", "LOAD0", "LOAD1"]
+OP = ["ADD", "ADDC", "SUB", "SUBB", "MUL", "MULH", "MULU", "EXTENDED", "CLZ",
+ "SLL", "SRL", "SRA", "AND", "NAND", "OR", "XOR", "MERGE", "SLT", "SLTU",
+ "SLE", "SLEU", "SEQ", "STATE", "LOOP", "JAL", "BLT", "BLTU", "BLE",
+ "BLEU", "BEQ", "DREAD", "DWRITE"]
+OUT = ["NONE", "ALU0", "ALU1", "LOAD0", "LOAD1", "IMMED0", "IMMED1",
+ "RESERVED", "IMMEDHIGH0", "IMMEDHIGH1", "IMMED32_0"]
+
+
+def regname(v):
+ return REG[v] if v < 30 else "V%d" % (v - 32)
+
+
+def mme64_decode(w0, w1, w2):
+ val = (w0 << 64) | (w1 << 32) | w2
+
+ def bits(hi, lo):
+ return (val >> lo) & ((1 << (hi - lo + 1)) - 1)
+
+ alus = []
+ for base in (10, 46):
+ alus.append((bits(base + 4, base), bits(base + 9, base + 5),
+ bits(base + 14, base + 10), bits(base + 19, base + 15),
+ bits(base + 35, base + 20)))
+ outs = []
+ for base in (82, 89):
+ outs.append((bits(base + 2, base), bits(base + 5, base + 3)))
+ return {
+ "endNext": bits(0, 0), "predMode": bits(4, 1), "pred": bits(9, 5),
+ "alu": alus, "out": outs,
+ }
+
+
+def mme64_text(d):
+ parts = []
+ for op, dst, s0, s1, im in d["alu"]:
+ if (op, dst, s0, s1, im) == (0, 0, 0, 0, 0):
+ continue
+ parts.append("%s %s, %s, %s, 0x%04x" %
+ (OP[op], regname(dst), regname(s0), regname(s1), im))
+ for meth, emit in d["out"]:
+ if meth or emit:
+ parts.append("OUT method-src=%s data-src=%s" %
+ (OUT[meth], OUT[emit]))
+ if d["endNext"]:
+ parts.append("endNext")
+ if d["predMode"]:
+ parts.append("pred=%s,%s" % (d["predMode"], regname(d["pred"])))
+ return " | ".join(parts) if parts else "NOP"
+
+
+def parse_golden(path):
+ text = open(path, encoding="utf-8").read()
+ pool = []
+ m = GOLDEN_WORDS_RE.search(text)
+ if m:
+ pool = [int(t, 16) for t in re.findall(r"0x[0-9a-fA-F]+", m.group(1))]
+ entries = {}
+ for m in GOLDEN_SLOT_RE.finditer(text):
+ entries[int(m.group(1))] = (int(m.group(2), 16), int(m.group(3)),
+ int(m.group(4)), int(m.group(5), 16))
+ return entries, pool
+
+
+def golden_slot(entries, j, entry0_fix):
+ """Model of gsp_phys_gr_golden_slot() (knob presumed on)."""
+ if j >= 64 or j not in entries:
+ return None
+ entry, words, off, flags = entries[j]
+ if not (flags & 0x1) or not words:
+ return None
+ if not entry0_fix and not entry:
+ return None
+ return entry, words, off, flags
+
+
+PRESENT = 0x1
+GMME_FLAGS = {0x2: "DRIVER", 0x4: "LIVE_VARIANT", 0x8: "GEFORCE"}
+
+
+def overlay_sim(entries, pool):
+ out = {}
+ for fix in (False, True):
+ overlaid, rejected = [], []
+ for j in range(64):
+ gs = golden_slot(entries, j, fix)
+ (overlaid if gs else rejected).append(j)
+ out[fix] = (sorted(overlaid), sorted(rejected))
+ return out
+
+
+# ------------------------------------------------------------------ walkers
+
+def walk_stream(words):
+ """Booter grammar walk: returns (ok, runs, image, calls, sa_pairs)."""
+ runs, image, calls, sa_pairs = [], {}, [], {}
+ off, n = 0, len(words)
+ ok = True
+ while off < n:
+ h = words[off]
+ op = (h >> 29) & 7
+ cnt = (h >> 16) & 0xfff
+ mthd = (h & 0x1fff) << 2
+ span = 1
+ if op in (1, 3, 5) and cnt:
+ span = 1 + cnt
+ if off + span > n:
+ ok = False
+ span = n - off
+ runs.append((off, op, cnt, mthd, span))
+ if mthd == 0x114 and span >= 3:
+ pc = words[off + 1]
+ code = words[off + 2:off + span]
+ for i in range(len(code) // 3):
+ image[pc + i] = tuple(code[3 * i:3 * i + 3])
+ if 0x3800 <= mthd <= 0x39fc:
+ j = (mthd - 0x3800) // 8
+ kind = "DATA" if (mthd & 4) else "MACRO"
+ payload = list(words[off + 1:off + span])
+ calls.append((j, off, kind, mthd, payload))
+ if mthd == 0x11c and span >= 3:
+ sa_pairs[words[off + 1]] = words[off + 2]
+ off += span
+ return ok, runs, image, calls, sa_pairs
+
+
+CRLF = re.compile(r"\[(\d+\.\d+)\]\s+vgsp-gr:\s+(.*)$")
+WIN_RE = re.compile(r"3D win\[\s*(\d+)\]:\s+((?:[0-9a-fA-F]+ ?)+)")
+WINRUN_DUMP_RE = re.compile(r"MME-WINRUN dump h=0x([0-9a-fA-F]+) push=0x([0-9a-fA-F]+) window=(\d+)")
+WINRUN_RUN_RE = re.compile(
+ r"MME-WINRUN off=([0-9a-fA-F]+) op=(\d+) cnt=(\d+) mthd=([0-9a-fA-F]+) d0=([0-9a-fA-F]+) d1=([0-9a-fA-F]+)")
+PRE_RE = re.compile(r"MME-PRE\[\s*(\d+)\]:?\s+((?:[0-9a-fA-F]{8} ?)+)")
+
+
+def parse_windows(path):
+ """Yield dicts for each 3D win[], MME-WINRUN and MME-PRE[] block."""
+ cur = None
+ win_words, wr_runs, wr_meta = [], [], None
+ pre_idx, pre_words = -1, []
+ with open(path, encoding="utf-8", errors="replace") as fh:
+ for line in fh:
+ m = CRLF.search(line)
+ if not m:
+ continue
+ ts, msg = m.group(1), m.group(2)
+ m = WIN_RE.search(msg)
+ if m:
+ off = int(m.group(1))
+ ws = [int(t, 16) for t in m.group(2).split()]
+ if win_words and off != len(win_words) and off != 0:
+ yield {"kind": "win", "ts": ts, "words": win_words}
+ win_words = []
+ if off == 0 and win_words:
+ yield {"kind": "win", "ts": ts, "words": win_words}
+ win_words = []
+ win_words.extend(ws)
+ continue
+ m = WINRUN_DUMP_RE.search(msg)
+ if m:
+ if wr_meta and wr_runs:
+ yield {"kind": "winrun", "ts": ts, **wr_meta, "runs": wr_runs}
+ wr_meta = {"h": int(m.group(1), 16), "push": int(m.group(2), 16),
+ "window": int(m.group(3))}
+ wr_runs = []
+ continue
+ m = WINRUN_RUN_RE.search(msg)
+ if m and wr_meta is not None:
+ wr_runs.append((int(m.group(1), 16), int(m.group(2)),
+ int(m.group(3)), int(m.group(4), 16),
+ int(m.group(5), 16), int(m.group(6), 16)))
+ continue
+ m = PRE_RE.search(msg)
+ if m:
+ idx = int(m.group(1))
+ ws = [int(t, 16) for t in m.group(2).split()]
+ if pre_words and idx != pre_idx + len(pre_words):
+ yield {"kind": "pre", "ts": ts, "words": pre_words}
+ pre_words = []
+ pre_words.extend(ws)
+ pre_idx = idx
+ continue
+ if win_words:
+ yield {"kind": "win", "ts": ts, "words": win_words}
+ win_words = []
+ if wr_meta and wr_runs is not None:
+ # runs may legitimately be empty (dump with no decoded runs)
+ yield {"kind": "winrun", "ts": ts, **wr_meta, "runs": wr_runs}
+ wr_meta, wr_runs = None, []
+ if pre_words:
+ yield {"kind": "pre", "ts": ts, "words": pre_words}
+ pre_words = []
+ if win_words:
+ yield {"kind": "win", "ts": ts, "words": win_words}
+ if wr_meta:
+ yield {"kind": "winrun", "ts": ts, **wr_meta, "runs": wr_runs}
+ if pre_words:
+ yield {"kind": "pre", "ts": ts, "words": pre_words}
+
+
+def walk_winrun(window, runs):
+ """Walk a decoded MME-WINRUN listing; returns (ok, calls, end)."""
+ seen, calls, end = set(), [], 0
+ for off, op, cnt, mthd, d0, d1 in runs:
+ span = 1 + cnt if op in (1, 3, 5) and cnt else 1
+ seen.add(off)
+ if 0x3800 <= mthd <= 0x39fc:
+ j = (mthd - 0x3800) // 8
+ kind = "DATA" if (mthd & 4) else "MACRO"
+ calls.append((j, off, kind, mthd, [d0, d1]))
+ end = max(end, off + span)
+ ok = end == window and len(seen) == len(runs)
+ return ok, calls, end
+
+
+# ------------------------------------------------------------ MME64 scanning
+
+def scan_slot(entries, pool, slot):
+ entry, words, off, flags = entries[slot]
+ rows = []
+ for i in range(words // 3):
+ w = tuple(pool[off + 3 * i:off + 3 * i + 3])
+ d = mme64_decode(*w)
+ rows.append((entry + i, i, w, d))
+ return rows
+
+
+def operand_map(entries, pool):
+ """For mission slots: flag emissions + suspect method constants."""
+ sus2 = {m >> 2: m for m in SUSPECT_METHODS}
+ out = []
+ for slot in MISSION_SLOTS:
+ if slot not in entries or not entries[slot][1]:
+ continue
+ for ir, idx, w, d in scan_slot(entries, pool, slot):
+ tags = []
+ for meth, emit in d["out"]:
+ if emit in (3, 4): # LOAD0/LOAD1 data source
+ tags.append("LOAD-sourced emission (method-src=%s)" % OUT[meth])
+ for word in w:
+ low = word & 0xfff
+ if low in sus2 and sus2[low] != 0x0d74 and sus2[low] != 0x0d78:
+ tags.append("suspect method %#x (field 11:0 of %08x)" % (sus2[low], word))
+ for op, dst, s0, s1, im in d["alu"]:
+ if im in SUSPECT_METHODS:
+ tags.append("suspect imm %#x (ALU immed)" % im)
+ if s0 == 24 and im == 0: # ZERO + 0 immediate
+ tags.append("zero-operand ALU (src0=ZERO immed=0)")
+ for t in tags:
+ out.append((slot, ir, w, t, mme64_text(d)))
+ return out
+
+
+# ----------------------------------------------------------- log-level facts
+
+FAULT_RE = re.compile(r'errString="([^"]+)"')
+ESR_RE = re.compile(r"esr 80000000->badf1201")
+
+
+def log_facts(path):
+ f = {"path": path}
+ counts = {"PAIR-DROP": 0, "PAIR-DROP-words": 0, "MISS-2054": 0,
+ "GOLDEN": [], "esr": 0, "macros": {}, "faults": [],
+ "trap2090": 0}
+ with open(path, encoding="utf-8", errors="replace") as fh:
+ for line in fh:
+ if "MME-PAIR-DROP" in line:
+ counts["PAIR-DROP"] += 1
+ m = re.search(r"MME-PAIR-DROP (\d+) word", line)
+ if m:
+ counts["PAIR-DROP-words"] += int(m.group(1))
+ if "pair addr=0x2054" in line and "-> MISS" in line:
+ counts["MISS-2054"] += 1
+ m = re.search(r"MME-GOLDEN overlay (\d+) slot", line)
+ if m:
+ counts["GOLDEN"].append(int(m.group(1)))
+ if ESR_RE.search(line):
+ counts["esr"] += 1
+ for m in re.finditer(r"macro-status=([0-9a-fA-F]{8})\(mpc=(\d+) mac=0x([0-9a-fA-F]+) run=(\d)\)", line):
+ counts["macros"][int(m.group(2))] = counts["macros"].get(int(m.group(2)), 0) + 1
+ if "trap=00002090" in line or "trap=80002090" in line:
+ counts["trap2090"] += 1
+ m = FAULT_RE.search(line)
+ if m:
+ counts["faults"].append(m.group(1).strip())
+ f["counts"] = counts
+ return f
+
+
+# ------------------------------------------------------------------- report
+
+def main():
+ ap = argparse.ArgumentParser()
+ here = os.path.dirname(os.path.abspath(__file__))
+ repo = os.path.abspath(os.path.join(here, "..", ".."))
+ ap.add_argument("--golden", default=os.path.join(repo, "kernel", "golden-mme-tu104.h"))
+ ap.add_argument("--logs", nargs="*", default=[])
+ ap.add_argument("--out", default="/tmp/opencode/r1449-audit.md")
+ args = ap.parse_args()
+
+ entries, pool = parse_golden(args.golden)
+ present = sorted(j for j in entries if entries[j][3] & PRESENT and entries[j][1])
+ absent = sorted(set(range(64)) - set(present))
+ lines = []
+ A = lines.append
+
+ A("# r1449 MME offline audit (mme-audit)")
+ A("")
+ A("- golden: `%s` (%d words, %d present slots)" % (args.golden, len(pool), len(present)))
+ A("- present: %s" % present)
+ A("- absent : %s" % absent)
+ A("")
+
+ A("## 1. Overlay simulation (gsp_phys_gr_golden_slot + force overlay)")
+ sim = overlay_sim(entries, pool)
+ old_over, old_rej = sim[False]
+ new_over, new_rej = sim[True]
+ A("")
+ A("| mode | overlaid | rejected (no golden) |")
+ A("|---|---|---|")
+ A("| pre-r1448 (`!gs->entry` rejects slot 0) | **%d** | %s |" % (len(old_over), old_rej))
+ A("| r1448 (entry 0 valid) | **%d** | %s |" % (len(new_over), new_rej))
+ A("")
+ A("slot 0: %s" % ("golden entry=0x0 words=%d flags=%s (ACCEPTED after fix)" %
+ (entries[0][1], "+".join(n for b, n in GMME_FLAGS.items() if entries[0][3] & b))
+ if 0 in entries else "absent"))
+ assert len(old_over) == 54 and len(new_over) == 55, "overlay sim mismatch"
+ A("")
+ A("ASSERT: 54 -> 55 after the entry-0 fix: OK")
+ A("")
+
+ A("## 2. Grammar walks (walk-end == len)")
+ A("")
+ A("| log | blocks | win | winrun | pre | end-mismatch | calls | 0x2054 | 0x2094 | 0x2154 |")
+ A("|---|---|---|---|---|---|---|---|---|---|")
+ wins = {}
+ for path in args.logs:
+ if not os.path.exists(path):
+ A("| %s | MISSING | | | | | | | | |" % path)
+ continue
+ nw = nwr = npre = nmis = ncall = 0
+ pair_counts = {0x2054: 0, 0x2094: 0, 0x2154: 0}
+ win_calls = []
+ for blk in parse_windows(path):
+ if blk["kind"] == "win":
+ ok, runs, image, calls, sa = walk_stream(blk["words"])
+ nw += 1
+ nmis += 0 if ok else 1
+ ncall += len(calls)
+ for j, off, kind, mthd, payload in calls:
+ win_calls.append((blk["ts"], j, off, kind, payload))
+ elif blk["kind"] == "winrun":
+ ok, calls, end = walk_winrun(blk["window"], blk["runs"])
+ nwr += 1
+ nmis += 0 if ok else 1
+ ncall += len(calls)
+ for off, op, cnt, mthd, d0, d1 in blk["runs"]:
+ if mthd in pair_counts:
+ pair_counts[mthd] += 1
+ for j, off, kind, mthd, payload in calls:
+ win_calls.append((blk["ts"], j, off, kind, payload))
+ elif blk["kind"] == "pre":
+ ok, runs, image, calls, sa = walk_stream(blk["words"])
+ npre += 1
+ nmis += 0 if ok else 1
+ ncall += len(calls)
+ wins[path] = win_calls
+ base = os.path.basename(path)
+ A("| %s | %d | %d | %d | %d | %d | %d | %d | %d | %d |" %
+ (base, nw + nwr + npre, nw, nwr, npre, nmis, ncall,
+ pair_counts[0x2054], pair_counts[0x2094], pair_counts[0x2154]))
+ A("")
+ A("Note: dmesg_live_r1448.log carries both r1448b and r1448c boots "
+ "(148098..148521 and 148520/148627 sentinels); the per-boot logs named "
+ "r1448b/r1448c were not present at audit time.")
+ A("")
+
+ A("## 3. Call census (windows that called MME macros)")
+ for path, calls in wins.items():
+ if not calls:
+ continue
+ A("")
+ A("### %s" % os.path.basename(path))
+ A("")
+ A("| ts | slot | off | kind | payload |")
+ A("|---|---|---|---|---|")
+ for ts, j, off, kind, payload in calls[:200]:
+ A("| %s | %d | 0x%x | %s | %s |" %
+ (ts, j, off, kind, " ".join("%08x" % p for p in payload[:8])))
+ if len(calls) > 200:
+ A("| ... | (%d more) | | | |" % (len(calls) - 200))
+ A("")
+
+ A("## 4. Operand map (mission slots; LOAD-sourced emissions + suspects)")
+ A("")
+ om = operand_map(entries, pool)
+ if not om:
+ A("no flagged instructions")
+ else:
+ A("| slot | IR | words | flag | decode |")
+ A("|---|---|---|---|---|")
+ for slot, ir, w, t, txt in om[:120]:
+ A("| %d | %d | %08x %08x %08x | %s | %s |" % (slot, ir, w[0], w[1], w[2], t, txt))
+ if len(om) > 120:
+ A("| ... | | | (%d more) | |" % (len(om) - 120))
+ A("")
+
+ A("## 5. Cross-boot pair/fault table")
+ A("")
+ A("| log | PAIR-DROP n | words | 0x2054 MISS | overlay | esr badf1201 | trap 0x2090 | first faults |")
+ A("|---|---|---|---|---|---|---|---|")
+ for path in args.logs:
+ if not os.path.exists(path):
+ continue
+ f = log_facts(path)
+ c = f["counts"]
+ A("| %s | %d | %d | %d | %s | %d | %d | %s |" %
+ (os.path.basename(path), c["PAIR-DROP"], c["PAIR-DROP-words"],
+ c["MISS-2054"], sorted(set(c["GOLDEN"])), c["esr"], c["trap2090"],
+ "; ".join(c["faults"][:4]) if c["faults"] else "-"))
+ A("")
+
+ A("## 6. Slot-57 focus: golden body around the r1448b/c stall")
+ A("")
+ if 57 in entries and entries[57][1]:
+ rows = scan_slot(entries, pool, 57)
+ A("entry=0x%x words=%d instructions=%d" % (entries[57][0], entries[57][1], len(rows)))
+ A("")
+ A("| IR | idx | words | decode |")
+ A("|---|---|---|---|")
+ for ir, idx, w, d in rows:
+ mark = ""
+ if ir == 899:
+ mark = " **<- r1448b stall (mpc=899)**"
+ elif ir == 900:
+ mark = " **<- r1448c stall (mpc=900)**"
+ if idx < 14 or idx >= 20:
+ A("| %d | %d | %08x %08x %08x | %s%s |" % (ir, idx, w[0], w[1], w[2], mme64_text(d), mark))
+ A("")
+ else:
+ A("slot 57 absent from golden library")
+
+ A("## 7. Method-name map for the pipeline family (0x2000 + j*64)")
+ A("")
+ names = {0x00: "SET_PIPELINE", 0x08: "PIPELINE_RESERVED_A",
+ 0x0c: "PIPELINE_REGISTER_COUNT", 0x10: "PIPELINE_BINDING",
+ 0x14: "PROGRAM_ADDRESS_A", 0x18: "PROGRAM_ADDRESS_B",
+ 0x1c: "PIPELINE_RESERVED_D", 0x20: "PIPELINE_RESERVED_E"}
+ for m in (0x2054, 0x2090, 0x2094, 0x2098, 0x2154, 0x2158):
+ j = (m - 0x2000) // 64
+ off = (m - 0x2000) % 64
+ A("- 0x%04x = SET_PIPELINE(%d) + 0x%02x = %s" % (m, j, off, names.get(off, "?")))
+ A("")
+
+ A("## 8. Stall-diagnosis evidence (r1448b/c residual)")
+ A("")
+ A("The MME-FAST `trap=<mthd> data=<d>` telemetry carries the method the FE")
+ A("last processed. Calibration against the window runs:")
+ A("")
+ TRAP_RE = re.compile(r"trap=([0-9a-fA-F]{8}) data=([0-9a-fA-F]{8})")
+ for path in args.logs:
+ if not os.path.exists(path):
+ continue
+ wr_pairs, trap_pairs, stall = set(), set(), []
+ with open(path, encoding="utf-8", errors="replace") as fh:
+ for line in fh:
+ m = WINRUN_RUN_RE.search(line)
+ if m:
+ wr_pairs.add((int(m.group(4), 16), int(m.group(5), 16)))
+ m = TRAP_RE.search(line)
+ if m:
+ trap_pairs.add((int(m.group(1), 16) & 0x7fffffff,
+ int(m.group(2), 16)))
+ if "macro-status=" in line and ("mpc=899" in line or "mpc=900" in line):
+ stall.append(line.rstrip())
+ hits = sorted(wr_pairs & trap_pairs)
+ n2090_wr = sum(1 for line in open(path, encoding="utf-8", errors="replace")
+ if WINRUN_RUN_RE.search(line) and "mthd=2090" in line)
+ n2090_trap = sum(1 for line in open(path, encoding="utf-8", errors="replace")
+ if "trap=00002090" in line or "trap=80002090" in line)
+ A("### %s" % os.path.basename(path))
+ A("")
+ A("- window-run `(mthd,d0)` vs telemetry `(trap,data)` intersections: %s" %
+ (" ".join("0x%x/0x%x" % p for p in hits[:8]) if hits else "none"))
+ A("- `mthd=2090` window runs: **%d**; `trap=...2090` telemetry lines: **%d**" %
+ (n2090_wr, n2090_trap))
+ for s in stall[:6]:
+ A("- stall: `%s`" % s)
+ A("")
+
+ A("## 9. Findings (synthesis)")
+ A("")
+ A("1. **Overlay completion:** the entry-0 fix takes the force overlay from")
+ A(" 54 to 55 slots (slot 0 SETUP_FIXED_CONST, entry 0x0, 15 words is the")
+ A(" only slot the old `!gs->entry` reject skipped).")
+ A("2. **r1448b/c residual:** the slots carried the program pairs (PAIR-DROP=0;")
+ A(" `mthd=2054/2094/2154 d1=0x19b0900/0x19b0200/0x19b0000`); the MME was")
+ A(" sampled at mpc=899 (r1448b, 3x then poison) / 900 (r1448c, 2x then")
+ A(" trap) inside slot 57. NOTE: the clean r1443b boot passes through the")
+ A(" same mpc=899/900 samples (and advances to mac=0x33), so the PC alone")
+ A(" is not the anomaly - the differentiator is `trap=0x2090 data=0`")
+ A(" (0 occurrences in r1443b/r1447/r1447c, 4 in r1448) followed by")
+ A(" Class Error Offset 00002090 ErrorCode 4.")
+ A("3. **0x2090 is macro-emitted, not client-emitted:** no window in any log")
+ A(" contains `mthd=2090`; the trap field is calibrated against window runs")
+ A(" (`mthd=22c d0=800` <-> `trap=0000022c data=00000800`). 0x2090 =")
+ A(" SET_PIPELINE(2)+0x10 = PIPELINE_BINDING(2), the stage-2 binding in the")
+ A(" same family as the carried pairs. It is emitted by the MME and")
+ A(" rejected only in the pair-carried boots.")
+ A("4. **Stall-site decode:** slot 57 IR 899 (idx 31) is an emission group")
+ A(" `ADD R3,R3,IMMEDPAIR,0x08e4 | OUT method-src=IMMED0 data-src=LOAD0`;")
+ A(" IR 903 repeats it; IR 900 (idx 32) is `JAL +0x1d` to the macro tail.")
+ A(" LOAD0 is never written inside the slot-57 body (first read at IR 868")
+ A(" as macro input word 0): the emitted binding payload is call-input")
+ A(" dependent and null-capable - the rejected `data=0` snapshot is")
+ A(" consistent with a zero call-input word on the stalling call.")
+ A("5. **Next lever:** the carried-pair launch must satisfy the stage-2")
+ A(" binding method (0x2090) the macro emits, or the emission must be")
+ A(" bracketed by a valid stage-2 selector/binding state (the window writes")
+ A(" `mthd=2080 SET_PIPELINE(2) d0=0x21 d1=0x20010850` but no 0x2090).")
+ A(" Alternative: keep the r1447 pairs-elided shape for the calls-kept")
+ A(" launch (it reached mpc=930/22) and carry the pairs only on held-call")
+ A(" launches.")
+ A("")
+
+ text = "\n".join(lines) + "\n"
+ with open(args.out, "w", encoding="utf-8") as fh:
+ fh.write(text)
+ print(text)
+ print("wrote", args.out, file=sys.stderr)
+
+
+if __name__ == "__main__":
+ main()