Skip to content

accel/ane: stage cold-acquired H17 AP-direct on shared firmware transport - #714

Merged
RyanTheTide merged 9 commits into
aurora-wipfrom
ane/h17-cold-acquired
Nov 1, 2026
Merged

RyanTheTide merged 9 commits into
aurora-wipfrom
ane/h17-cold-acquired

Conversation

@RyanTheTide

@RyanTheTide RyanTheTide commented Oct 31, 2026 •

Copy link
Copy Markdown

H17 can run AP-direct only after a proved cold acquisition. This draft adds the T8140 staged backend to the shared H16/H17 transport from #706, keeps production DT nodes disabled, and preserves all nonzero DART SIDs instead of resetting every stream at generic DART probe.

The initial write of probe to firmware_stage is installed before platform driver registration, so the platform bus cannot power genpd or attach default DMA ahead of the read-only diagnostic. Acquisition requires loader raw-boot evidence plus the measured CPU, child-power, PWGATE, CE and DART reset state. Physically-on ANE_SYS is handled explicitly; genpd's off label alone is not a cold marker. The stages then acquire SID0 on three DARTs, copy reserved iBoot preload segments into private coherent memory, verify/write the four DT DAPF ranges, run the scratch handshake and send PRINT_ENABLE, START, CONFIG_GET and RESOURCE_INFO_GET. Completion is polled; IRQs 655 and 668 are never enabled.

Secure-mode commands 0x27/0x28/0x34 and Exclave commands 0x30/0x31 are denied at the transport publication boundary. 0x2f is shared-event initialization, is not on that deny list, and is not sent by startup.

The internal program backend reuses the shared transport and H16/H17 EXECUTE/UUID helpers for LOAD/CREATE, 0x2d/EXECUTE/0x2d, TERMINATE/UNLOAD and the observed SHAREDMALLOC FREE response. It checks owned mappings, rejects legacy kernel operation tag 2 in favor of the kernel LOAD resource index 1007, poisons output and requires exact expected bytes after terminal UUID/ID validation.

One program lifetime per firmware boot is mandatory and KUnit-covered. A later program's first job can write to the previous program's output when EXECUTE buffer counts match; a larger output can overrun the old mapping and crash firmware. Extra TLB flushes do not fix this. The backend keeps normal mapping synchronization, refuses a second LOAD with a clear error even after UNLOAD/FREE, and retains all mapping backing until reboot. Unexpected output or any acquisition/firmware timeout quarantines immediately. No in-place retry or reset is offered. System sleep and kexec are blocked after acquisition.

This remains an integration draft:

  • The companion t-3871 original-HWX userspace frontend is not available yet. This PR provides internal allocation and program-run hooks, not a new section-upload ABI or a claim of usable H17 inference ioctls.
  • The loader must implement the cold-evidence and reserved-preload contract documented in Documentation/accel/apple-ane-cold.rst. The test DTS deliberately does not forge evidence or hard-code personalized preload addresses.
  • TEXT has the measured 26.6.2 build pin. The loader's full live-DATA digest checks preservation, not a pinned immutable-DATA manifest; that manifest is still required before production enablement.
  • DVA|1 with zero length/handle is the observed accepted FREE response. Its canonical protocol form is not yet proved. A missing/delayed FREE at teardown times out and quarantines; backing is never recycled.

Validation: strict checkpatch on the final source, binding and DT changes (checked separately with maintenance coverage) reports zero errors, warnings or checks. Both updated DT bindings pass dt-doc-validate. A supplementary native compatibility harness passes 31 transport cases and 6 cold-policy cases under ASAN/UBSAN; this is not Linux KUnit. Controller-approved buildbox requests h-46858 (arm64 LLVM W=1 Image/modules/test DTB) and h-46859 (Linux x86_64 KUnit with KASAN/UBSAN) remain queued and unrun. No Neo test was requested or run by this worker.

