DE25-Nano wave 1: aarch64 target builds green, board DTS, patch series, per-board guards - #133
Conversation
Implements docs/de25-readiness-ledger.md §5. One sourced-only table, scripts/lib/board-expectations.sh, feeds both the defconfig lockstep check and the buildroot-build action's toolchain fingerprint sentinels, keyed by an explicit BOARD that defaults to de10nano. The merged de10nano row is textually identical to the former literal lists; the no-arg and BOARD=de10nano runs are byte-identical (checked), a broken kernel defconfig still fails with the same text and exit 1, and an unknown board exits 2 / ::error:: naming the board — no fallback row. The de25nano row's CPU symbol is [U] until the DE25 defconfig lands. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
arm64 selects ARCH_HAS_SYSCALL_WRAPPER, so the C-callable sys_ioctl() the stock loop_setup() invokes has no prototype and no symbol there, and fs/init.c's init_* helpers deliberately have no init_ioctl(). The initramfs boot path carries no architecture-specific line at all. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
…ail on an empty set Ledger §6.5: ~20 literal board paths made lint silent for any second board tree. Both shipped-script steps now discover boards, build the per-board target list from the conventional relative paths, print what they lint, and exit 1 with ::error:: when discovery finds nothing. The de10nano file set is unchanged (verified by running both steps). Trigger paths widen to board/mister/** — a strict superset. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
…atches 32 relative symlinks into the DE10 series (29 to linux-patches/, 3 — 0015/0030/0037 — to the 7.x-anchored linux-patches-beta/ copies, which is load-bearing: the 6.18 copies hard-fail at -F0 on 7.2.2). Excluded: the 7 de10-only patches, 0002 (MiSTer audio SPI: dma_addr_t rework and the 32-bit FPGA wire descriptor question, audit Q8, owner decision) and 0047 (btusb ID already in-tree at 7.2). README.md maps every audit row. 0101 sdhci-cadence: intel,agilex5-sd4hc entry whose sdhci_ops .set_dma_mask caps DMA at 40 bits (mainline hook, no vendor quirk), plus the binding enum entry. 0102 stratix10-svc: match intel,agilex5-svc so mainline's own Agilex 5 svc node binds. Both carried pending upstream. Verified: apply-patches.sh on pristine 7.2.2 — 34 applied, 0 fuzz, 0 rejects; lint-kernel-patches PASS; no dangling symlinks. Compile still owed by the D2.1 build. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
configs/mister_de25nano_defconfig: BR2_aarch64 + cortex-a76.cortex-a55, internal glibc toolchain with C++, headers 7.0 (newest series Buildroot 2026.05.2 offers; the kernel is 7.2.2 via CUSTOM_VERSION with the hash shared by symlink from the DE10 registry), arm64 arch default config + board/mister/de25nano/linux.fragment (FPGA mgr/region/OF overlay built in, sdhci-cadence, SMMUv3, socfpga clk, stmmac, exfat; RSU deliberately off — it exists to rewrite QSPI, which posture 1 forbids), uncompressed Image, in-tree socdk DTS as a placeholder until the board DTS is validated, 256M ext4 BusyBox rootfs, ttyS0 console. Bare developer OS. Makefile: output-de25/ variant mirroring the rt family (de25, de25-clean, de25-menuconfig, de25-linux-menuconfig, distclean/help updated); de25 does not depend on initramfs. external.mk: the initramfs-embedding kernel fixup now keys on BR2_LINUX_KERNEL && BR2_arm so an aarch64 kernel never gets the armv7 stage-1 cpio. Verified: toolchain builds green in 8 min (gcc 14.4.0, glibc 2.43, -mcpu=cortex-a76.cortex-a55 reaches cc1); savedefconfig round-trip adds nothing; all 38 fragment symbols survive olddefconfig on pristine 7.2.2; DE10 outputs and defconfigs untouched, lockstep check still OK. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
Formalises the nine owner decisions from de25-implementation-path.md §1/§1.1 and maps each to its ADR 0027 disposition point. Records the open decisions (p2 filesystem, shared-base defconfig refactor, U-Boot/ TF-A pairing, upstream submission) and four places where the source docs disagreed with each other, resolved explicitly rather than restated. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
socfpga_agilex5_de25nano.dts on mainline's socfpga_agilex5.dtsi: mainline intel,agilex5-svc kept (binds via carried 0102) with the fpga-mgr child on the two-string compatible; root fpga-region, no bridges; smmu okay; mmc0 authored in SD4HC form as "intel,agilex5-sd4hc", "cdns,sd4hc" with iommus + dma-coherent (an undescribed master under an enabled SMMUv3 aborts, it does not bypass); uart1 console per all three references; 1 GiB memory per the factory SPL DTB; QSPI deliberately absent (posture 1); vendor-only properties dropped with a grep each. docs/de25-dts-rationale.md has the node table, the dtbs_check classification and the re-run commands. dtc: 0 warnings at default and W=1 (W=2 matches the socdk baseline). dtbs_check on 7.2.2+0101+0102: 7 warnings, all attributable — 5 are the known fpga-mgr two-string form, 2 want clocks/iommus/dma-coherent added to cdns,sdhci.yaml (folded into 0101 next). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
…dhci.yaml Completes the binding half of the sdhci-cadence patch so a conforming Agilex 5 mmc node (two clocks, behind SMMUv3 on an I/O-coherent port) passes dtbs_check. Driver hunk unchanged. Verified: apply-patches.sh on pristine 7.2.2 (34/0/0), git apply --check, lint-kernel-patches PASS, dt_binding_check on the schema, zero regressions on the uniphier-ld20 and elba consumers, and the DE25 DTS now warns only on the five fpga-mgr two-string lines (upstream binding gap, §2.5). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
Fable review: sdhci-of-esdhc sets its 40-bit mask from ->enable_dma; the ->set_dma_mask precedent is sdhci-tegra. Note that replacing sdhci_set_dma_mask() skips the 32-bit retry (PIO fallback instead). linux.fragment's console comment said UART0/0x10c02000; the board's console is uart1, as the DTS already selects. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
Fable adversarial review, verified against 7.2.2 source: mainline stratix10-svc takes the SDM buffer from the GET_MEM SMC, keeps physical addresses in its gen_pool and hands them to the SDM raw (no iommu_map/dma_map anywhere), while the inherited iommus = <&smmu 10> attaches the svc device to a translated default domain. With the SMMU on, mainline can bind the fpga-mgr but provably cannot program; the one SMMU-on configuration is the one that cannot work. SMMU-off is unproven, not disproven, and is what the §2.6 test runs first. Every iommus property stays (inert via of_iommu -ENODEV); the SMMU-on form is kept as a labelled alternative. mmc0 gains max-frequency = 25 MHz for first boot: mainline sdhci-cadence programs none of the cdns,phy-* values, and the only mainline-driver boot of this board had to drop to 25 MHz after SCR corruption. Memory node comment corrected: 1 GiB is Terasic's U-Boot DTS constant, U-Boot rewrites /memory from IO96B anyway. Rationale: U1 (uart1 console) promoted to [V]; new U9 (BL31 GET_MEM vs service_reserved, dyndbg check before the first reconfiguration) and U10 (can mainline svc program at all, SMMU off). dtc 0 warnings; dtbs_check 5, all the fpga-mgr two-string binding gap. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
…k list configs/mister_de25nano_defconfig now points BR2_LINUX_KERNEL_CUSTOM_DTS_PATH at board/mister/de25nano/socfpga_agilex5_de25nano.dts and drops the socdk placeholder. The DTS includes the SoC file as arm64/intel/socfpga_agilex5.dtsi (kbuild's include-prefixes form) because Buildroot copies a custom DTS into arch/arm64/boot/dts/, not dts/intel/, where the bare include fails; both placements compile to the same blob. Verified: linux-rebuild all exits 0 and output-de25/images/socfpga_agilex5_de25nano.dtb carries the board model, the sd4hc compatible pair, the 25 MHz cap and the uart1 console. docs/de25-nano-tasks.md gains the wave-1 record (six tracks, commits, what the Fable review changed, the borrowed-board test conditions) and a refreshed next-steps list. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
There was a problem hiding this comment.
🟡 Changes recommended
A few introduced guard/docs paths are internally inconsistent or incomplete (notably de25 artifact assertions and BOARD guard semantics), which could mislead users or allow “green” builds that lack required outputs.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Introduces “wave 1” of DE25-Nano bring-up work in this Buildroot-based repo: adding an aarch64 DE25 developer image build target, board DTS + kernel fragment + patch series scaffolding, and updating CI/guard scripts to be board-aware while preserving DE10 behavior.
Changes:
- Add DE25-Nano build support (
make de25, new Buildroot defconfig, kernel fragment, board DTS). - Add DE25-specific kernel patch carry set (0101/0102) plus symlinked shared patch series documentation.
- Generalize CI/guards to be per-board (new expectations table, lint workflow updates, composite action board input).
File summaries
| File | Description |
|---|---|
| scripts/lib/board-expectations.sh | New per-board expectation registry for arch/toolchain sentinel checks. |
| scripts/check-kernel-defconfig-sync.sh | Table-driven sentinels/families keyed by BOARD. |
| README.md | Documentation update explaining why the stock loop= patch is ARM32-only. |
| Makefile | Adds de25 build family + output dir + help text + artifact assertions. |
| external.mk | Guards initramfs embedding hook to BR2_arm builds only. |
| docs/decisions/0029-de25-implementation-path.md | New ADR 0029 capturing DE25 wave-1 bounding decisions. |
| docs/de25-nano-tasks.md | Records wave-1 execution results and updates next steps. |
| docs/de25-dts-rationale.md | New rationale doc for DE25 DTS choices and validation results. |
| configs/mister_de25nano_defconfig | New Buildroot defconfig for DE25 (aarch64, 7.2.2, ext4 rootfs). |
| board/mister/de25nano/socfpga_agilex5_de25nano.dts | New mainline-based DE25 board DTS (SMMU disabled, mmc0 + fpga nodes). |
| board/mister/de25nano/linux.fragment | Kernel config delta layered on arm64 defconfig for DE25 boot plumbing. |
| board/mister/de25nano/linux-patches/README.md | Explains DE25 patch-series shape, symlink strategy, and audit mapping. |
| board/mister/de25nano/linux-patches/0101-mmc-sdhci-cadence-agilex5-40-bit-dma-mask.patch | Adds Agilex5 SD4HC compatible + 40-bit DMA mask + binding updates. |
| board/mister/de25nano/linux-patches/0102-firmware-stratix10-svc-match-agilex5-svc.patch | Adds DT match-table entry for intel,agilex5-svc. |
| board/mister/de25nano/linux-patches/.gitkeep | Keeps directory present in-tree. |
| .github/workflows/lint.yml | Makes board script shellcheck/executable-bit checks board-agnostic + fails closed on empty sets. |
| .github/actions/buildroot-build/action.yml | Adds board input and per-board fingerprint sentinel assertions. |
Review details
- Files reviewed: 49/50 changed files
- Comments generated: 7
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- make de25 asserts images/rootfs.ext4 exists (the summary claimed it without checking); dtb-glob comment no longer describes the retired socdk placeholder. - check-kernel-defconfig-sync.sh validates BOARD against both BOARD_ARCH_SENTINELS and BOARD_ARCH_FAMILIES so a half-added row is a usage error naming the table, not a set -u trace; header now says plainly that BOARD selects the expectation row only and the compared pair stays the DE10 defconfigs (ledger §5.7 risk 3). - board-expectations.sh de25nano rows promoted [U] -> [V] against the landed defconfig. - DE25 defconfig console comment names uart1 (serial@10c02100), matching the DTS, instead of uart0. No-arg and BOARD=de10nano outputs remain byte-identical; BOARD=bogus exits 2; shellcheck clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
There was a problem hiding this comment.
🟡 Changes recommended
Board routing and parallel setup contain functional gaps, while the ADR and test instructions contradict the shipped patch and SMMU design.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (4)
Previously missed (3) — in code that hasn't changed since the last review.
configs/mister_de25nano_defconfig:265
- “Byte-identical rebuilds” contradicts this block's own statement that the ext4 UUID and hash seed remain random.
BR2_REPRODUCIBLEstabilizes timestamps and kernel build metadata here, but it does not make the assertedrootfs.ext4byte-identical until those filesystem inputs are pinned.
docs/decisions/0029-de25-implementation-path.md:168 - This conclusion predates the final SMMU-off design and is now false: the DTS rationale §4.4 says the 40-bit truncation cannot occur with physical DMA below 4 GiB and explicitly calls 0101 “not load-bearing in the shipped configuration.” Dropping the 7.2 pin prevents SD boot, but dropping 0101 affects the future SMMU-on test rather than the shipped SMMU-off boot path.
This issue also appears on line 180 of the same file.
docs/decisions/0029-de25-implementation-path.md:206
- The shipped DTS cannot satisfy this test with “no driver patches”: its lone
intel,agilex5-svccompatible only binds because 0102 adds the match-table entry. Without 0102,fpga0/region0cannot probe, so the test would report a binding failure before exercising mainline svc behavior. Specify that 0102 remains applied (while behavioral/vendor svc patches are absent), or use the documented DTS fallback for this test.
docs/decisions/0029-de25-implementation-path.md:182
- This decision records the opposite of the implementation in this PR: the DTS keeps
intel,agilex5-svc, and patch 0102 is explicitly carried locally to add the match entry. Since this ADR is the source of record, update D8 to describe the carried match patch and retain the compatible override only as the fallback.
- Files reviewed: 49/50 changed files
- Comments generated: 4
- Review effort level: Balanced
- Makefile: hostshim is an order-only prerequisite of output-de25/.config itself, so make -j de25 cannot invoke Buildroot before the shim exists. - buildroot-build action: BOARD must be both in the registry AND routed; only de10nano is routed today (defconfig, cache key, output dir and target are still DE10-fixed), so de25nano is rejected up front instead of failing its sentinel late. Documented as BOARD_ROUTED. - linux.fragment: SMMU comment describes the shipped SMMU-off design; ARM_SMMU_V3=y is kept for the second test leg, not load-bearing. - DTS rationale: last correction row no longer says the board file turns the SMMU on. - DE25 defconfig: BR2_REPRODUCIBLE comment no longer claims byte-identical images while the ext4 UUID/hash seed are random. - ADR 0029: D7's consequences say 0101 is not load-bearing for the shipped SMMU-off boot path; D8 records the carried 0102 match patch with the compatible override as fallback; D9's test keeps 0102 applied and runs the SMMU-off leg first. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
Summary
Wave 1 of the DE25-Nano bring-up (follows #132, ADR 0027 → ADR 0029). Everything a machine without the board can do: the aarch64 target builds green end to end, the board device tree compiles through Buildroot, the kernel patch series is compile-verified on aarch64/7.2.2, and the per-board CI guards are in place. Nothing here has run on hardware.
DE10 invariant: no DE10 file, defconfig or output directory changes behaviour.
check-kernel-defconfig-sync.shno-arg output is byte-identical; lint's de10nano file set is unchanged (verified by running the rewritten steps).What's in it
9d47643scripts/lib/board-expectations.shfeeds both guards;BOARDdefaults tode10nano, unknown board fails closedlint.ymlffcc78cboard/mister/*/, errors on an empty set (ledger §6.5)cf32b7e,10ce9c9,1a38cceintel,agilex5-svcmatch. 34/34 apply at-F0, both compiledmake de25b29c0b4external.mkinitramfs hook keyed onBR2_arm01d54d8,a2e7df4,ab9f4bddocs/de25-dts-rationale.mdb43c5c1548214eloop=patch is 32-bit-ARM-only by constructionThe one finding that changed the plan
The Fable adversarial review showed, from 7.2.2 source, that mainline
stratix10-svchands physical addresses to the SDM while the dtsi'siommusputs the svc device behind a translated SMMU stream. With the SMMU on, mainline can bind the FPGA manager but cannot program the fabric. Wave 1 therefore ships&smmu { status = "disabled"; }(everyiommuskept, inert), and the §2.6 fabric test runs in that shape first. SMMU-off is unproven, not disproven.Owner decisions surfaced (not blocking)
CONFIG_INTEL_STRATIX10_RSU=n— it exists to rewrite QSPI (posture 1).defconfig+ fragment: 1,481 modules / 90 MB. A curated config is wave-2 work.Testing on a borrowed board
Requires the factory QSPI (our card relies on the factory SPL's contract). Restore is the documented
quartus_pgm … golden_top_hps.jicstep; conditions and the safety bar are indocs/de25-nano-tasks.md→ "Testing on a borrowed board".🤖 Generated with Claude Code
https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm