ReviewOS

home-lang/home-os

S8: de-stub `arch/arm64/arm64.home` — real MMIO with barriers, sysreg access, wfe/wfi — and route every Pi driver through it (no more raw `@ptrFromInt` derefs)

#60
Closed chris opened this 8 days ago ·
8 days ago

Epic: #113 · Milestone: MC2 — Pi 5 bring-up

Why

kernel/src/arch/arm64/arm64.home is 40 lines: mmio_read32 returns 0, mmio_write32/nop/wfe/wfi are empty. This is stub S8 in the register ("every ARM64/Pi driver is inert"). Worse, most Pi drivers bypass it: bcm_emmc.home, gpio.home, i2c.home, spi.home use core/memory.home raw derefs, and arch/arm64/rpi5.home uses Zig-era @as(*volatile u32, @ptrFromInt(...)).

Tasks

  • Implement mmio_read{8,16,32,64} / mmio_write{…} over the A3 intrinsics with the documented barrier policy (write → dmb oshst before DMA doorbells; read of status regs → dmb oshld after).
  • read_sysreg/write_sysreg wrappers for the registers the MMU/GIC/timer code uses; wfe, wfi, sev, isb, dsb sy, ic iallu, tlbi vmalle1.
  • Codemod every driver under kernel/src/rpi/, kernel/src/arch/arm64/, kernel/src/drivers/{bcm_emmc,gpio,i2c,spi,pwm}.home to the arm64.mmio_* API; forbid raw MMIO derefs via a static check (static-checks/no-raw-mmio.sh) that fails CI outside arm64.home.
  • Remove the // STUB(S8) marker and update MASTER_PLAN §7 + scripts/stub-check.sh expectations.

Acceptance

stub-register job passes with S8 closed; a GPIO LED toggle (gpio shell command through RP1, see #72) or the UART itself proves reads return real values on hardware.

Size: M · Depends on: #53 · Blocks: #58, #61, all MC3 drivers

8 days ago

This issue is now the critical path, and it needs a decision

Measured after the ARM64 backend landed (home-lang/home-os@b856128): 13 of 70 Appendix A files lower for aarch64, against 70/70 for x86-64.

The gap is not a compiler gap. It is kernel/src/core/foundation.home, which the whole tree imports, and its 29 asm volatile blocks. Inline assembly is emitted verbatim — that is what it means — so an x86 block reaches the ARM assembler as x86 text and is rejected.

Eight of the 29 had direct architecture-neutral equivalents and are gone as of @578ddc6. The remaining 21 are genuinely x86-only CPU state and have no neutral spelling:

constructcountARM64 counterpart
port I/O (inb/inw/inl/outb/outw/outl)6none — MMIO replaces it entirely
cpuid3MIDR_EL1, ID_AA64*_EL1 via mrs
mov %cr2 / %cr3 / %cr43FAR_EL1, TTBR0_EL1, SCTLR_EL1/TCR_EL1
stac / clac2PAN bit in PSTATE
pushfq/popfq (save/restore flags + cli)2mrs x, daif / msr daif, x
rdtsc1CNTVCT_EL0
ltr1no TSS on ARM; per-CPU state is TPIDR_EL1
lgdt1no GDT on ARM; VBAR_EL1 for vectors
lock xaddq1ldaddal, or ldxr/stxr loop

Every one has an ARM64 answer. What HomeOS lacks is a way to select between the two implementations per target, and there are two credible designs:

A — build-time file selection. kernel/src/arch/x86_64/cpu.home and kernel/src/arch/arm64/cpu.home expose the same function names; the build picks one. No language change; this is what Linux does with arch/$(ARCH)/. Costs: mvk-compiles.sh compiles files standalone, so the set needs per-target expectations, and Home's import resolution needs a path that varies by target.

B — a compile-time target predicate in Home. @targetArch() plus dead-branch elimination for a comptime-known condition, so one file can carry both and the branch not taken is never emitted. More compiler work, and the dead-branch elimination has to be real — an x86 asm volatile surviving into ARM output defeats the whole point. This is the Zig idiom Home inherits, and CLAUDE.md's "extend Home first" points at it.

They are not mutually exclusive — B for small branches, A for whole subsystems — but one of them has to be chosen first, and it should be an ADR, because it sets the shape of every arch-specific module HomeOS will ever have.

Blocked on this: the aarch64 ratchet moving past 13/70, and therefore #61 (MMU), #63 (hardware boot), and the whole Pi 5 track.

Sign in to comment on this issue.