Skip to content

Fixes for Xilinx ZynqMP ZCU102 SD card boot with Linux#750

Open
dgarske wants to merge 1 commit intowolfSSL:masterfrom
dgarske:zynqmp_bb
Open

Fixes for Xilinx ZynqMP ZCU102 SD card boot with Linux#750
dgarske wants to merge 1 commit intowolfSSL:masterfrom
dgarske:zynqmp_bb

Conversation

@dgarske
Copy link
Copy Markdown
Contributor

@dgarske dgarske commented Apr 14, 2026

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):

  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.

@dgarske dgarske self-assigned this Apr 14, 2026
@dgarske dgarske requested review from Copilot and danielinux April 14, 2026 19:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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/bootargs runtime 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.
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.

4 participants