Skip to content

Commit 51592bc

Browse files
committed
Add Xilinx Zynq-7000 (ZC702) wolfBoot port
1 parent 8c7b864 commit 51592bc

18 files changed

Lines changed: 2601 additions & 87 deletions

.github/workflows/test-configs.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,18 @@ jobs:
648648
arch: aarch64
649649
config-file: ./config/examples/zynqmp_sdcard.config
650650

651+
zynq7000_test:
652+
uses: ./.github/workflows/test-build.yml
653+
with:
654+
arch: arm
655+
config-file: ./config/examples/zynq7000.config
656+
657+
zc702_sdcard_test:
658+
uses: ./.github/workflows/test-build.yml
659+
with:
660+
arch: arm
661+
config-file: ./config/examples/zc702_sdcard.config
662+
651663
versal_vmk180_test:
652664
uses: ./.github/workflows/test-build-aarch64.yml
653665
with:

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,10 @@ ifeq ($(TARGET),sama5d3)
285285
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
286286
endif
287287

288+
ifeq ($(TARGET),zynq7000)
289+
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
290+
endif
291+
288292
ifeq ($(TARGET),rp2350)
289293
MAIN_TARGET:=include/target.h keytools wolfboot_signing_private_key.der pico-sdk-info
290294
endif

arch.mk

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,28 @@ ifeq ($(ARCH),ARM)
303303
CFLAGS+=-DWOLFBOOT_USE_STDLIBC
304304
endif
305305

306+
ifeq ($(TARGET),zynq7000)
307+
# AMD/Xilinx Zynq-7000 (Cortex-A9, ARMv7-A) - ZC702 Evaluation Kit.
308+
# Loaded by Xilinx FSBL into DDR; see hal/zynq7000.{c,h,ld}.
309+
CORTEX_A9=1
310+
UPDATE_OBJS:=src/update_ram.o
311+
CFLAGS+=-DWOLFBOOT_DUALBOOT -fno-builtin -ffreestanding
312+
# Do NOT define WOLFBOOT_USE_STDLIBC: newlib's memcpy uses unaligned
313+
# LDRs which fault on ARMv7-A whenever the active mapping treats memory
314+
# as Strongly-Ordered (typically MMU off, but also some boot-stage
315+
# configurations). wolfBoot's startup keeps FSBL's MMU + flat 1:1
316+
# mapping enabled to avoid that, but we still link against the
317+
# aligned-safe memcpy in src/string.c so unaligned loads can never
318+
# surprise us regardless of MMU state.
319+
# U-Boot legacy 64-byte header strip is only meaningful for the
320+
# Linux/U-Boot payload variant (zynq7000_linux.config). Bare-metal
321+
# payloads (zynq7000.config, zc702_sdcard.config) shouldn't risk a
322+
# ~1-in-2^32 false-positive collision with UBOOT_IMG_HDR_MAGIC.
323+
ifeq ($(LINUX_PAYLOAD),1)
324+
CFLAGS+=-DWOLFBOOT_UBOOT_LEGACY
325+
endif
326+
endif
327+
306328
ifeq ($(TARGET),va416x0)
307329
CFLAGS+=-I$(WOLFBOOT_ROOT)/hal/vorago/ \
308330
-I$(VORAGO_SDK_DIR)/common/drivers/hdr/ \
@@ -344,6 +366,49 @@ ifeq ($(CORTEX_A5),1)
344366
-DWOLFSSL_ARM_ARCH=7 -DWOLFSSL_ARMASM_INLINE -DWOLFSSL_ARMASM_NO_NEON
345367
endif
346368
endif
369+
else
370+
ifeq ($(CORTEX_A9),1)
371+
# Cortex-A9 (ARMv7-A, 32-bit) - Zynq-7000.
372+
# Build in ARM state (-marm); reset vector lands in ARM mode after FSBL.
373+
# Note: do not filter out -mthumb from CFLAGS/LDFLAGS - that converts the
374+
# variables to simple-expansion flavor and breaks lazy $(LSCRIPT) expansion
375+
# in test-app/Makefile. -marm appended later wins over -mthumb anyway.
376+
FPU=-mfpu=vfp3-d16
377+
CFLAGS+=-mcpu=cortex-a9 -mtune=cortex-a9 -marm -mno-unaligned-access
378+
LDFLAGS+=-mcpu=cortex-a9 -mtune=cortex-a9 -marm -static \
379+
-Wl,-z,noexecstack
380+
# Cortex-A9 uses the same generic ARMv7-A startup as Cortex-A5
381+
# (src/boot_arm32_start.S handles VBAR, per-mode stacks, cache
382+
# invalidate, async-abort enable for any ARMv7-A target).
383+
OBJS+=src/boot_arm32.o src/boot_arm32_start.o
384+
# Linux/U-Boot payload: enable MMU + FDT codepaths in update_ram.c so DTBs
385+
# can be loaded from a separate signed PART_DTS_BOOT partition. The MMU
386+
# itself stays inherited from FSBL's flat 1:1 mapping; wolfBoot does not
387+
# manage page tables on Cortex-A9.
388+
ifeq ($(MMU),1)
389+
CFLAGS+=-DMMU -DWOLFBOOT_FDT
390+
OBJS+=src/fdt.o
391+
endif
392+
# SD card / eMMC boot: swap the update_ram loader for update_disk + GPT.
393+
# The SDHCI HAL hooks live in hal/zynq7000.c and translate the generic
394+
# Cadence-layout driver to the Arasan SDHCI v2.0 controller.
395+
ifneq ($(filter 1,$(DISK_SDCARD) $(DISK_EMMC)),)
396+
CFLAGS+=-DWOLFBOOT_UPDATE_DISK -DMAX_DISKS=1
397+
UPDATE_OBJS:=src/update_disk.o
398+
OBJS += src/gpt.o
399+
OBJS += src/disk.o
400+
endif
401+
ifeq ($(NO_ASM),1)
402+
MATH_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sp_c32.o
403+
else
404+
MATH_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sp_arm32.o
405+
ifneq ($(NO_ARM_ASM),1)
406+
OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/arm/armv8-32-sha256-asm.o
407+
OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/arm/armv8-32-sha256-asm_c.o
408+
CFLAGS+=-DWOLFSSL_SP_ARM32_ASM -DWOLFSSL_ARMASM -DWOLFSSL_ARMASM_NO_HW_CRYPTO \
409+
-DWOLFSSL_ARM_ARCH=7 -DWOLFSSL_ARMASM_INLINE -DWOLFSSL_ARMASM_NO_NEON
410+
endif
411+
endif
347412
else
348413
# All others use boot_arm.o
349414
OBJS+=src/boot_arm.o
@@ -456,6 +521,7 @@ else
456521
endif
457522
endif
458523
endif
524+
endif
459525

