Skip to content

Add bare-metal wolfIP ports for UltraScale+ MPSoC (ZCU102), Versal VMK180 and Zynq-7000 (ZC702)#121

Open
dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:port_amd_fpga
Open

Add bare-metal wolfIP ports for UltraScale+ MPSoC (ZCU102), Versal VMK180 and Zynq-7000 (ZC702)#121
dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:port_amd_fpga

Conversation

@dgarske

@dgarske dgarske commented May 18, 2026

Copy link
Copy Markdown
Member

Add bare-metal wolfIP ports for AMD/Xilinx PS-GEM SoCs

Adds bare-metal wolfIP ports for three AMD/Xilinx SoCs under a single shared tree src/port/amd/:

  • ZCU102 - UltraScale+ MPSoC, Cortex-A53, AArch64, EL3
  • Versal Gen 1 / VMK180 - Cortex-A72, AArch64, EL3
  • Zynq-7000 / ZC702 - Cortex-A9, ARMv7-A, SVC

Each is a standalone build (boards/<board>/, own Makefile, emits app.elf) running a DHCP + ICMP + UDP-echo demo. Shared code lives once: common/ (demo app, Cadence GEM core, entropy, API headers), arch/{aarch64,armv7}/ (startup, MMU, cache, timer), ip/ (build-selected UART / GIC / GEM-RX / PHY drivers). Boards select components in their Makefile; minimal #ifdef.

Validated on hardware

All three brought up on real boards - DHCP bind, ping, and UDP echo confirmed: ZC702 (Marvell 88E1518), VMK180 (DP83867, GICv3), ZCU102 (DP83867, GICv2 IRQ-driven RX). GEM BD rings are mapped non-cacheable so DMA descriptors are coherent without per-descriptor cache maintenance.

Notes

  • No changes to the wolfIP core; all additions under src/port/amd/ (+ a standalone ZCU102 JTAG loader in tools/scripts/zcu102/).
  • JTAG/SD boot flows and per-board bring-up notes are in each boards/<board>/README.md; the shared-tree layout is in src/port/amd/README.md.

@dgarske dgarske self-assigned this May 18, 2026
Copilot AI review requested due to automatic review settings May 18, 2026 18:52
@dgarske dgarske requested a review from danielinux May 18, 2026 18:54

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

Adds a new bare-metal AArch64 (Cortex-A53 EL3) wolfIP port targeting the Xilinx ZCU102 board, including a clean-room Cadence GEM3 + DP83867 PHY driver, minimal EL3 MMU/GIC/UART bring-up, and supporting JTAG/bootgen/SD tooling.

Changes:

  • Introduces src/port/zcu102/ (startup vectors, MMU setup, GICv2 driver, polled UART, GEM3 Ethernet + DP83867 PHY, UDP echo + DHCP demo, build/link scripts).
  • Adds ZCU102 JTAG loader scripts (generic tools/scripts/zcu102/ and port-specific src/port/zcu102/jtag/).
  • Adds BOOT.BIN generation templates and an SD flashing helper.

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
tools/scripts/zcu102/README.md Documents the generic ZCU102 xsdb loader pattern and constraints.
tools/scripts/zcu102/jtag_load.tcl Generic xsdb JTAG loader for AArch64 EL3 apps (OCM load + RVBAR loop + entry jump).
src/port/zcu102/.gitignore Ignores local build artifacts for the ZCU102 port.
src/port/zcu102/board.h Board-specific base addresses/IRQs/clock/reset regs and default MAC.
src/port/zcu102/config.h UDP-focused wolfIP configuration for the ZCU102 port.
src/port/zcu102/flash_sd.sh Helper to copy BOOT.BIN to an SD boot partition with safety checks.
src/port/zcu102/gem.h Public GEM3 + MDIO API surface for the port.
src/port/zcu102/gem.c Clean-room GEM3 driver (BD rings, MDIO, polled RX/TX integration with wolfIP).
src/port/zcu102/gic.h Minimal GICv2 interface and IRQ dispatch hooks.
src/port/zcu102/gic.c GIC-400 bring-up and dispatch implementation (plus polled dispatch helper).
src/port/zcu102/jtag/boot.sh Port-local wrapper to build a flat binary and invoke xsdb boot sequence.
src/port/zcu102/jtag/boot.tcl Port-local xsdb sequence to init PS, load OCM, and run the app.
src/port/zcu102/jtag/boot_iter.sh Developer iteration helper (power-cycle + hw_server restart + boot).
src/port/zcu102/main.c Demo app (wolfIP init, DHCP, UDP echo) + wrapped memset/memcpy + exception reporting.
src/port/zcu102/mmu.h Declares EL3 MMU enable entrypoint.
src/port/zcu102/mmu.c Static EL3 page tables and MMU enable sequence (TCR/MAIR/TTBR setup).
src/port/zcu102/phy_dp83867.h DP83867 PHY init/link-status API.
src/port/zcu102/phy_dp83867.c DP83867 configuration (strap fix, delays, AN/link polling) via MDIO.
src/port/zcu102/README.md Port-level documentation (features, build/boot workflow, expected output).
src/port/zcu102/startup.S EL3 vectors + startup (BSS clear, MMU enable, IRQ trampoline, exception trampolines).
src/port/zcu102/target.ld AArch64 linker script for OCM-based layout and special sections.
src/port/zcu102/timer.h Generic timer-based delay utilities.
src/port/zcu102/uart.h UART API for the port.
src/port/zcu102/uart.c Polled Cadence UART0 driver and small print helpers.
src/port/zcu102/bootgen/boot.bif BOOT.BIN template for bootgen.
src/port/zcu102/bootgen/build_bootbin.sh Script to render the BIF template and run bootgen.
src/port/zcu102/Makefile Port-local build (app.elf + BOOT.BIN) and core compilation strategy.

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

