Skip to content

Support for wolfBoot ZynqMP (UltraScale+ MPSoC) SD Card#699

Open
dgarske wants to merge 7 commits intowolfSSL:masterfrom
dgarske:zynqmp_sdcard
Open

Support for wolfBoot ZynqMP (UltraScale+ MPSoC) SD Card#699
dgarske wants to merge 7 commits intowolfSSL:masterfrom
dgarske:zynqmp_sdcard

Conversation

@dgarske
Copy link
Contributor

@dgarske dgarske commented Feb 26, 2026

No description provided.

@dgarske dgarske self-assigned this Feb 26, 2026
Copilot AI review requested due to automatic review settings February 26, 2026 21:34
Copy link
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

This PR adds SD card boot support for the AMD Zynq UltraScale+ MPSoC (ZynqMP) platform, complementing the existing QSPI boot capability. wolfBoot can now load firmware images from MBR-partitioned SD cards using the Arasan SDHCI controller.

Changes:

  • Implements SDHCI platform support for ZynqMP with register translation between Cadence SD4HC and Arasan layouts
  • Adds conditional compilation for QSPI initialization to support SD-only boot configurations
  • Documents SD card boot setup with MBR partitioning and dual A/B firmware images

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
hal/zynq.h Adds SD/SDHCI controller base addresses and clock/reset control register definitions
hal/zynq.c Implements SDHCI platform hooks with register translation and conditional QSPI initialization
docs/Targets.md Documents SD card boot configuration, partition layout, and setup procedures
config/examples/zynqmp_sdcard.config Provides complete SD card boot configuration with MBR partition support
Comments suppressed due to low confidence (2)

config/examples/zynqmp_sdcard.config:1

  • The size specification '128M' is ambiguous in sfdisk context. sfdisk expects sector counts or explicit +size notation. Use size=+128M or calculate the sector count (262144 sectors for 128MB with 512-byte sectors) to ensure consistent partition creation across different sfdisk versions.
# wolfBoot configuration for AMD ZynqMP ZCU102 - SD Card Boot

config/examples/zynqmp_sdcard.config:1

  • The size specifications '200M' should use explicit +size notation for clarity. Use size=+200M to ensure sfdisk interprets these as size specifications rather than potential sector counts.
# wolfBoot configuration for AMD ZynqMP ZCU102 - SD Card Boot

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

Copilot AI review requested due to automatic review settings February 26, 2026 23:44
Copy link
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

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.


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

Copilot AI review requested due to automatic review settings March 3, 2026 01:14
Copy link
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

Copilot reviewed 10 out of 11 changed files in this pull request and generated 6 comments.


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

… passing. Only issue is test-app EL level. Peer review fixes.
@dgarske dgarske marked this pull request as ready for review March 4, 2026 00:35
Copilot AI review requested due to automatic review settings March 4, 2026 00:35
Copy link
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

Copilot reviewed 10 out of 11 changed files in this pull request and generated 6 comments.


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

You can also share your feedback on Copilot code review. Take the survey.

#define RST_LPD_IOU2_SDIO1 (1UL << 6)

/* IOU_SLCR SD Configuration (feeds into SDHCI Capabilities register) */
#define IOU_SLCR_SD_CONFIG_REG2 (*((volatile uint32_t*)(IOU_SLCR_BASSE + 0x320)))
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

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

Typo in macro: IOU_SLCR_BASSE should be IOU_SLCR_BASE. This will cause a compilation error if IOU_SLCR_BASSE is not defined elsewhere.

Copilot uses AI. Check for mistakes.
*(.gnu.linkonce.t.*)
*(.plt)
*(.gnu_warning)
*(.gcc_execpt_table)
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

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

Typo in section name: .gcc_execpt_table should be .gcc_except_table. This misspelling means exception table entries in this section will not be collected, which could cause issues with C++ exception handling or unwinding.

Suggested change
*(.gcc_execpt_table)
*(.gcc_except_table)

