Add Xilinx Zynq-7000 (ZC702) wolfBoot port#770
Open
dgarske wants to merge 1 commit intowolfSSL:masterfrom
Open
Add Xilinx Zynq-7000 (ZC702) wolfBoot port#770dgarske wants to merge 1 commit intowolfSSL:masterfrom
dgarske wants to merge 1 commit intowolfSSL:masterfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds an initial wolfBoot port for Xilinx Zynq-7000 on the ZC702 board, extending the codebase with a new ARMv7-A / Cortex-A9 target that boots via the Xilinx FSBL, verifies images from QSPI, and chain-loads a staged payload from DDR.
Changes:
- Adds a new
zynq7000target across the HAL, startup code, linker scripts, and build system for FSBL-loaded Cortex-A9 boot. - Introduces a Zynq-7000 QSPI/UART HAL, RAM-boot configuration, and a minimal test application for bring-up validation.
- Documents the target, JTAG workflow, QSPI layout, and adds helper scripts for XSDB/bootgen usage.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
tools/scripts/zc702/zc702_qspi.bif |
Adds a bootgen BIF template for packaging FSBL + wolfBoot into BOOT.BIN. |
tools/scripts/zc702/jtag_load.tcl |
Adds an XSDB script for JTAG bring-up by running FSBL and loading wolfboot.elf into DDR. |
test-app/app_zynq7000.c |
Adds a minimal bare-metal ZC702 test app that prints a boot banner and heartbeat on UART1. |
test-app/Makefile |
Wires the new target into test-app builds with the ARM32 startup object and target linker script. |
test-app/ARM-zynq7000.ld |
Adds the linker script for the staged Zynq-7000 test application in DDR. |
src/boot_zynq7000_start.S |
Adds Zynq-7000-specific ARMv7-A startup, vector setup, stack initialization, and early CPU state handling. |
src/boot_arm32.c |
Adjusts ARM32 inline assembly immediate syntax used during chain-load handoff. |
hal/zynq7000.ld |
Adds the wolfBoot linker script for execution from DDR at the FSBL handoff address. |
hal/zynq7000.h |
Defines Zynq-7000 register maps and bitfields for UART, QSPI, and related peripherals. |
hal/zynq7000.c |
Implements the new Zynq-7000 HAL, including UART, QSPI external flash access, and boot-preparation logic. |
docs/Targets.md |
Documents the new ZC702 target, configuration, memory map, JTAG flow, and expected output. |
config/examples/zynq7000.config |
Adds an example configuration for ECC256/SHA256 RAM-boot from external QSPI flash. |
arch.mk |
Adds target selection and Cortex-A9-specific compiler/object settings for zynq7000. |
Makefile |
Includes the new target in the default main build outputs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a wolfBoot port for the Xilinx Zynq-7000 SoC (Cortex-A9 dual-core, ARMv7-A 32-bit), verified end-to-end on the ZC702 Evaluation Kit (XC7Z020). wolfBoot replaces U-Boot in the Zynq-7000 boot flow -- BootROM loads FSBL, FSBL loads wolfBoot into DDR, wolfBoot verifies and chain-loads either a bare-metal app or a Linux kernel directly. There is no U-Boot stage. This is a distinct port from the existing ZynqMP/
zynqtarget: different CPU architecture (A9 vs A53), different QSPI controller (XQspiPsvsXQspiPsuGQSPI), different SDHCI revision (Arasan v2.0 vs v3.0), different clock/reset infrastructure (SLCR vs CRL_APB), and a simpler boot model (FSBL -> wolfBoot, no PMUFW/BL31).New features
TARGET=zynq7000with full HAL, linker script, and Cortex-A9 startup support.hal/zynq7000.{c,h,ld}covers UART, QSPI, SDHCI, timer, cache, and chain-load handoff for the XC7Z020. Selected automatically via theCORTEX_A9arch.mk block.config/examples/zynq7000.configconfig/examples/zynq7000_sdcard.configLINUX_PAYLOAD=1 MMU=1 ELF=1set in both configs, the same wolfBoot binary boots either a signed bare-metal.binor a signed Linux zImage, picking the right register handoff at chain-load time. Bare-metal apps don't pay any runtime cost beyond ~5 KB of unused FDT/MMU code.hal/zynq7000.c, the older Linear/Static QSPI on Z7, not the GQSPI on ZynqMP). Two paths: I/O mode for short command ops (RDID/RDSR/WREN/SE/PP) using the TXD1/TXD2/TXD3 auto-start FIFOs, and Linear/XIP mode for bulk reads via the memory-mapped0xFC000000window with 32-bit AXI reads + byte unpack (single-byte loads to the linear window are unreliable). Wired toext_flash_read/write/erase;hal_flash_*are no-ops since Z7 has no internal flash.src/sdhci.cCadence SD4HC register layout to the Arasan v2.0 standard SDHCI layout. Adds SLCR clock and reset for the SDIO0 controller, plus ARMv7 D-cache maintenance via CP15 for SDMA buffers. Handles the v2.0 quirks (3.3V-only, no UHS-I, masks UMS / 1.8V / sampling-clock / HV4E / A64 in SRS15, masks HSE in HostCtrl1).hal_get_timer_us()and the SDHCI driver'sudelay().BOOT.BINas a regular file in that FAT32 root. wolfBoot'sdisk.cfalls back to MBR parsing when no protective-GPT entry is present.BOOT_PART_A/BOOT_PART_Bindex the MBR entries (0-indexed) for the boot/update raw partitions.src/boot_arm32_start.S(was SAMA5D3-Cortex-A5-specific). Now handles per-mode stacks (IRQ/FIQ/ABT/UND/SVC), VBAR setup viacp15 c12.c0.0, SCTLR.{A,V,C,I} clearing, TLB / I-cache / branch-predictor invalidate, async-abort enable, and.data/.bsssetup. Used by both SAMA5D3 (Cortex-A5) and Zynq-7000 (Cortex-A9). The previous SAMA5D3-specific startup path is retired (build-tested for SAMA5D3 regression at 22.6 KB).do_boot(src/boot_arm32.c). NewWOLFBOOT_LINUX_PAYLOAD#ifdefbranch follows the kernel's documented register handoff:r0 = 0,r1 = ~0(no machine ID, use DTB),r2 = DTB physical address,r3 = 0, entry point inr4. Default behaviour (legacy DTS-in-r0 for bare-metal) is preserved when the flag is unset. Single inline-asm block with proper operand and clobber annotations -- avoids the cross-asm volatile-block register lifetime problem the previous implementation had.tools/scripts/zynq7000/prepare_linux.sh. Defaults toAPPENDED=1, which concatenates the DTB onto the zImage and signs the pair as one wolfBoot image. The kernel finds the DTB embedded in itself viaCONFIG_ARM_APPENDED_DTB, independent ofr2. This works around an ARMv7 zImage decompressorr2-loss observed on this kernel/load combo where__atags_pointerends up 0 if we rely on the standardr2-as-DTB-pointer path.APPENDED=0is plumbed through but currently has a known bug in sharedupdate_ram.c(kept out of this PR -- happy to send as a follow-up).tools/scripts/zynq7000/:zynq7000_qspi.bif-- bootgen template forBOOT.BIN(FSBL + wolfboot.elf), shared by all configs.jtag_load.tcl-- xsdb script for JTAG-loaded development via Platform Cable II.prepare_linux.sh-- signs zImage for the Linux flow (APPENDED-DTB or raw-DTB), uses a whitelisted awk parser to read partition addresses from.config(noeval, no shell-injection risk), exportsIMAGE_HEADER_SIZEso the sign tool matches the running config.prepare_sdcard.sh-- lays out a pure-MBR SD card (parted msdos + manual MBR type/active patch), formats p1 as FAT32, copies BOOT.BIN, dd's the signed image into raw partitions p2 and p3. Refuses/dev/sda,/dev/nvme*,/dev/mmcblk0, and non-removable block devices by default; explicit env-var overrides for the unusual cases (ALLOW_MMCBLK0=1,ALLOW_NON_REMOVABLE=1). Trims whitespace fromlsblk -ndo RMoutput before the comparison so the removable check is robust.hal_initprints storage type, post-init clock, payload ABI, partition addresses, and Cortex-A9 GTimer frequency on every boot, so the UART log identifies which config the running image was built for.DISK_BLOCK_SIZE=0x80000(512 KB) in the SD config. Theupdate_disk.cdefault of 512 B issues onedisk_read(== one CMD17 PIO read) per 512 B chunk; for a 4.76 MB Linux zImage that's 9k+ commands and the card eventually times out (SRS12 bit 20 / EDT) under that pace. 512 KB chunks issue ~10 CMD18 SDMA transfers and complete in well under a second, matching what ZynqMP does.test-app/app_zynq7000.c+test-app/ARM-zynq7000.ld. Minimal banner + heartbeat dot loop over UART1 to validate the chain-load handoff, on either QSPI or SD.int main(void) __attribute__((noreturn))for portability..github/workflows/test-configs.ymladdszynq7000_testandzynq7000_sdcard_testbuild jobs using the existingtest-build.ymlreusable workflow witharch: armand the wolfboot-ci-arm container image -- same setup the SAMA5D3 build uses, no new toolchain needed.docs/Targets.md"Xilinx Zynq-7000 (ZC702)" section covering prerequisites (Vitissettings64.sh, Platform Cable II driver install, prebuilt FSBL clone), JTAG bring-up, QSPI flashing recipe, DDR map, sample cold-boot UART output,TEST_EXT_FLASHselftest expected output, SD-card layout + Arasan v2.0 quirks, and a comparison table vs the ZynqMP port.