Comment thread src/port/zcu102/startup.S Outdated
Comment thread src/port/zcu102/mmu.c Outdated
Comment thread src/port/zcu102/gic.c Outdated
Comment thread src/port/zcu102/gem.c Outdated
Comment thread src/port/zcu102/target.ld Outdated
Comment thread src/port/zcu102/main.c Outdated
Comment thread src/port/zcu102/board.h Outdated
Comment thread src/port/zcu102/main.c Outdated
Comment thread src/port/zcu102/README.md Outdated
Comment thread src/port/zcu102/Makefile Outdated
@dgarske dgarske requested a review from Copilot June 10, 2026 00:07
@dgarske dgarske changed the title Add ZCU102 (UltraScale+ A53 EL3) bare-metal wolfIP port with GEM3 Add bare-metal wolfIP ports for ZCU102, Versal and Zynq-7000 Jun 10, 2026

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 76 out of 76 changed files in this pull request and generated 34 comments.

Comment thread src/port/zynq7000/uart.h Outdated
Comment thread src/port/zynq7000/uart.h Outdated
Comment thread src/port/zynq7000/gic.h Outdated
Comment thread src/port/zynq7000/gic.h Outdated
Comment thread src/port/zynq7000/gem.h Outdated
Comment thread src/port/versal/phy_dp83867.h Outdated
Comment thread src/port/versal/gic.h Outdated
Comment thread src/port/zynq7000/gem.h Outdated
Comment thread src/port/zynq7000/gic.h Outdated
Comment thread src/port/zynq7000/phy_dp83867.h Outdated
@dgarske dgarske removed the request for review from danielinux June 10, 2026 23:27
@dgarske dgarske changed the title Add bare-metal wolfIP ports for ZCU102, Versal and Zynq-7000 Add bare-metal wolfIP ports for UltraScale+ MPSoC (ZCU102), Versal VMK180 and Zynq-7000 (ZC702) Jun 11, 2026
@dgarske dgarske requested review from Copilot and danielinux June 11, 2026 23:57

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 72 out of 72 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (6)

tools/scripts/zcu102/jtag_load.tcl:1

  • binary scan format string iu is not a single 32-bit word specifier in Tcl; it will scan multiple fields and/or advance by the wrong number of bytes, which will corrupt the loaded image. Use a single 32-bit format (e.g., unsigned 32-bit) and keep the scan width aligned to 4 bytes.
    src/port/amd/boards/zcu102/jtag/boot.tcl:1
  • Same issue as the standalone loader: binary scan ... iu is not a correct 4-byte word scan and will mis-load the binary. Fix the format string to scan exactly one 32-bit word per iteration.
    src/port/amd/ip/gic_gicv3.c:1
  • This config enables Group 1 Secure in the distributor (ENG1S), but then marks all SPIs as Group 1 Non-secure (IGROUPR=1). That combination prevents interrupts from being delivered to the secure context (and matches the stated symptom that the GEM SPI isn’t delivered). A concrete fix is to either (a) configure SPIs as Group 0 (clear IGROUPR bits for those INTIDs and enable ENG0), or (b) correctly configure Group 1 Secure using IGRPMODR and enable the corresponding secure group in both distributor and CPU interface.
    src/port/amd/ip/gic_gicv3.c:1
  • gic_enable_spi() explicitly sets the interrupt to Group 1 Non-secure by setting IGROUPR bits. If the intent is “secure EL3 handles this SPI” (as implied by GICD_CTLR_ENG1S and icc_igrpen1_el1_set(1)), this is the wrong group assignment and will block delivery. Change this to assign the SPI to the intended group (e.g., Group 0 by clearing the bit, or Group 1 Secure via IGRPMODR), consistent with the distributor/CPU interface enablement.
    src/port/amd/ip/uart_pl011.c:1
  • SP804/SP805 are PrimeCell timer/watchdog blocks, not the PL011 UART. This comment should be corrected to avoid sending readers to the wrong TRM/IP block; keep the PL011 reference (DDI 0183) and remove the SP804/SP805 mention.
    src/port/amd/ip/uart_cadence.c:1
  • uart_puts/uart_puthex/uart_putdec/uart_putip4 are duplicated verbatim between the Cadence and PL011 drivers. Consider moving these formatting/helpers into a shared common/uart_util.c (leaving only uart_init/uart_putc hardware-specific) to reduce drift and keep fixes consistent across UART implementations.

Comment on lines +92 to +94
/* Default A53-0 EL3 stack location (set in startup.S, mirrored here for
* any C code that needs to know). */
#define A53_STACK_TOP 0x00100000UL /* 1 MB - 8 B */
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