Copilot uses AI. Check for mistakes.
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
*(.gnu.linkonce.armexidix.*.*)
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

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

Typo in section name: .gnu.linkonce.armexidix should be .gnu.linkonce.armexidx. The misspelling means ARM exception index entries will not be collected into the .ARM.exidx section.

Suggested change
*(.gnu.linkonce.armexidix.*.*)
*(.gnu.linkonce.armexidx.*.*)

Copilot uses AI. Check for mistakes.
Comment on lines +2178 to +2185
(void)is_write;
/* After DMA: clean and invalidate to ensure CPU sees DMA-written data */
uintptr_t addr;
uintptr_t start = (uintptr_t)buf & ~(CACHE_LINE_SIZE - 1);
uintptr_t end = (uintptr_t)buf + sz;

for (addr = start; addr < end; addr += CACHE_LINE_SIZE) {
__asm__ volatile("dc civac, %0" : : "r"(addr) : "memory");
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

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

After a DMA write (card←memory), sdhci_platform_dma_complete unconditionally runs dc civac (clean-and-invalidate) on the output buffer. For a write transfer, there is no need to invalidate — the DMA has only read from memory, not written to it. Invalidating after a write could cause dirty cache lines written between the prepare and complete calls to be discarded, potentially corrupting data. The is_write flag should be used to skip invalidation for write transfers, matching the asymmetric prepare logic.

Suggested change
(void)is_write;
/* After DMA: clean and invalidate to ensure CPU sees DMA-written data */
uintptr_t addr;
uintptr_t start = (uintptr_t)buf & ~(CACHE_LINE_SIZE - 1);
uintptr_t end = (uintptr_t)buf + sz;
for (addr = start; addr < end; addr += CACHE_LINE_SIZE) {
__asm__ volatile("dc civac, %0" : : "r"(addr) : "memory");
/* After DMA read (cardmemory): invalidate so CPU sees DMA-written data.
* For DMA write (cardmemory): DMA only read from memory, so there is no
* new data for the CPU to see and invalidation could discard dirty lines. */
uintptr_t addr;
uintptr_t start = (uintptr_t)buf & ~(CACHE_LINE_SIZE - 1);
uintptr_t end = (uintptr_t)buf + sz;
if (!is_write) {
for (addr = start; addr < end; addr += CACHE_LINE_SIZE) {
__asm__ volatile("dc civac, %0" : : "r"(addr) : "memory");
}

Copilot uses AI. Check for mistakes.
Comment on lines +94 to +95
# DTS (Device Tree) load address
WOLFBOOT_LOAD_DTS_ADDRESS?=0x1000
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

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

The DTS load address 0x1000 (4 KB) is unusually low and likely conflicts with the exception vector table or other low-memory structures on AArch64, where the reset vector starts at 0x0. On ZynqMP, low physical addresses (below a few MB) are typically used for interrupt vectors or OCM. A more typical device tree load address would be in DDR, e.g., 0x40000000 or similar. Please verify this is intentional.

Suggested change
# DTS (Device Tree) load address
WOLFBOOT_LOAD_DTS_ADDRESS?=0x1000
# DTS (Device Tree) load address (place in DDR to avoid low-memory conflicts)
WOLFBOOT_LOAD_DTS_ADDRESS?=0x40000000

Copilot uses AI. Check for mistakes.
**QSPI layout**
| Partition | Size | Address | Description |
|-------------|--------|-------------|--------------------------------|
| Bootloader | - | 0x7FF00000 | wolfBoot in DDR (loaded by FSBL) |
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

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

The QSPI layout table still lists the wolfBoot DDR address as 0x7FF00000, but hal/zynq.ld was updated to 0x7FE00000. This entry should be updated to 0x7FE00000 to match the linker script change.

Suggested change
| Bootloader | - | 0x7FF00000 | wolfBoot in DDR (loaded by FSBL) |
| Bootloader | - | 0x7FE00000 | wolfBoot in DDR (loaded by FSBL) |

Copilot uses AI. Check for mistakes.
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