Skip to content

RFC: boards: arm: add Corstone-1000-A320 FVP board support#104035

Open
npitre wants to merge 5 commits intozephyrproject-rtos:mainfrom
npitre:corstone1000_a320
Open

RFC: boards: arm: add Corstone-1000-A320 FVP board support#104035
npitre wants to merge 5 commits intozephyrproject-rtos:mainfrom
npitre:corstone1000_a320

Conversation

@npitre
Copy link

@npitre npitre commented Feb 13, 2026

Add board support for the Arm Corstone-1000-A320 Fixed Virtual Platform (FVP),
featuring the Cortex-A320 (ARMv9.2-A) host processor.

  • Full sysbuild integration: TF-M (Secure Enclave, Cortex-M0+) and TF-A
    (Host CPU) are built alongside Zephyr automatically
  • Single-core (fvp_corstone1000/a320) and quad-core SMP
    (fvp_corstone1000/a320/smp) variants

Dependencies

  • west.yml: points TF-A and TF-M to repos carrying Cortex-A320 support;
    this needs a better resolution
  • TF-M patch (included via west patch): DSU-120T PPU driver for Cortex-A320
    host power-on
    (upstream: https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/45749)
  • TF-A patch (included via west patch): fix secondary core hold pen cache
    coherency

Currently no Ethos-85 support.

@npitre npitre added the In progress For PRs: is work in progress and should not be merged yet. For issues: Is being worked on label Feb 13, 2026
@github-actions
Copy link

github-actions bot commented Feb 13, 2026

The following west manifest projects have changed revision in this Pull Request:

Name Old Revision New Revision Diff
trusted-firmware-a zephyrproject-rtos/trusted-firmware-a@0a29cac (master) zephyrproject-rtos/trusted-firmware-a#8 zephyrproject-rtos/trusted-firmware-a#8/files
trusted-firmware-m zephyrproject-rtos/trusted-firmware-m@3ddfef0 zephyrproject-rtos/trusted-firmware-m@27023e9 (zephyr_tf-m_v2.2.2) zephyrproject-rtos/trusted-firmware-m@3ddfef0e..27023e9c

DNM label due to: 1 project with PR revision

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@github-actions github-actions bot added manifest manifest-trusted-firmware-a DNM (manifest) This PR should not be merged (controlled by action-manifest) labels Feb 13, 2026
@zephyrbot zephyrbot added area: ARM64 ARM (64-bit) Architecture area: TF-A ARM Trusted Firmware-A (TF-A) area: Build System area: Boards/SoCs labels Feb 13, 2026
@@ -0,0 +1,118 @@
From 50c206814218dc6e654e7b9491e693ad3b023407 Mon Sep 17 00:00:00 2001
From: Nicolas Pitre <npitre@baylibre.com>
Date: Thu, 12 Feb 2026 21:17:53 -0500
Copy link
Contributor

Choose a reason for hiding this comment

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

we do not add patches to zephyr

@@ -0,0 +1,2 @@
# Copyright (c) 2026 BayLibre SAS
# SPDX-License-Identifier: Apache-2.0
Copy link
Contributor

Choose a reason for hiding this comment

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

file to go

Copy link
Author

Choose a reason for hiding this comment

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

Done — file removed.

@@ -0,0 +1,2 @@
# Copyright (c) 2026 BayLibre SAS
# SPDX-License-Identifier: Apache-2.0
Copy link
Contributor

Choose a reason for hiding this comment

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

file to go

Copy link
Author

Choose a reason for hiding this comment

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

Done — file removed.

# 1. TF-M for the Secure Enclave (Cortex-M0+)
# 2. TF-A + Zephyr for the Host (Cortex-A320)

config CORSTONE1000_BUILD_TFM
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be done using board targets, not a sysbuild Kconfig @tomi-font can probably explain

Copy link
Contributor

Choose a reason for hiding this comment

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

seems the Kconfig is gone -- @npitre do you want to make TF-M optional or always enabled?

Copy link
Author

Choose a reason for hiding this comment

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

TF-M is always required on Corstone-1000 — the Secure Enclave (Cortex-M0+) runs TF-M which handles provisioning, verified boot, and powers on the host CPU via the DSU-120T PPU. Without TF-M, the Cortex-A320 never starts.

The original board variant selection Kconfig that @nordicjm commented on has been removed. The remaining Kconfig.sysbuild only exposes debug/log-level knobs for the TF-M and TF-A builds.

