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,106 @@
# Phase C+7-only diff (synthesized from working tree minus cumulative C+5/C+6/C+6½/XAM changes)
#
# Full uncommitted diff is in `fix.diff` (1431 lines, includes all
# pre-existing Phase C work since HEAD).
#
# This file isolates the ~30 LOC body changes + ~160 LOC test additions
# that constitute Phase C+7.
--- a/crates/xenia-kernel/src/exports.rs (C+6½ baseline)
+++ b/crates/xenia-kernel/src/exports.rs (C+7)
# Body 1: ke_set_event — match canary's constant-1 return (xevent.cc:60-64)
-fn ke_set_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelState) {
- let h = ctx.gpr[3] as u32;
- ensure_dispatcher_object(state, mem, h);
- let previous = match state.objects.get_mut(&h) {
- Some(KernelObject::Event { signaled, .. }) => {
- let prev = *signaled;
- *signaled = true;
- prev as u32
- }
- _ => 0,
- };
- state.audit_signal(h, ctx.lr as u32, "KeSetEvent", previous as u64);
- wake_eligible_waiters(state, h);
- ctx.gpr[3] = previous as u64;
-}
+fn ke_set_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelState) {
+ let h = ctx.gpr[3] as u32;
+ ensure_dispatcher_object(state, mem, h);
+ // Canary parity (xevent.cc:60-64): `XEvent::Set` returns constant `1`
+ // on success, NOT the prior signaled state as the NT contract claims.
+ // We compute `previous` for internal bookkeeping (audit_signal,
+ // wake_eligible_waiters honor the prior-state read), but report
+ // `1` for success / `0` for "no dispatcher found" to match the
+ // canary Phase A oracle. See Phase C+7 investigation.md.
+ let (previous, found) = match state.objects.get_mut(&h) {
+ Some(KernelObject::Event { signaled, .. }) => {
+ let prev = *signaled;
+ *signaled = true;
+ (prev as u32, true)
+ }
+ _ => (0u32, false),
+ };
+ state.audit_signal(h, ctx.lr as u32, "KeSetEvent", previous as u64);
+ wake_eligible_waiters(state, h);
+ ctx.gpr[3] = if found { 1 } else { 0 };
+}
# Body 2: nt_set_event — out-pointer writes constant 1 not prior state
# (xboxkrnl_threading.cc:610-628 + xevent.cc:60-64 chain)
-fn nt_set_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelState) {
- let handle = ctx.gpr[3] as u32;
- let prev_ptr = ctx.gpr[4] as u32;
- let previous = match state.objects.get_mut(&handle) {
- Some(KernelObject::Event { signaled, .. }) => {
- let prev = *signaled;
- *signaled = true;
- prev as u32
- }
- _ => 0,
- };
- state.audit_signal(handle, ctx.lr as u32, "NtSetEvent", previous as u64);
- wake_eligible_waiters(state, handle);
- if prev_ptr != 0 {
- mem.write_u32(prev_ptr, previous);
- }
- ctx.gpr[3] = STATUS_SUCCESS;
-}
+fn nt_set_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelState) {
+ let handle = ctx.gpr[3] as u32;
+ let prev_ptr = ctx.gpr[4] as u32;
+ // Canary parity (xboxkrnl_threading.cc:610-628): the optional out-pointer
+ // is filled with `was_signalled` = `ev->Set()` = constant 1 (see
+ // xevent.cc:60-64), NOT the prior signaled state. r3 carries
+ // STATUS_SUCCESS. We retain `previous` for internal audit/wake plumbing.
+ let (previous, found) = match state.objects.get_mut(&handle) {
+ Some(KernelObject::Event { signaled, .. }) => {
+ let prev = *signaled;
+ *signaled = true;
+ (prev as u32, true)
+ }
+ _ => (0u32, false),
+ };
+ state.audit_signal(handle, ctx.lr as u32, "NtSetEvent", previous as u64);
+ wake_eligible_waiters(state, handle);
+ if prev_ptr != 0 && found {
+ mem.write_u32(prev_ptr, 1);
+ }
+ ctx.gpr[3] = STATUS_SUCCESS;
+}
# Test additions (in tests module): 6 new unit tests; see file lines 7179-7340
# - ke_set_event_returns_constant_one_on_unsignaled_auto_reset
# - ke_set_event_returns_constant_one_on_already_signaled_manual_reset
# - nt_set_event_null_prev_ptr_returns_status_success_no_write
# - nt_set_event_valid_prev_ptr_writes_constant_one_and_returns_success
# - nt_set_event_on_signaled_event_writes_one
# - ke_set_event_post_fix_still_wakes_waiter
# LOC summary (Phase C+7 only, additive on C+6½ baseline):
# body changes: ~14 net added lines across 2 functions
# test additions: ~160 lines (6 tests)
# total: ~174 LOC, 1 file