460526

461527
## Renesas RX
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
ARCH?=ARM
2+
TARGET?=zynq7000
3+
SIGN?=ECC256
4+
HASH?=SHA256
5+
6+
# Cortex-A9 ZC702 SD-card boot variant. Uses the generic SDHCI driver
7+
# (src/sdhci.c) with HAL hooks in hal/zynq7000.c that translate between the
8+
# driver's Cadence SD4HC register layout and the Arasan SDHCI v2.0 standard
9+
# layout used by the Zynq-7000 controller (same IP family as ZynqMP's v3.0,
10+
# just an older revision; the translation is reused from hal/zynq.c).
11+
DEBUG?=0
12+
DEBUG_UART?=1
13+
V?=0
14+
SPMATH?=1
15+
16+
# SD card boot - swaps update_ram.o for update_disk.o + GPT/disk support.
17+
DISK_SDCARD=1
18+
NO_XIP=1
19+
20+
# Stage payload at low DDR (clear of wolfBoot at 0x04000000-0x040FFFFF).
21+
WOLFBOOT_LOAD_ADDRESS=0x10000000
22+
23+
# MBR partition layout on the SD card. Pure MBR (no GPT) - the Zynq-7000
24+
# BootROM (UG821 ch.6.3) only accepts MBR with the first partition as
25+
# FAT32 and the Active flag set. wolfBoot's src/disk.c falls back to MBR
26+
# parsing when no protective-GPT entry is present.
27+
# MBR p1 (wolfBoot idx 0): FAT32-LBA Active - holds BOOT.BIN for BootROM.
28+
# MBR p2 (wolfBoot idx 1): Linux raw (0x83) - signed boot image.
29+
# MBR p3 (wolfBoot idx 2): Linux raw (0x83) - signed update image.
30+
# tools/scripts/zc702/prepare_sdcard.sh lays this out; BOOT_PART_A/B tell
31+
# update_disk.c which MBR entries (0-indexed) to use for boot/update.
32+
CFLAGS_EXTRA+=-DBOOT_PART_A=1 -DBOOT_PART_B=2
33+
34+
# Arasan SDHCI v2.0 on Zynq-7000 is 3.3V-only, no UHS-I. The generic
35+
# driver tries to push the card to UHS-I SDR25 / 50 MHz / High Speed mode
36+
# which is invalid for our v2.0 + 3.3V combo and causes DTOE on the first
37+
# data transfer (MBR read). Cap the post-init clock at SD default-speed
38+
# 25 MHz; the HSE bit is also masked in hal/zynq7000.c sdhci_reg_write so
39+
# the controller stays in single-edge timing the card matches.
40+
# Cap the post-init SDHCI clock at 6 MHz. The Arasan SDHCI v2.0 on
41+
# Zynq-7000 has a clock-dependent state-cleanup issue: at 12 MHz multi-
42+
# block reads (CMD18) work, but a single-block read (CMD17) issued
43+
# immediately after a CMD18+CMD12 sequence times out (DTOE) on the first
44+
# data block. At 24 MHz even the very first CMD17 fails. 6 MHz / 4-bit
45+
# bus is plenty fast for boot-time loading (~3 MB/s) and is well below
46+
# the v2.0 quirk threshold; raise this if a future fix in src/sdhci.c
47+
# adds an explicit DAT-line reset between transfers.
48+
CFLAGS_EXTRA+=-DSDHCI_CLK_50MHZ=6000 -DSDHCI_CLK_25MHZ=6000
49+
50+
# Uncomment to enable verbose SDHCI driver logging when bringing up
51+
# new boards or debugging timing issues.
52+
#CFLAGS_EXTRA+=-DDEBUG_SDHCI
53+
54+
# Image-header partition addresses are unused for disk boot (kept for the
55+
# Makefile sanity checks). update_disk.c finds images by GPT entry, not by
56+
# memory address.
57+
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x00100000
58+
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x00700000
59+
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x00D00000
60+
WOLFBOOT_PARTITION_SIZE=0x00600000
61+
# Sector size of WOLFBOOT_PARTITION (not the SD physical sector, which is
62+
# always 512 B). Used as the smallest erase/copy unit for the BOOT/UPDATE
63+
# partitions; must be > IMAGE_HEADER_SIZE.
64+
WOLFBOOT_SECTOR_SIZE=0x1000
65+
66+
IMAGE_HEADER_SIZE=1024
67+
68+
CROSS_COMPILE=arm-none-eabi-