Comment on lines +12 to +21
# Find the FVP binary. Board-specific HINTS supplement the global ARMFVP_BIN_PATH.
find_program(ARMFVP
NAMES ${ARMFVP_BIN_NAME}
HINTS
${ARMFVP_BIN_PATH}
$ENV{ARMFVP_BIN_PATH}
)

# Set minimum FVP version for Corstone-1000-A320
set(ARMFVP_MIN_VERSION 11.27.31)
Copy link
Contributor

Choose a reason for hiding this comment

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

The bottom variable seems unused, you might want to use https://github.com/zephyrproject-rtos/zephyr/blob/main/cmake/modules/python.cmake#L14 to find a minimum version

Copy link
Author

Choose a reason for hiding this comment

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

ARMFVP_MIN_VERSION is consumed by cmake/emu/armfvp.cmake — it queries the FVP binary version at configure time and warns if it is below the board-specified minimum. This is the existing mechanism used by other FVP boards (e.g. fvp_base_revc_2xaem).

Comment on lines 188 to 191
For early boot debugging before the UART is available, semihosting can be
used. Add ``CONFIG_SEMIHOST=y`` and ``CONFIG_SEMIHOST_CONSOLE=y`` to the
board defconfig (replacing ``CONFIG_UART_CONSOLE=y``). The FVP has
semihosting enabled by default.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
For early boot debugging before the UART is available, semihosting can be
used. Add ``CONFIG_SEMIHOST=y`` and ``CONFIG_SEMIHOST_CONSOLE=y`` to the
board defconfig (replacing ``CONFIG_UART_CONSOLE=y``). The FVP has
semihosting enabled by default.
For early boot debugging before the UART is available, semihosting can be used by enabling
:kconfig:option:`CONFIG_SEMIHOST` and :kconfig:option:`CONFIG_SEMIHOST_CONSOLE`, and disabling
:kconfig:option:`CONFIG_UART_CONSOLE`. The FVP has
semihosting enabled by default.
Copy link
Author

Choose a reason for hiding this comment

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

Done — applied the suggested wording.

# cmake -DZEPHYR_BASE=/path/to/zephyr -P setup_tfa_module.cmake