Lead runbook (one-shot GRUB entry, rollback = reboot):

  1. Build CONFIG_DRM_ACCEL_ANE=y, CONFIG_APPLE_DART=y, CONFIG_KUNIT=y and CONFIG_DRM_ACCEL_ANE_FW_KUNIT_TEST=y as one matching kernel/DTB set. Acquisition requires built-in ANE because the current tree's kexec blocker is built-in-only; a module can perform U2 observation only.
  2. Prepare a separate ANE cold U2 (one-shot) GRUB entry by copying the known-good entry's root/initrd/watchdog/bootguard settings and substituting only the test kernel and t8140-j700-ane-test.dtb. Keep the saved production default unchanged. Select it once with grub-reboot 'ANE cold U2 (one-shot)', then reboot through the normal bootguard fallback. Do not replace the production DTB, boot object or saved default.
  3. U2 first: locate the ANE device's firmware_stage file under /sys/devices/platform, then write probe as root. Expected dmesg: H17 ANE: read-only staged observer ready; three U2 DART lines with version low 16 bits 0x203, protect/lock without TTBR bit 0 or DAPF lock bit 2; CPU control 0, status 0x6a, RVBAR 0x10000000001; cold child/PWGATE/CE; DAPF words logged without using random record contents as a cold marker. With valid loader evidence, expect ANE probe: cold reset state and raw-boot evidence verified; no writes. Otherwise expect one cold-acquisition refusal after the diagnostic. Preserve the full log privately and reboot.
  4. Only with loader evidence/reservations/digest supplied by the trusted boot path, use a fresh one-shot boot and repeat probe, then write map. Expected: ANE power: ANE_SYS on, child/PWGATE/CE ready, then ANE map: reserved preload, SID0 on three DARTs, DAPF verified.
  5. Write boot. Expected: ANE boot: READY, then ANE boot: eight channels armed, scratch3 cleared (polled). No RTKit exchange is awaited. Write startup. Expect four zero-ack lines for 0x4, 0x0, 0x3 and 0x22, ANE CONFIG_GET tick=24000000 and the 100-byte RESOURCE_INFO log.
  6. Program testing waits for original-HWX frontend integration. When wired, use one validated open H17 program with immutable expected output per fresh firmware boot. Expect UUID/ID completion, exact output and FREE acknowledgment. A second LOAD must refuse with one program per firmware boot; reboot required.
  7. At the first unexpected value, failure or timeout, preserve diagnostics and systemctl reboot. Never unload or retry after map/RUN. Rollback is the unchanged saved production entry on reboot; suspend is refused while retained. No audio is needed.

Validate the dynamic channel table before arming host rings, publish pool-backed commands, check replies and consume owned reports. Provide bounded SHAREDMALLOC allocations and match-data IRQ helpers with absolute command deadlines and retained failure state.

Exercise malformed descriptors, ring ordering, reply corruption, report ownership, allocation ceilings and deadline expiry using synthetic KUnit accessors. Keep probe and hardware ownership unchanged.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Install a read-only observer before the platform bus can power or attach
DMA. Require loader raw-boot evidence and the measured cold CPU, child,
CE and DART state before acquisition. Add staged power, private SID0
mapping, preload verification, scratch boot and four-command startup.

Restrict the ANE DART profile to SID0 without resetting foreign streams.
Deny secure and Exclave commands at publication. Add an internal program
path with kernel-tag validation, UUID and exact-output completion and an
observed FREE acknowledgment that retains backing until reboot.

Refuse a second program lifetime: H17 can reuse the previous output BAR
on a later program's first job. Normal map synchronization remains; extra
TLB invalidates do not fix this defect. Original-HWX frontend integration
and a production immutable-DATA manifest remain pending.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Describe the measured child PWGATE window, four DAPF ranges and the
loader's per-boot DATA preservation digest. Allow disabled nodes to
specify firmware DVAs before the loader supplies preload reservations.

Give the three ANE DARTs a dedicated compatible so their SID0-only
ownership profile is determined by DT rather than an operator knob.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Supply PMGR, PWGATE and the four ordinary SID0 DAPF ranges. Remove the
high-only DART DMA window so the private domain can reach the identity
MMIO pages as well as the firmware DVAs. Keep production nodes disabled.

Add a separate test DTB that enables the ANE and its three SID0-only
DARTs. It supplies neither loader cold-boot evidence nor personalized
preload addresses; the trusted loader must provide those for acquisition.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Hold the system sleep lock across staged actions so acquisition cannot
race a suspend preparation that observed the old unretained state.
Document maintenance coverage for the explicit lead test DTB.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Keep the one-program-per-firmware-boot restriction at the shared
publication boundary as well as in the backend. Verify refusal after a
successful LOAD and UNLOAD without writes, pool consumption or a pending
transaction. Retain the kernel-tag and secure-command policy tests.

Track allocation tags so teardown waits for the exact CREATE EXPP pool's
FREE rather than an unrelated free. Reject duplicate DART phandles and
malformed CPU-load notifications before using their state.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Keep the transport publication calls separate from the assertion macros
so the second-LOAD cases pass strict checkpatch alignment checks.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Include platform_device.h before dereferencing the backend platform
device and of_device.h for of_dma_configure(). The arm64 LLVM build
otherwise fails on incomplete types and an implicit function declaration.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Describe the engine, PMGR and PWGATE windows required by the T8140
binding, and include its required DAPF ranges. The old example only
provided the engine window, causing dt_binding_check diagnostics.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
@RyanTheTide

