Fixes for Xilinx ZynqMP ZCU102 SD card boot with Linux#750
Open
dgarske wants to merge 1 commit intowolfSSL:masterfrom
Open
Fixes for Xilinx ZynqMP ZCU102 SD card boot with Linux#750dgarske 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
Note
Copilot was unable to run its full agentic suite in this review.
Targets reliable SD-card Linux boot on Xilinx ZynqMP (ZCU102) by improving SDHCI init timing, adding timer support, patching DT bootargs at runtime, and ensuring ARM64 Linux entry requirements are met when booting from EL2.
Changes:
- Add SDHCI delays/retries to avoid CMD0 cold-boot timeout on Arasan SDHCI.
- Add ZynqMP timer + DTB
/chosen/bootargsruntime fixup to match wolfBoot partitioning. - Add EL2 cache clean + MMU/I/D-cache disable path before jumping to Linux.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 11 comments.
| File | Description |
|---|---|
| src/sdhci.c | Adds settle delays and CMD0 retry loop to stabilize SD card initialization timing. |
| src/boot_aarch64_start.S | Introduces an EL2 cleanup/jump helper to satisfy Linux boot protocol cache/MMU requirements. |
| src/boot_aarch64.c | Calls the EL2 cleanup/jump helper when booting from EL2. |
| hal/zynq.c | Implements DTB bootargs fixup and adds a microsecond timer using the ARMv8 generic timer. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Five targeted changes required to cleanly boot a PetaLinux 2025.2
fitImage from SD card on the Xilinx ZCU102 (Zynq UltraScale+ MPSoC):
1. hal/zynq: implement hal_dts_fixup() to patch /chosen/bootargs in the
DTB at runtime. Previously a TODO stub; now mirrors the Versal
implementation. Uses LINUX_BOOTARGS / LINUX_BOOTARGS_ROOT to override
the PetaLinux-baked root= value, allowing wolfBoot's A/B partition
layout (where rootfs is on mmcblk0p4, not p2).
2. hal/zynq: add hal_get_timer_us() using the ARMv8 generic timer
(CNTPCT_EL0 / CNTFRQ_EL0). Required so sdhci.c udelay() works. Uses
a __uint128_t intermediate to avoid overflow of (count * 1e6) at
long uptimes.
3. src/sdhci: fix CMD0 cold-boot timeout on Arasan SDHCI v3.0. Add 1ms
udelay after sdhci_platform_init(), 1ms after sdhci_set_clock(400KHz),
1ms after successful power-on, and a 10-retry loop with 10ms udelay
between retries around the initial CMD0. Gate the CMD0 loop on
sdhci_set_power() success so power-set failures are not silently
masked. Without these delays, CMD0 races the SD card power-up when
DEBUG_SDHCI printf delays are not present.
4. src/boot_aarch64: clean D-cache to PoC and disable MMU + I/D-cache at
EL2 before jumping to Linux. ARM64 Linux boot protocol requires MMU
off and image cleaned to PoC; otherwise arm64_panic_block_init()
panics with 'Non-EFI boot detected with MMU and caches enabled'. Adds
el2_cleanup_and_jump_to_linux() asm helper (dc cisw loop + ic iallu +
SCTLR_EL2.{M,C,I} clear + br) called from do_boot() when
current_el() == 2. Gated on defined(MMU) && defined(LINUX_BOOTARGS_ROOT)
so bare-metal / RTOS EL2 payloads fall through to the legacy direct
br x4 path.
5. src/boot_aarch64: include the platform HAL header (hal/zynq.h,
hal/nxp_ls1028a.h) alongside the existing hal/versal.h include, so
EL2_HYPERVISOR is visible to do_boot(). Previously BOOT_EL1=1 was
silently inert on zynq/ls1028a because the symbol was only defined
in a header not pulled into boot_aarch64.c.
Also:
- config/examples/zynqmp_sdcard.config: default BOOT_EL1 off (EL2 handoff
for Linux), DEBUG off, and root=/dev/mmcblk0p4 with a comment on
mmcblk0 vs mmcblk1 enumeration depending on which SDHCI controllers
are enabled in the XSA / device tree.
- hal/versal.c: align default LINUX_BOOTARGS_ROOT (mmcblk0p2 -> mmcblk0p4)
with the new wolfBoot A/B partition convention.
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.
Fixes for Xilinx ZynqMP ZCU102 SD card boot with Linux
Five targeted changes required to cleanly boot a PetaLinux 2025.2
fitImage from SD card on the Xilinx ZCU102 (Zynq UltraScale+ MPSoC):
hal/zynq: implement hal_dts_fixup() to patch /chosen/bootargs in the
DTB at runtime. Previously a TODO stub; now mirrors the Versal
implementation. Uses LINUX_BOOTARGS / LINUX_BOOTARGS_ROOT to override
the PetaLinux-baked root= value, allowing wolfBoot's A/B partition
layout (where rootfs is on mmcblk0p4, not p2).
hal/zynq: add hal_get_timer_us() using the ARMv8 generic timer
(CNTPCT_EL0 / CNTFRQ_EL0). Required so sdhci.c udelay() works. Uses
a __uint128_t intermediate to avoid overflow of (count * 1e6) at
long uptimes.
src/sdhci: fix CMD0 cold-boot timeout on Arasan SDHCI v3.0. Add 1ms
udelay after sdhci_platform_init(), 1ms after sdhci_set_clock(400KHz),
1ms after successful power-on, and a 10-retry loop with 10ms udelay
between retries around the initial CMD0. Gate the CMD0 loop on
sdhci_set_power() success so power-set failures are not silently
masked. Without these delays, CMD0 races the SD card power-up when
DEBUG_SDHCI printf delays are not present.
src/boot_aarch64: clean D-cache to PoC and disable MMU + I/D-cache at
EL2 before jumping to Linux. ARM64 Linux boot protocol requires MMU
off and image cleaned to PoC; otherwise arm64_panic_block_init()
panics with 'Non-EFI boot detected with MMU and caches enabled'. Adds
el2_cleanup_and_jump_to_linux() asm helper (dc cisw loop + ic iallu +
SCTLR_EL2.{M,C,I} clear + br) called from do_boot() when
current_el() == 2. Gated on defined(MMU) && defined(LINUX_BOOTARGS_ROOT)
so bare-metal / RTOS EL2 payloads fall through to the legacy direct
br x4 path.
src/boot_aarch64: include the platform HAL header (hal/zynq.h,
hal/nxp_ls1028a.h) alongside the existing hal/versal.h include, so
EL2_HYPERVISOR is visible to do_boot(). Previously BOOT_EL1=1 was
silently inert on zynq/ls1028a because the symbol was only defined
in a header not pulled into boot_aarch64.c.
Also:
for Linux), DEBUG off, and root=/dev/mmcblk0p4 with a comment on
mmcblk0 vs mmcblk1 enumeration depending on which SDHCI controllers
are enabled in the XSA / device tree.
with the new wolfBoot A/B partition convention.