# Find west topdir
execute_process(
Copy link
Contributor

Choose a reason for hiding this comment

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

this does not look like something zephyr should have

Copy link
Author

Choose a reason for hiding this comment

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

Done — file removed.

file(MAKE_DIRECTORY ${TFA_BINARY_DIR})
file(MAKE_DIRECTORY ${FIRMWARE_DIR})

# =============================================================================
Copy link
Contributor

Choose a reason for hiding this comment

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

this is not how TF-M is built in zephyr, please use the existing infrastructure

Copy link
Author

Choose a reason for hiding this comment

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

The Corstone-1000 is architecturally different from existing Zephyr TF-M boards: TF-M runs on a separate Cortex-M0+ Secure Enclave, not on the same CPU as Zephyr via TrustZone.

The existing Zephyr TF-M sysbuild infrastructure (modules/trusted-firmware-m/) assumes the TrustZone SPE/NSPE split model where TF-M and Zephyr share the same CPU and the same toolchain. On the Corstone-1000:

  • TF-M targets a Cortex-M0+ (SE) — requires arm-zephyr-eabi (ARM 32-bit) toolchain
  • Zephyr targets a Cortex-A320 (Host) — uses aarch64-zephyr-elf (AArch64) toolchain
  • The SE has its own ROM (BL1), flash layout, and provisioning cycle
  • Communication between the two CPUs is via a hardware mailbox, not TrustZone secure calls

Zephyr's existing TF-M integration produces SPE/NSPE image pairs for one CPU. Here we need to cross-compile TF-M for a completely different architecture and then package the output (bl1.bin, flash image with GPT partitions) into the FVP's ROM/flash loading scheme.

I don't see how the existing infrastructure can be adapted for this dual-CPU topology without major changes to it. If there's a path I'm missing, I'm happy to hear about it — but given the fundamental architectural mismatch, I believe ExternalProject is the right approach here.

Copy link
Contributor

Choose a reason for hiding this comment

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

How about extending the TF-M integration so that your use case is possible with just some additional configuration? So that the logic for that would be in modules/trusted-firmware-m and not in boards directly.

Copy link
Author

Choose a reason for hiding this comment

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

I looked into what extending modules/trusted-firmware-m would require for this dual-CPU topology. The gap is substantial:

  1. Toolchain decoupling — The current code hardcodes TF-M's toolchain to match Zephyr's. We'd need a separate TFM_TOOLCHAIN_* selection mechanism since TF-M targets arm-zephyr-eabi (Cortex-M0+) while Zephyr uses aarch64-zephyr-elf (Cortex-A320).

  2. New Kconfig triggerBUILD_WITH_TFM requires TRUSTED_EXECUTION_NONSECURE + ARM_TRUSTZONE_M, neither of which applies to an AArch64 host. A new entry path would be needed.

  3. Different artifact model — The existing infrastructure produces s_veneers.o and merged hex for a shared-CPU TrustZone split. Corstone-1000 needs SE ROM images, GPT flash layout, MCUboot signing of TF-A BL2, and FIP assembly — none of which overlaps with the current post-processing pipeline.

  4. Board mappingTFM_BOARD maps one Zephyr board to one TF-M platform on the same CPU. Here the TF-M platform (arm/corstone1000) targets a completely different processor than Zephyr's.

In practice, the only thing the board-local ExternalProject shares with the standard infrastructure is the ExternalProject_Add call to invoke TF-M's CMake. Everything else — toolchain setup, configuration, artifact consumption, image assembly — is Corstone-1000-specific. Generalizing this into modules/trusted-firmware-m would mean adding a parallel code path that doesn't reuse the existing one, while making the module more complex for all users.

Given that we don't know yet how many other platforms will need this mixed-architecture TF-M model, is the added infrastructure complexity justified at this point? If more dual-CPU boards appear in the future, the board-local logic would be a natural starting point for extracting a shared implementation.

That said, I may be missing a simpler integration path — if you see a way to hook into the existing infrastructure without a major overhaul, I'm all ears.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah no I think you know better what it would take. I'm fine with doing it this way if there's no other board in Zephyr which is in the same situation. Though if/when another such board shows up we should build the infrastructure for it so we don't end up with different boards redoing the same thing by themselves.

@wearyzen
Copy link
Contributor

Upstream docker doesn't have the FVP_Corstone-1000-A320 could we add it so that ci can actually test these changes?
For reference other FVPs are added here: https://github.com/zephyrproject-rtos/docker-image/blob/main/Dockerfile.base#L43

west.yml Outdated
- tee
- name: trusted-firmware-a
revision: 0a29cac8fe0f7bdb835b469d9ea11b8e17377a92
remote: arm-software
Copy link
Contributor

Choose a reason for hiding this comment

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

AFAIR Zephyr doesn't allow fetching code from external repos. TF-M changes should be added to https://github.com/zephyrproject-rtos/trusted-firmware-m following the common guidelines mentioned here: https://docs.zephyrproject.org/latest/develop/modules.html#submitting-changes-to-modules and here: https://github.com/zephyrproject-rtos/mbedtls#additional-patches

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, if you want to make additions to TF-A you'll need to make them to Zephyr's fork of it just like you did with TF-M.

npitre pushed a commit to npitre/docker-image that referenced this pull request Feb 17, 2026
Add the Arm Corstone-1000-A320 Ecosystem FVP (version 11.30.27) to the
CI container image. This FVP is needed by the Zephyr fvp_corstone1000/a320
board (zephyrproject-rtos/zephyr#104035).

The Corstone-1000-A320 uses a different CDN permalink pattern from the
existing Corstone SSE models, so it is installed separately rather than
being added to the FVP_INSTALLABLE loop.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
@npitre
Copy link
Author

npitre commented Feb 17, 2026

Done — submitted zephyrproject-rtos/docker-image#286 to add the Corstone-1000-A320 FVP to the CI container.

stephanosio pushed a commit to zephyrproject-rtos/docker-image that referenced this pull request Feb 18, 2026
Add the Arm Corstone-1000-A320 Ecosystem FVP (version 11.30.27) to the
CI container image. This FVP is needed by the Zephyr fvp_corstone1000/a320
board (zephyrproject-rtos/zephyr#104035).

The Corstone-1000-A320 uses a different CDN permalink pattern from the
existing Corstone SSE models, so it is installed separately rather than
being added to the FVP_INSTALLABLE loop.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
@github-actions github-actions bot removed manifest-trusted-firmware-a DNM (manifest) This PR should not be merged (controlled by action-manifest) labels Feb 19, 2026
@wearyzen
Copy link
Contributor

Done — submitted zephyrproject-rtos/docker-image#286 to add the Corstone-1000-A320 FVP to the CI container.

I see the docker PR is merged, @stephanosio could you please help updating the ci image to include the new FVP so that this PR could be tested?

Nicolas Pitre added 2 commits February 23, 2026 13:50
The ARM Architecture Reference Manual (DDI 0487) requires a context
synchronization event (ISB) between modifying SVE trap control registers
(CPTR_EL3.EZ, CPTR_EL2.TZ, CPACR_EL1.ZEN) and accessing the
corresponding ZCR_ELx registers: "The effect of the change is guaranteed
to be observable only after a Context synchronization event."

Without the ISB, the processor may still observe the old trap
configuration and generate an UNDEFINED exception on the ZCR write.

This also fixes the EL2 SVE initialization for non-VHE mode
(HCR_EL2.E2H=0): CPTR_EL2 bits [17:16] (ZEN) are RES0 in non-VHE
format and must not be set. SVE trapping at EL2 in non-VHE mode is
controlled by the TZ bit (bit 8) instead. The previous code wrote the
VHE-format ZEN bits which is architecturally UNPREDICTABLE in non-VHE
mode. Match the Linux kernel sequence (arch/arm64/include/asm/el2_setup.h).

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
The existing code unconditionally appends bp.secureflashloader,
bp.flashloader0, and cluster0.cpu0 load parameters which assume the
Base FVP model topology. FVP models with a different firmware loading
scheme (e.g. a secure enclave ROM loader and flash data regions) cannot
use these parameters.

Add an ARMFVP_SKIP_FW_ARGS guard so boards that handle firmware loading
entirely in their own ARMFVP_FLAGS can opt out of the generic firmware
argument generation.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
@github-actions github-actions bot added manifest manifest-trusted-firmware-m manifest-trusted-firmware-a DNM (manifest) This PR should not be merged (controlled by action-manifest) labels Feb 23, 2026
@zephyrbot zephyrbot added the area: TF-M ARM Trusted Firmware-M (TF-M) label Feb 23, 2026
@wearyzen
Copy link
Contributor

Hi @npitre now that this PR links to TF-A and TF-M PRs, we don't need the patches anymore. So, could you please remove the zephyr/patches folder and patch files from this PR?

@npitre
Copy link
Author

npitre commented Feb 24, 2026

@wearyzen The remaining patch (0003) is not covered by the TF-M or TF-A module PRs. It's a fix for a secondary core hold pen cache coherency bug that is still pending upstream review on Gerrit:

https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/48505

Without it, SMP boot fails on the Corstone-1000-A320. Once it gets merged upstream and into the Zephyr TF-A mirror, we can drop this last patch.

@wearyzen
Copy link
Contributor

@wearyzen The remaining patch (0003) is not covered by the TF-M or TF-A module PRs. It's a fix for a secondary core hold pen cache coherency bug that is still pending upstream review on Gerrit:

https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/48505

Without it, SMP boot fails on the Corstone-1000-A320. Once it gets merged upstream and into the Zephyr TF-A mirror, we can drop this last patch.

Ok, I missed that. But then in that case the patch should still be removed and included in the TF-A PR because Zephyr PRs don't allow patches in PR.

@npitre
Copy link
Author

npitre commented Feb 25, 2026

@wearyzen Per the module contribution policy, changes to a module's codebase before they have been merged in the upstream project should be limited to urgent fixes such as security vulnerabilities. The hold pen cache coherency fix is currently pending upstream review on Gerrit (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/48505), so it wouldn't be appropriate to add it to the TF-A mirror PR at this stage. If you know how to speed up the upstream review, that would be welcome.

@wearyzen wearyzen closed this Feb 26, 2026
@wearyzen wearyzen reopened this Feb 26, 2026
@wearyzen
Copy link
Contributor

closed and re-opened the PR because this is the simplest way I know to start the CI 🤷
There is a new docker image release https://github.com/zephyrproject-rtos/docker-image/releases/tag/v0.28.8 with Corstone-1000-A320 FVP so we should see some test built with it now.

@wearyzen
Copy link
Contributor

wearyzen commented Feb 27, 2026

@npitre I tried to run a hello_world with the upstream docker image but it seems gdisk is not installed. Could you please add that to the docker image as well along with anything else that is needed and request for another image spin if it works locally for you in the container?

I also found that TFM build tries to clone QCBOR and T_COSE repositories which is also allowed in Zephyr.
Would you like to turn off the attestation to avoid this? I tried below -DTFM_PARTITION_INITIAL_ATTESTATION=OFF to TFM_CMAKE_ARGS in boards/arm/fvp_corstone1000/sysbuild.cmake and that seems to avoid the clone.

Unless I am doing something wrong, west build -p -b fvp_corstone1000/a320 samples/hello_world --sysbuild -t run does not work as a single command but the split to build and then run works, that looks like a bug.
It would actually be better and more natural if we could just do west build -p -b fvp_corstone1000/a320 samples/hello_world -t run without the --sysbuild or splitting the commands in two.

@tomi-font tomi-font requested a review from nordicjm February 27, 2026 12:27
Nicolas Pitre added 3 commits February 27, 2026 13:59
Point west.yml TF-M and TF-A revisions to add Cortex-A320 support:

- TF-M: DSU-120T PPU driver for Cortex-A320 host power-on (merged)
  zephyrproject-rtos/trusted-firmware-m#172

- TF-A: Cortex-A320 support (GICv3, MPIDR layout,
  Ethos-U85/SRAM mappings, multicore hold pen)
  PR: zephyrproject-rtos/trusted-firmware-a#8

Add west patch for TF-A generic hold pen with cache coherency fix
(upstream review):
  https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/48636
  https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/48505
  https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/48637
  https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/48638

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Add Zephyr board support for the Arm Corstone-1000-A320 Fixed Virtual
Platform (FVP) with the full reference firmware stack:

  SE: BL1 -> MCUboot -> TF-M SPE
  Host: TF-A BL2 -> BL31 -> Zephyr (BL33)

The board uses sysbuild to orchestrate the multi-image build:
- TF-M for the Secure Enclave (Cortex-M0+) as a CMake ExternalProject
- TF-A for the Host CPU (Cortex-A320) with Zephyr as BL33
- MCUboot ECDSA signing of TF-A BL2 for verified boot
- GPT flash image assembly with FIP partition

TF-A build flags are aligned with the Yocto CORSTONE1000-2025.12
reference build, including ENABLE_PIE=1 for position-independent BL2,
GICv3 driver selection, and ARMv9 feature enables.

The FVP runner (board.cmake) sets ARMFVP_SKIP_FW_ARGS to bypass the
generic Base FVP firmware loading and provides Corstone-1000-specific
parameters for the secure enclave ROM loader and flash data regions.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Add an SMP variant (fvp_corstone1000/a320/smp) that enables all 4
Cortex-A320 CPUs on the Corstone-1000-A320 FVP.

Changes:
- Add board variant 'smp' with DTS, defconfig, and yaml
- Add PSCI node to dtsi (needed for PM_CPU_OPS_PSCI)
- Enable ENABLE_MULTICORE in both TF-M and TF-A sysbuild args
  so TF-M boots all 4 host CPUs and TF-A provides PSCI CPU_ON
- Add TF-A patch fixing secondary core hold pen cache coherency:
  BL2's dcsw_op_all during BL2-to-BL31 transition pushes stale
  cached data over WAIT values written by secondary CPUs from
  non-cached context

Tested with tests/kernel/smp on FVP_Corstone-1000-A320:
all 4 CPUs boot and all SMP test cases pass.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
@npitre
Copy link
Author

npitre commented Feb 27, 2026

Thanks for testing this @wearyzen!

I've submitted zephyrproject-rtos/docker-image#287 to add gdisk and uuid-runtime to the container. I verified the full build and FVP run succeed in the container with those additions.

Good catch on the attestation — I've added -DTFM_PARTITION_INITIAL_ATTESTATION=OFF to the TFM_CMAKE_ARGS in this PR.

Regarding west build -p ... --sysbuild -t run-p + -t run need to be separate steps since pristine wipes the build directory. As for dropping --sysbuild, that would require making sysbuild the default for this board which I can look into.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ARM64 ARM (64-bit) Architecture area: Boards/SoCs area: Build System area: TF-A ARM Trusted Firmware-A (TF-A) area: TF-M ARM Trusted Firmware-M (TF-M) DNM (manifest) This PR should not be merged (controlled by action-manifest) In progress For PRs: is work in progress and should not be merged yet. For issues: Is being worked on manifest manifest-trusted-firmware-a manifest-trusted-firmware-m

5 participants