RFC: boards: arm: add Corstone-1000-A320 FVP board support#104035
RFC: boards: arm: add Corstone-1000-A320 FVP board support#104035npitre wants to merge 5 commits intozephyrproject-rtos:mainfrom
Conversation
|
The following west manifest projects have changed revision in this Pull Request:
⛔ DNM label due to: 1 project with PR revision Note: This message is automatically posted and updated by the Manifest GitHub Action. |
| @@ -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 | |||
There was a problem hiding this comment.
we do not add patches to zephyr
| @@ -0,0 +1,2 @@ | |||
| # Copyright (c) 2026 BayLibre SAS | |||
| # SPDX-License-Identifier: Apache-2.0 | |||
| @@ -0,0 +1,2 @@ | |||
| # Copyright (c) 2026 BayLibre SAS | |||
| # SPDX-License-Identifier: Apache-2.0 | |||
| # 1. TF-M for the Secure Enclave (Cortex-M0+) | ||
| # 2. TF-A + Zephyr for the Host (Cortex-A320) | ||
|
|
||
| config CORSTONE1000_BUILD_TFM |
There was a problem hiding this comment.
This should be done using board targets, not a sysbuild Kconfig @tomi-font can probably explain
There was a problem hiding this comment.
seems the Kconfig is gone -- @npitre do you want to make TF-M optional or always enabled?
There was a problem hiding this comment.
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.
| # 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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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).
| 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. |
There was a problem hiding this comment.
| 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. |
There was a problem hiding this comment.
Done — applied the suggested wording.
| # cmake -DZEPHYR_BASE=/path/to/zephyr -P setup_tfa_module.cmake | ||
|
|
||
| # Find west topdir | ||
| execute_process( |
There was a problem hiding this comment.
this does not look like something zephyr should have
| file(MAKE_DIRECTORY ${TFA_BINARY_DIR}) | ||
| file(MAKE_DIRECTORY ${FIRMWARE_DIR}) | ||
|
|
||
| # ============================================================================= |
There was a problem hiding this comment.
this is not how TF-M is built in zephyr, please use the existing infrastructure
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
I looked into what extending modules/trusted-firmware-m would require for this dual-CPU topology. The gap is substantial:
-
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 targetsarm-zephyr-eabi(Cortex-M0+) while Zephyr usesaarch64-zephyr-elf(Cortex-A320). -
New Kconfig trigger —
BUILD_WITH_TFMrequiresTRUSTED_EXECUTION_NONSECURE+ARM_TRUSTZONE_M, neither of which applies to an AArch64 host. A new entry path would be needed. -
Different artifact model — The existing infrastructure produces
s_veneers.oand 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. -
Board mapping —
TFM_BOARDmaps 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.
There was a problem hiding this comment.
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.
65c3e66 to
138f658
Compare
|
Upstream docker doesn't have the |
west.yml
Outdated
| - tee | ||
| - name: trusted-firmware-a | ||
| revision: 0a29cac8fe0f7bdb835b469d9ea11b8e17377a92 | ||
| remote: arm-software |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
138f658 to
345046e
Compare
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>
|
Done — submitted zephyrproject-rtos/docker-image#286 to add the Corstone-1000-A320 FVP to the CI container. |
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>
345046e to
2b2cd46
Compare
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? |
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>
2b2cd46 to
13d4e88
Compare
|
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? |
|
@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. |
|
@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. |
|
closed and re-opened the PR because this is the simplest way I know to start the CI 🤷 |
|
@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. Unless I am doing something wrong, |
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>
13d4e88 to
08c01b4
Compare
|
Thanks for testing this @wearyzen! I've submitted zephyrproject-rtos/docker-image#287 to add Good catch on the attestation — I've added Regarding |
|



Add board support for the Arm Corstone-1000-A320 Fixed Virtual Platform (FVP),
featuring the Cortex-A320 (ARMv9.2-A) host processor.
(Host CPU) are built alongside Zephyr automatically
fvp_corstone1000/a320) and quad-core SMP(
fvp_corstone1000/a320/smp) variantsDependencies
this needs a better resolution
west patch): DSU-120T PPU driver for Cortex-A320host power-on
(upstream: https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/45749)
west patch): fix secondary core hold pen cachecoherency
Currently no Ethos-85 support.