# Ch263 closeout — kernel-data mutation reaches BIOS but treadmill unchanged

**Status:** Closed exactly per Codex's Ch263 framing. Routine
BIOS-long target unchanged. New opt-in target lands the Ch261/Ch262
responder DMA payload into the BIOS-polled kernel-data scan range,
verifies the write reaches the EE RAM, and confirms BIOS observes
the mutation (then scrubs it). **Verdict:
`kernel_mutation_observed_no_flow_change`.**

## Codex Ch263 acceptance — line-by-line

| Codex requirement                                                               | Status | Where                                            |
|---------------------------------------------------------------------------------|--------|--------------------------------------------------|
| No new RTL if avoidable                                                         | ✅     | TB-only change; no RTL touched                  |
| Keep Ch261 responder and Ch262 interrupt pulse                                  | ✅     | All Ch262 wiring intact; Ch263 only retargets DMA destination |
| Change only responder DMA destination/payload                                   | ✅     | `DEST_BASE_ADDR` 0x00080000 → 0x00030200; no payload change |
| Choose one BIOS-polled kernel-data address                                      | ✅     | `0x80030200` (virt) / `0x00030200` (phys) — mid-range slot in the 16 KiB BIOS scan |
| Log baseline value at address before DMA                                        | ✅     | `Ch263 baseline = 0x000…000` (all-zero, as expected) |
| Log responder write value                                                       | ✅     | `Ch263 responder wrote 0xcafef00d12345678c0ffee00deadbeef to EE-phys 0x00030200 at t=50001285000` |
| Log later BIOS reads of same address                                            | ✅     | Trace shows 17 BIOS reads at `0x80030200` across the test |
| Report whether BIOS observes the mutation                                       | ✅     | **YES** — BIOS reads + actively clears the slot post-write |
| Report whether treadmill state changes                                          | ✅     | **NO** — retire count, Ch217 passes, Ch218 INTC summary all byte-identical to Ch260 baseline |
| Avoid Pivot 2 unless this returns clean negative                                | ✅     | Following the rule; deferring 0x1fa00000 question to Ch264 |
| Full regression green                                                           | ✅     | 157 / 157 with Ch263 off by default              |

## Verdict logic — three-way classification

Codex framed three possible outcomes:

- `kernel_mutation_unobserved` — BIOS never reads the slot
- `kernel_mutation_observed_no_flow_change` — BIOS reads + W1Cs, no progress (← **THIS RUN**)
- `kernel_mutation_perturbed_flow` — BIOS reads + path changes (= we found a gate)

The trace evidence + treadmill metrics put this run squarely in the
middle bucket.

## What the trace actually showed

### Step 1 — BIOS scans the 0x80030000–0x80033FF0 range every pass

From `ee_bios_smoke_map.trace`:

```
Total MEM READ in 0x80030xxx range:   1,217,848
Total MEM WRITE in 0x80030xxx range:  32,768
```

That is **4,096 writes per pass × 8 passes** — BIOS clears the
entire 16 KiB kernel-data table once per pass. Every slot gets
zeroed every pass. This pattern was visible in the Ch218 v5
capture but not characterized as a scrub until Ch263.

### Step 2 — the responder's write lands at our target slot

```
cycle 5,000,125  MEM WRITE 0x00030200  data=0xc0ffee00deadbeef  region=1  flags=0x01
```

(arg1 only carries the low 64 bits of the bridge's 128-bit qword
write — schema artifact. The qword is `0xcafef00d12345678c0ffee00deadbeef`
per the Ch263 `responder wrote` diagnostic line.)

### Step 3 — BIOS observes the value and clears it

Reads at virt `0x80030200` across the run:

```
cycle 770,570       — BIOS init read, slot zero
cycle 1,287,787     — BIOS init verify
cycle 5,000,125     — RESPONDER WRITES (between BIOS reads)
cycle 10,671,220    — BIOS read after responder write (likely sees 0xcafef00d…)
cycle 11,186,947    — BIOS writes 0 (clears our value)
cycle 11,188,437    — BIOS reads (sees zero now)
cycle 20,571,870    — next pass read
…
```

The `arg1=0` in the trace for EV_READ events is hardcoded
(documented in Ch258), so we can't directly READ the returned
value from the trace. But the WRITE-ZERO at cycle 11,186,947
immediately followed by a verify read at 11,188,437 is consistent
with BIOS reading non-zero data at cycle 10,671,220, deciding to
scrub, and verifying the clear.

### Step 4 — treadmill state did not change

