From 8ac284f8c18c1ac0796181cdc71ced3732677cc7 Mon Sep 17 00:00:00 2001 From: Robert Allan James Date: Mon, 3 Aug 2026 11:31:26 -0400 Subject: [PATCH] =?UTF-8?q?FABRIC.md=20=C2=A725:=20GAP-B2=20verified=20and?= =?UTF-8?q?=20fixed,=20GAP-B3=20fixed=20=E2=80=94=20FP=20state=20and=20EL?= =?UTF-8?q?=20scope?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit B2, verified against Makefile.starkernel: no architecture restricts FP register use. amd64 has no -mno-sse (:124) -- works with live interrupts today, save-set adequacy unverified. aarch64 lacks -mgeneral-regs-only (:146). riscv64 builds -march=rv64gc -mabi=lp64d (:162) -- hard-float ABI, and kernel code genuinely uses doubles (hotwords_stats_print). Items 0.2 and 0.5 now require saving the ABI caller-saved FP set plus control/status registers, with the exact lists verified against the psABI/AAPCS64 rather than this document, and explicitly forbid "fixing" it via soft-float, which would break existing code. B3: item 0.4's EL detection now governs everything EL-dependent -- vector base register (today's isr.S writes VBAR_EL1 unconditionally, never consulted for exceptions taken at EL2), saved-state pair, eret target, and timer registers. Item 0.5's hardcoded ELR_EL1/SPSR_EL1 wording replaced accordingly. Co-Authored-By: Claude Fable 5 --- FABRIC.md | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/FABRIC.md b/FABRIC.md index 686c337..5145918 100644 --- a/FABRIC.md +++ b/FABRIC.md @@ -2009,6 +2009,12 @@ on until there is a tick on all three architectures (§16.1, §16.5).* Replace the one-way `riscv64_trap_entry` in `arch/riscv64/isr.S` with save / dispatch / restore / `sret`. Route `scause` bit 63 + cause 5 to the timer path; everything else keeps falling through to the existing fatal handler. + **FP state is not optional (B2 verified):** the kernel builds `-march=rv64gc -mabi=lp64d` + (`Makefile.starkernel:162`) — hard-float ABI, and kernel code genuinely uses doubles + (`hotwords_stats_print`). The trap entry must save the ABI's caller-saved FP registers + plus `fcsr` alongside the integer set; verify the exact register list against the RISC-V + psABI, not this document. Do not "fix" this by switching to soft-float — that breaks + existing code and is a build-system decision nobody has made. *Done when:* riscv64 boots to the prompt unchanged, having taken and returned from at least one trap. Exceptions still halt with the same diagnostic as before. @@ -2025,15 +2031,27 @@ on until there is a tick on all three architectures (§16.1, §16.5).* relying on it; if it is absent, stop and report rather than falling back silently. - [ ] **0.4 — aarch64: determine the exception level at runtime.** - Read `CurrentEL` in `timer_init()` and select the `CNTP_*_EL0` or `CNTHP_*_EL2` register - set accordingly. Do not hardcode either. + Read `CurrentEL` once, early, and let it govern **everything EL-dependent**, not just the + timer (B3): the vector base register (`VBAR_EL1` vs `VBAR_EL2` — today's `isr.S` writes + `VBAR_EL1` unconditionally, which is never consulted for exceptions taken at EL2), the + saved-state pair (`ELR_ELx`/`SPSR_ELx`), and the timer register set (`CNTP_*_EL0` vs + `CNTHP_*_EL2`). Do not hardcode either level anywhere. *Done when:* the boot log states which EL was detected, on real QEMU output. - [ ] **0.5 — aarch64: IRQ vector split.** - Split `irq_spx` out of the shared fatal handler in `arch/aarch64/isr.S`: save `x0`–`x30`, - `ELR_EL1`, `SPSR_EL1`, call a C handler, restore, `eret`. The other fifteen vectors are - unchanged. Note the 128-byte slot limit — the save sequence will not fit inline and must - branch to a trampoline. + Split `irq_spx` out of the shared fatal handler in `arch/aarch64/isr.S`: save `x0`–`x30` + plus the saved-state registers (see B3 note below), call a C handler, restore, `eret`. + The other fifteen vectors are unchanged. Note the 128-byte slot limit — the save sequence + will not fit inline and must branch to a trampoline. + **FP state is not optional (B2 verified):** the kernel builds without + `-mgeneral-regs-only` (`Makefile.starkernel:146`), so the compiler may use SIMD registers + anywhere. Save the ABI's caller-saved SIMD set plus `FPSR`/`FPCR` alongside the integer + set; verify the exact list against the AAPCS64, not this document. + **EL governs the whole path (B3):** this item previously hardcoded `ELR_EL1`/`SPSR_EL1`, + while 0.4 refuses to hardcode the EL — and today's `isr.S` installs `VBAR_EL1`, which is + never consulted for exceptions taken at EL2. The EL detected in 0.4 must select the + vector base register (`VBAR_ELx`), the saved-state pair (`ELR_ELx`/`SPSR_ELx`), and the + `eret` target state, not just the timer registers. *Done when:* aarch64 boots to the prompt having taken and returned from at least one IRQ. - [ ] **0.6 — aarch64: minimal GICv2.**