Skip to content

Add Agilex 5 FCS and wolfBoot integration - #846

Open
aidangarske wants to merge 5 commits into
wolfSSL:masterfrom
aidangarske:agilex5-tfa-port
Open

Add Agilex 5 FCS and wolfBoot integration#846
aidangarske wants to merge 5 commits into
wolfSSL:masterfrom
aidangarske:agilex5-tfa-port

Conversation

@aidangarske

@aidangarske aidangarske commented Aug 6, 2026

Copy link
Copy Markdown
Member

Description

  • Adds the Altera Agilex 5 013B wolfBoot port for the GSRD SD-card boot flow
  • Preserves the existing SPL and TF-A responsibilities for DDR, clocks, resets, PSCI, and EL3
  • Loads wolfBoot as the signed BL33 payload at 0x80200000
  • Adds Agilex 5 SDHCI and platform initialization support
  • Integrates signed Linux FIT images with wolfBoot verification
  • Adds a four-partition WIC layout with initialized A and B image slots
  • Adds Yocto/meta-wolfSSL integration, CI coverage, and customer bring-up documentation
  • Validated the generated WIC through the customer Kas build and on Agilex 5 hardware

partner pr: wolfSSL/meta-wolfssl#177

Copilot AI lite review requested due to automatic review settings August 6, 2026 23:19

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

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Adds an Altera Agilex 5 (013B) port and integration points to boot wolfBoot as BL33 in the GSRD SD-card flow, including SDHCI/platform init, memory mapping, example FIT artifacts, and CI build coverage.

Changes:

  • Adds Agilex 5 HAL (C + header), linker script, FIT example, and a BL33 smoke-test app.
  • Updates AArch64 startup/MMU mappings and SDHCI behavior to support Agilex 5 boot/SD timing.
  • Updates disk-boot logging and adds docs/config + GitHub Actions build coverage for the new target.

Reviewed changes

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

Show a summary per file
File Description
test-app/app_agilex5.c Adds a BL33 smoke-test app for Agilex 5 (timer + EL print).
src/update_disk.c Improves disk-boot debug output (block size + pointer-format prints).
src/sdhci.c Adds command-line reset, inhibit timeouts, optional post-command delay, and CMD8 retry logic.
src/boot_aarch64_start.S Adds Agilex 5 include, adjusts CNTFRQ/RVBAR handling, and adds Agilex 5 MMU mappings.
src/boot_aarch64.c Adds Agilex 5 HAL include selection for AArch64 boot code.
include/sdhci.h Adds reset bit definitions and new SDHCI tuning/behavior macros.
hal/agilex5.ld New linker script matching BL33 placement at 0x80200000.
hal/agilex5.its Example FIT description for Agilex 5 Linux payload (kernel + DTB).
hal/agilex5.h New Agilex 5 target configuration and platform constants.
hal/agilex5.c New Agilex 5 HAL implementation (timer, UART, DT fixups, SDHCI PHY + DMA cache ops).
docs/Targets.md Documents the new Agilex 5 target and references Agilex5 bring-up doc.
docs/Agilex5.md Adds bring-up and integration documentation (GSRD/FIT/WIC/test order/CI).
config/examples/agilex5_013b_sdcard.config Adds a buildable example config for Agilex 5 SD-card boot flow.
arch.mk Adds Agilex 5 AArch64 flags + target-specific bootloader responsibilities.
.github/workflows/test-configs.yml Adds Agilex 5 config to existing CI matrix via reusable workflow.
.github/workflows/test-build-agilex5.yml Adds a dedicated Agilex 5 build workflow (path-filtered).

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

Comment thread test-app/app_agilex5.c Outdated
Comment thread test-app/app_agilex5.c Outdated
Comment thread src/update_disk.c
Comment thread src/sdhci.c
Comment thread hal/agilex5.c
Comment thread docs/Agilex5.md Outdated
Comment thread src/boot_aarch64_start.S Outdated

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fenrir Automated Review — PR #846

Scan targets checked: wolfboot-bugs, wolfboot-src

Findings: 4
4 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread hal/agilex5.h Outdated
Comment thread src/update_disk.c Outdated
Comment thread include/sdhci.h
Comment thread hal/agilex5.c Outdated
@aidangarske
aidangarske marked this pull request as ready for review August 7, 2026 21:23
@dgarske dgarske removed their assignment Aug 10, 2026
@dgarske
dgarske requested a review from night1rider August 10, 2026 19:58
@danielinux

Copy link
Copy Markdown
Member

@aidangarske please rebase.