Copy link
Copy Markdown
Author

Verification completed on 2026-10-31.

PR Verified source x86_64 KASAN/UBSAN arm64 KASAN/UBSAN arm64 LLVM W=1
#706 8f9cd9c 49/49 49/49 clean
#699 4a08e30 50/50 50/50 clean
#714 8ebdf63 59/59 59/59 clean

Fixed two verification failures with new commits:

  • 6e5627c: include platform_device.h and of_device.h for platform-device access and of_dma_configure().
  • 8ebdf63: complete the T8140 binding example with its three register windows and required DAPF ranges.

The final head passed all 59 cases on each architecture, including 31 transport and 6 cold-policy cases. ANE and DART dt_binding_check (including yamllint and compiled examples) passed without diagnostics. CHECK_DTBS=y validation of apple/t8140-j700-ane-test.dtb also passed without diagnostics.

The separate W=1 DTB compile succeeded and emitted five existing base-DTS warnings (four UAT reserved-memory unit names and the GPU/mailbox duplicate unit address). The ANE driver W=1 build is clean. These checks establish build and synthetic-test results; live ANE boot/inference was not tested.

All six QEMU runs used LLVM with CONFIG_KASAN=y, CONFIG_KASAN_GENERIC=y, CONFIG_KASAN_INLINE=y, CONFIG_UBSAN=y and CONFIG_UBSAN_BOUNDS=y. Saved final configurations confirm the options were enabled; raw kernel logs contain no KASAN/UBSAN reports or failed tests. Tool versions: Clang 22.1.6, QEMU 11.0.1.

The driver builds enabled ARCH_APPLE, APPLE_MAILBOX, APPLE_RTKIT, APPLE_DART, DRM_ACCEL_ANE and both ANE KUnit options as built-ins. Each log below is from a fresh driver compilation after make clean:

