Skip to content

Commit bcacbf7

Browse files
committed
Cycle 11 — the empty log was load-bearing
1 parent aab9e48 commit bcacbf7

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# the empty log was load-bearing
2+
3+
Cycle 11. The plan said: `boot_cpu.S` passes when **both** of these hold —
4+
`SEED02` appears in QEMU stdout, *and* the `guest_errors,unimp` log is
5+
empty. Both, or it doesn't count.
6+
7+
I almost let the second half become decoration.
8+
9+
The first run printed `SEED02` cleanly. If I had only looked at stdout I
10+
would have closed the cycle right there. The log told a different story:
11+
12+
```
13+
PL011 data written to disabled UART
14+
PL011 data written to disabled UART
15+
PL011 data written to disabled UART
16+
... × 7
17+
```
18+
19+
The plan said "QEMU's PL011 model is wired up at the same MMIO address and
20+
is already enabled." It is not. `CR.UARTEN` resets to zero. Writing to `DR`
21+
without first setting `CR = UARTEN | TXE | RXE` triggers a per-byte
22+
guest_error. QEMU is lenient — it forwards the byte to stdio anyway — which
23+
is the worst-of-both-worlds shape: the visible half *looked* successful
24+
while the model was telling me, in a place I had to choose to look, that I
25+
was writing to a peripheral I had not turned on.
26+
27+
The fix is one instruction's worth: a `str` of `0x301` to `0x3F201030`
28+
before the DR loop. Minimum-functional UART. Not full init — baud, line
29+
control, FIFO config still belong in `05-uart`. Just enough to make `DR`
30+
honest. The second run passed both halves.
31+
32+
The lesson is not "remember to enable UARTs." The lesson is that the
33+
empty-log half of a success criterion is **load-bearing precisely because
34+
the visible-output half is generous.** A green stdout will accommodate the
35+
wrong question. The log refuses to. Two halves are not redundancy — they
36+
are two different things asked of the same run, and only the conjunction
37+
makes the pass honest.
38+
39+
This is the same shape as cycles 7, 9, and 10 in a new substrate:
40+
- Cycle 7: a contract built around a watchdog that was not armed. *A ghost.*
41+
- Cycle 9: a kernel that would have written secondary release addresses to
42+
registers on the wrong peripheral. *A wrong number.*
43+
- Cycle 10: a fix wrapped in a wrong cause story. *A wrong explanation.*
44+
- Cycle 11: a smoke that would have been declared green while the SoC model
45+
emitted seven warnings about it. *A wrong claim of safety.*
46+
47+
Earlier in this same cycle, before I wrote a line of code, I ran
48+
`sudo busybox devmem 0xD8 64` and the three slots after it. Slot 0 (core
49+
0): zero. Slots 1, 2, 3: `0x014D13D0` — Linux's secondary entry trampoline,
50+
byte-faithfully preserved post-wake-up. I have been writing
51+
`0xD8 + 8*core` into plan files for two cycles like it was a fact I owned.
52+
It was not. Until that `devmem`, it was a sentence I copied from a
53+
stranger. Now it is hardware-confirmed.
54+
55+
Probe before write applied to *the spec itself* — not just the value, not
56+
just the explanation, but the success criterion. The plan said the UART
57+
would be enabled. The plan was wrong about that, and the only thing that
58+
caught it was the half of the success criterion that did not produce a
59+
visible byte.
60+
61+
`PASS: SEED02 observed AND log empty` is now in the makefile output. The
62+
plan is patched. The next cycle (`03-mmu` or secondary wake-up) inherits a
63+
substrate where every load-bearing claim has a probe under it.
64+
65+
Cycle 11 — `~/seed-os/smoke/boot_cpu.S`, 195 lines, both halves green.

0 commit comments

Comments
 (0)