Comment thread src/sdhci.c
SDHCI_REG_SET(SDHCI_SRS12, SDHCI_SRS12_CC); /* clear command complete */
while ((SDHCI_REG(SDHCI_SRS09) & SDHCI_SRS09_CICMD) != 0);
timeout = 0x000FFFFF;
while (((SDHCI_REG(SDHCI_SRS09) & SDHCI_SRS09_CICMD) != 0U) &&

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This trailing inhibit wait is now bounded, but the one at the top of sdhci_send_cmd_internal is untouched:

/* src/sdhci.c:582 */
while ((SDHCI_REG(SDHCI_SRS09) & SDHCI_SRS09_CICMD) != 0);

That is the loop this PR makes most likely to hang. arch.mk:178 sets SDHCI_SKIP_HOST_RESET=1 for agilex5, which deliberately inherits whatever state SPL/TF-A left the Cadence host in. If that stage leaves CMD inhibit asserted — exactly the condition skipping the soft reset exposes you to — the first command spins forever, before any of the new timeouts can fire, with no output at all.

Bounding the entry wait with the same idiom and the same sdhci_reset_cmd_line() recovery is what makes SDHCI_SKIP_HOST_RESET safe to ship.

Comment thread src/sdhci.c
}
}

#if SDHCI_WAIT_AFTER_CMD_US > 0U

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This fires on every command, not just the init commands arch.mk:179 describes ("the controller's required post-command settle time"). sdhci_send_cmd_internal is the common path for CMD17/18/24/25 and CMD12 as well.

With SDHCI_WAIT_AFTER_CMD_US=1000 and DISK_BLOCK_SIZE=0x80000, each 512 KB chunk pays ~1 ms for CMD18, ~1 ms for CMD12, and ~1 ms per sdhci_wait_busy() CMD13 — several hundred ms to over a second of pure udelay on a Linux FIT, for a settle requirement that only applies to command setup.

The sharper problem is the footgun for the next target: combined with SDHCI_FORCE_SINGLE_BLOCK_READ (zynq/versal/mpfs250 use it) this becomes 1 ms per 512-byte block, i.e. roughly seven minutes for a 200 MB read. Either scope the delay to sdhci_init() / the card-init sequence, or document that the two options are mutually exclusive.

Comment thread src/sdhci.c

#define DEVICE_BUSY 1

static int sdhci_reset_cmd_line(void)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This changes command-error recovery on every SDHCI target, not just agilex5 — sdhci_reset_cmd_line() now runs on the EINT path for zynq, versal, mpfs250, zynq7000 and tegra234 too.

It is the right thing per SDHCI spec 3.10.1, and it arguably fixes the pre-existing CMD0 retry loop which retried without ever resetting the line. But it is an unguarded change to five validated paths backed by hardware testing on one board, while the other two behaviour changes in this PR (SDHCI_SKIP_HOST_RESET, SDHCI_WAIT_AFTER_CMD_US) are both opt-in.

Either gate it the same way, or state in the PR description that it is a deliberate cross-target change so it isn't discovered later.

Comment thread src/sdhci.c
uint32_t timeout = 0x000FFFFF;

sdhci_reg_or(SDHCI_SRS11, SDHCI_SRS11_RESET_CMD);
while (((SDHCI_REG(SDHCI_SRS11) & SDHCI_SRS11_RESET_CMD) != 0U) &&

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There is already a reset helper 130 lines below this one, and it is the unbounded one:

/* src/sdhci.c:691 */
static inline void sdhci_reset_lines(void)
{
    sdhci_reg_or(SDHCI_SRS11, SDHCI_SRS11_RESET_DAT_CMD);
    while (SDHCI_REG(SDHCI_SRS11) & SDHCI_SRS11_RESET_DAT_CMD);
}

Same register, same wait, no bound — and it is on the data-transfer path (sdhci_transfer calls it at :1365 and again at the end). Since you are already in this code adding a bounded version, giving sdhci_reset_lines() the same treatment, or expressing one in terms of the other, closes a hang the rest of the PR is otherwise eliminating.

Comment thread include/sdhci.h
uint32_t sdhci_platform_set_clock(uint32_t clock_khz, uint32_t base_clk_khz);

/* Preserve a host controller initialized by an earlier boot stage. */
#ifndef SDHCI_SKIP_HOST_RESET

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Both new knobs break if defined without a value. #if SDHCI_SKIP_HOST_RESET == 0 here, and #if SDHCI_WAIT_AFTER_CMD_US > 0U at :492, are preprocessor errors when the macro expands to nothing — so -DSDHCI_SKIP_HOST_RESET fails where -DSDHCI_SKIP_HOST_RESET=1 works.

The neighbouring SDHCI options are all #ifdef-style (SDHCI_FORCE_CARD_DETECT, SDHCI_SDMA_DISABLED, SDHCI_BLOCK_VIA_PDMA), so the valueless form is what someone will reach for. #if defined(X) && (X != 0) costs nothing and removes the trap.

Comment thread hal/agilex5.c
UART_REG(UART_THR) = '\r';
timeout = UART_TIMEOUT;
}
while (((UART_REG(UART_LSR) & UART_LSR_THRE) == 0U) &&

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The timeout is measured but not acted on: both THRE waits fall through to UART_REG(UART_THR) = ... whether or not timeout reached zero, so a wedged UART produces corrupted output rather than dropped output.

Not a boot hazard — bounding the loop is the important part and you have that — but skipping the write when the timeout expires is one line and makes the bound mean something.

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.

7 participants