Skip to content

wolfBoot ZynqMP FSBL: signed FIT Linux boot + direct-EL3 security (eFuse / PUF / AES-CSU)#817

Draft
dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:zynqmp_fsbl
Draft

wolfBoot ZynqMP FSBL: signed FIT Linux boot + direct-EL3 security (eFuse / PUF / AES-CSU)#817
dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:zynqmp_fsbl

Conversation

@dgarske

@dgarske dgarske commented Jul 3, 2026

Copy link
Copy Markdown
Member

Summary

Adds support for running wolfBoot as the Xilinx ZynqMP FSBL replacement (ZCU102 / xczu9eg). The BootROM authenticates and loads wolfBoot into OCM at EL3; wolfBoot runs psu_init() (PLLs/DDR/MIO/clocks/PS-GTR serdes), loads and verifies a signed FIT (kernel + ATF/BL31 + FDT) from QSPI with its own keys, loads the PMU configuration object over the APU->PMU IPI, and hands off to BL31 which drops to Linux. Validated end-to-end on real hardware to a petalinux login: prompt.

On top of the boot path, this adds direct-at-EL3 access to the CSU / eFuse / PUF / AES engines for FSBL mode, where the usual SMC-to-ATF path is unavailable (there is no ATF beneath wolfBoot).

What's included

  • FSBL boot flow: OCM link script, psu_init shim (timer/serdes), PMU config-object load, BL31 (TF-A) handoff via PMU_GLOBAL scratch registers, signed-FIT load/verify. New config config/examples/zynqmp_fsbl.config (+ SD variant); build with ZYNQMP_FSBL=1.
  • Dual-mode PMU transport: pmu_mmio_read/write use direct MMIO under WOLFBOOT_ZYNQMP_FSBL and the existing SMC path in BL33 mode, so the whole csu_* tree works in both without change.
  • eFuse read (ZYNQMP_SEC=1): read-only dump of the eFuse cache (SEC_CTRL, PPK0 hash, PUF CHASH/AUX) directly from the controller at EL3.
  • Finer CSU gate: the CSU SHA3 HAL is separated from the eFuse/PUF/AES code so FSBL builds keep software SHA3 for verify without a multiply-defined wc_Sha3_384_*.
  • PUF and AES-CSU: PUF register/regenerate (KEK) and AES-GCM with a user (KUP) key, reusing the existing csu_puf_* / csu_aes code. csu_aes is refactored to csu_aes_ex (selectable key source + KUP load) with the device-key wrapper preserved.
  • eFuse writes are intentionally not implemented (read-only); OTP programming is left for a separate, explicitly-gated change.
  • Cross-target fixes the FSBL work touched: the RAM image/wolfBoot overlap guard is restored for RAMBOOT targets without WOLFBOOT_ORIGIN (and hardened against a wrapped end address), and the EL3 exception printers are gated on DEBUG_UART so release EL3 targets (e.g. nxp_ls1028a) keep the silent stub.

Hardware validation (ZCU102)

  • Full cold boot from QSPI to Linux login on the pruned/refactored wolfBoot.
  • eFuse dump matches a TRACE32 DAP read of the same registers exactly.
  • PUF register and regenerate both succeed at EL3 (no eFuses programmed).
  • AES-256-GCM with a KUP key matches a software known-answer test exactly and round-trips (encrypt then decrypt with the CSU GCM tag enforced).

Testing / build coverage

  • tools/unit-tests: 19/19 pass, including new unit-update-ram overlap-predicate cases.
  • Builds verified: FSBL (default, ZYNQMP_SEC, and PUF/AES self-tests), a normal ZynqMP BL33 target with HW_SHA3=1 (CSU SHA3 HAL intact), and nxp_ls1028a (both DEBUG_UART settings).
  • The PUF and AES self-tests are opt-in bring-up validation, gated off by default (ZYNQMP_PUF_SELFTEST / ZYNQMP_AES_SELFTEST).

Notes for reviewers

  • The board-specific psu_init_gpl.c and pm_cfg_obj.c (Xilinx-tool-generated numeric design data) are supplied at build time from ZYNQMP_PSU_INIT_DIR and are not part of this tree.
  • BL31 is upstream Xilinx TF-A (xlnx_rebase_v2.12) plus the small in-tree DTB-forwarding patch under tools/scripts/zcu102/.
  • Docs: see docs/Targets.md for the ZynqMP FSBL section and packaging (bootgen BIF files under tools/scripts/zcu102/).

@dgarske dgarske self-assigned this Jul 3, 2026
Copilot AI review requested due to automatic review settings July 3, 2026 00:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a ZynqMP (ZCU102) “wolfBoot as FSBL replacement” boot flow, where BootROM loads wolfBoot into OCM at EL3, wolfBoot performs PS init (psu_init), verifies a signed FIT (kernel/DTB/optional BL31), and optionally hands off to TF-A BL31 for Linux boot.

Changes:

  • Add ZynqMP FSBL-replacement build configuration, OCM linker script, PS-init shims, and PMU configuration-object support.
  • Add BL31 handoff plumbing (handoff parameter block + PMU scratch registers) and TF-A patch for DTB forwarding to direct-kernel BL33.
  • Rework ZynqMP GQSPI read path and add diagnostics to improve reliability for large QSPI DMA reads.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tools/scripts/zcu102/zynqmp_wolfboot_fsbl.bif Bootgen BIF for BootROM loading wolfBoot as bootloader (FSBL replacement).