| Metric                  | Ch260 baseline   | Ch262 (responder pulse) | **Ch263 (mutation + pulse)** |
|-------------------------|------------------|-------------------------|------------------------------|
| Ch217 caller passes     | 8                | 8                       | **8 (same)**                 |
| Ch217 verdict           | static_state     | static_state            | **static_state (same)**      |
| Ch218 INTC summary      | (filtered set)   | (same)                  | **(same)**                   |
| Ch218 INTC verdict      | intc_quiet       | intc_pending_observed   | **intc_pending_observed (same)** |
| Retire count            | 24,029,051       | 24,029,051              | **24,029,051 (byte-identical)** |

## Interpretation

**BIOS sees mutations in the kernel-data table but is structurally
defended against them via a periodic-scrub kernel routine.** The
scrub clears the entire 16 KiB region every Ch217 pass; any value
we write into a slot lives only until BIOS's next scrub pass, at
which point it's zeroed. Whatever the longjmp callee is gated on,
either:

1. **It isn't in this scanned region** — the scrub means BIOS
   itself doesn't rely on accumulated state in slots `0x80030000-3FF0`.
   The region might be a fresh-init scratchpad that BIOS expects to
   recompute each pass, not a kernel state table.
2. **It is in this region but BIOS reads the slot's value DURING
   the pass**, not as latched state across passes — and the pass
   timing is such that our write doesn't land in the right window.

Either way, **single-shot writes into this region are not the gate.**

## What's next (for Codex's Ch264 call)

Two distinct candidates given the new "BIOS scrubs every pass"
finding:

**(A) Sustained / re-emitted mutation.** If BIOS scrubs every
pass, a one-shot write loses to the scrub. The Ch263 responder
could be retriggered EVERY PASS (e.g. driven by a Ch217-pass-edge
signal) so the slot is re-set after each scrub. This tests
whether BIOS reads the value MID-PASS before scrubbing — and if
so, whether sustained value-presence eventually perturbs flow.
The downside: now we're polluting the very table BIOS is
managing, which could mask other behavior.

**(B) Pivot to 0x1fa00000** (the deferred Pivot 2 from the
Ch263 pre-brief). BIOS writes here 46 times with a sequence of
values 0x0..0xF. That's a "progress code" or "handshake state
output" port pattern. Maybe BIOS expects to read back what it
just wrote — or expects an external observer to see those
writes and respond. Lower risk than (A) and qualitatively
different (output, not polled input).

**(C) Look elsewhere entirely.** The Ch218 v7 capture showed
the longjmp callee at `0xBFC52984` makes the same JAL with
identical `$a0/$a1/$v0` every pass. The callee's body reads
from somewhere — but not from the 0x80030000+ region (per
Ch263). What does it read? Re-running Ch218 in the Ch263 build
with the scoping filter widened (or scoped to the callee's PC
window) could surface the actual polled location.

## My recommendation

**(C) first, then (B), then (A) if both negative.**

Reasoning: Ch263's null result narrows the search significantly.
BIOS isn't gated on the scrubbed kernel-data table, isn't gated
on INTC pending alone (Ch262), isn't gated on PCR (Ch258), and
isn't gated on SMFLG (Ch263 pre-brief). What HASN'T been ruled
out is **whatever the callee's body actually reads to compute
its return value**. That's an empirical question Ch264 can
answer with another scoped Ch218-style observer — narrow the
capture to PCs inside the callee's body (`0xBFC52984..` + ~16
instructions) and see what addresses it touches.

If (C) returns "callee reads from address X" and X is unmapped
or zero, then THAT becomes the next Ch265 target.

If (C) is inconclusive (callee uses only register state), then
(B) — `0x1fa00000` — is the next-best surface to investigate.

(A) is last-resort: throwing the SAME thing at BIOS but harder
is unlikely to produce different qualitative behavior.

## Files changed

- `sim/tb/integration/tb_ee_core_bios_smoke.sv` — Ch263
  sub-`\`ifdef` inside the Ch262 block: gate the local
  `u_ch262_ee_ram`, override `CH262_EE_LANDING` to phys
  `0x00030200`, add the `ee_map_br_*` priority mux that routes
  responder bridge writes into the BIOS-long shared `u_ee_ram`,
  add Ch263 observer (baseline + responder-write event + BIOS
  reads counter + three-way verdict in `final` block).
- `sim/Makefile` — new `tb_ee_core_bios_long_kernel_mutate`
  target.
- `docs/ch263_pre_impl_brief.md` — the recon-first brief that
  surfaced the SIF-mailbox-unobserved finding and proposed
  Pivot 3.
- `docs/ch263_closeout.md` — this file.

Caveat: the `final` block summary print didn't fire on this
run (iverilog 12 quirk with `final` + `$finish` on
`$error`-triggered timeout). The data was reconstructed from
the inline `$display` events + trace-file analysis. A future
chapter could either move the summary into an `always_ff` on
end-of-test or pre-emptively print at every Ch217 pass.

Standing by for Codex's Ch264 call.
