Files
LithosAnanake/capsules
Robert Allan JamesandClaude Sonnet 5 43aa0a2a36 aarch64: arm the ARM Generic Timer -- CNTP/CNTHP TVAL+CTL, per-tick re-arm
Punch list §25 item 0.7 complete. This is what finally makes items 0.5 and
0.6 provably work end to end.

apic_timer_start(): writes CNTP_TVAL_EL0 (or CNTHP_TVAL_EL2 at EL2 --
aarch64_current_el(), same EL-aware discipline as 0.4-0.6) to
s_timer_period_tsc, then CTL.ENABLE=1/IMASK=0, followed by an ISB. The ISB
is not decorative: confirmed against Linux's own arch_timer_reg_write_cp15()
(arch/arm64/include/asm/arch_timer.h) that only the *control* register write
needs synchronising before the enable/mask state is guaranteed visible to
the interrupt pipeline -- TVAL/CVAL writes do not carry the same
requirement, which is why apic_timer_rearm() omits it.

TVAL is architecturally 32-bit but MSR-to-system-register is always a
64-bit instruction form -- passing a uint32_t operand directly failed to
build (-Wasm-operand-widths). Fixed by truncating to 32 bits ourselves then
zero-extending back to 64 for the operand, which supplies explicit,
provably-correct zeros in the RES0 upper field rather than depending on
unverified hardware behaviour -- Linux's own driver never exercises this
path (it always uses the 64-bit CVAL form instead), so there was no local
source to confirm the alternative against.

apic_timer_rearm() (new): re-writes TVAL only, no ISB needed. TVAL is
relative to "now," not an absolute deadline like riscv64's SBI interface
(item 0.3), so there is no drift-correction bookkeeping -- each write means
"N ticks from this instant." Wired into aarch64_irq_handler() and called
*first*, before heartbeat_tick(), matching riscv64_timer_rearm()'s ordering
discipline exactly: the ARM Generic Timer does not auto-reload, so a return
path that skips this leaves the interrupt condition latched, which the GIC
would redeliver the instant it's EOI'd -- a real storm, the same class of
failure item 0.6's verification investigated (and that time found absent,
because nothing was armed yet).

Verified: builds clean; every generated instruction checked against
disassembly, not just reviewed by eye (both EL branches, correct TVAL/CTL
register names, single shared ISB in apic_timer_start(), no ISB in
apic_timer_rearm()). Boots to ok> with no regression, dict_hash
0x3d4e1daf289da94f unchanged.

Rate measured directly against real wall-clock time via QEMU's own -d int
trap trace (same method as riscv64's item 0.3), two independent windows:
1,090 interrupts over 11.05 s (98.679 Hz) and 4,031 over 40.88 s (98.614 Hz)
-- consistent across both, so this is a real, small, systematic bias
(~1.3-1.4% slow), not measurement noise from polling granularity, which
would have shrunk with the longer window and did not. Attributed to genuine
per-interrupt service latency: TVAL is rewritten mid-ISR, so the trampoline
save/restore, GICC_IAR read, EL branch and GICC_EOIR write all lengthen the
effective period slightly versus the nominal 10 ms, inherent to any
relative-countdown re-arm scheme. Reported as measured, not smoothed over.
The interrupt sustained continuously across both windows with no stall and
no storm, which is the primary evidence re-arm-every-tick is correct;
the small rate bias is overhead, not a defect.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 22:14:52 -04:00
..
2026-08-01 07:49:56 -04:00
2026-08-01 07:49:56 -04:00
2026-08-01 07:49:56 -04:00

capsules/

FORTH personality files loaded by the VM at boot. A capsule is an immutable, content-addressed payload; its XXHash64 hash is its identity. Any mutation changes the hash and the birth protocol rejects the image.

Key files

File Type Purpose
init.4th (m) MAMA_INIT Default Mama VM personality — loaded at LBN 2048
ACL.4th user Word-level ACL system; self-activating at boot
zuse.4th user Bootstrap superuser; loaded by ACL.4th
doe.4th user DoE workload words (EXEC-DOE) — opt-in
init-0.4thinit-9.4th (p) Numbered personality variants
init-l8-*.4th (p) L8 Jacquard mode variants (stable/volatile/diverse/temporal/transition/omni)
hermes/init.4th (p) Hermes baby VM personality
artemis/init.4th (p) Artemis baby VM personality

Block namespace

Block ranges are shared across all loaded capsules — collisions cause silent word-definition overwrites.

Range Owner
20482099 init.4th
21002199 doe.4th
30003999 workload capsules
4000+ user-defined (ACL.4th, zuse.4th, …)

Each block is limited to 1024 bytes. Verify with wc -c before committing.

See also