tools/scripts/zcu102/zynqmp_wolfboot_fsbl_auth.bif Authenticated Bootgen BIF (RSA) for hardware root-of-trust boot.
tools/scripts/zcu102/zcu102-ca53-qspi.cmm TRACE32 script update for flashing signed FIT to the boot partition offset.
tools/scripts/zcu102/tf-a-zynqmp-wolfboot-dtb.patch TF-A patch to forward DTB pointer to direct-kernel BL33 via PMU scratch.
src/update_ram.c RAM boot path updates: improved overlap check, QSPI load diagnostics, optional BL31 load/handoff.
src/update_disk.c Disk boot path updates: optional BL31 load/handoff from FIT.
src/boot_aarch64.c Add EL3 exception reporting handlers for improved fault visibility.
src/boot_aarch64_start.S FSBL-replacement timer-frequency behavior and new EL3→BL31 handoff routine.
include/wolfboot_smc.h New SMC ABI definition for wolfBoot EL3 monitor services and shared-memory region.
hal/zynqmp/xil_io.h Minimal Xilinx-compatible MMIO/types shim for unmodified psu_init_gpl.c.
hal/zynqmp/sleep.h Minimal Xilinx-compatible sleep/usleep shim API for psu_init_gpl.c.
hal/zynqmp_psu_shim.c Delay/timer primitives and psu_init wrapper sequence (incl. optional SERDES and debug markers).
hal/zynqmp_ocm.ld New linker script to run wolfBoot entirely from OCM for FSBL-replacement boot.
hal/zynqmp_fsbl.its FIT source for kernel+DTB+BL31 packaging for wolfBoot FSBL-replacement boot.
hal/zynqmp_atf.h BL31 handoff API for wolfBoot-as-FSBL.
hal/zynqmp_atf.c BL31 handoff parameter block construction + PMU scratch publication + EL3 teardown/branch.
hal/zynq.h Add GQSPI DMA max-chunk configuration constant.
hal/zynq.c Significant QSPI DMA/read sequencing changes, cache maintenance adjustments, and FSBL-mode PM config loading.
hal/board/zynqmp/README.txt Documentation for supplying board-generated psu_init_gpl.* into the build.
hal/board/zynqmp/pm_cfg_obj.c PMU configuration object blob for ZCU102/design permissions (EEMI table).
hal/board/zynqmp/.gitignore Ignore board-generated psu_init_gpl.* artifacts.
docs/Targets.md Add a documented ZynqMP FSBL-replacement target and boot flow instructions.
config/examples/zynqmp_fsbl.config New FSBL-replacement QSPI configuration example.
config/examples/zynqmp_fsbl_sd.config New FSBL-replacement SD configuration example.
arch.mk Build-system integration for FSBL-replacement (OCM link, psu_init integration, optional PM config/SERDES).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tools/scripts/zcu102/zynqmp_wolfboot_fsbl.bif
Comment thread hal/zynqmp_fsbl.its Outdated
Comment thread hal/zynqmp_fsbl.its Outdated
Comment thread hal/zynqmp_fsbl.its Outdated
Comment thread hal/zynqmp_fsbl.its Outdated
Comment thread hal/zynq.c
Comment thread hal/zynq.c
Comment thread src/update_ram.c Outdated
@dgarske dgarske changed the title Add wolfBoot ZynqMP FSBL with signed FIT Linux boot (BL31 handoff, PMU config object, PS-GTR serdes) wolfBoot ZynqMP FSBL: signed FIT Linux boot + direct-EL3 security (eFuse / PUF / AES-CSU) Jul 6, 2026
@dgarske dgarske requested a review from Copilot July 6, 2026 20:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 7 comments.

Comment thread src/update_ram.c Outdated
Comment thread config/examples/zynqmp_fsbl.config Outdated
Comment thread config/examples/zynqmp_fsbl_sd.config Outdated
Comment thread hal/zynqmp_fsbl.its
Comment thread hal/zynqmp_fsbl.its
Comment thread hal/zynqmp_fsbl.its
Comment thread hal/zynq.c Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 4 comments.

Comment thread hal/zynq.c
Comment on lines +685 to +689
flush_dcache_range((unsigned long)iv, (unsigned long)iv + CSU_AES_IV_SZ);
flush_dcache_range((unsigned long)in,
(unsigned long)in + sz + CSU_AES_GCM_TAG_SZ);
flush_dcache_range((unsigned long)out,
(unsigned long)out + sz + CSU_AES_GCM_TAG_SZ);
Comment thread hal/zynq.c
Comment on lines +756 to +763
if (ret == 0)
ret = csu_dma_transfer(CSUDMA_CH_SRC, (uintptr_t)in, sz,
CSUDMA_SIZE_LAST_WORD);
if (ret == 0 && csu_dma_wait_done(CSUDMA_CH_SRC) != 0)
ret = -11; /* ciphertext transfer timeout */
if (ret == 0)
ret = csu_dma_transfer(CSUDMA_CH_SRC, (uintptr_t)(in + sz),
CSU_AES_GCM_TAG_SZ, CSUDMA_SIZE_LAST_WORD);
Comment thread src/update_disk.c
}
load_address = new_load;
}
#if defined(WOLFBOOT_ZYNQMP_FSBL)
Comment thread hal/zynq.c
Comment on lines +778 to +780
/* Invalidate the DMA-written output so the CPU reads fresh data */
flush_dcache_range((unsigned long)out,
(unsigned long)out + sz + CSU_AES_GCM_TAG_SZ);
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.

2 participants