handoff: VSync/event-wedge fixes + iterate 2.A–2.BC research notes

Source changes (dormant parity infra, retained from iterate 2.AI/2.AO):
- xenia-kernel/exports.rs: nt_create_event manual_reset polarity +
  related event wiring
- xenia-gpu/mmio_region.rs: D1MODE_VBLANK_VLINE_STATUS hardcode parity

Also lands the audit-runs/ analysis notes (.md/.txt/.json digests) for the
iterate 2.x VSync/0x10e8/0x1004 wedge investigation. Raw trace dumps
(.jsonl/.gz/.csv/.stdout) and agent worktrees (.claude/) are gitignored as
regenerable local artifacts — see memory + HANDOFF for the running findings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-05 07:19:08 +02:00
parent acd1656753
commit ef93a4fa14
620 changed files with 108303 additions and 1 deletions

View File

@@ -0,0 +1,78 @@
# Phase C — fix patch
The fix is in the **diff/snapshot infrastructure**, not in either
engine's XEX loader. No engine bug was found; the Phase B STOP
invariant was over-strict.
## Files modified
1. `xenia-rs/tools/diff-state/diff_state.py` — relaxed STOP invariant.
When `--xex-json` is supplied AND both snapshots have `image.bin`,
compute `image_canonical_sha256` (XEX import slots masked) and check
that as the STOP key. The raw `image_loaded_sha256` is reported but
informational.
2. `xenia-rs/crates/xenia-kernel/src/phase_b_snapshot.rs` — when
`phase_b_dump_section_content` is set, also write `image.bin` with
raw bytes of the XEX-image region. Default-off; inert when cvar OFF
(cvar-OFF digest byte-identical to pre-Phase-C baseline).
3. `xenia-canary/src/xenia/kernel/phase_b_snapshot.cc` — same.
## Diff (relative to pre-Phase-C state)
Generated via `git diff --no-index` against an unmodified baseline. The
full unified diffs are below; see also re-validation.md for proof both
engines still build and all gates pass.
--- /dev/fd/63 2026-05-13 22:41:06.597568277 +0200
+++ /dev/fd/62 2026-05-13 22:41:06.596568265 +0200
@@ -1,2 +1,25 @@
let _ = write_file(&engine_dir.join("manifest.json"), &body);
+
+ // Phase C: when dump_section_content is on, write raw bytes of the
+ // XEX image region to <engine_dir>/image.bin. This is the only
+ // region positionally matched between canary and ours, so it's the
+ // only one suitable for byte-level diff.
+ if state.phase_b_dump_section_content && state.image_base != 0 {
+ let mut sz: u32 = 0;
+ let mut a = state.image_base;
+ while mem.is_mapped(a) {
+ sz = sz.wrapping_add(4096);
+ let next = a.wrapping_add(4096);
+ if next < a {
+ break;
+ }
+ a = next;
+ }
+ if sz > 0 {
+ let bytes = read_bytes(mem, state.image_base, sz);
+ if let Err(e) = std::fs::write(engine_dir.join("image.bin"), &bytes) {
+ tracing::warn!("phase_b_snapshot: image.bin write failed: {}", e);
+ }
+ }
+ }
}
---canary phase_b_snapshot.cc change (only the appended block):
// Phase C: when dump_section_content is on, write raw bytes of the
// XEX image region to <engine_dir>/image.bin. This is the only
// region positionally matched between canary and ours, so it's the
// only one suitable for byte-level diff.
if (cvars::phase_b_dump_section_content) {
auto exec_module = kstate->GetExecutableModule();
if (exec_module) {
uint32_t image_base = exec_module->xex_module()->base_address();
uint32_t image_size = exec_module->xex_module()->image_size();
uint8_t* host =
kstate->memory()->TranslateVirtual<uint8_t*>(image_base);
if (host && image_size > 0) {
std::filesystem::path ip = engine_dir / "image.bin";
std::FILE* bf = std::fopen(ip.string().c_str(), "wb");
if (bf) {
std::fwrite(host, 1, image_size, bf);
std::fflush(bf);
std::fclose(bf);
}
}
}
}
}