Epic: #113 · Milestone: MC1 — Toolchain: aarch64
Why
MASTER_PLAN names A3 as "the prerequisite for ever un-stubbing arm64.home honestly". On x86 a plain pointer dereference to MMIO mostly works because the memory model is strong; on ARMv8 it does not: the compiler may reorder or merge accesses, and device memory needs dmb/dsb around DMA hand-offs. Today kernel/src/drivers/bcm_emmc.home, gpio.home, i2c.home, spi.home do MMIO through core/memory.home's read_u32/write_u32 — raw @ptrFromInt derefs, no barriers — so closing S8 alone would not make them correct.
Language surface (proposed)
*volatile Talready exists per CLAUDE.md; define its semantics precisely: every read/write is a single access of the natural size, never elided, merged, or reordered with other volatile accesses.- Intrinsics:
@mmio_read(u8|u16|u32|u64, addr),@mmio_write(...),@barrier(.{ .kind = .dmb|.dsb|.isb, .domain = .sy|.ish|.osh|.ld|.st }),@wfe/@wfi/@sev,@read_sysreg("CurrentEL"),@write_sysreg("HCR_EL2", v). - Lowering on aarch64:
ldr/stron a register-addressed pointer for volatile;dmb ishon@barrier;mrs/msrfor sysregs. On x86:mov+mfence/lfence/sfencemapping.
Tasks
- Spec section in the Home language reference; tests that assert instruction sequences in the codegen test suite.
- Implement in both kernel codegen paths so drivers stay arch-neutral.
kernel/src/core/memory.home: makeread_u32/write_u32wrappers over the intrinsics (with explicit barrier variantsread_u32_relaxed,write_u32_release).
Acceptance
Codegen tests green on both arches; a QEMU virt kernel toggles a PL011 register through *volatile and the emitted asm contains no merged/elided accesses (asserted by grep on the .s).