config/examples/zynq7000.config

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
ARCH?=ARM
2+
TARGET?=zynq7000
3+
SIGN?=ECC256
4+
HASH?=SHA256
5+
6+
# Cortex-A9 (Zynq-7000) - selected automatically via TARGET=zynq7000 in arch.mk.
7+
# This single config supports bare-metal, U-Boot, and Linux payloads from QSPI.
8+
DEBUG?=0
9+
DEBUG_UART?=1
10+
V?=0
11+
SPMATH?=1
12+
13+
# Linux/U-Boot payload support (no-op for plain bare-metal payloads):
14+
# LINUX_PAYLOAD=1 -> do_boot uses ARM Linux boot ABI (r0=0, r1=~0,
15+
# r2=DTB_phys, r3=0). Bare-metal apps don't read these
16+
# registers, so the same ABI is fine for them.
17+
# MMU=1 -> enables update_ram.c DTB-load codepath and pulls in
18+
# src/fdt.o. wolfBoot itself does NOT manage page
19+
# tables; it inherits FSBL's flat 1:1 DDR mapping.
20+
# ELF=1 -> wolfBoot understands ELF inputs (vmlinux / u-boot.elf)
21+
# and loads only their LOAD segments. Flat binaries
22+
# (zImage, bare-metal .bin) fall through to raw-binary
23+
# boot.
24+
# Cost vs. a strictly bare-metal-only build: ~5 KB extra wolfBoot binary
25+
# from the FDT/MMU/ELF support, in exchange for one config that covers all
26+
# three payload types.
27+
LINUX_PAYLOAD=1
28+
MMU=1
29+
ELF=1
30+
31+
# wolfBoot itself is staged by FSBL to DDR at 0x04000000 (hal/zynq7000.ld);
32+
# the verified payload (kernel/U-Boot/bare-metal app) is staged at
33+
# WOLFBOOT_LOAD_ADDRESS, well clear of wolfBoot. 1 GB DDR3 on ZC702
34+
# starts at 0x00000000.
35+
WOLFBOOT_LOAD_ADDRESS=0x10000000
36+
37+
# DTB load address (Linux only). Kernel reads it from r2. 16 MB clear of
38+
# WOLFBOOT_LOAD_ADDRESS. Ignored for bare-metal payloads.
39+
WOLFBOOT_LOAD_DTS_ADDRESS=0x11000000
40+
41+
# QSPI flash (16 MB N25Q128A on ZC702) via XQspiPs (hal/zynq7000.c).
42+
# Override EXT_FLASH=0 on the make command line for JTAG-only dev builds.
43+
EXT_FLASH?=1
44+
NO_XIP=1
45+
46+
# QSPI partition layout (16 MB total) - sized for a full Linux kernel + DTB
47+
# pair so the same layout also works for bare-metal payloads.
48+
# 0x000000 - 0x07FFFF BOOT.BIN (FSBL + wolfboot, 512 KB)
49+
# 0x080000 - 0x0FFFFF DTS_BOOT (signed DTB, 512 KB - Linux only)
50+
# 0x100000 - 0x6FFFFF BOOT_A (~6 MB primary)
51+
# 0x700000 - 0x77FFFF DTS_UPD (signed update DTB, 512 KB - Linux only)
52+
# 0x780000 - 0xDFFFFF UPDATE_B (~6.5 MB update)
53+
# 0xE00000 - 0xE0FFFF SWAP (64 KB scratch)
54+
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x00100000
55+
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x00780000
56+
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x00E00000
57+
WOLFBOOT_PARTITION_SIZE=0x00600000
58+
WOLFBOOT_SECTOR_SIZE=0x10000
59+
60+
WOLFBOOT_DTS_BOOT_ADDRESS=0x00080000
61+
WOLFBOOT_DTS_UPDATE_ADDRESS=0x00700000
62+
63+
IMAGE_HEADER_SIZE=1024
64+
65+
CROSS_COMPILE?=arm-none-eabi-

0 commit comments

Comments
 (0)