make O="$OUT" ARCH=arm64 LLVM=1 W=1 -j8 drivers/accel/ane/
Complete clean arm64 LLVM W=1 driver build log (exit 0)
make[1]: Entering directory '$WORK/out/714/driver'
  HOSTCC  scripts/basic/fixdep
  SYSHDR  arch/arm64/include/generated/uapi/asm/unistd_64.h
  UPD     include/generated/utsrelease.h
  SYSTBL  arch/arm64/include/generated/asm/syscall_table_32.h
  SYSTBL  arch/arm64/include/generated/asm/syscall_table_64.h
  SYSHDR  arch/arm64/include/generated/asm/unistd_32.h
  SYSHDR  arch/arm64/include/generated/asm/unistd_compat_32.h
  HOSTCC  scripts/dtc/dtc.o
  HOSTCC  scripts/dtc/flattree.o
  HOSTCC  scripts/dtc/fstree.o
  HOSTCC  scripts/dtc/data.o
  HOSTCC  scripts/dtc/livetree.o
  HOSTCC  scripts/dtc/treesource.o
  HOSTCC  scripts/dtc/srcpos.o
  HOSTCC  scripts/dtc/checks.o
  HOSTCC  scripts/dtc/util.o
  LEX     scripts/dtc/dtc-lexer.lex.c
  YACC    scripts/dtc/dtc-parser.tab.[ch]
  HOSTCC  scripts/dtc/libfdt/fdt.o
  HOSTCC  scripts/dtc/libfdt/fdt_ro.o
  HOSTCC  scripts/dtc/libfdt/fdt_wip.o
  HOSTCC  scripts/dtc/libfdt/fdt_sw.o
  HOSTCC  scripts/dtc/libfdt/fdt_rw.o
  HOSTCC  scripts/dtc/libfdt/fdt_strerror.o
  HOSTCC  scripts/dtc/libfdt/fdt_empty_tree.o
  HOSTCC  scripts/dtc/libfdt/fdt_addresses.o
  HOSTCC  scripts/dtc/libfdt/fdt_overlay.o
  HOSTCC  scripts/dtc/fdtoverlay.o
  HOSTCC  scripts/dtc/dtc-lexer.lex.o
  HOSTCC  scripts/dtc/dtc-parser.tab.o
  HOSTLD  scripts/dtc/fdtoverlay
  HOSTLD  scripts/dtc/dtc
  HOSTCC  scripts/kallsyms
  HOSTCC  scripts/sorttable.o
  HOSTCC  scripts/elf-parse.o
  HOSTCC  scripts/asn1_compiler
  HOSTLD  scripts/sorttable
  GEN     arch/arm64/include/generated/asm/cpucap-defs.h
  GEN     arch/arm64/include/generated/asm/kernel-hwcap.h
  GEN     arch/arm64/include/generated/asm/sysreg-defs.h
  CC      scripts/mod/empty.o
  HOSTCC  scripts/mod/mk_elfconfig
  CC      scripts/mod/devicetable-offsets.s
  MKELF   scripts/mod/elfconfig.h
  HOSTCC  scripts/mod/modpost.o
  HOSTCC  scripts/mod/file2alias.o
  HOSTCC  scripts/mod/sumversion.o
  HOSTCC  scripts/mod/symsearch.o
  HOSTLD  scripts/mod/modpost
  CC      kernel/bounds.s
  CHKSHA1 $WORK/src/include/linux/atomic/atomic-arch-fallback.h
  CHKSHA1 $WORK/src/include/linux/atomic/atomic-instrumented.h
  CHKSHA1 $WORK/src/include/linux/atomic/atomic-long.h
  CC      arch/arm64/kernel/asm-offsets.s
  CC      kernel/sched/rq-offsets.s
  CALL    $WORK/src/scripts/checksyscalls.sh 
  LDS     arch/arm64/kernel/vdso/vdso.lds
  CC      arch/arm64/kernel/vdso/vgettimeofday.o
  AS      arch/arm64/kernel/vdso/note.o
  AS      arch/arm64/kernel/vdso/sigreturn.o
  CC      arch/arm64/kernel/vdso/vgetrandom.o
  AS      arch/arm64/kernel/vdso/vgetrandom-chacha.o
  LD      arch/arm64/kernel/vdso/vdso.so.dbg
  VDSOSYM include/generated/vdso-offsets.h
  OBJCOPY arch/arm64/kernel/vdso/vdso.so
  LDS     arch/arm64/kernel/vdso32/vdso.lds
  CC32    arch/arm64/kernel/vdso32/note.o
  CC32    arch/arm64/kernel/vdso32/vgettimeofday.o
  HOSTCC  arch/arm64/kernel/vdso32/../../../arm/vdso/vdsomunge
  LD32    arch/arm64/kernel/vdso32/vdso.so.raw
  MUNGE   arch/arm64/kernel/vdso32/vdso32.so.dbg
  OBJCOPY arch/arm64/kernel/vdso32/vdso.so
  CC      drivers/accel/ane/ane_drv.o
  CC      drivers/accel/ane/ane_tm.o
  CC      drivers/accel/ane/ane_dart.o
  CC      drivers/accel/ane/ane_boost.o
  CC      drivers/accel/ane/ane_fw_platform.o
  CC      drivers/accel/ane/ane_fw_cold.o
  CC      drivers/accel/ane/ane_t6021_rtclient_main.o
  CC      drivers/accel/ane/ane_t6021_fwload.o
  CC      drivers/accel/ane/ane_t6021_boot.o
  CC      drivers/accel/ane/ane_drv_test.o
  CC      drivers/accel/ane/ane_fw_platform_test.o
  CC      drivers/accel/ane/ane_fw_protocol_test.o
  CC      drivers/accel/ane/ane_h16_tasks_test.o
  CC      drivers/accel/ane/ane_h16_execute_test.o
  CC      drivers/accel/ane/ane_fw_transport_test.o
  CC      drivers/accel/ane/ane_fw_cold_test.o
  AR      drivers/accel/ane/built-in.a
make[1]: Leaving directory '$WORK/out/714/driver'

ANE and DART dt_binding_check log (exit 0)
make[1]: Entering directory '$WORK/out/714/driver'
  SCHEMA  Documentation/devicetree/bindings/processed-schema.json
  CHKDT   $WORK/src/Documentation/devicetree/bindings
  LINT    $WORK/src/Documentation/devicetree/bindings
  STYLE   $WORK/src/Documentation/devicetree/bindings
  DTEX    Documentation/devicetree/bindings/iommu/apple,dart.example.dts
  DTEX    Documentation/devicetree/bindings/npu/apple,ane.example.dts
  DTC [C] Documentation/devicetree/bindings/iommu/apple,dart.example.dtb
  DTC [C] Documentation/devicetree/bindings/npu/apple,ane.example.dtb
make[1]: Leaving directory '$WORK/out/714/driver'

t8140-j700-ane-test DTB validation log (exit 0)
make[1]: Entering directory '$WORK/out/714/driver'
  SYNC    include/config/auto.conf
  UPD     include/config/kernel.release
  DTC [C] arch/arm64/boot/dts/apple/t8140-j700-ane-test.dtb
make[1]: Leaving directory '$WORK/out/714/driver'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant