1
0
mirror of https://git.yoctoproject.org/meta-arm synced 2026-07-18 04:27:08 +00:00

Compare commits

...

50 Commits

Author SHA1 Message Date
Jon Mason 28606c7215 CI: fix sstate-mirror
We should be using OE_FRAGMENTS for the upstream sstate mirror, and
BB_HASHSERVE is in base.yml

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-07-14 12:00:03 -04:00
Jon Mason b4fbbaf196 arm/optee-ftpm: update recipe name
optee-ftpm tagged the 4.10 release, but had no functional changes (that
is, they tagged the same commit of 4.9.0 with 4.10.0).  Update the
recipe name to match the latest version, and not have people think that
one package was held back.

Also, modify the version checking to be less incorrect

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-07-14 10:00:08 -04:00
Jon Mason c2a169b18e arm/opencsd: update to 1.8.3
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-07-14 10:00:08 -04:00
Jon Mason ea93de35ae arm-bsp/external-system: update to the latest commit
The source tree is question is not tagged or branched with any version.
Update to the latest commit, change the recipe name to denote it is
'git' and not versioned, and fix the upgrade-status.  Also, update the
git URL.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-07-14 10:00:05 -04:00
Jon Mason 82711f1a48 arm-bsp/corstone1000-external-sys-tests: update to the latest commit
The source tree is question is not tagged or branched with any version.
Update to the latest commit, change the recipe name to denote it is
'git' and not versioned, and fix the upgrade-status.  Also, update the
git URL.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-07-14 10:00:05 -04:00
Jon Mason 451dfc3712 arm-toolchain: Update to new toolchain version
Update the recipes to the newest release.  Also, Arm Binary Toolchains
have moved to https://gitlab.arm.com/tooling/gnu-toolchains-for-arm

The new location has a new layout, which means the upstream version
check needs to change.  Unfortunately, they are not using tags, but do
seem to use branch names like a tag.  So, using that for the version
check.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-07-14 10:00:03 -04:00
Jon Mason 9607ed4eee arm-bsp: Lengthen Boot timeout for rdv2/rdn2
CI is seeing intermittent boot test timeout errors, where the FVP is
almost to shell but times out before getting there.  To get around this,
lengthen the timeout to allow for more opportunity to complete
successfully.

By default, the timeout is 600 seconds.  Increase this by 50% to 900.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-07-07 10:00:04 -04:00
Harsimran Singh Tungal 94e19cb2b9 ci: enable testimage coverage for Corstone-1000 A320 FVP
Update the Corstone-1000 A320 FVP CI matrix to run testimage jobs.

This enables testimage coverage for both the firmware-only and no-firmware
entries.

Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-30 09:00:03 -04:00
Harsimran Singh Tungal 589e16aebc fvp:corstone1000-a320: update Corstone-1000 A320 FVP to 11.31
Update the Corstone-1000 with Cortex-A320 FVP recipe to use the
11.31.cs1000_a320_2 release from Arm Developer.

Switch the source URL to the new package layout, add the architecture-specific
download tokens, and update the x86_64 and aarch64 SHA256 checksums.

The new package extracts directly into the FVP install directory, so update the
install step and license paths accordingly.

Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-30 09:00:03 -04:00
Harsimran Singh Tungal 793354dbf2 arm-bsp/documentation: corstone1000-a320: update 2026.05 wrynose release documentation
Update the Corstone-1000 with Cortex-A320 changelog, release notes,
user guide, tests documentation and metadata for the 2026.05 release.

Add the new 2026.05 changelog entry for the Corstone-1000 with
Cortex-A320 specific updates and align the component version tables and
Yocto distribution component versions with the current release content.

Refresh the user guide and tests documentation to align with the
2026.05 release state, including release tag references, recipe version
references, report links

Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-30 09:00:03 -04:00
Harsimran Singh Tungal c6febbdd02 arm-bsp/documentation: corstone1000: update 2026.05 wrynose release documentation
Update the Corstone-1000 changelog, release notes and user guide for
the 2026.05 wrynose release.

Add the new 2026.05 changelog entry and capture the main release work,
including the component upgrades, TF-M GPT and PSA FWU changes, and the
updated SSH-enabled build flow.
Refresh the component version tables and Yocto distribution component
versions in changelog for the new release.

Update the user guide to align with the 2026.05 release branch and
documentation state, including the Yocto release name, recipe version
references, release tag references, and related asset and report links.

Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-30 09:00:03 -04:00
Jon Mason 847af9c082 arm/u-boot: fix uefi-secureboot on u-boot v2026.04
u-boot v2026.04 changed to kbuild 6.1, which broke how ubootefi.var is
used.  Apply patch from u-boot mailing list to address the issue.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-25 18:00:03 -04:00
Jon Mason 3681201897 arm/optee: update to 4.10.0
Update the recipes to 4.10.0 and update the git recipes to 4.10.0
Since corstone1000 is still using 4.9.0, move that to meta-arm-bsp

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-18 09:50:49 -04:00
Jon Mason 9014a4e935 arm/opencsd: upgrade to v1.8.2
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-18 09:50:49 -04:00
Jon Mason 200ccaa637 arm/uefi: update edk2-firmware to 202605
Update edk2-firmware to the latest release.
Of note, GCC5 make variable has been removed.  Use the GCC make variable
instead.  Also, these changes caused the need to modify the sbsa-acs
patches.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-18 09:50:49 -04:00
Jon Mason cef3e3a22c arm/trusted-firmware-a: Update git recipe to the latest commit
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-18 09:50:49 -04:00
Jon Mason dd460eb29d arm/trusted-firmware-a: Update LTS to 2.14.2
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-18 09:50:49 -04:00
Jon Mason 66c46946f5 arm/trusted-firmware-a: remove older LTS versions
The policy in meta-arm is to only have the latest version and the
latest LTS version.  Remove all of the older LTS versions to comply with
this policy.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-18 09:50:46 -04:00
Jon Mason f1098681f4 arm/trusted-firmware-a: Add support for v2.15.0
Add support for the newest release of TF-A.
mnedtls was made a git submodule, and moved location.  Given that this
will be the location going forward, I thought it best to change inc file
to point by default to the new location, and have the LTS versions to
point to the old location in their recipes.

Also, seeing some weird behavior with CPUs not coming on line in
sbsa-ref and qemuarm-secureboot.  So, pinning those back to the LTS
until they can be sorted out.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-18 09:50:03 -04:00
Arthur Cassegrain 8df56513d9 arm/trusted-services: enable devtool modify for ts-psa-api-test
Place psa-arch-tests under ${S}/ts-external/psatest and update the
recipe paths to match.

This keeps the external source layout aligned with trusted-services,
updates the Corstone-1000 patch locations, and lets devtool modify work
against the same psa-arch-tests tree that CMake and
apply_local_src_patches use.

Signed-off-by: Arthur Cassegrain <arthur.cassegrain@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-17 09:13:31 -04:00
Jon Mason d718d02774 arm/trusted-firmware-m: remove 2.1.4
Remove the older LTS, since there is a policy of the most recent release
and the previous LTS.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-17 09:13:31 -04:00
Jon Mason c5df984862 arm/trusted-firmware-m: Add 2.3.0 Support
Add recipes for newest version of tf-m.  Of note, mbedtls has been
removed in favor of the TF-PSA-Crypto library.  This is having a cascade
into the other recipes, with a removal from the core inc file and add of
the individual lines to the specific versions.

TF-PSA-Crypto is Apache 2.0 licensed.  So, no need to change the recipe
license field.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-17 09:13:31 -04:00
Jon Mason 22de042eaf CI: use Musca S1 for LTS testing
In TF-M 2.3.0, Musca S1 was removed, but B1 is still present.  In an
effort to keep coverage, swapping S1 and B1.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-17 09:13:31 -04:00
Ross Burton fe60f0804e CI: add option to control whether warnings should be fatal or not
Warnings being always fatal is quite anti-social because sometimes there
are temporary warnings that we don't want to break the CI.

Signed-off-by: Ross Burton <ross.burton@arm.com>
2026-06-16 16:51:12 +01:00
Ross Burton dea9d913d8 CI: use a single multiline script statement in .build
No change to the script, just formatting.

Signed-off-by: Ross Burton <ross.burton@arm.com>
2026-06-16 16:48:01 +01:00
Ross Burton c53fcf76e2 CI: default CACHE_DIR to CI_PROJECT_DIR
Set the default cache directory to be the build tree so we don't assume
anything about the runner environment by default.

After this change, runners that don't set CACHE_DIR will need to set it
explicltly in their variables.

Signed-off-by: Ross Burton <ross.burton@arm.com>
2026-06-16 16:42:24 +01:00
Ross Burton ab0930aa96 CI: remove cve.yml and NVDCVE_API_KEY
This yml fragment wasn't actually used by our CI, and the cve-check class
no longer exists.

Signed-off-by: Ross Burton <ross.burton@arm.com>
2026-06-16 16:39:25 +01:00
Jon Mason 9aaee17adb arm/scp-firmware: add CVE_PRODUCT
Per https://nvd.nist.gov/products/cpe/detail/593B1385-F4BE-452B-AE3B-51627F6CAE45
add CVE_PRODUCT entry.  Since there wasn't one existing, there is no
need to remove anything.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-11 10:12:32 -04:00
Jon Mason d0b93e582c arm/trusted-firmware-m: add CVE_PRODUCT
Per https://nvd.nist.gov/products/cpe/detail/C0F7CF14-9ACD-42C5-A1F8-839937F8C4DC
add CVE_PRODUCT entry.  Since there wasn't one existing, there is no
need to remove anything.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-11 10:12:32 -04:00
Jon Mason e2e63f20b5 arm/trusted-firmware-a: modify CVE_PRODUCT
Per https://nvd.nist.gov/products/cpe/detail/2E1BD3E8-DF65-42E3-A0BA-747137D6DEF2
Adding "trustedfirmware:trusted_firmware-a"

We can probably remove "arm:trusted_firmware-a", since it has been
depreciated.  Fearing unintended issues, leaving it in for now.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-11 10:12:32 -04:00
Jon Mason 81f5a92193 arm/optee: modify CVE_PRODUCT
Per https://nvd.nist.gov/products/cpe/detail/EB42962B-24FD-4716-B3E2-69F3258A57CF
adding "trustedfirmware:op-tee"

We can probably remove "linaro:op-tee", since it has been depreciated.
Fearing unintended issues, leaving it in for now.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-11 10:12:32 -04:00
Jon Mason 02d361b435 arm/ts-sp-common: Workaround unused-but-set-variable errors
With the new GCC, we're seeing the following error:
| In file included from /builder/meta-arm/build/tmp/work/armv8-5a-poky-linux/ts-sp-smm-gateway/git/sources/ts/components/common/dlmalloc/malloc_wrapper.c:62:
| /builder/meta-arm/build/tmp/work/armv8-5a-poky-linux/ts-sp-smm-gateway/git/sources/ts/components/common/dlmalloc/malloc.c: In function 'add_segment':
| /builder/meta-arm/build/tmp/work/armv8-5a-poky-linux/ts-sp-smm-gateway/git/sources/ts/components/common/dlmalloc/malloc.c:4002:7: error: variable 'nfences' set but not used [-Werror=unused-but-set-variable=]
|  4002 |   int nfences = 0;
|       |       ^~~~~~~

To workaround this issue, add "-Wno-error=unused-but-set-variable" to TARGET_CFLAGS

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-02 09:00:04 -04:00
Jon Mason f23b86a59c arm/tf-a-tests: Workaround GCC errors for 'unused-but-set-variable'
New GCC is logging errors for unused-but-set-variable in
tftf/tests/runtime_services/standard_service/psci/api_tests/psci_stat/test_psci_stat.c

Workaround this by adding -Wno-unused-but-set-variable to the Makefile
Refer to https://github.com/TrustedFirmware-A/tf-a-tests/issues/4
For the upstream resolution, if/when that arrives.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-02 09:00:04 -04:00
Michael Safwat 6e6567869f arm-bsp/docs: corstone1000-a320: Add standalone A320 documentation
Add a separate Corstone-1000 Armv9-A Edge-AI documentation
set for the Cortex-A320 platform.

Populate the new documentation tree with the initial index,
user guide, software architecture, release notes, change log,
and supporting images.

Keep common Corstone-1000 material in the existing documentation
set and move A320-specific content into the new standalone
document set.

Signed-off-by: Michael Safwat <michael.safwat@arm.com>
Signed-off-by: Lisa Durbin <lisa.durbin@arm.com>
Signed-off-by: Alex Chapman <alex.chapman@arm.com>
Signed-off-by: Hugues KAMBA MPIANA <hugues.kambampiana@arm.com>
2026-05-28 09:47:59 -04:00
Michael Safwat 6ab14ea640 runfvp: add --dry-run option
Add a --dry-run option to scripts/runfvp to print the constructed
FVP command line and exit without launching the model.

This is useful for checking parameters and reusing them with different
FVP binaries.

Signed-off-by: Michael Safwat <michael.safwat@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-28 05:00:03 -04:00
Gyorgy Sarvari 3c07303388 arm/trusted-firmware-a: don't set LD if LTO is enabled
Some platforms (like Allwinner A64/sun50i_a64) have LTO enabled
in the Makefiles, which causes a linking error when using ld:

| [...]/aarch64-oe-linux/aarch64-oe-linux-ld: -f may not be used without -shared

Add an option to be able to indicate in the recipe if the plaform has LTO enabled,
and only pass LD to make in case LTO is disabled, otherwise let it use $CC (as set by the Makefile).

The option is disabled by default to keep the existing behavior.

Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-24 07:00:05 -04:00
Alex Chapman ce5b4c4b0a arm/edk2-basetools-native: Add missing libuuid dependency
GenFv requires libuuid in the native sysroot.

Add util-linux-libuuid-native and pass required flags through to the
BaseTools makefiles. This can be missed on machines with libuuid
headers installed, as the build may find the host copy instead.

Signed-off-by: Alex Chapman <alex.chapman@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-20 10:00:03 -04:00
Marek Bykowski e04ac672d5 arm-bsp: use IMAGE_LINK_NAME for FVP disk image path
${IMAGE_NAME} expands to a timestamped filename which gets written into
the .fvpconf. A mismatch occurs when do_image reruns (regenerating the
.fvpconf with a new timestamp) but do_image_wic hits sstate (leaving the
old .wic on disk), causing the FVP to fail at startup with:

  Can't stat <image>-<timestamp>.wic! (error 2)

Use IMAGE_LINK_NAME instead, which is the stable symlink that always
points to the most recently built .wic.

Signed-off-by: Marek Bykowski <marek.bykowski@gmail.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-19 12:00:03 -04:00
Michael Safwat 33cc743536 arm-bsp/docs: corstone1000: Drop A320 content from base documentation
Remove Cortex-A320-specific content from the base Corstone-1000
documentation.

Drop the A320-only sections, commands, notes, and subsystem image from
the shared Corstone-1000 software architecture and user guide now that
the platform is documented in its own standalone document set.

Signed-off-by: Michael Safwat <michael.safwat@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-18 15:00:03 -04:00
Hugues KAMBA MPIANA dd2437f8d6 ci: Add Corstone-1000 with Cortex-A320 builds
Add CI coverage for the Corstone-1000 with Cortex-A320 FVP machine.

Build the Corstone-1000 with Cortex-A320 FVP with the firmware-only
configuration and run both `none` and `tftf`.
Also run `none` for the no-firmware build.

Signed-off-by: Alex Chapman <alex.chapman@arm.com>
Signed-off-by: Hugues KAMBA MPIANA <hugues.kambampiana@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-18 15:00:03 -04:00
Alex Chapman 7ea8654517 arm-bsp:corstone1000: Create a standalone corstone1000-a320-fvp machine
Add `corstone1000-a320-fvp` as a dedicated machine instead of enabling
the Cortex-A320 variant through a kas overlay on `corstone1000-fvp`.

Move the A320-specific machine features, overrides, FVP executable
selection, and Ethos-U85 configuration into the new machine
configuration. Keep the generic `corstone1000-fvp` machine focused on
the base FVP platform.

Update the A320 kas to use `corstone1000-a320-fvp` directly, and
allow pregenerated SSH host keys for the new virtual machine.

Signed-off-by: Alex Chapman <alex.chapman@arm.com>
Signed-off-by: Hugues KAMBA MPIANA <hugues.kambampiana@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-18 15:00:03 -04:00
Alex Chapman faaa3b84a4 arm-bsp/docs,kas:corstone1000: Add SSH image build support
Add a shared Corstone-1000 kas configuration for building SSH-enabled
mass storage images across the supported Corstone-1000 machines.

Enable Dropbear SSH in the mass storage OS image, add pregenerated SSH
host keys for FVP builds, and document the SSH image build flow in the
user guides.

SSH support is too large for the flash OS image, so provide a dedicated
`core-image-minimal` kas configuration for SSH-enabled mass storage
images instead.

Signed-off-by: Alex Chapman <alex.chapman@arm.com>
Signed-off-by: Hugues KAMBA MPIANA <hugues.kambampiana@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-18 15:00:03 -04:00
Alex Chapman 3f14fc635c arm-bsp/tf-a: corstone1000: Fix Cortex-A320 errata override
Fix the Corstone-1000 with Cortex-A320 override for the
Trusted Firmware-A errata list.
The override was misspelled as
`ENABLE_CORTEX_A35_ERRATA:cortexta320` instead of
`ENABLE_CORTEX_A35_ERRATA:cortexa320`.

Rename the list to `ENABLE_CORTEX_A_ERRATA`, since it is shared by
the Cortex-A35 and Cortex-A320 variants.

Signed-off-by: Alex Chapman <alex.chapman@arm.com>
Signed-off-by: Hugues KAMBA MPIANA <hugues.kambampiana@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-18 15:00:03 -04:00
Ross Burton 120782d5fe CI: use kas 5.2
Upgrade to the latest version of Kas.

Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-18 12:00:03 -04:00
Harsimran Singh Tungal 1843e9e2eb arm-bsp: corstone1000: Enable FF-A-backed EFI runtime variables and selftests
This series wires up Arm FF-A support for EFI runtime services by
factoring runtime-safe helpers into the FF-A bus, layer the EFI
variable TEE transport on top, and then rehome the helper exports
so there’s a single implementation shared between boot and
runtime paths. Corstone1000 enables the self-test command and
expands the runtime variable selftest so it exercises non-volatile
storage across reboots.

Key Changes
===========
 - Add the FF-A runtime transport patch stack to the corstone1000
   U-Boot recipe.

 - Enable EFI runtime variable handling over FF-A and include the
   bootefi selftests and sandbox FF-A runtime transport test.

 - Increase the FIP partition sizes from 2MiB to 2.5MiB
   and update TFA_FIP_RE_SIGN_BIN_SIZE from 0x00200000 to 0x00280000
   to reflect the new allocation. The size of u-boot-EFI-2025.10-r0.bin
   has increased from ~707KB to ~944KB following the FF-A/EFI runtime
   related changes. As this binary is packaged within the FIP, the
   overall signed FIP size has grown accordingly.

 - Add a Yocto patch to increase the FIP partition size from
   2MB to 2.5MB in the TF-M flash layout for Corstone-1000.

Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-12 12:00:04 -04:00
David Hu da39013db9 arm/trusted-firmware-m: Enable regression test build
TF-M build system has introduced a ground-breaking change since v2.0.0.
Enable TF-M regression test build, following build instructions in TF-M
document [1].

Add the BUILD_REGRESSION_TESTS variable to enable regression test
builds. Individual regression test suites can be selected by
passing the appropriate TF-M CMake options through EXTRA_OECMAKE.
If regression test is enabled, build TF-M and tests from tf-m-tests
directory.

The build files for Normal World build will be installed.

[1]: https://trustedfirmware-m.readthedocs.io/en/latest/building/tests_build_instruction.html

Signed-off-by: David Hu <david.hu2@arm.com>
Signed-off-by: Gergely Kovacs <Gergely.Kovacs2@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-11 08:00:04 -04:00
Jon Mason 4112fda50b arm-bsp/edk2-firmware: workaround apcica changes
With the latest version of acpica (20260408), the following error is
being encountered in edk2 platforms for Arm SGI

| "iasl"  -p/builder/meta-arm/build/tmp/work/rdn2-poky-linux/edk2-firmware/202602/build/Build/RdN2/DEBUG_GCC5/AARCH64/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables/OUTPUT/./SsdtEvents.aml /builder/meta-arm/build/tmp/work/rdn2-poky-linux/edk2-firmware/202602/build/Build/RdN2/DEBUG_GCC5/AARCH64/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables/OUTPUT/./SsdtEvents.iiii
| /builder/meta-arm/build/tmp/work/rdn2-poky-linux/edk2-firmware/202602/build/Build/RdN2/DEBUG_GCC5/AARCH64/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables/OUTPUT/./SsdtEvents.iiii     61:       Printf ("GPIO0 Pin0 Toggled")
| Error    6010 -                                                                                                                                                                                  Internal compiler error ^  (Invalid parse opcode in OpcGenerateAmlOpcode)

Since this appears to be a debug message, and the relevant platforms are
a work in progress.  Work around this issue by removing the printf.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-05 13:11:15 -04:00
Jon Mason f3a2db0561 arm-bsp/u-boot: Update fvp-base, juno, corstone1000 patches
Fuzz detected when applying patch.  Use devtool to update and clean-up
the relevant patches.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-01 10:00:10 -04:00
Alex Chapman 3aa085566e arm-bsp/docs:corstone1000: Reduce sudo dependency in OOB tests
- Add `wic`` image manipulation requirement, `mtools`, to prerequisites
- switch the `kas` install step to a user-local virtual environment
  removing `sudo` requirement
- Add `wic` install step
- replaced the mount/unmount acs_results and capsule staging steps
  with non-`sudo` wic-based image manipulation.
- Adds guidance for using serial-console without `sudo`
- Standardise capsule transfer to the root of the BOOT partition
- Update docs to align with new non-`sudo` requirement for
  `create_keys_and_sign.sh` interactive script.

These updates remove several unnecessary `sudo`` dependencies when
running OOB CS1K testing.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-01 10:00:03 -04:00
Alex Chapman 85bd24f7b0 arm-bsp/docs:corstone1000: Fix secure boot script path
- Use the correct `${WORKSPACE}` script path without the stray `./` prefix.

This avoids an invalid command path.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-01 10:00:03 -04:00
137 changed files with 6171 additions and 1328 deletions
+25 -12
View File
@@ -1,4 +1,4 @@
image: ${MIRROR_GHCR}/siemens/kas/kas:4.7
image: ${MIRROR_GHCR}/siemens/kas/kas:5.2
variables:
# These are needed as the k8s executor doesn't respect the container
@@ -9,14 +9,16 @@ variables:
CPU_REQUEST: ""
# The default machine tag for the build jobs
DEFAULT_TAG: ""
# The directory to use as the persistent cache (the root for DL_DIR, SSTATE_DIR, etc)
CACHE_DIR: $CI_BUILDS_DIR/persist
# The directory to use as the persistent cache (the root for DL_DIR,
# SSTATE_DIR, etc). The default is the build tree which will not be
# persistent, so this should be set in the runner.
CACHE_DIR: $CI_PROJECT_DIR
# The container mirror to use
MIRROR_GHCR: ghcr.io
# The list of extra Kas fragments to be used when building
EXTRA_KAS_FILES: ""
# The NVD API key to use when fetching CVEs
NVDCVE_API_KEY: ""
# Whether warnings should be fatal (0/1)
FATAL_WARNINGS: 0
stages:
- prep
@@ -61,13 +63,15 @@ stages:
# Catch all for everything else
- if: '$KERNEL != "linux-yocto-dev"'
script:
- KASFILES=$(./ci/jobs-to-kas "$CI_JOB_NAME" $EXTRA_KAS_FILES):lockfile.yml
- echo KASFILES=$KASFILES
- kas dump --update --force-checkout --resolve-refs --resolve-env $KASFILES
- kas build $KASFILES
- ./ci/check-warnings $KAS_BUILD_DIR/warnings.log
- kas shell ci/base.yml:lockfile.yml --command "$CI_PROJECT_DIR/ci/junit.sh $KAS_WORK_DIR/build"
- |
KASFILES=$(./ci/jobs-to-kas "$CI_JOB_NAME" $EXTRA_KAS_FILES):lockfile.yml
echo KASFILES=$KASFILES
kas dump --update --force-checkout --resolve-refs --resolve-env $KASFILES
kas build $KASFILES
if [ $FATAL_WARNINGS -ne 0 ]; then
./ci/check-warnings $KAS_BUILD_DIR/warnings.log
fi
kas shell ci/base.yml:lockfile.yml --command "$CI_PROJECT_DIR/ci/junit.sh $KAS_WORK_DIR/build"
artifacts:
name: "logs"
when: on_failure
@@ -156,6 +160,15 @@ corstone1000-mps3:
- FIRMWARE: none
SECUREDEBUG: [none, secure-debug]
corstone1000-a320-fvp:
extends: .build
parallel:
matrix:
- FIRMWARE: corstone1000-firmware-only
TESTING: [testimage, tftf]
- FIRMWARE: none
TESTING: testimage
documentation:
extends: .setup
script:
@@ -2,8 +2,7 @@
header:
version: 14
includes:
- ci/corstone1000-fvp.yml
local_conf_header:
a320: |
MACHINE_FEATURES += "cortexa320"
OVERRIDES .= ":cortexa320"
machine: corstone1000-a320-fvp
-20
View File
@@ -1,20 +0,0 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/siemens/kas/master/kas/schema-kas.json
header:
version: 14
local_conf_header:
cve: |
INHERIT += "cve-check"
# Allow the runner environment to provide an API key
NVDCVE_API_KEY = "${@d.getVar('BB_ORIGENV').getVar('NVDCVE_API_KEY') or ''}"
# Just show the warnings for our layers
CVE_CHECK_SHOW_WARNINGS = "0"
CVE_CHECK_SHOW_WARNINGS:layer-arm-toolchain = "1"
CVE_CHECK_SHOW_WARNINGS:layer-meta-arm = "1"
CVE_CHECK_SHOW_WARNINGS:layer-meta-arm-bsp = "1"
# Ignore the kernel, we sometime carry kernels in meta-arm
CVE_CHECK_SHOW_WARNINGS:pn-linux-yocto = "0"
+4 -3
View File
@@ -5,6 +5,7 @@ header:
local_conf_header:
latest_revisions: |
PREFERRED_VERSION_trusted-firmware-a ?= "2.10.%"
PREFERRED_VERSION_tf-a-tests ?= "2.10.%"
PREFERRED_VERSION_trusted-firmware-m ?= "2.1.%"
PREFERRED_VERSION_trusted-firmware-a ?= "2.14.%"
PREFERRED_VERSION_tf-a-tests ?= "2.14.%"
PREFERRED_VERSION_trusted-firmware-m ?= "2.2.%"
PREFERRED_VERSION_trusted-firmware-m-scripts-native ?= "2.2.%"
-5
View File
@@ -6,11 +6,6 @@ header:
- ci/base.yml
- ci/meta-openembedded.yml
local_conf_header:
version_for_ci: |
# For better CI coverage, use the LTS version of tf-m
PREFERRED_VERSION_trusted-firmware-m ?= "2.1.%"
machine: musca-b1
target:
+5
View File
@@ -6,6 +6,11 @@ header:
- ci/base.yml
- ci/meta-openembedded.yml
local_conf_header:
version_for_ci: |
# For better CI coverage, use the LTS version of tf-m
PREFERRED_VERSION_trusted-firmware-m ?= "2.2.%"
machine: musca-s1
target:
+1 -3
View File
@@ -5,7 +5,5 @@ header:
local_conf_header:
sstate_mirror: |
BB_HASHSERVE_UPSTREAM = "wss://hashserv.yoctoproject.org/ws"
SSTATE_MIRRORS = "file://.* http://sstate.yoctoproject.org/all/PATH;downloadfilename=PATH"
BB_HASHSERVE = "auto"
BB_SIGNATURE_HANDLER = "OEEquivHash"
OE_FRAGMENTS += "core/yocto/sstate-mirror-cdn"
+22
View File
@@ -0,0 +1,22 @@
header:
version: 14
includes:
- kas/corstone1000-base.yml
- kas/corstone1000-image-configuration.yml
- kas/corstone1000-firmware-only.yml
- kas/fvp-eula.yml
env:
DISPLAY:
WAYLAND_DISPLAY:
XAUTHORITY:
local_conf_header:
testimagefvp: |
IMAGE_CLASSES += "fvpboot"
mass-storage: |
# Ensure the Mass Storage device is absent
FVP_CONFIG[board.msd_mmc.p_mmc_file] = "invalid.dat"
machine: corstone1000-a320-fvp
+13
View File
@@ -0,0 +1,13 @@
header:
version: 14
includes:
- ci/debug.yml
local_conf_header:
sshd: |
IMAGE_FEATURES += "ssh-server-dropbear"
fvp_sshkeys: |
CORE_IMAGE_EXTRA_INSTALL:append = " ssh-pregen-hostkeys"
target:
- core-image-minimal
@@ -0,0 +1,17 @@
#@TYPE: Machine
#@NAME: corstone1000-a320-fvp machine
#@DESCRIPTION: Machine configuration for Corstone1000 64-bit FVP with A320 CPU
require conf/machine/include/corstone1000-a320.inc
require conf/machine/corstone1000-fvp.conf
# Ethos-U85 FVP configuration
ETHOSU_NUM_MACS ?= "256"
FVP_CONFIG[host.ethosu.num_macs] = "${ETHOSU_NUM_MACS}"
# Reuse FVP recipe overrides
MACHINEOVERRIDES .= ":corstone1000-fvp"
# Override FVP executable provider and executable name.
FVP_PROVIDER:corstone1000-a320-fvp ??= "fvp-corstone1000-a320-native"
FVP_EXE:corstone1000-a320-fvp = "FVP_Corstone-1000-A320"
@@ -6,9 +6,6 @@ require conf/machine/include/corstone1000.inc
require ${@bb.utils.contains('MACHINE_FEATURES', 'corstone1000-extsys', \
'conf/machine/include/corstone1000-extsys.inc', '', d)}
require ${@bb.utils.contains('MACHINE_FEATURES', 'cortexa320', \
'conf/machine/include/corstone1000-a320.inc', '', d)}
TFA_TARGET_PLATFORM = "fvp"
TFM_PLATFORM_IS_FVP = "TRUE"
@@ -24,9 +21,7 @@ DEFAULT_TEST_SUITES:append = " fvp_boot fvp_devices"
# FVP Config
FVP_PROVIDER ?= "fvp-corstone1000-native"
FVP_PROVIDER:cortexa320 ?= "fvp-corstone1000-a320-native"
FVP_EXE ?= "FVP_Corstone-1000"
FVP_EXE:cortexa320 = "FVP_Corstone-1000-A320"
FVP_CONSOLES[default] = "host_terminal_0"
FVP_CONSOLES[tf-a] = "host_terminal_1"
FVP_CONSOLES[se] = "secenc_terminal"
@@ -65,7 +60,7 @@ FVP_CONFIG[board.msd_mmc.diagnostics] ?= "0"
FVP_CONFIG[board.msd_mmc.p_max_block_count] ?= "0xFFFF"
FVP_CONFIG[board.msd_config.pl180_fifo_depth] ?= "16"
FVP_CONFIG[board.msd_mmc.support_unpadded_images] ?= "true"
FVP_CONFIG[board.msd_mmc.p_mmc_file] ?= "${IMAGE_NAME}.wic"
FVP_CONFIG[board.msd_mmc.p_mmc_file] ?= "${IMAGE_LINK_NAME}.wic"
# MMC2 card configuration
FVP_CONFIG[board.msd_mmc_2.card_type] ?= "SDHC"
+1 -1
View File
@@ -60,7 +60,7 @@ FVP_CONFIG[cluster0.stage12_tlb_size] ?= "1024"
FVP_CONFIG[cluster1.stage12_tlb_size] ?= "1024"
FVP_CONFIG[bp.secureflashloader.fname] ?= "trusted-firmware-a/bl1.bin"
FVP_CONFIG[bp.flashloader0.fname] ?= "trusted-firmware-a/fip.bin"
FVP_CONFIG[bp.virtioblockdevice.image_path] ?= "${IMAGE_NAME}.wic"
FVP_CONFIG[bp.virtioblockdevice.image_path] ?= "${IMAGE_LINK_NAME}.wic"
# FVP Base default is 8.0, so there is no has_arm_v8-0 for it. However, this is needed for every version after. So set this accordingly
FVP_EXTRA_ARGS = "--parameter cluster0.has_arm_v${ARM_ISA_MAJOR}-${ARM_ISA_MINOR}=1 --parameter cluster1.has_arm_v${ARM_ISA_MAJOR}-${ARM_ISA_MINOR}=1"
@@ -1,3 +1,4 @@
ETHOSU_NUM_MACS ?= "256"
FVP_CONFIG[host.ethosu.num_macs] = "${ETHOSU_NUM_MACS}"
# Cortex-A320 variant of the Corstone-1000 platform.
MACHINEOVERRIDES =. "corstone1000-a320:"
MACHINE_FEATURES += "cortexa320"
OVERRIDES .= ":cortexa320"
@@ -6,6 +6,7 @@ MACHINEOVERRIDES =. "corstone1000:"
# TF-M
PREFERRED_VERSION_trusted-firmware-m ?= "2.2.%"
PREFERRED_VERSION_trusted-firmware-m-scripts-native ?= "2.2.%"
# TF-A
TFA_PLATFORM = "corstone1000"
+6 -1
View File
@@ -49,10 +49,15 @@ FVP_CONFIG[board.dram_size] ?= "0x200000000"
FVP_CONFIG[board.virtio_net.enabled] ?= "1"
FVP_CONFIG[board.virtio_net.hostbridge.userNetworking] ?= "1"
FVP_CONFIG[board.virtio_net.hostbridge.userNetPorts] = "2222=22"
FVP_CONFIG[board.virtioblockdevice.image_path] ?= "${IMAGE_NAME}.wic"
FVP_CONFIG[board.virtioblockdevice.image_path] ?= "${IMAGE_LINK_NAME}.wic"
FVP_CONSOLES[default] = "terminal_ns_uart_ap"
FVP_TERMINALS[css.scp.terminal_uart_scp] ?= "SCP Console"
FVP_TERMINALS[css.mcp.terminal_uart_mcp] ?= "MCP Console"
FVP_TERMINALS[css.terminal_ns_uart_ap] ?= "NS Console"
FVP_TERMINALS[css.terminal_s_uart_ap] ?= "S Console"
# Seeing intermittent test timeout errors in CI where the boot is almost
# complete. Lengthen the timeout to allow for more opportunity to
# complete successfully.
TEST_FVP_LINUX_BOOT_TIMEOUT = "900"
+6 -1
View File
@@ -51,10 +51,15 @@ FVP_CONFIG[board.dram_size] ?= "0x200000000"
FVP_CONFIG[board.virtio_net.enabled] ?= "1"
FVP_CONFIG[board.virtio_net.hostbridge.userNetworking] ?= "1"
FVP_CONFIG[board.virtio_net.hostbridge.userNetPorts] = "2222=22"
FVP_CONFIG[board.virtioblockdevice.image_path] ?= "${IMAGE_NAME}.wic"
FVP_CONFIG[board.virtioblockdevice.image_path] ?= "${IMAGE_LINK_NAME}.wic"
FVP_CONSOLES[default] = "terminal_ns_uart_ap"
FVP_TERMINALS[css.scp.terminal_uart_scp] ?= "SCP Console"
FVP_TERMINALS[css.mcp.terminal_uart_mcp] ?= "MCP Console"
FVP_TERMINALS[css.terminal_ns_uart_ap] ?= "NS Console"
FVP_TERMINALS[css.terminal_s_uart_ap] ?= "S Console"
# Seeing intermittent test timeout errors in CI where the boot is almost
# complete. Lengthen the timeout to allow for more opportunity to
# complete successfully.
TEST_FVP_LINUX_BOOT_TIMEOUT = "900"
+2
View File
@@ -26,6 +26,8 @@ EFI_PROVIDER ?= "${@bb.utils.contains("DISTRO_FEATURES", "systemd", "systemd-boo
SERIAL_CONSOLES ?= "115200;ttyAMA0 115200;hvc0"
EXTRA_IMAGEDEPENDS += "edk2-firmware"
#FIXME - in 2.15.0, new logic for pen hold the SMP cores was added, which breaks this platform. Hold this back until it can be resolved.
PREFERRED_VERSION_trusted-firmware-a ?= "2.14.%"
QB_SYSTEM_NAME = "qemu-system-aarch64"
QB_MACHINE = "-machine sbsa-ref"
@@ -0,0 +1,12 @@
version: 2
build:
os: "ubuntu-22.04"
tools:
python: "3.9"
sphinx:
configuration: meta-arm-bsp/documentation/corstone1000-a320/conf.py
formats:
- pdf
python:
install:
- requirements: meta-arm-bsp/documentation/requirements.txt
@@ -0,0 +1,117 @@
# SPDX-FileCopyrightText: <text>Copyright 2026 Arm Limited and/or its
# affiliates <open-source-office@arm.com></text>
#
# SPDX-License-Identifier: MIT
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# sys.path.insert(0, os.path.abspath('.'))
import os
import re
import sys
import yaml
# Append the documentation directory to the path, so we can import variables
sys.path.append(os.path.dirname(__file__))
_metadata_path = os.path.join(os.path.dirname(__file__), 'corstone-a320_metadata.yaml')
with open(_metadata_path, encoding='utf-8') as metadata_file:
_metadata = yaml.safe_load(metadata_file) or {}
_metadata_variables = {
item['name']: item['value']
for item in _metadata.get('variables', [])
if item.get('name') and item.get('value')
}
# -- Project information -----------------------------------------------------
project = 'Corstone-1000 Armv9-A Edge-AI'
copyright = '2026, Arm Limited'
author = 'Arm Limited'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'myst_parser',
'sphinx_rtd_theme',
]
source_suffix = {
'.rst': 'restructuredtext',
'.md': 'markdown',
}
myst_enable_extensions = [
'colon_fence',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = [
'_build',
'Thumbs.db',
'.DS_Store',
'docs/infra',
'corstone-a320_map.md',
'corstone-a320_metadata.yaml',
]
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
html_theme_options = {
'flyout_display': 'attached',
}
# Define the canonical URL if you are using a custom domain on Read the Docs
html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "")
# Tell Jinja2 templates the build is running on Read the Docs
if os.environ.get("READTHEDOCS", "") == "True":
if "html_context" not in globals():
html_context = {}
html_context["READTHEDOCS"] = True
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static']
def _replace_metadata_variables(app, docname, source):
source[0] = re.sub(
r'\$([A-Za-z0-9_]+)',
lambda match: _metadata_variables.get(match.group(1), match.group(0)),
source[0],
)
def setup(app):
app.connect('source-read', _replace_metadata_variables)
@@ -0,0 +1,6 @@
- topics/introducing.md
- topics/software-architecture.md
- topics/user-guide.md
- topics/tests.md
- topics/release-notes.md
- topics/change-log.md
@@ -0,0 +1,106 @@
---
title: Corstone-1000 with Cortex-A320
subtitle: ""
abstract: Arm Corstone-1000 with Cortex-A320 is a reference solution for IoT devices. It is part of Total Solution for IoT which consists of hardware and software reference implementation.
author: Arm
status: REL
keywords: [IoT, software]
bookpartno: 112000
product: Corstone-1000 with Cortex-A320
product_type: Open Source Projects
product_revision:
- prefix: Version
version: "0101"
version_label: "2026.02"
output_type: "software"
conformance_notice: "true"
content_type: User Guide
audience:
- Software Developers
categories:
- IoT
themes:
- IoT
intended_audience: Software Developers
terminology_review: new
releases:
- revision: 0100-01
date: 2026-05-01
change_summary: Update
permissions: nonconfidential
variables:
- name: arm_developer_cs1000_website
value: 'https://developer.arm.com/Tools%20and%20Software/Corstone-1000%20Software'
- name: arm_developer_cs1000_search
value: 'https://developer.arm.com/search#q=corstone-1000'
- name: arm_developer_mhu_website
value: 'https://developer.arm.com/documentation/ka005129/latest/#:~:text=An%20MHU%20is%20a%20device,that%20a%20message%20is%20available'
- name: arm_developer_secureboot_website
value: 'https://developer.arm.com/documentation/PRD29-GENC-009492/c/TrustZone-Software-Architecture/Booting-a-secure-system/Secure-boot'
- name: arm_architecture_security_features_platform_security
value: 'https://www.arm.com/architecture/security-features/platform-security'
- name: linux_repository
value: 'https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/'
- name: arm_trustzone_for_cortex_a_website
value: 'https://www.arm.com/technologies/trustzone-for-cortex-a'
- name: arm_fmw_framework_a_profile_pdf
value: 'https://developer.arm.com/documentation/den0077/latest'
- name: arm_fmw_framework_m_profile_pdf
value: 'https://developer.arm.com/architectures/Firmware%20Framework%20for%20M-Profile'
- name: platform_security_fwu_for_a_profile_pdf
value: 'https://developer.arm.com/documentation/den0118/a/'
- name: psa_firmware_update_ihi_0093_api_reference_website
value: 'https://arm-software.github.io/psa-api/fwu/1.0/api/api.html'
- name: edk2_capsule_generation_tool_repository
value: 'https://github.com/tianocore/edk2/blob/master/BaseTools/Source/Python/Capsule/GenerateCapsule.py'
- name: psa_fwu_den0018_specification_website
value: 'https://developer.arm.com/documentation/den0118/latest/'
- name: ts_psa_fwu_service_website
value: 'https://trusted-services.readthedocs.io/en/stable/services/fwu/psa-fwu-m.html'
- name: tfm_shim_layer_website
value: 'https://trustedfirmware-m.readthedocs.io/en/latest/design_docs/services/tfm_fwu_service.html#shim-layer-between-fwu-and-bootloader'
- name: op_tee_os_repository
value: 'https://github.com/OP-TEE/optee_os'
- name: psa_certified_website
value: 'https://www.psacertified.org/'
- name: psa_l2_ready
value: 'https://www.psacertified.org/products/corstone-1000/'
- name: systemready_ir_certification
value: 'https://armkeil.blob.core.windows.net/developer/Files/pdf/certificate-list/arm-systemready-ve-arm-neoverse.pdf'
- name: trusted_board_boot_requirements_client_pdf
value: 'https://developer.arm.com/documentation/den0006/latest'
- name: trusted_firmware_m_website
value: 'https://www.trustedfirmware.org/projects/tf-m/'
- name: trusted_firmware_m_bl1_website
value: 'https://trustedfirmware-m.readthedocs.io/en/latest/design_docs/booting/bl1.html'
- name: trusted_firmware_a_bl2_website
value: 'https://developer.arm.com/documentation/108028/0000/RD-TC22-software/Software-components/AP-firmware/Trusted-firmware-A-BL2'
- name: trusted_firmware_a_fip_guide
value: 'https://trustedfirmware-a.readthedocs.io/en/latest/design/firmware-design.html#firmware-image-package-fip'
- name: trusted_services_website
value: 'https://www.trustedfirmware.org/projects/trusted-services/'
- name: trusted_services_uefi_smm_website
value: 'https://trusted-services.readthedocs.io/en/integration/services/uefi-smm-services.html#'
- name: das_u_boot_repository
value: 'https://github.com/u-boot/u-boot.git'
- name: keil_rtx5_website
value: 'https://developer.arm.com/Tools%20and%20Software/Keil%20MDK/RTX5%20RTOS'
- name: ppa_website
value: 'https://developer.arm.com/documentation/102738/0100/Power--performance--and-area-analysis'
- name: mcuboot_website
value: 'https://docs.mcuboot.com/'
- name: arm_developer_fvp
value: 'https://developer.arm.com/tools-and-software/open-source-software/arm-platforms-software/arm-ecosystem-fvps'
- name: secure_debug_manager_repo_readme
value: 'https://github.com/ARM-software/secure-debug-manager/tree/master?tab=readme-ov-file#secure-debug-manager-psa-adac--sdc-600'
- name: secure_debug_manager_armds_integration
value: 'https://github.com/ARM-software/secure-debug-manager?tab=readme-ov-file#arm-development-studio-integration'
- name: meta_arm_repository_release_branch
value: 'https://docs.yoctoproject.org/next/migration-guides/migration-6.0.html'
- name: arm_ulink_pro_website
value: 'https://www.arm.com/products/development-tools/debug-probes/ulink-pro'
- name: arm_ds_website
value: 'https://www.arm.com/products/development-tools/embedded-and-software/arm-development-studio'
- name: edk2_repository
value: 'https://github.com/tianocore/edk2'
Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

@@ -0,0 +1,12 @@
# Corstone-1000 Armv9-A Edge-AI
```{toctree}
:maxdepth: 2
topics/introducing
topics/software-architecture
topics/user-guide
topics/tests
topics/release-notes
topics/change-log
```
@@ -0,0 +1,150 @@
# Change log {.chapter permissions=non-confidential}
This document contains a summary of the new features, changes and fixes in each release of the Corstone-1000 with Cortex-A320 software stack.
## Version 2026.05 {.reference}
The following changes are present in this release:
- Continued Corstone-1000 with Cortex-A320 enablement across U-Boot, TF-A, TF-M, OP-TEE, and Linux with the split A320 device tree, GIC-700 support, Ethos-U85 DT alignment, and NPU reset via the external-system controller.
- Enabled and documented FVP SMP builds and platform-agnostic multicore support, including the errata override fixes for Corstone-1000 with Cortex-A320 and removal of the reboot workaround note.
- Split Corstone-1000 with Cortex-A320 FVP support into a dedicated machine configuration and standalone documentation.
### Corstone-1000 with Cortex-A320 components versions {.reference}
The following component versions are available:
Table: Corstone-1000 with Cortex-A320 component versions
+----------------------------------------+-----------------------------------+
| Component | Version |
+========================================+===================================+
| linux-yocto | 6.19 |
+----------------------------------------+-----------------------------------+
| u-boot | 2025.10 |
+----------------------------------------+-----------------------------------+
| external-system | 0.1.0 |
+----------------------------------------+-----------------------------------+
| optee-client | 4.9.0 |
+----------------------------------------+-----------------------------------+
| optee-os | 4.9.0 |
+----------------------------------------+-----------------------------------+
| trusted-firmware-a | 2.14.1 |
+----------------------------------------+-----------------------------------+
| trusted-firmware-m | 2.2.2 |
+----------------------------------------+-----------------------------------+
| libts | v1.3.0 |
+----------------------------------------+-----------------------------------+
| ts-sp-{se-proxy, smm-gateway} | v1.3.0 |
+----------------------------------------+-----------------------------------+
| ts-psa-{crypto, iat, its. ps}-api-test | 74dc6646ff |
+----------------------------------------+-----------------------------------+
### Yocto distribution components versions {.reference}
The following Yocto distribution components versions are available:
Table: Yocto distribution component versions
+-------------------+------------+
| Component | Version |
+===================+============+
| meta-arm | wrynose |
+-------------------+------------+
| bitbake | 22021758e6 |
+-------------------+------------+
| meta-openembedded | 9af4488d46 |
+-------------------+------------+
| openembedded-core | 06dd66e622 |
+-------------------+------------+
| meta-yocto | 8251bdad5f |
+-------------------+------------+
| meta-secure-core | 07a99ae241 |
+-------------------+------------+
| busybox | 1.37.0 |
+-------------------+------------+
| musl | 1.2.6 |
+-------------------+------------+
| gcc-arm-none-eabi | 15.2.rel1 |
+-------------------+------------+
| gcc-cross-aarch64 | 15.2.0 |
+-------------------+------------+
| openssl | 3.5.6 |
+-------------------+------------+
## Version 2025.12 {.reference}
The following changes are present in this release:
- Delivered end-to-end Cortex-A320 enablement across U-Boot, TF-A, TF-M, OP-TEE, Yocto machine layers, and documentation, including device-tree updates, MPIDR handling, and FVP model renaming.
- Rolled out the PSA Firmware Update (DEN0118) pipeline: U-Boot capsule parsing, Bootloader Abstraction Layer in TF-M, ESRT exposure, and Trusted Services IPC bridges replacing legacy capsule code.
- Hardened the new firmware update flow with EFI self-tests, metadata restructuring for partial and multi-image acceptance, and RSE-COMMS gating refinements.
- Upgraded key firmware components (TF-A 2.13.0, TF-M 2.2.1, Trusted Services 1.2.0, OP-TEE OS 4.7.0) and introduced targeted test skips plus integer-only build modes to keep validation green.
- Cleaned and renumbered downstream patch series across Trusted Services and TF-M while removing obsolete integrations to align with upstream baselines.
- Refreshed release material and architecture guides to describe the A320 profile, PSA FWU behavior, and updated software stack.
- Added KAS profiles, machine includes, and automated FVP selection logic to streamline developer workflows for the refreshed platform configuration.
### Corstone-1000 with Cortex-A320 components versions {.reference}
The following component versions are available:
Table: Corstone-1000 with Cortex-A320 component versions
+----------------------------------------+-----------------------------------+
| Component | Version |
+========================================+===================================+
| linux-yocto | 6.12.60 |
+----------------------------------------+-----------------------------------+
| u-boot | 2025.04 |
+----------------------------------------+-----------------------------------+
| optee-client | 4.7.0 |
+----------------------------------------+-----------------------------------+
| optee-os | 4.7.0 |
+----------------------------------------+-----------------------------------+
| trusted-firmware-a | 2.13.0 |
+----------------------------------------+-----------------------------------+
| trusted-firmware-m | 2.2.1 |
+----------------------------------------+-----------------------------------+
| libts | v1.2.0 |
+----------------------------------------+-----------------------------------+
| ts-sp-{se-proxy, smm-gateway} | v1.2.0 |
+----------------------------------------+-----------------------------------+
| ts-psa-{crypto, iat, its. ps}-api-test | 74dc6646ff |
+----------------------------------------+-----------------------------------+
### Yocto distribution components versions {.reference}
The following Yocto distribution components versions are available:
Table: Yocto distribution component versions
+-------------------+------------+
| Component | Version |
+===================+============+
| meta-arm | whinlatter |
+-------------------+------------+
| bitbake | 0dde1a3ff8 |
+-------------------+------------+
| meta-openembedded | fc0152e434 |
+-------------------+------------+
| openembedded-core | 4bd920ad7d |
+-------------------+------------+
| meta-yocto | b3b6592635 |
+-------------------+------------+
| meta-secure-core | 63209fb150 |
+-------------------+------------+
| meta-ethos | aa2504a32f |
+-------------------+------------+
| meta-sca | e68f1a9d17 |
+-------------------+------------+
| busybox | 1.37.0 |
+-------------------+------------+
| musl | 1.2.5 |
+-------------------+------------+
| gcc-arm-none-eabi | 13.3.rel1 |
+-------------------+------------+
| gcc-cross-aarch64 | 15.2.0 |
+-------------------+------------+
| openssl | 3.5.4 |
+-------------------+------------+
@@ -0,0 +1,14 @@
# Introduction {.chapter permissions=non-confidential}
Arm Corstone-1000 with Cortex-A320 is a reference solution for IoT devices
based on Arm Corstone-1000, but with Cortex-A320 CPU, Ethos-U85 NPU and
GIC700 (Generic Interrupt Controller). It is part of Total Solution
for IoT which consists of hardware and software reference implementations.
## Disclaimer {.reference}
Arm reference solutions are Arm public example software projects that track and
pull upstream components, incorporating their respective security fixes
published over time. Arm partners are responsible for ensuring that the
components they use contain all the required security fixes, if and when they
deploy a product derived from Arm reference solutions.
@@ -0,0 +1,40 @@
# Release notes {.chapter permissions=non-confidential}
You expressly assume all liabilities and risks relating to your use or operation
of your software and hardware designed or modified using the Arm Tools,
including without limitation, your software or hardware designed or
intended for safety-critical applications. Should your software or hardware
prove defective, you assume the entire cost of all necessary servicing, repair
or correction.
## Release notes - 2026.05 {.reference}
The following knowns issues and limitations are present in this release:
- Crypto isolation is not supported in the Secure world of Corstone-1000. Additionally, clients in
the Normal world are not isolated from one another. Therefore, if an end user wants to add a new
Secure Partition (SP) (such as a software TPM) that accesses the Crypto service via the SE-Proxy,
they are responsible for implementing their own isolation mechanisms to ensure proper security boundaries.
- DSTREAM debug probe may experience unreliable USB connectivity when used with Arm DS for secure debug.
This issue is under active investigation, and we are working to identify and resolve compatibility issues in a future update.
As a more stable alternative, the ULINKpro debug probe is recommended for use with Corstone-1000 in secure debug scenarios.
## Release notes - 2025.12 {.reference}
The following knowns issues and limitations are present in this release:
- Corstone-1000 with Cortex-A320 FVP does not currently support Symmetric Multiprocessing
- Corstone-1000 with Cortex-A320 FVP becomes unresponsive when the Linux kernel driver for the Ethos-U85 NPU loads automatically after a software reboot.
- Crypto isolation is not supported in the Secure world of Corstone-1000. Additionally, clients in
the Normal world are not isolated from one another. Therefore, if an end user wants to add a new
Secure Partition (SP) (such as a software TPM) that accesses the Crypto service via the SE-Proxy,
they are responsible for implementing their own isolation mechanisms to ensure proper security boundaries.
- DSTREAM debug probe may experience unreliable USB connectivity when used with Arm DS for secure debug.
This issue is under active investigation, and we are working to identify and resolve compatibility issues in a future update.
As a more stable alternative, the ULINKpro debug probe is recommended for use with Corstone-1000 in secure debug scenarios.
## Support {.reference}
For technical support, email [Arm subsystem support](mailto:support-subsystem-iot@arm.com).
For security issues, contact [Arm Security](mailto:psirt@arm.com).
@@ -0,0 +1,311 @@
# Software architecture {.chapter permissions=non-confidential}
The combination of Corstone-1000 software and hardware reference solution is [PSA Level-2 ready certified]($psa_l2_ready) as well as [Arm SystemReady Devicetree certified]($systemready_ir_certification). Please rely on the Corstone-1000 platform for certification needs.
More information on the Corstone-1000 subsystems product(s), variants and design can be
found on [Arm Developer]($arm_developer_cs1000_website).
This document explicitly focuses on the software part of the solution and
provides internal details on the software components. The reference
software package of the platform can be retrieved following instructions
present in the user guide document.
## Design overview {.reference}
This variant of the Corstone-1000 platform replaces the Host System's Cortex-A35
processor with a Cortex-A320. In this configuration, the optional External System
(previously a Cortex-M3) is replaced by an Arm Ethos-U85 Neural Processing Unit (NPU).
The Ethos-U85 runs in the direct drive configuration, where the Host System is
responsible for managing the NPU directly.
![Cortex-A320 subsystems](../images/CorstoneA320Subsystems.png)
## Secure boot chain {.reference}
For the security of a device, it is essential that only authorized
software should run on the device.
The Corstone-1000 boot uses a [Secure boot]($arm_developer_secureboot_website) chain process
where an already authenticated image verifies and loads the following software in the chain.
For the boot chain process to work, the start of the chain should be trusted, forming the
Root of Trust (RoT) of the device. The RoT of the device is immutable in
nature and encoded into the device by the device manufacturer before it
is deployed into the field.
In Corstone-1000, the content of the ROM and CC312 One Time Programmable (OTP) memory forms the RoT.
Verification of an image can happen either by comparing the computed and stored hashes, or by
checking the signature of the image if the image is signed.
![Secure boot chain](../images/SecureBootChain.png)
It is a lengthy chain to boot the software on Corstone-1000.
### TF-M BL1\_1 {.reference}
On power-up, the Secure Enclave begins execution from TF-M BL1\_1, which resides in ROM and serves as
the Root of Trust (RoT) for the device.
TF-M BL1\_1 is the immutable bootloader and is responsible for:
- Provisioning the device during the first boot
- Performing hardware initialization
- Verifying the integrity and authenticity of the next stage in the boot chain
At boot time, TF-M BL1\_1:
- Copies the TF-M BL1\_2 image from OTP to RAM.
- Verifies the integrity of BL1\_2 by comparing its computed hash with the hash stored in OTP.
### TF-M BL1\_2 {.reference}
During provisioning, the TF-M BL1\_2 binary, along with its hashes and cryptographic keys, is stored
in One-Time Programmable (OTP) memory.
Once verified, TF-M BL1\_2:
- Takes control and verifies the next stage in the boot chain, which is TF-M BL2.
- Computes the hash of the BL2 image and compares it with the BL2 hash stored in OTP to ensure
integrity before transferring execution to BL2.
The TF-M BL1 design details can be found in the [TF-M design documents]($trusted_firmware_m_bl1_website).
:::note
Corstone-1000 has some differences compared to this design due to memory (OTP/ROM) limitations:
- BL1\_1 code size is larger than needed because it handles most of the hardware initialization instead of the BL1\_2.
- BL1\_2 cannot be updated during provisioning time because the provisioning bundle that contains its code is located in the ROM.
- BL1\_2 does not use the post-quantum LMS verification.
- BL2 cannot be updated because it is verified by comparing the computed hash to the hash stored in the OTP.
:::
### TF-M BL2 {.reference}
In this system, TF-M BL2 refers to MCUBoot.
On the first boot, MCUBoot can provision additional cryptographic keys. It is responsible for authenticating both:
- TF-M (Trusted Firmware-M), and
- The initial bootloader of the Host system, [Trusted Firmware-A (TF-A) BL2]($trusted_firmware_a_bl2_website)
This authentication is done by verifying the digital signatures of the respective images.
MCUBoot performs image verification in the following steps:
1. Load the image from non-volatile memory into RAM.
2. Validate the image's signature using the corresponding public key.
:::note
The public key present in the image header is validated by comparing with the hash. Depending on the image, the hash of the public key is either stored in the OTP or part of the software which is being already verified in the previous stages.
:::
The execution control is passed to TF-M after the verification.
As the runtime executable of the Secure Enclave, TF-M initializes itself before
bringing the Host system out of reset.
### Host system authentication {.reference}
The Host system follows the boot standard defined in [Trusted Board Boot Requirements Client]($trusted_board_boot_requirements_client_pdf)
to authenticate the Secure and Non-secure software.
The [Firmware Image Package (FIP)]($trusted_firmware_a_fip_guide) packs bootloader images and
other payloads into a single archive.
![FIPDiagram](../images/FIPDiagram.png)
The FIP for Corstone-1000 contains:
- Trusted firmware-A BL2
- AP EL3 Runtime firmware, BL31 image
- AP Secure Payload, BL32 image
- AP Normal world firmware -U-boot, BL33 image
- Trusted OS Firmware configuration file used by Trusted OS (BL32), TOS_FW_CONFIG
- Key certificates
- Content certificates
To load and validate TF-A BL2, TF-M BL2 first parses the GUID Partition Table (GPT)
to locate the FIP. It then determines the offset of TF-A BL2 within the FIP.
:::note
TF-M does not check the FIP signature, it only checks the TF-A BL2's signature in the FIP.
:::
The implicitly trusted components are:
- A SHA-256 hash of the Root of Trust Public Key (ROTPK.) For development purposes, a development ROTPK is used and its hash embedded into the TF-A BL2 image. This public key is provided by the TF-A source code.
- TF-A BL2 image - it can be trusted because it has been verified by TF-M BL2 before starting TF-A.
The remaining components in the Chain of Trust (CoT) are either certificates or bootloader images.
#### Bootloader authentication {.reference}
The FIP contains two types of certificates:
- Content Certificates used to store the hash of a bootloader image.
- Key Certificates used to verify public keys used to sign Content Certificates.
The Host system bootloader images are authenticated by computing their hash and comparing it to the corresponding hash found in the Content Certificate.
#### Certificates verification {.reference}
The public keys defined in the Trusted Key Certificate are used to verify the later certificates in
the CoT process. The Trusted Key Certificate is verified with the Root of Trust Public Key.
#### UEFI authenticated variables {.reference}
For UEFI Secure Boot, authenticated variables can be accessed from the secure flash.
The feature has been integrated in U-Boot, which authenticates the images as per the UEFI
specification before executing them.
## Secure services {.reference}
Corstone-1000 is unique in offering a secure environment for running trusted workloads.
While the Host system includes TrustZone technology, the platform also features a hardware-isolated
Secure Enclave, specifically designed to execute these secure workloads.
In Corstone-1000, essential Secure Services—such as Cryptography, Protected Storage,
Internal Trusted Storage, and Attestation—are provided through PSA Functional APIs implemented in TF-M.
From the user's perspective, there is no difference when communicating with these services,
whether they run in the Secure Enclave or in the Secure world of the Host system.
The diagram below illustrates the data flow for such calls.
![Secure services](../images/SecureServices.png)
The Secure Enclave Proxy Secure Partition (SE Proxy SP) is a proxy managed by OP-TEE that forwards
Secure Service calls to the Secure Enclave. This communication uses the
[RSE communication protocol](https://tf-m-user-guide.trustedfirmware.org/platform/arm/rse/rse_comms.html).
While the protocol supports shared memory and MHU interrupts as a doorbell mechanism between cores,
in Corstone-1000, the entire message is currently transmitted through the MHU channels.
Corstone-1000 implements Isolation Level 2 using the Cortex-M0+ Memory Protection Unit (MPU).
Users can define their own secure services to run either in the Host system's Secure World or in
the Secure Enclave. This choice involves a trade-off between latency and security.
Services running in the Secure Enclave benefit from strong, hardware-enforced isolation,
offering higher security but at the cost of increased latency. In contrast, services running in the
Host Secure World experience lower latency, but rely on TrustZone technology for virtualized isolation,
which offers comparatively less robust security.
## PSA secure firmware update {.reference}
The Corstone-1000 platform necessitates a robust, secure, and flexible firmware update mechanism
including partial capsule update to ensure fielded devices can receive critical patches, feature enhancements,
and security fixes without compromising system integrity. To meet these requirements, we have implemented the
Platform Security Architecture (PSA) Firmware Update (FWU) framework on Corstone-1000, leveraging Trusted Firmware-M (TF-M)
for the Secure Enclave, U-Boot as the host-side client on Cortex-A, and the UEFI capsule update mechanism for payload
encapsulation. This design supports the Fixed Virtual Platform (FVP) target, providing consistent behavior across
simulation-based deployments. The Corstone-1000 supports FWU
which complies with the
[Platform Security Firmware Update for the A-profile Arm Architecture]($platform_security_fwu_for_a_profile_pdf)
and [PSA Firmware Update IHI 0093]($psa_firmware_update_ihi_0093_api_reference_website)
specifications.
To standardize and streamline capsule creation with multiple FMP payloads, the
[EDK2 capsule generation tool]($edk2_capsule_generation_tool_repository)
tool has been integrated into the meta-arm Yocto layer for Corstone-1000. This integration involves defining
build rules for generating UEFI capsules as part of the firmware image build process. Configuration parameters
exposed in the recipe allow developers to specify the number of FMP payloads, target image GUIDs, version numbers etc.
This capsule ensures that all update payloads conform to the UEFI FMP specification and are ready for
validation and delivery by UBoot.
The FWU solution for Corstone-1000 is composed of three primary domains:
- Host System
- Trusted Services intermediary
- Secure Enclave
Each domain has distinct responsibilities and communicates through standardized interfaces.
![System architecture PSA firmware update](../images/SystemArchitecturePSAFirmwareUpdate.png)
On the host side, U-Boot functions as the FWU client and orchestrates the update process from capsule retrieval to
payload delivery based on [PSA FWU DEN0018 specification]($psa_fwu_den0018_specification_website)
via Arm FF-A framework. The Trusted-Services SE Proxy secure partition serves as a gateway between the non-secure host
environment and the Secure Enclave. The [PSA FWU service]($ts_psa_fwu_service_website) running in the Trusted Services
implementation forwards the data to the Secure Enclave via MHU-based PSA calls. Within the Secure Enclave, the PSA FWU
Agent, conforming to [PSA Firmware Update IHI 0093]($psa_firmware_update_ihi_0093_api_reference_website) specification,
orchestrates the actual flash programming, metadata management, and rollback protection mechanisms. The agent relies on a
bespoke [shim layer]($tfm_shim_layer_website) to abstract hardwarespecific flash operations and bootloader interactions.
As defined in the specification, the external flash is divided into two banks: one bank holds the
currently running images, while the other is used to stage new images.
There are four updatable components: **BL2**, **TF-M**, **the FIP** and **the Kernel Image** (the initramfs bundle).
New images are delivered and accepted in the form of UEFI capsules.
![External flash](../images/ExternalFlash.png)
When a FWU is initiated on Corstone-1000, the following sequence of operations takes place:
1. Capsule Retrieval and Preparation
U-Boot on the host system retrieves the firmware capsule.
It validates the capsule header and parses the FMP (Firmware Management Protocol) descriptor list to identify the payloads to be updated.
For each FMP descriptor, U-Boot:
Splits the firmware payload into 4 KiB chunks.
Invokes the PSA_FWU_Update API for each chunk, transmitting the buffer address via the FF-A (Firmware Framework for Arm) shared memory interface.
2. Secure Transmission and Forwarding
The PSA Firmware Update (FWU) service, running as part of Trusted Services, receives the chunks through Secure Partition Client (SPC) calls.
It forwards these chunks to the Secure Enclave using MHU-based PSA calls.
3. Flashing Within the Secure Enclave
Inside the Secure Enclave, the PSA FWU Agent dispatches each chunk to the shim layer.
The shim layer:
Erases the corresponding sectors in the non-active flash bank.
Writes the received firmware chunks at the correct offsets.
During partial updates, it also copies static partitions from the active bank to the non-active one to maintain consistency.
4. Finalization and Boot Preparation
After all chunks are successfully written:
The shim updates the firmware manifest and the EFI System Resource Table (ESRT) entries to reflect the new image version.
This step enables the bootloader to recognize the new firmware for a trial boot.
The platform then performs an automatic reset, booting into the non-active bank in trial mode.
5. Trial Boot and Confirmation
In trial mode, U-Boot evaluates the new firmware and issues either an accept or reject command using the PSA FWU ABI.
These commands are sent to the Secure Enclave, instructing the shim to update the firmware metadata accordingly.
6. Recovery and Fallback Mechanism
If the trial boot is successful, the host sends an acknowledgment, transitioning the firmware state from 'trial' to 'regular'.
If the system fails or becomes unresponsive:
A watchdog timer triggers a system reset.
The BL1 firmware in the Secure Enclave detects repeated failures and reverts to the previously known-good flash bank.
This rollback mechanism ensures the device remains operational and recoverable, even after a failed update.
![Secure firmware update](../images/SecureFirmwareUpdate.png)
## UEFI runtime support in U-Boot {.reference}
The implementation of UEFI boot-time and runtime APIs requires persistent variable storage. In
Corstone-1000, UEFI variables are stored using the Protected Storage (PS) service.
The diagram below illustrates the data flow for storing UEFI variables. U-Boot's UEFI subsystem
communicates with the Secure World using the U-Boot FF-A driver, which interfaces with the
[UEFI System Management Mode (SMM) service]($trusted_services_uefi_smm_website).
The SMM service provides support for the UEFI System Management Mode. This support is implemented by the SMM Gateway secure partition.
The SMM service then uses the Proxy Protected Storage (PS) provided by the SE Proxy SP.
These PS calls are forwarded to the Secure Enclave, following the communication path described earlier.
![UEFI runtime support flow](../images/UEFISupport.png)
## References {.reference}
For more information, see:
- [Arm Developer]($arm_developer_cs1000_search)
- [Arm Security Architectures]($arm_architecture_security_features_platform_security)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,265 @@
# Build, flash and run {.chapter permissions=non-confidential}
The Arm Corstone-1000 with Cortex-A320 software stack uses the Yocto Project to build a tiny Linux distribution suitable for the Arm Corstone-1000 with Cortex-A320 platform (kernel and initramfs filesystem less than 6 MB on the flash).
The Corstone-1000 with Cortex-A320 software stack can be run on [Arm Corstone-1000 with Cortex-A320 FVP (Fixed Virtual Platform)](https://developer.arm.com/downloads/-/arm-ecosystem-fvps) and is built on top of Yocto Project's [Wrynose release]($meta_arm_repository_release_branch).
The Yocto Project relies on the [BitBake](https://docs.yoctoproject.org/bitbake.html#bitbake-documentation) tool as its build tool. Please see the [Yocto Project documentation](https://docs.yoctoproject.org/) for more information.
## Prerequisites {.reference}
This guide assumes that your host machine is running Ubuntu 24.04 LTS (with `sudo` rights), with at least
32GB of free disk space and 16GB of RAM as minimum requirement.
The following prerequisites must be available on the host system:
- Git 2.39.2 or greater.
- Python 3.11.2 or greater.
- GNU Tar 1.34 or greater.
- GNU Compiler Collection 12.2 or greater.
- GNU Make 4.3 or greater.
- tmux 3.3 or greater.
Please follow the steps described in the Yocto mega manual:
- [Compatible Linux Distribution](https://docs.yoctoproject.org/singleindex.html#compatible-linux-distribution)
- [Build Host Packages](https://docs.yoctoproject.org/singleindex.html#build-host-packages)
## Software components {.reference}
Within the Yocto Project, each component included in the Corstone-1000 with Cortex-A320 software stack is specified as
a [BitBake recipe](https://docs.yoctoproject.org/bitbake/2.2/bitbake-user-manual/bitbake-user-manual-intro.html#recipes).
The recipes specific to the Corstone-1000 with Cortex-A320 BSP are located at:
`${WORKSPACE}/meta-arm/meta-arm-bsp/`.
`${WORKSPACE}` refers to the absolute path to your workspace where the `meta-arm` repository will be cloned. Consider exporting it (e.g., `export WORKSPACE=$(realpath .)`) if you're already in the workspace directory,
so you can copy and paste the commands from this guide verbatim.
The Yocto machine config files are at:
- `${WORKSPACE}/meta-arm/meta-arm-bsp/conf/machine/include/corstone1000-a320.inc`
- `${WORKSPACE}/meta-arm/meta-arm-bsp/conf/machine/corstone1000-a320-fvp.conf`
:::note
All the paths stated in this document are absolute paths.
:::
### Host processor components {.reference}
This section describes the components used in the host processor.
#### Trusted Firmware-A {.reference}
The following [Trusted Firmware-A](https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git) components are used:
Table: Trusted Firmware-A components
| Type | Path |
| --------- | ---------------------------------------------------------------------------------------------------------------- |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a_%.bbappend` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-bsp/trusted-firmware-a/trusted-firmware-a_2.14.1.bb` |
#### Trusted Services {.reference}
The following [Trusted Services](https://trusted-services.readthedocs.io/en/latest/index.html) components are used:
Table: Trusted Services components
| Type | Path |
| --------- | ---------------------------------------------------------------------------------------------------------------- |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-security/trusted-services/libts_%.bbappend` |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-psa-crypto-api-test_%.bbappend` |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-psa-iat-api-test_%.bbappend` |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-psa-its-api-test_%.bbappend` |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-psa-ps-api-test_%.bbappend` |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-sp-se-proxy_%.bbappend` |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-security/trusted-services/ts-sp-smm-gateway_%.bbappend` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-security/trusted-services/libts_git.bb` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-security/trusted-services/ts-psa-crypto-api-test_git.bb` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-security/trusted-services/ts-psa-iat-api-test_git.bb` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-security/trusted-services/ts-psa-its-api-test_git.bb` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-security/trusted-services/ts-psa-ps-api-test_git.bb` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-security/trusted-services/ts-sp-smm-gateway_git.bb` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-security/trusted-services/ts-sp-se-proxy_git.bb` |
#### OP-TEE {.reference}
The following [OP-TEE](https://git.trustedfirmware.org/OP-TEE/optee_os.git) components are used:
Table: OP-TEE components
| Type | Path |
| --------- | ---------------------------------------------------------------------------------------------------------------- |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_%.bbappend` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-security/optee/optee-os_4.9.0.bb` |
#### U-Boot {.reference}
The following [U-Boot](https://github.com/u-boot/u-boot.git) components are used:
Table: U-Boot components
| Type | Path |
| --------- | ---------------------------------------------------------------------------------------------------------------- |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm/recipes-bsp/u-boot/u-boot_%.bbappend` |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot_%.bbappend` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot_2025.10.bb` |
#### Linux {.reference}
The distribution is based on the [Poky](https://docs.yoctoproject.org/ref-manual/terms.html#term-Poky)
distribution which is a Linux distribution stripped down to a minimal configuration.
The provided distribution is based on [BusyBox](https://www.busybox.net/) and built using [musl libc](https://musl.libc.org/).
The following Linux components are used:
Table: Linux components
| Type | Path |
| --------- | ---------------------------------------------------------------------------------------------------------------- |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto_%.bbappend` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto_6.19.bb` |
| defconfig | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/defconfig` |
### Secure enclave components {.reference}
This section describes the secure enclave components.
#### Trusted Firmware-M {.reference}
The following [Trusted Firmware-M](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git) are used:
Table: Trusted Firmware-M secure enclave components
| Type | Path |
| --------- | ---------------------------------------------------------------------------------------------------------------- |
| bbappend | `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/trusted-firmware-m_%.bbappend` |
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-bsp/trusted-firmware-m/trusted-firmware-m_2.2.2.bb` |
## Build {.reference}
To build the software stack, do the following:
:::note
Building binaries natively on Windows and AArch64 Linux is not supported. Use an Intel or AMD 64-bit architecture Linux based development machine to build the software stack and transfer the binaries to run the software stack on an FVP in Windows or AArch64 Linux if required.
:::
1. Create a new folder that will be your workspace:
```
mkdir ${WORKSPACE}
cd ${WORKSPACE}
```
2. Install kas version 4.4 with `sudo` rights:
```
sudo pip3 install kas==4.4
```
Ensure the kas installation directory is visible on the `$PATH` environment variable.
3. Clone the `meta-arm` Yocto layer in the workspace `${WORKSPACE}`.
```
cd ${WORKSPACE}
git clone https://git.yoctoproject.org/git/meta-arm -b CORSTONE1000-2026.05
```
4. Accept the EULA on the [Arm Developer](https://developer.arm.com/downloads/-/arm-ecosystem-fvps/eula) site to build a Corstone-1000 with Cortex-A320 image for FVP as follows:
```
export ARM_FVP_EULA_ACCEPT="True"
```
5. Build a Corstone-1000 with Cortex-A320 image:
```
kas build meta-arm/kas/corstone1000-a320-fvp.yml:meta-arm/ci/debug.yml
```
A clean build takes a significant amount of time given that all of the development machine utilities are also
built along with the target images. Those development machine utilities include executables (Python,
CMake, etc.) and the required toolchains.
Once the build succeeds, all output binaries will be placed in `${WORKSPACE}/build/tmp/deploy/images/corstone1000-a320-fvp/`.
Everything apart from the Secure Enclave ROM firmware is bundled into a single binary, the
`corstone1000-flash-firmware-image-corstone1000-a320-fvp.wic` file.
The output binaries run in the Corstone-1000 with Cortex-A320 platform are the following:
- The Secure Enclave ROM firmware: `${WORKSPACE}/build/tmp/deploy/images/corstone1000-a320-fvp/trusted-firmware-m/bl1.bin`
- The internal firmware flash image: `${WORKSPACE}/build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000-flash-firmware-image-corstone1000-a320-fvp.wic`
## Build with SSH {.reference}
The `meta-arm/kas/corstone1000-a320-fvp.yml` build produces an image for booting from flash.
To build a bootable mass storage OS image with Dropbear SSH enabled, run:
```
kas build meta-arm/ci/corstone1000-a320-fvp.yml:meta-arm/kas/corstone1000-ssh.yml
```
The mass storage OS image can be found at `${WORKSPACE}/build/tmp/deploy/images/corstone1000-a320-fvp/core-image-minimal-corstone1000-a320-fvp.wic`
:::note
The generated `core-image-minimal-corstone1000-a320-fvp.fvpconf` attaches the mass storage OS image to `board.msd_mmc.p_mmc_file`.
:::
## Run {.reference}
Once the platform is turned ON, the Secure Enclave will start to boot, wherein the relevant memory contents of the `*.wic`
file are copied to their respective memory locations. Firewall policies are enforced
on memories and peripherals before bringing the Host Processor out of reset.
The Host Processor will boot TrustedFirmware-A, OP-TEE, U-Boot and then Linux before presenting a login prompt.
A Fixed Virtual Platform (FVP) model of the Corstone-1000 with Cortex-A320 platform must be available to run the
Corstone-1000 with Cortex-A320 FVP software image.
A Yocto recipe is provided to download the latest supported FVP version.
The recipe is located at `${WORKSPACE}/meta-arm/meta-arm/recipes-devtools/fvp/fvp-corstone1000-a320.bb`.
The latest FVP version is `11.31.cs1000_a320_2` for Corstone-1000 with Cortex-A320, and the model is automatically downloaded and installed when using the `runfvp` command as follows:
```
kas shell meta-arm/kas/corstone1000-a320-fvp.yml:meta-arm/ci/debug.yml \
-c "../meta-arm/scripts/runfvp -- --version"
```
The FVP can also be manually downloaded from [Arm Developer](https://developer.arm.com/downloads/-/arm-ecosystem-fvps) to download the Corstone-1000 with Cortex-A320 FVP package.
To set up the FVP:
1. Run `tmux`:
```
cd ${WORKSPACE} && tmux
```
2. Run the FVP within `tmux`:
```
kas shell meta-arm/kas/corstone1000-a320-fvp.yml:meta-arm/ci/debug.yml \
-c "../meta-arm/scripts/runfvp --terminals=tmux"
```
When the script is executed, three terminal instances will be launched:
- one for the Secure Enclave processing element
- two for the Host processor processing element.
```
corstone1000-a320-fvp login:
```
3. Log in using the `root` username.
## Security issue reporting {.reference}
To report any security issues identified with Corstone-1000 with Cortex-A320, please send an email to [psirt@arm.com](mailto:psirt@arm.com).
@@ -10,6 +10,71 @@ Change Log
This document contains a summary of the new features, changes and
fixes in each release of Corstone-1000 software stack.
***************
Version 2026.05
***************
Changes
=======
- Upgraded key Corstone-1000 components to U-Boot 2025.10, TF-A 2.14.1, TF-M 2.2.2, OP-TEE 4.9.0, Trusted Services 1.3.0, and Linux 6.19.
- Added GPT support in TF-M and updated MCUboot to use the GPT library for firmware-update partitions.
- Extended the TF-M firmware update flow with GPT fixes, partition create/remove/duplicate operations, metadata-only handling, flash erase protection, stale partition cleanup, and better handling of older images during PSA FWU.
- Added SSH-enabled build overlay for FVP mass-storage images.
- Removed GRUB from the initramfs boot package set.
Corstone-1000 components versions
=================================
+-------------------------------------------+-------------------+
| linux-yocto | 6.19 |
+-------------------------------------------+-------------------+
| u-boot | 2025.10 |
+-------------------------------------------+-------------------+
| external-system | 0.1.0 |
+-------------------------------------------+-------------------+
| optee-client | 4.9.0 |
+-------------------------------------------+-------------------+
| optee-os | 4.9.0 |
+-------------------------------------------+-------------------+
| trusted-firmware-a | 2.14.1 |
+-------------------------------------------+-------------------+
| trusted-firmware-m | 2.2.2 |
+-------------------------------------------+-------------------+
| libts | v1.3.0 |
+-------------------------------------------+-------------------+
| ts-sp-{se-proxy, smm-gateway} | v1.3.0 |
+-------------------------------------------+-------------------+
| ts-psa-{crypto, iat, its. ps}-api-test | 74dc6646ff |
+-------------------------------------------+-------------------+
Yocto distribution components versions
======================================
+-------------------------------------------+----------------+
| meta-arm | wrynose |
+-------------------------------------------+----------------+
| bitbake | 22021758e6 |
+-------------------------------------------+----------------+
| meta-openembedded | 9af4488d46 |
+-------------------------------------------+----------------+
| openembedded-core | 06dd66e622 |
+-------------------------------------------+----------------+
| meta-yocto | 8251bdad5f |
+-------------------------------------------+----------------+
| meta-secure-core | 07a99ae241 |
+-------------------------------------------+----------------+
| busybox | 1.37.0 |
+-------------------------------------------+----------------+
| musl | 1.2.6 |
+-------------------------------------------+----------------+
| gcc-arm-none-eabi | 15.2.rel1 |
+-------------------------------------------+----------------+
| gcc-cross-aarch64 | 15.2.0 |
+-------------------------------------------+----------------+
| openssl | 3.5.6 |
+-------------------------------------------+----------------+
***************
Version 2025.12
***************
@@ -19,6 +19,12 @@ intended for safety-critical applications. Should Your Software or Your Hardware
prove defective, you assume the entire cost of all necessary servicing, repair
or correction.
***********************
Release notes - 2026.05
***********************
The same notes as the 2025.05 release still apply.
***********************
Release notes - 2025.12
***********************
@@ -116,19 +116,6 @@ The Corstone-1000 architecture is designed to cover a range of
`Power, Performance, and Area (PPA) <ppa-website_>`__ applications, and enable extension
for use-case specific applications, for example, sensors, cloud connectivity, and edge computing.
**************************************
Corstone-1000 with Cortex-A320 Variant
**************************************
This variant of the Corstone-1000 platform replaces the Host System's Cortex-A35 processor
with a Cortex-A320. In this configuration, the optional External System (previously a Cortex-M3)
is replaced by an Arm Ethos-U85 Neural Processing Unit (NPU).
The Ethos-U85 runs in the direct drive configuration, where the Host System is responsible for managing the NPU directly.
.. image:: images/CorstoneA320Subsystems.png
:width: 720
:alt: CorstoneA320Subsystems
*****************
Secure Boot Chain
*****************
@@ -28,6 +28,7 @@ The following prerequisites must be available on the host system:
- GNU Tar 1.34 or greater.
- GNU Compiler Collection 12.2 or greater.
- GNU Make 4.3 or greater.
- mtools 4.0 or greater.
- tmux 3.3 or greater.
Please follow the steps described in the Yocto mega manual:
@@ -50,7 +51,7 @@ The Corstone-1000 software stack can be run on:
Yocto Stable Branch
-------------------
Corstone-1000 software stack is built on top of Yocto Project's `Whinlatter release <meta-arm-repository-release-branch_>`__.
Corstone-1000 software stack is built on top of Yocto Project's `Wrynose release <meta-arm-repository-release-branch_>`__.
Software Components
-------------------
@@ -91,7 +92,7 @@ Host Processor Components
+----------+-------------------------------------------------------------------------------------------------------+
| bbappend | ``${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a_%.bbappend`` |
+----------+-------------------------------------------------------------------------------------------------------+
| Recipe | ``${WORKSPACE}/meta-arm/meta-arm/recipes-bsp/trusted-firmware-a/trusted-firmware-a_2.14.0.bb`` |
| Recipe | ``${WORKSPACE}/meta-arm/meta-arm/recipes-bsp/trusted-firmware-a/trusted-firmware-a_2.14.1.bb`` |
+----------+-------------------------------------------------------------------------------------------------------+
`Trusted Services <https://trusted-services.readthedocs.io/en/latest/index.html>`__
@@ -131,7 +132,7 @@ Host Processor Components
================================================================
+----------+------------------------------------------------------------------------------------------+
| bbappend | ``${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_4.%.bbappend`` |
| bbappend | ``${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_%.bbappend`` |
+----------+------------------------------------------------------------------------------------------+
| Recipe | ``${WORKSPACE}/meta-arm/meta-arm/recipes-security/optee/optee-os_4.9.0.bb`` |
+----------+------------------------------------------------------------------------------------------+
@@ -144,7 +145,7 @@ Host Processor Components
+----------+----------------------------------------------------------------------------------+
| bbappend | ``${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot_%.bbappend`` |
+----------+----------------------------------------------------------------------------------+
| Recipe | ``${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot_2025.04.bb`` |
| Recipe | ``${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot_2025.10.bb`` |
+----------+----------------------------------------------------------------------------------+
Linux
@@ -172,7 +173,7 @@ Secure Enclave Components
+----------+-------------------------------------------------------------------------------------------------------+
| bbappend | ``${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/trusted-firmware-m_%.bbappend`` |
+----------+-------------------------------------------------------------------------------------------------------+
| Recipe | ``${WORKSPACE}/meta-arm/meta-arm/recipes-bsp/trusted-firmware-m/trusted-firmware-m_2.2.1.bb`` |
| Recipe | ``${WORKSPACE}/meta-arm/meta-arm/recipes-bsp/trusted-firmware-m/trusted-firmware-m_2.2.2.bb`` |
+----------+-------------------------------------------------------------------------------------------------------+
************************************
@@ -210,20 +211,29 @@ Build
mkdir ${WORKSPACE}
cd ${WORKSPACE}
#. Install kas version 4.4 with ``sudo`` rights.
#. Create a Python virtual environment and activate it.
.. code-block:: console
sudo pip3 install kas==4.4
python3 -m venv ${WORKSPACE}/venv_cs1k
source ${WORKSPACE}/venv_cs1k/bin/activate
Ensure the kas installation directory is visible on the ``$PATH`` environment variable.
#. Install ``kas`` and ``wic`` inside the virtual environment.
.. code-block:: console
python3 -m pip install kas==5.1 "git+https://git.yoctoproject.org/wic@v0.3.0"
.. note::
Ensure the kas and wic installation directory is visible on the ``$PATH`` environment variable.
#. Clone the `meta-arm` Yocto layer in the workspace ``${WORKSPACE}``.
.. code-block:: console
cd ${WORKSPACE}
git clone https://git.yoctoproject.org/git/meta-arm -b CORSTONE1000-2025.12
git clone https://git.yoctoproject.org/git/meta-arm -b CORSTONE1000-2026.05
#. Build a Corstone-1000 image:
@@ -243,8 +253,6 @@ Build
.. warning::
**The External System Processor is not available on the Corstone-1000 with Cortex-A320 FVP.**
Access to the External System Processor is disabled by default on **Corstone-1000 with Cortex-A35**.
To build the Corstone-1000 image with External System Processor enabled, run:
@@ -253,18 +261,6 @@ Build
kas build meta-arm/kas/corstone1000-${TARGET}.yml:meta-arm/ci/debug.yml:meta-arm/kas/corstone1000-extsys.yml
.. warning::
**The Ethos-U85 Neural Processing Unit (NPU) is only available on
the Corstone-1000 with Cortex-A320 FVP.**
To build the Corstone-1000 image with the Ethos-U85 NPU enabled, run:
.. code-block:: console
kas build meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml:meta-arm/kas/corstone1000-a320.yml
A clean build takes a significant amount of time given that all of the development machine utilities are also
built along with the target images. Those development machine utilities include executables (Python,
CMake, etc.) and the required toolchains.
@@ -280,6 +276,34 @@ The output binaries run in the Corstone-1000 platform are the following:
- The External System Processor firmware: ``${WORKSPACE}/build/tmp/deploy/images/corstone1000-${TARGET}/es_flashfw.bin``
- The internal firmware flash image: ``${WORKSPACE}/build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000-flash-firmware-image-corstone1000-${TARGET}.wic``
Build with SSH
--------------
The ``meta-arm/kas/corstone1000-${TARGET}.yml`` build produces an image for
booting from flash.
.. important::
The SSH-enabled mass storage image is supported only for the FVP target.
It is not supported for the MPS3 target, because it relies on pre-generated
SSH host keys intended for virtual platforms.
To build a bootable mass storage OS image with Dropbear SSH enabled for FVP,
run:
.. code-block:: console
kas build meta-arm/ci/corstone1000-fvp.yml:meta-arm/kas/corstone1000-ssh.yml
The mass storage OS image can be found at
``${WORKSPACE}/build/tmp/deploy/images/corstone1000-fvp/core-image-minimal-corstone1000-fvp.wic``
.. note::
The generated ``core-image-minimal-corstone1000-fvp.fvpconf`` configures
the mass storage OS image using ``board.msd_mmc.p_mmc_file``.
.. _flashing-firmware-images:
Flash
@@ -371,8 +395,8 @@ Flash
#. Copy ``bl1.bin`` from ``${WORKSPACE}/build/tmp/deploy/images/corstone1000-mps3/trusted-firmware-m/`` to the ``SOFTWARE`` directory of the FPGA bundle.
#. Copy ``es_flashfw.bin`` from ``${WORKSPACE}/build/tmp/deploy/images/corstone1000-mps3`` to the ``SOFTWARE`` directory of the FPGA bundle
and rename the binary to ``es0.bin``.
#. Remove ``ES0.bin`` from the ``SOFTWARE`` directory of the FPGA bundle. Copy ``es_flashfw.bin`` from
``${WORKSPACE}/build/tmp/deploy/images/corstone1000-mps3`` to the ``SOFTWARE`` directory of the FPGA bundle and rename the binary to ``es0.bin``.
#. Copy ``corstone1000-flash-firmware-image-corstone1000-mps3.wic`` from ``${WORKSPACE}/build/tmp/deploy/images/corstone1000-mps3`` to the ``SOFTWARE``
directory of the FPGA bundle and rename the wic image to ``cs1000.bin``.
@@ -425,6 +449,10 @@ MPS3
sudo picocom -b 115200 /dev/ttyUSB3
.. note::
If the user is a member of the ``dialout`` group, ``sudo`` is not required for this step.
.. important::
Plug a connected Ethernet cable to the MPS3 or it will
wait for a network connection for a considerable amount of time, printing the following
@@ -457,14 +485,9 @@ Corstone-1000 FVP software image.
A Yocto recipe is provided to download the latest supported FVP version.
The recipe is located at ``${WORKSPACE}/meta-arm/meta-arm/recipes-devtools/fvp/fvp-corstone1000.bb``.
This recipe supports selecting different Corstone1000 FVP models via MACHINE_FEATURES:
- ``cortexa320`` use the Cortex-A320 Host Processor with Ethos U85 enabled FVP build
- (default) use the Cortex-A35 Host Processor with Cortex-M3 External System FVP build
The latest FVP version is ``11.23.25`` for Corstone-1000 with Cortex-A35 and ``11.30.27`` for
Corstone-1000 with Cortex-A320, and each model is automatically downloaded and installed when using
the ``runfvp`` command as detailed below.
The latest FVP version is ``11.23.25`` and is automatically
downloaded and installed when using the ``runfvp`` command as detailed below.
.. note::
@@ -521,8 +544,8 @@ Tests
Reports
-------
Reports for the tests conducted on the `Corstone-1000 software (CORSTONE1000-2025.12) <https://git.yoctoproject.org/meta-arm/tag/?h=CORSTONE1000-2025.12>`__
release are available for reference `here <https://gitlab.arm.com/arm-reference-solutions/arm-reference-solutions-test-report/-/tree/CORSTONE1000-2025.12/embedded-a/corstone1000/CORSTONE1000-2025.12?ref_type=tags>`__.
Reports for the tests conducted on the `Corstone-1000 software (CORSTONE1000-2026.05) <https://git.yoctoproject.org/meta-arm/tag/?h=CORSTONE1000-2026.05>`__
release are available for reference `here <https://gitlab.arm.com/arm-reference-solutions/arm-reference-solutions-test-report/-/tree/CORSTONE1000-2026.05/embedded-a/corstone1000/CORSTONE1000-2026.05?ref_type=tags>`__.
.. _clean-secure-flash:
@@ -541,7 +564,7 @@ Clean Secure Flash
.. code-block:: console
cd ${WORKSPACE}
git clone https://git.gitlab.arm.com/arm-reference-solutions/iot-platform-assets.git -b CORSTONE1000-2025.12
git clone https://git.gitlab.arm.com/arm-reference-solutions/iot-platform-assets.git -b CORSTONE1000-2026.05
#. Copy the secure flash cleaning Git patch file to your copy of `meta-arm`.
@@ -779,7 +802,12 @@ MPS3
cd ${WORKSPACE}/arm-systemready/IR/prebuilt_images/v23.09_2.1.0
sudo dd if=ir-acs-live-image-generic-arm64.wic of=/dev/sdc iflag=direct oflag=direct bs=1M status=progress; sync
#. Plug the USB drive to the MPS3. At this point you should have both the USB drive with the ESP and the USB drive with the ACS image plugged to the MPS3.
#. Unplug the ESP USB drive from the MPS3, if connected.
#. Plug only the ACS image USB drive to the MPS3.
The ESP USB drive must remain unplugged while the ACS image is booting,
otherwise GRUB might fail to find the bootable partition on the ACS image USB drive.
#. Reboot the MPS3.
@@ -787,12 +815,10 @@ The MPS3 will reset multiple times during the test, and it might take approximat
.. important::
Unplug the ESP USB drive from the MPS3 if it is preventing GRUB
from finding the bootable partition. Leave only the ACS image USB drive
plugged in to run the ACS tests.
The ESP USB drive can be plugged in again after
selecting the `Linux Boot` option in the GRUB menu at the end of the ACS tests.
Keep the ESP USB drive unplugged until the GRUB menu is displayed during
the Linux boot timeout workaround described below. Plug the ESP USB drive
back in just before selecting the `Linux Boot` option, so it is available
for the remaining ACS tests.
.. warning::
@@ -803,6 +829,7 @@ The MPS3 will reset multiple times during the test, and it might take approximat
#. Press Enter at the Linux prompt.
#. Open the file `/etc/systemd/system.conf` and set `DefaultDeviceTimeoutSec=infinity`.
#. Reboot the platform using the `reboot` command.
#. When the GRUB menu appears, plug the ESP USB drive back into the MPS3.
#. Select the `Linux Boot` option from the GRUB menu.
#. Allow Linux to boot and run the remaining ACS tests until completion.
@@ -847,18 +874,19 @@ If GRUB is not interrupted, the tests are executed automatically in the followin
- UEFI BSA
- FWTS
The results can be fetched from the `acs_results` folder in the ``BOOT`` partition of the USB drive (for MPS3) or SD Card (for FVP).
The results can be fetched from the `acs_results` folder in the ``BOOT`` partition of the ACS image USB drive (for MPS3) or SD Card (for FVP).
.. note::
Access the `acs_results` folder in FVP by running the following commands:
Access the `acs_results` folder in FVP by copying it from the same ACS image that was used to boot the FVP.
The following command copies the ``acs_results`` directory from the ACS image to
``${WORKSPACE}/acs_results`` on the host development machine.
.. code-block:: console
sudo mkdir /mnt/test
sudo mount -o rw,offset=1048576 \
${WORKSPACE}/arm-systemready/IR/prebuilt_images/v23.09_2.1.0/ir-acs-live-image-generic-arm64.wic \
/mnt/test
cd ${WORKSPACE}
wic cp ${WORKSPACE}/arm-systemready/IR/prebuilt_images/v23.09_2.1.0/ir-acs-live-image-generic-arm64.wic:1/acs_results \
${WORKSPACE}
#####################################################
@@ -918,6 +946,11 @@ Generate Capsules
for the host machine during the firmware image building process.
The tool can be found at ``${WORKSPACE}/build/tmp/sysroots-components/aarch64/edk2-basetools-native/usr/bin/edk2-BaseTools/BinWrappers/PosixLike/GenerateCapsule``.
.. note::
The ``aarch64`` part of this path depends on the build host architecture
and can be different on another host.
A JSON file containing metadata about the capsule payloads needs to be created using the script
found at ``${WORKSPACE}/meta-arm/meta-arm/scripts/generate_capsule_json_multiple.py``.
This JSON file is required by EDK II's ``GenerateCapsule`` tool to generate the capsule.
@@ -1066,7 +1099,7 @@ MPS3
#. Prepare a USB drive as explained in `this <mps3-instructions-for-acs-image_>`_ section.
#. Copy the capsule file to the root directory of the ``BOOT`` partition in the USB drive.
#. Copy the capsule files to the root directory of the ``BOOT`` partition in the USB drive.
.. code-block:: console
@@ -1077,60 +1110,46 @@ MPS3
.. note::
``/dev/sdc`` is the assumed path for the ACS Image USB drive.
Replace it with the actual device path as enumerated on your development machine.
The staging steps below are shared between ``mps3`` and ``fvp``.
#. Download and extract the ACS image `as described for the MPS3 <mps3-instructions-for-acs-image_>`_.
The ACS image extraction location will be referred below as ``${ACS_IMAGE_PATH}``.
#. Copy the ACS image to the workspace root directory and rename it to
``ir-acs-live-image-generic-arm64-staged.wic``. The staged image will then be
populated with the capsule files.
``${ACS_STAGED_IMAGE}`` refers to
``${WORKSPACE}/ir-acs-live-image-generic-arm64-staged.wic``.
.. code-block:: console
cp ${ACS_IMAGE_PATH}/ir-acs-live-image-generic-arm64.wic \
${ACS_STAGED_IMAGE}
#. Copy the capsules to the staged ACS image:
.. code-block:: console
cd ${WORKSPACE}
wic cp ${WORKSPACE}/build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000-${TARGET}-v6.uefi.capsule \
${ACS_STAGED_IMAGE}:1/corstone1000-${TARGET}-v6.uefi.capsule
wic cp ${WORKSPACE}/corstone1000-${TARGET}-v5.uefi.capsule \
${ACS_STAGED_IMAGE}:1/corstone1000-${TARGET}-v5.uefi.capsule
wic cp ${WORKSPACE}/corstone1000-${TARGET}-partial-v7.uefi.capsule \
${ACS_STAGED_IMAGE}:1/corstone1000-${TARGET}-partial-v7.uefi.capsule
.. important::
The direct Capsule Update method requires that the capsule files not be placed in the ``EFI/UpdateCapsule`` directory,
as doing so might inadvertently trigger the on-disk update method.
FVP
MPS3
===
#. Download and extract the ACS image `as described for the MPS3 <mps3-instructions-for-acs-image_>`_.
The ACS image extraction location will be referred below as ``${ACS_IMAGE_PATH}``.
.. note::
Creating a USB drive with the ACS image is not required as the image will be mounted with the steps below.
#. Find the first partition's offset of the ``ir-acs-live-image-generic-arm64.wic`` image using the ``fdisk`` tool.
The partition table can be listed using:
.. code-block:: console
fdisk -lu ${ACS_IMAGE_PATH}/ir-acs-live-image-generic-arm64.wic
Device Start End Sectors Size Type
${ACS_IMAGE_PATH}/ir-acs-live-image-generic-arm64.wic1 2048 309247 307200 150M Microsoft basic data
${ACS_IMAGE_PATH}/ir-acs-live-image-generic-arm64.wic2 309248 1343339 1034092 505M Linux filesystem
Given that the first partition starts at sector 2048 and each sector is 512 bytes in size,
the first partition is at offset 1048576 (2048 x 512).
#. Mount the ``ir-acs-live-image-generic-arm64.wic`` image using the previously calculated offset:
.. code-block:: console
sudo mkdir /mnt/ir-acs-live-image-generic-arm64
sudo mount -o rw,offset=<first_partition_offset> ${ACS_IMAGE_PATH}/ir-acs-live-image-generic-arm64.wic /mnt/ir-acs-live-image-generic-arm64
#. Copy the capsules:
.. code-block:: console
sudo cp ${WORKSPACE}/build/tmp/deploy/images/corstone1000-fvp/corstone1000-fvp-v6.uefi.capsule /mnt/ir-acs-live-image-generic-arm64/
sudo cp ${WORKSPACE}/corstone1000-fvp-v5.uefi.capsule /mnt/ir-acs-live-image-generic-arm64/
sudo cp ${WORKSPACE}/corstone1000-fvp-partial-v7.uefi.capsule /mnt/ir-acs-live-image-generic-arm64/
sync
#. Unmount the IR image:
.. code-block:: console
sudo umount /mnt/ir-acs-live-image-generic-arm64
#. Write ``${ACS_STAGED_IMAGE}`` to the ACS USB drive by following the
`MPS3 ACS image steps <mps3-instructions-for-acs-image_>`_ and replacing
``ir-acs-live-image-generic-arm64.wic`` with ``${ACS_STAGED_IMAGE}``.
************************
Run Capsule Update Tests
@@ -1150,7 +1169,7 @@ This will be followed by using the invalid capsule to run the rollback protectio
Positive Full Capsule Update Test
=================================
#. Run Corstone-1000 with the ACS image containing the two capsule files:
#. Run Corstone-1000 with the ACS image containing the capsule files:
- MPS3:
@@ -1169,13 +1188,14 @@ Positive Full Capsule Update Test
.. code-block:: console
cd ${WORKSPACE}
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml \
-c "../meta-arm/scripts/runfvp --terminals=tmux \
-- -C board.msd_mmc.p_mmc_file=${ACS_IMAGE_PATH}/ir-acs-live-image-generic-arm64.wic"
-- -C board.msd_mmc.p_mmc_file=${ACS_STAGED_IMAGE}"
.. warning::
``${ACS_IMAGE_PATH}`` must be an absolute path. Ensure there are no spaces before or after of ``=`` of the ``-C board.msd_mmc.p_mmc_file`` option.
``${ACS_STAGED_IMAGE}`` must be an absolute path. Ensure there are no spaces before or after of ``=`` of the ``-C board.msd_mmc.p_mmc_file`` option.
#. Wait until U-Boot loads EFI from the ACS image and interrupt the EFI shell by pressing the ``Escape`` key when the following prompt is displayed on the Host Processor terminal (``ttyUSB2`` for MPS3).
@@ -1196,7 +1216,7 @@ Positive Full Capsule Update Test
.. code-block:: console
EFI/BOOT/app/CapsuleApp.efi EFI/BOOT/corstone1000-mps3-v6.uefi.capsule
EFI/BOOT/app/CapsuleApp.efi corstone1000-mps3-v6.uefi.capsule
- FVP:
@@ -1213,42 +1233,40 @@ Positive Full Capsule Update Test
The software stack copies the capsule content to the external flash, which is shared between the Secure Enclave and the Host Processor
before rebooting the system.
After the first reboot, TrustedFirmware-M should apply the valid capsule and display the following log on the Secure Enclave terminal (``ttyUSB1`` for MPS3)
before rebooting the system a second time:
before rebooting the system, and the following logs should be displayed on the Secure Enclave terminal (``ttyUSB1`` for MPS3):
.. code-block:: console
...
SysTick_Handler: counted = 10, expiring on = 360
SysTick_Handler: counted = 20, expiring on = 360
SysTick_Handler: counted = 30, expiring on = 360
...
fwu_bootloader_install_image: enter
metadata_read: success: active = 0, previous = 1
fwu_update_metadata: enter
metadata_write: success: active = 1, previous = 0
flash_full_capsule: exit
corstone1000_fwu_flash_image: exit: ret = 0
fwu_update_metadata: exit: ret = 0
fwu_bootloader_install_image: exit: ret = 0
...
The above log snippet indicates that the new capsule image is successfully applied, and the board is booting with the external flash's Bank-1.
After a second reboot, the following log should be displayed on on the Secure Enclave terminal (``ttyUSB1``):
.. code-block:: console
...
fmp_set_image_info:133 Enter
FMP image update: image id = 0
FMP image update: status = 0version=6 last_attempt_version=6.
fmp_set_image_info:157 Exit.
corstone1000_fwu_host_ack: exit: ret = 0
...
The above log snippet indicates that the new capsule image is successfully applied.
After the first reboot,
#. Interrupt the U-Boot shell.
.. code-block:: console
Hit any key to stop autoboot:
After the first reboot, TrustedFirmware-M should display the following log on the Secure Enclave terminal (``ttyUSB1`` for MPS3):
.. code-block:: console
...
[INF] Starting TF-M BL1_1
metadata_read: success: active = 1, previous = 0
get_fwu_agent_state: exit: FWU Agent PSA_FWU_TRIAL (index mismatch)
bl1_get_active_bl2_image: booting from trial bank: 1
bl1_get_active_bl2_image: exit: booting from bank = 1, offset = 0x1002000
...
#. Run the following commands in order to run the Corstone-1000 Linux kernel.
@@ -1261,6 +1279,18 @@ Positive Full Capsule Update Test
$ loadm 0x90000000 $kernel_addr_r $filesize
$ bootefi $kernel_addr_r $fdtcontroladdr
After executing above set of commands, the following log should be displayed on the Secure Enclave terminal (``ttyUSB1``):
.. code-block:: console
...
fwu_accept_image: success: fwu state is changed to regular
update_nv_counters: success
disable_host_ack_timer: timer to reset is disabled
FMP image update: status = 0version=6 last_attempt_version=6.
fwu_bootloader_mark_image_accepted: exit: ret = 0
...
#. The first boot after a capsule update is considered the trial stage, during which the FWU image is accepted.
However, to view the updated contents of the EFI System Resource Table (ESRT), an additional reboot is required.
@@ -1340,7 +1370,7 @@ Rollback Protection Capsule Update Test
.. code-block:: console
EFI/BOOT/app/CapsuleApp.efi EFI/BOOT/corstone1000-mps3-v5.uefi.capsule
EFI/BOOT/app/CapsuleApp.efi corstone1000-mps3-v5.uefi.capsule
- FVP:
@@ -1354,21 +1384,20 @@ Rollback Protection Capsule Update Test
.. code-block:: console
...
uefi_capsule_retrieve_images: image 0 at 0xa0000070, size=15654928
uefi_capsule_retrieve_images: exit
flash_full_capsule: enter: image = 0x0xa0000070, size = 7764541, version = 5
ERROR: flash_full_capsule: version error
private_metadata_write: enter: boot_index = 1
private_metadata_write: success
fmp_set_image_info:133 Enter
FMP image update: image id = 0
FMP image update: status = 1version=6 last_attempt_version=5.
fmp_set_image_info:157 Exit.
corstone1000_fwu_flash_image: exit: ret = -1
fmp_get_image_info:232 Enter
pack_image_info:207 ImageInfo size = 105, ImageName size = 34, ImageVersionName
size = 36
fmp_get_image_info:236 Exit
fwu_bootloader_load_image: enter: block_offset = 0
FMP version: 0x5, metadata version : 0x7
private_metadata_write: enter: boot_index = 0
private_metadata_write: success
fmp_set_image_info:160 Enter
FMP image update: image id = 0
FMP image update: status = 1version=7 last_attempt_version=5.
fmp_set_image_info:184 Exit.
ERROR: fwu_bootloader_load_image: version error
remove_all_stale_partitions: Removed GPT partition 'bl2_secondary'
remove_all_stale_partitions: Removed GPT partition 'tfm_secondary'
remove_all_stale_partitions: Removed GPT partition 'FIP_B'
remove_all_stale_partitions: Removed GPT partition 'kernel_secondary'
fwu_bootloader_load_image: exit: ret = -248
...
The Secure Enclave tries to load the new image a predetermined number of times
@@ -1631,7 +1660,7 @@ Corstone-1000 on-board non-volatile storage size is insufficient for installing
dd if=/dev/zero of=${WORKSPACE}/fvp_distro_system_drive.img \
bs=1 count=0 seek=10G; sync; \
parted -s fvp_distro_system_drive.img mklabel gpt
parted -s ${WORKSPACE}/fvp_distro_system_drive.img mklabel gpt
#. This MMC image will be used as the primary drive to boot the distribution.
@@ -1656,6 +1685,10 @@ MPS3
sudo picocom -b 115200 /dev/ttyUSB2
.. note::
If the user is a member of the ``dialout`` group, ``sudo`` is not required for this step.
#. When the installation screen is displayed on ``ttyUSB2``, plug in the (still empty) system drive to the MPS3.
#. Start the distribution installation process.
@@ -1685,6 +1718,10 @@ FVP
-C board.msd_mmc.p_mmc_file=${WORKSPACE}/fvp_distro_system_drive.img \
-C board.msd_mmc_2.p_mmc_file=${DISTRO_INSTALLER_ISO_PATH}"
.. note::
The FVP distribution installation process can take 6-8 hours to complete.
The Linux distribution will be installed on ``fvp_distro_system_drive.img``.
@@ -1693,7 +1730,7 @@ Debian Installation Extra Steps
Debian installation may need some extra steps, that are indicated below:
#. Answer ``Yes`` to the question ``Force grub installation to the EFI removable media path?``.
#. Answer ``Yes`` to the question ``Install the GRUB boot loader``.
If the GRUB installation fails, these are the steps to follow on the subsequent
popups:
@@ -1852,8 +1889,7 @@ Generate Keys, Signed Image and Unsigned Image
cd ${WORKSPACE}
git clone https://gitlab.arm.com/arm-reference-solutions/iot-platform-assets \
-b CORSTONE1000-2025.12
-b CORSTONE1000-2026.05
#. Set the current working directory to build directory's subdirectory containing the software stack build images.
@@ -1865,7 +1901,7 @@ Generate Keys, Signed Image and Unsigned Image
.. code-block:: console
./${WORKSPACE}/iot-platform-assets/corstone1000/secureboot/create_keys_and_sign.sh \
${WORKSPACE}/iot-platform-assets/corstone1000/secureboot/create_keys_and_sign.sh \
-d ${TARGET} \
-v ${CERTIFICATE_VALIDITY_DURATION_IN_DAYS}
@@ -1873,19 +1909,17 @@ Generate Keys, Signed Image and Unsigned Image
The `efitools <https://github.com/vathpela/efitools/>`__ package is required to execute the script.
The ``mtools`` package is required on the host development machine to execute the script.
``${CERTIFICATE_VALIDITY_DURATION_IN_DAYS}`` is an integer that specifies the certificate's validity period in days.
.. note::
Consult the image signing script help message (``-h``) for more information about other optional arguments.
The script is interactive and contains commands that require ``sudo`` level permissions.
The keys, signed kernel image, and unsigned kernel image will be copied to the exisiting ESP image.
The modified ESP image can be found at ``${WORKSPACE}/build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000-esp-image-corstone1000-${TARGET}.wic``.
****************************
Run Unsigned Image Boot Test
****************************
@@ -1899,7 +1933,7 @@ MPS3
#. Perform a cold boot of the MPS3.
#. On the Host Processor terminal host side, stop the execution of U-Boot when prompted to do so with the message ``Press any key to stop``.
#. On the Host Processor terminal host side, stop the execution of U-Boot when prompted to do so with the message ``Hit any key to stop autoboot``.
.. warning::
@@ -1972,7 +2006,7 @@ FVP
#. Run the software stack as described `here <running-software-stack-fvp_>`__.
#. On the Host Processor terminal host side, stop the execution of U-Boot when prompted to do so with the message ``Press any key to stop``.
#. On the Host Processor terminal host side, stop the execution of U-Boot when prompted to do so with the message ``Hit any key to stop autoboot``.
.. warning::
@@ -2073,9 +2107,12 @@ As a result, U-Boot reads these variables and verifies the Linux kernel image be
In a typical boot scenario, the Linux kernel image is not signed, which will prevent the system from booting due to failed image authentication.
To resolve this, the Platform Key (one of the UEFI authenticated variables for secure boot) needs to be deleted.
#. Perform a cold boot of the MPS3.
#. For MPS3, perform a cold boot.
#. On the Host Processor terminal host side, stop the execution of U-Boot when prompted to do so with the message ``Press any key to stop``.
#. For FVP, continue in the same boot cycle in which the UEFI secure boot keys were enrolled.
Do not cold boot FVP before deleting the Platform Key, because the secure flash contents are not preserved across an FVP cold boot.
#. On the Host Processor terminal host side, stop the execution of U-Boot when prompted to do so with the message ``Hit any key to stop autoboot``.
#. On the U-Boot console, delete the Platform Key (PK).
@@ -2156,42 +2193,21 @@ Symmetric Multiprocessing
.. warning::
Symmetric multiprocessing (SMP) mode is supported on Corstone-1000
with Cortex-A35 FVP and Corstone-1000 with Cortex-A320 FVP, but is disabled by default.
Symmetric multiprocessing (SMP) mode is supported on FVP but is disabled by default.
#. Build the software stack with SMP mode enabled:
#. Build the software stack with SMP mode enabled.
For Corstone-1000 with Cortex-A35 FVP:
.. code-block:: console
.. code-block:: console
kas build meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml:meta-arm/kas/corstone1000-multicore.yml
For Corstone-1000 with Cortex-A320 FVP:
.. code-block:: console
kas build meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml:meta-arm/kas/corstone1000-a320.yml:\
meta-arm/kas/corstone1000-multicore.yml
#. Run the Corstone-1000 FVP.
For Corstone-1000 with Cortex-A35 FVP:
.. code-block:: console
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml:meta-arm/kas/corstone1000-multicore.yml \
-c "../meta-arm/scripts/runfvp"
For Corstone-1000 with Cortex-A320 FVP:
.. code-block:: console
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml:meta-arm/kas/corstone1000-a320.yml:\
meta-arm/kas/corstone1000-multicore.yml \
-c "../meta-arm/scripts/runfvp"
#. Verify that the FVP is running the Host Processor with more than one CPU core:
.. code-block:: console
@@ -2199,78 +2215,6 @@ Symmetric Multiprocessing
nproc
4 # number of processing units
Ethos-U85 NPU
-------------
.. warning::
The Ethos-U85 NPU is only supported on Corstone-1000 with Cortex-A320 FVP.
#. Clone the `iot-platform-assets` repository to your ``${WORKSPACE}``.
.. code-block:: console
cd ${WORKSPACE}
git clone https://git.gitlab.arm.com/arm-reference-solutions/iot-platform-assets.git \
-b CORSTONE1000-2025.12
#. Copy the additional kas configuration file to:
.. code-block:: console
cp ${WORKSPACE}/iot-platform-assets/corstone1000/ethos-u85_test/ethos-u85-test.yml \
${WORKSPACE}/meta-arm/kas/
#. Copy the mesa package Git patch file to your copy of meta-arm.
.. code-block:: console
cp -f ${WORKSPACE}/iot-platform-assets/corstone1000/ethos-u85_test/0001-arm-bsp-mesa-Package-Teflon-test-runner-and-models.patch \
${WORKSPACE}/meta-arm/
#. Apply the Git patch to meta-arm.
.. code-block:: console
cd ${WORKSPACE}/meta-arm/
git apply 0001-arm-bsp-mesa-Package-Teflon-test-runner-and-models.patch
cd ${WORKSPACE}
#. Re-Build the Corstone-1000 with Cortex-A320 FVP software stack as follows:
.. code-block:: console
kas build meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml:meta-arm/kas/corstone1000-a320.yml:\
meta-arm/kas/ethos-u85-test.yml
#. Run the Corstone-1000 with Cortex-320 FVP:
.. code-block:: console
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml:meta-arm/kas/corstone1000-a320.yml:\
meta-arm/kas/ethos-u85-test.yml \
-c "../meta-arm/scripts/runfvp"
#. To verify you are running the Corstone-1000 with Cortex-A320, build and run the FVP and inspect the CPU model
reported in ``/proc/cpuinfo`` as shown below. Inside the FVP shell, confirm the core type:
.. code-block:: console
grep -E 'CPU part|model name' /proc/cpuinfo
# Expect: CPU part : 0xd8f (which corresponds to Cortex-A320)
#. Run the `test_teflon` test application inside the FVP shell as follows:
.. code-block:: console
export TEFLON_TEST_DELEGATE=/usr/lib/libteflon.so
export TEFLON_TEST_DATA=/usr/share/teflon/tests
test_teflon --gtest_filter='Models.*'
The test completes in approximately one minute.
Secure Debug
------------
@@ -2369,7 +2313,7 @@ and `Arm Development Studio <arm-ds-website_>`__ versions 2022.2, 2022.c, or 202
.. _arm-developer-fvp: https://developer.arm.com/tools-and-software/open-source-software/arm-platforms-software/arm-ecosystem-fvps
.. _secure-debug-manager-repo-readme: https://github.com/ARM-software/secure-debug-manager/tree/master?tab=readme-ov-file#secure-debug-manager-psa-adac--sdc-600
.. _secure-debug-manager-armds-integration: https://github.com/ARM-software/secure-debug-manager?tab=readme-ov-file#arm-development-studio-integration
.. _meta-arm-repository-release-branch: https://docs.yoctoproject.org/next/migration-guides/migration-5.3.html
.. _meta-arm-repository-release-branch: https://docs.yoctoproject.org/next/migration-guides/migration-6.0.html
.. _arm-ulink-pro-website: https://www.arm.com/products/development-tools/debug-probes/ulink-pro
.. _arm-ds-website: https://www.arm.com/products/development-tools/embedded-and-software/arm-development-studio
.. _edk2-repository: https://github.com/tianocore/edk2
@@ -7,5 +7,6 @@ jinja2==3.1.1
# Required to build the documentation
sphinx==7.1.2
myst-parser~=3.0.1
sphinx_rtd_theme~=3.0.0
docutils~=0.18.1
@@ -23,7 +23,7 @@ part --source rawcopy --size 144k --sourceparams="file=trusted-firmware-m/bl2_si
part --source rawcopy --size 320k --sourceparams="file=trusted-firmware-m/tfm_s_signed.bin" --align 4 --part-name="tfm_primary" --uuid 07F9616C-1233-439C-ACBA-72D75421BF70 --part-type 7FAD470E-5EC5-5C03-A2C1-4756B495DE61
# Rawcopy of the FIP binary
part --source rawcopy --size 2 --sourceparams="file=signed_fip.bin" --align 4 --part-name="FIP_A" --uuid B9C7AC9D-40FF-4675-956B-EEF4DE9DF1C5 --part-type F1933675-5A8C-5B6D-9EF4-846739E89BC8
part --source rawcopy --size 2560k --sourceparams="file=signed_fip.bin" --align 4 --part-name="FIP_A" --uuid B9C7AC9D-40FF-4675-956B-EEF4DE9DF1C5 --part-type F1933675-5A8C-5B6D-9EF4-846739E89BC8
# Rawcopy of kernel with initramfs
part --source rawcopy --size 12 --sourceparams="file=Image.gz-initramfs-${MACHINE}.bin" --align 4 --part-name="kernel_primary" --uuid BF7A6142-0662-47FD-9434-6A8811980816 --part-type F771AFF9-C7E9-5F99-9EDA-2369DD694F61
@@ -5,13 +5,14 @@ HOMEPAGE = "https://git.linaro.org/landing-teams/working/arm/external-system.git
DEPENDS = "gcc-arm-none-eabi-native"
INHIBIT_DEFAULT_DEPS = "1"
LICENSE = "BSD-3-Clause & Apache-2.0"
LIC_FILES_CHKSUM = "file://license.md;md5=e44b2531cd6ffe9dece394dbe988d9a0 \
LIC_FILES_CHKSUM = "file://LICENSE;md5=e44b2531cd6ffe9dece394dbe988d9a0 \
file://cmsis/LICENSE.txt;md5=e3fc50a88d0a364313df4b21ef20c29e"
SRC_URI = "gitsm://git.gitlab.arm.com/arm-reference-solutions/corstone1000/external_system/rtx.git;protocol=https;branch=master \
SRC_URI = "gitsm://gitlab.arm.com/arm-reference-solutions/corstone1000/external_system/rtx.git;protocol=https;branch=master \
file://0001-tools-gen_module_code-atomically-rewrite-the-generat.patch"
SRCREV = "8c9dca74b104ff6c9722fb0738ba93dd3719c080"
PV .= "+git"
SRCREV = "3a38cef6e9582907ad6f79950e3d54330c9ab42c"
UPSTREAM_CHECK_COMMITS = "1"
COMPATIBLE_MACHINE = "(corstone1000)"
PACKAGE_ARCH = "${MACHINE_ARCH}"
@@ -160,7 +160,7 @@ TFA_FIP_BINARY = "fip.bin"
TFA_BL2_RE_IMAGE_LOAD_ADDRESS = "0x62353000"
TFA_BL2_RE_SIGN_BIN_SIZE = "0x2d000"
TFA_FIP_RE_IMAGE_LOAD_ADDRESS = "0x68130000"
TFA_FIP_RE_SIGN_BIN_SIZE = "0x00200000"
TFA_FIP_RE_SIGN_BIN_SIZE = "0x00280000"
RE_LAYOUT_WRAPPER_VERSION = "0.0.7"
TFM_SIGN_PRIVATE_KEY = "${libdir}/tfm-scripts/root-EC-P256_1.pem"
RE_IMAGE_OFFSET = "0x1000"
@@ -11,6 +11,7 @@ SRC_URI:append = " \
TFA_DEBUG = "1"
TFA_UBOOT ?= "1"
#FIXME - this can be removed after moving to 2.15.0
TFA_MBEDTLS = "1"
TFA_BUILD_TARGET = "bl2 bl31 fip"
@@ -23,10 +24,10 @@ TFA_SPMD_SPM_AT_SEL2 = "0"
# BL2 loads BL32 (optee). So, optee needs to be built first:
DEPENDS += "optee-os"
ENABLE_CORTEX_A35_ERRATA = " \
ENABLE_CORTEX_A_ERRATA = " \
ERRATA_A35_855472=1 \
"
ENABLE_CORTEX_A35_ERRATA:cortexta320 = ""
ENABLE_CORTEX_A_ERRATA:cortexa320 = ""
FVP_GIC_DRIVER ?= "FVP_GICV2"
FVP_GIC_DRIVER:cortexa320 = "FVP_GICV3"
@@ -54,7 +55,7 @@ EXTRA_OEMAKE:append = " \
NR_OF_IMAGES_IN_FW_BANK=4 \
COT=tbbr \
ARM_ROTPK_LOCATION=devel_rsa \
${ENABLE_CORTEX_A35_ERRATA} \
${ENABLE_CORTEX_A_ERRATA} \
ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
BL32=${RECIPE_SYSROOT}/${nonarch_base_libdir}/firmware/tee-pager_v2.bin \
FVP_USE_GIC_DRIVER=${FVP_GIC_DRIVER} \
@@ -55,9 +55,6 @@ TFA_PLATFORM = "fvp"
# Disable debug build if measured boot is enabled.
TFA_DEBUG := "${@bb.utils.contains('MACHINE_FEATURES', 'ts-attestation', '0',\
d.getVar('TFA_DEBUG'), d)}"
# Add mbedtls if measured boot is enabled
TFA_MBEDTLS := "${@bb.utils.contains('MACHINE_FEATURES', 'ts-attestation',\
'1', d.getVar('TFA_MBEDTLS'), d)}"
TFA_UBOOT ?= "1"
TFA_BUILD_TARGET = "bl1 bl2 bl31 dtbs fip"
@@ -3,7 +3,6 @@
COMPATIBLE_MACHINE = "juno"
TFA_PLATFORM = "juno"
TFA_DEBUG = "1"
TFA_MBEDTLS = "1"
TFA_UBOOT ?= "1"
TFA_BUILD_TARGET = "bl1 bl2 bl31 dtbs fip"
@@ -27,3 +27,29 @@ SRCREV_tfa = "a4b376b128bb5b91771002f7808566f53c8d9f3a"
SRC_URI:remove = "file://0001-feat-build-add-HOSTLDFLAGS-to-pass-flags-to-host-lin.patch"
LIC_FILES_CHKSUM:remove = "file://docs/license.rst;md5=6ed7bace7b0bc63021c6eba7b524039e"
LIC_FILES_CHKSUM += "file://docs/license.rst;md5=1118e32884721c0be33267bd7ae11130"
# sub-directory in which mbedtls will be downloaded
# Only needed for legacy versions, as v2.15.0 added this as a git submodule
TFA_MBEDTLS_DIR ?= "mbedtls"
# This should be set to MBEDTLS download URL if MBEDTLS is needed
SRC_URI_MBEDTLS ??= ""
# This should be set to MBEDTLS LIC FILES checksum
LIC_FILES_CHKSUM_MBEDTLS ??= ""
# add MBEDTLS to our sources if activated
SRC_URI:append = " ${@bb.utils.contains('TFA_MBEDTLS', '1', '${SRC_URI_MBEDTLS}', '', d)}"
# Update license variables
LICENSE:append = "${@bb.utils.contains('TFA_MBEDTLS', '1', ' & Apache-2.0', '', d)}"
LIC_FILES_CHKSUM:append = "${@bb.utils.contains('TFA_MBEDTLS', '1', ' ${LIC_FILES_CHKSUM_MBEDTLS}', '', d)}"
# add mbed TLS to version
SRCREV_FORMAT:append = "${@bb.utils.contains('TFA_MBEDTLS', '1', '_mbedtls', '', d)}"
# Handle MBEDTLS
EXTRA_OEMAKE += "${@bb.utils.contains('TFA_MBEDTLS', '1', 'MBEDTLS_DIR=${TFA_MBEDTLS_DIR}', '', d)}"
# in TF-A src, docs/getting_started/prerequisites.rst lists the expected version mbedtls
# mbedtls-3.6.5
SRCBRANCH_MBEDTLS = "mbedtls-3.6"
SRC_URI_MBEDTLS = "gitsm://github.com/Mbed-TLS/mbedtls;name=mbedtls;protocol=https;destsuffix=${BB_GIT_DEFAULT_DESTSUFFIX}/mbedtls;branch=${SRCBRANCH_MBEDTLS}"
SRCREV_mbedtls = "e185d7fd85499c8ce5ca2a54f5cf8fe7dbe3f8df"
LIC_FILES_CHKSUM_MBEDTLS = "file://mbedtls/LICENSE;md5=379d5819937a6c2f1ef1630d341e026d"
@@ -27,3 +27,29 @@ SRCREV_tfa = "a4b376b128bb5b91771002f7808566f53c8d9f3a"
SRC_URI:remove = "file://0001-feat-build-add-HOSTLDFLAGS-to-pass-flags-to-host-lin.patch"
LIC_FILES_CHKSUM:remove = "file://docs/license.rst;md5=6ed7bace7b0bc63021c6eba7b524039e"
LIC_FILES_CHKSUM += "file://docs/license.rst;md5=1118e32884721c0be33267bd7ae11130"
# sub-directory in which mbedtls will be downloaded
# Only needed for legacy versions, as v2.15.0 added this as a git submodule
TFA_MBEDTLS_DIR ?= "mbedtls"
# This should be set to MBEDTLS download URL if MBEDTLS is needed
SRC_URI_MBEDTLS ??= ""
# This should be set to MBEDTLS LIC FILES checksum
LIC_FILES_CHKSUM_MBEDTLS ??= ""
# add MBEDTLS to our sources if activated
SRC_URI:append = " ${@bb.utils.contains('TFA_MBEDTLS', '1', '${SRC_URI_MBEDTLS}', '', d)}"
# Update license variables
LICENSE:append = "${@bb.utils.contains('TFA_MBEDTLS', '1', ' & Apache-2.0', '', d)}"
LIC_FILES_CHKSUM:append = "${@bb.utils.contains('TFA_MBEDTLS', '1', ' ${LIC_FILES_CHKSUM_MBEDTLS}', '', d)}"
# add mbed TLS to version
SRCREV_FORMAT:append = "${@bb.utils.contains('TFA_MBEDTLS', '1', '_mbedtls', '', d)}"
# Handle MBEDTLS
EXTRA_OEMAKE += "${@bb.utils.contains('TFA_MBEDTLS', '1', 'MBEDTLS_DIR=${TFA_MBEDTLS_DIR}', '', d)}"
# in TF-A src, docs/getting_started/prerequisites.rst lists the expected version mbedtls
# mbedtls-3.6.5
SRCBRANCH_MBEDTLS = "mbedtls-3.6"
SRC_URI_MBEDTLS = "gitsm://github.com/Mbed-TLS/mbedtls;name=mbedtls;protocol=https;destsuffix=${BB_GIT_DEFAULT_DESTSUFFIX}/mbedtls;branch=${SRCBRANCH_MBEDTLS}"
SRCREV_mbedtls = "e185d7fd85499c8ce5ca2a54f5cf8fe7dbe3f8df"
LIC_FILES_CHKSUM_MBEDTLS = "file://mbedtls/LICENSE;md5=379d5819937a6c2f1ef1630d341e026d"
@@ -0,0 +1,32 @@
From 9edcdd272a7d2d872f7e04b3a9db5185fd24fd97 Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Tue, 28 Apr 2026 08:57:06 +0100
Subject: [PATCH] platform: corstone1000: Increase FIP partition size
Increase the FIP partition size from 2MB to 2.5MB in the
Corstone-1000 flash layout.
The previous size is insufficient for current FIP images,
which may lead to overflow during image generation or
deployment. Expanding the partition ensures adequate
space for firmware components packaged in the FIP.
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/50628]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
platform/ext/target/arm/corstone1000/partition/flash_layout.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platform/ext/target/arm/corstone1000/partition/flash_layout.h b/platform/ext/target/arm/corstone1000/partition/flash_layout.h
index e2219d80a..b7282beb2 100644
--- a/platform/ext/target/arm/corstone1000/partition/flash_layout.h
+++ b/platform/ext/target/arm/corstone1000/partition/flash_layout.h
@@ -139,7 +139,7 @@
#define TFM_PARTITION_SIZE (0x50000) /* 320 KB */
#define TFM_PARTITION_BANK_OFFSET (SE_BL2_PARTITION_SIZE)
-#define FIP_PARTITION_SIZE (0x200000) /* 2 MB */
+#define FIP_PARTITION_SIZE (0x280000) /* 2.5 MB */
#define FIP_PARTITION_BANK_OFFSET (TFM_PARTITION_BANK_OFFSET + TFM_PARTITION_SIZE)
#define INITRAMFS_PARTITION_SIZE (0xC00000) /* 12 MB */
@@ -91,6 +91,7 @@ SRC_URI:append:corstone1000 = " \
file://0057-plat-cs1k-Add-flash-erase-protection.patch \
file://0058-plat-cs1k-Remove-unused-FWU-partitions-upon-version-.patch \
file://0059-plat-cs1k-Duplicate-old-images-in-FWU.patch \
file://0060-platform-corstone1000-Increase-FIP-partition-size.patch \
"
SRCREV_tfm-psa-adac:corstone1000 = "f2809ae231be33a1afcd7714f40756c67d846c88"
@@ -86,6 +86,24 @@ SRC_URI:append = " \
file://0040-configs-corstone1000-disable-EFI-debug-support.patch \
"
# Add FF-A bus runtime support
SRC_URI:append = " \
file://0041-efi_loader-add-runtime-memset-helper.patch \
file://0042-arm-ffa-add-FF-A-bus-runtime-support.patch \
file://0043-efi_loader-add-FF-A-runtime-support-in-EFI-variable-.patch \
file://0044-efi_loader-enable-EFI-runtime-SetVariable-GetVariabl.patch \
file://0045-efi_loader-move-runtime-GetVariable-helpers-to-efi_v.patch \
file://0046-corstone1000-enable-bootefi-selftest.patch \
file://0047-efi-selftest-add-runtime-variable-tests-with-non-vol.patch \
file://0048-test-dm-add-sandbox-FF-A-runtime-transport-tests.patch \
file://0049-sandbox-ffa-share-synthetic-partition-metadata-via-m.patch \
file://0050-doc-arm64-document-FF-A-runtime-path-for-EFI-variabl.patch \
file://0051-doc-bootefi-note-two-phase-runtime-variables-selftes.patch \
file://0052-efi_loader-align-FF-A-cache-maintenance-with-runtime.patch \
file://0053-efi_loader-fix-AllocatePages-overlap-status.patch \
file://0054-corstone1000-a320-enable-bootefi-selftest.patch \
"
uboot_configure_config:append() {
openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=CRT/ -keyout ${B}/CRT.key -out ${S}/CRT.crt -nodes -days 365
}
@@ -1,4 +1,4 @@
From e070ae0f02b10bfd482146a748095ca782f73039 Mon Sep 17 00:00:00 2001
From e1b46cabacd2bbbde5ac42a01af21126788f274e Mon Sep 17 00:00:00 2001
From: Frazer Carsley <frazer.carsley@arm.com>
Date: Mon, 19 Jan 2026 15:16:52 +0000
Subject: [PATCH] corstone1000: enable OF_UPSTREAM device tree support
@@ -502,7 +502,7 @@ index 1b9c3a9ed16..db8919298e1 100644
if (!virtio_bus) {
log_err("Cannot find virtio device, err (%d)\n", ret);
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index 450d69762ab..350607892fa 100644
index 4ec23b4af1c..6ff855e7ce9 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -7,7 +7,7 @@ CONFIG_NR_DRAM_BANKS=1
@@ -514,7 +514,7 @@ index 450d69762ab..350607892fa 100644
CONFIG_SYS_BOOTM_LEN=0x800000
CONFIG_SYS_LOAD_ADDR=0x82100000
CONFIG_IDENT_STRING=" corstone1000 aarch64 "
@@ -55,6 +55,9 @@ CONFIG_CMD_RTC=y
@@ -56,6 +56,9 @@ CONFIG_CMD_RTC=y
CONFIG_CMD_TIME=y
CONFIG_CMD_GETTIME=y
CONFIG_OF_CONTROL=y
@@ -524,4 +524,3 @@ index 450d69762ab..350607892fa 100644
CONFIG_VERSION_VARIABLE=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_REGMAP=y
@@ -1,8 +1,7 @@
From df01111a866a37fcf875b3c2e2394414d27c89da Mon Sep 17 00:00:00 2001
From dd4db190281802141c4c787a9869f8153d93b1a4 Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Wed, 24 Sep 2025 13:42:25 +0000
Subject: [PATCH] corstone1000: dts: use 32-bit cells for
/reserved-memory node
Subject: [PATCH] corstone1000: dts: use 32-bit cells for /reserved-memory node
Switch the *reserved-memory* node from two-cell (64-bit) encoding to
one-cell (32-bit) encoding and adjust the `reg` property accordingly
@@ -34,4 +33,3 @@ index a75bc7016aa..4ea6f1d9724 100644
no-map;
};
};
@@ -1,4 +1,4 @@
From da23886f3b38812c60a4597db129ab96df74bb99 Mon Sep 17 00:00:00 2001
From 9b0a2622667bfe5794c77161d973d6f59871668c Mon Sep 17 00:00:00 2001
From: Frazer Carsley <frazer.carsley@arm.com>
Date: Wed, 25 Feb 2026 14:28:08 +0000
Subject: [PATCH] corstone1000-a320: Add Corstone1000 board variant
@@ -400,7 +400,7 @@ index 00000000000..e62978b487e
+F: board/armltd/corstone1000-a320/
+F: configs/corstone1000-a320_defconfig
diff --git a/board/armltd/corstone1000/corstone1000.c b/board/armltd/corstone1000/corstone1000.c
index db8919298e1..2f65eac7bf4 100644
index db8919298e1..fe6929e94e0 100644
--- a/board/armltd/corstone1000/corstone1000.c
+++ b/board/armltd/corstone1000/corstone1000.c
@@ -1,6 +1,6 @@
@@ -0,0 +1,63 @@
From 7e878429dc5f186ff945281513593c54beaf03f6 Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Fri, 10 Apr 2026 17:20:59 +0100
Subject: [PATCH 41/53] efi_loader: add runtime memset helper
Add efi_memset_runtime() for EFI runtime paths
This keeps buffer initialization in runtime-resident code after
ExitBootServices() and avoids relying on non-runtime helpers.
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
include/efi_loader.h | 3 +++
lib/efi_loader/efi_runtime.c | 21 +++++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 0340847c0b4..ec30042665b 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -1149,6 +1149,9 @@ struct pkcs7_message *efi_parse_pkcs7_header(const void *buf,
/* runtime implementation of memcpy() */
void efi_memcpy_runtime(void *dest, const void *src, size_t n);
+/* runtime implementation of memset */
+__efi_runtime void *efi_memset_runtime(void *dest, int c, size_t n);
+
/* commonly used helper functions */
u16 *efi_create_indexed_name(u16 *buffer, size_t buffer_size, const char *name,
unsigned int index);
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 35eb6a77766..e91b1583b6e 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -209,6 +209,27 @@ void __efi_runtime efi_memcpy_runtime(void *dest, const void *src, size_t n)
*d++ = *s++;
}
+/**
+ * efi_memset_runtime() - fill a memory region with a byte value
+ *
+ * At runtime memset() is not available.
+ *
+ * @dest: pointer to the block of memory to fill.
+ * @c: value to be set. The value is passed as an int, but the
+ * function fills the block of memory using the u8 conversion of this value.
+ * @n: number of bytes to be set to the value.
+ * Return: dest is returned
+ */
+__efi_runtime void *efi_memset_runtime(void *dest, int c, size_t n)
+{
+ u8 *d = dest;
+
+ for (; n; --n)
+ *d++ = c;
+
+ return dest;
+}
+
/**
* efi_update_table_header_crc32() - Update crc32 in table header
*
@@ -0,0 +1,975 @@
From 2f4000043db3a5658e946a66f1e2b8b8c48dffc7 Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Thu, 20 Nov 2025 21:56:22 +0000
Subject: [PATCH 42/53] arm-ffa: add FF-A bus runtime support
Enable FF-A runtime transport for EFI services
This patch introduces the FF-A runtime infrastructure that enables
U-Boot to use the Arm Firmware Framework for Arm A-profile (FF-A)
transport layer after ExitBootServices().
The runtime transport provides persistent, runtime-safe
implementations of key FF-A functions used by EFI runtime services.
Summary of key changes:
-----------------------
- Add drivers/firmware/arm-ffa/arm-ffa-runtime.c implementing FF-A
runtime operations.
- Introduce include/arm_ffa_runtime.h exporting FF-A runtime
functions and data structures.
- Move FF-A error mapping into runtime context.
- Introduce invoke_ffa_fn_runtime() as runtime safe SMC wrapper.
- Add runtime SMC wrapper for sandbox emulation.
- Add ARM_FFA_RT_MODE Kconfig to enable runtime support.
- Register ExitBootServices hook for runtime context.
- Copy ffa_priv runtime fields into resident storage at
ExitBootServices.
- Extend Makefile to build arm-ffa-runtime.c.
All runtime functions and global data are tagged with __efi_runtime or
__efi_runtime_data to ensure persistence after ExitBootServices().
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
drivers/firmware/arm-ffa/Kconfig | 11 +
drivers/firmware/arm-ffa/Makefile | 4 +-
drivers/firmware/arm-ffa/arm-ffa-runtime.c | 293 +++++++++++++++++++++
drivers/firmware/arm-ffa/arm-ffa-uclass.c | 113 ++------
drivers/firmware/arm-ffa/arm-ffa.c | 16 +-
drivers/firmware/arm-ffa/ffa-emul-uclass.c | 12 +
include/arm_ffa.h | 16 +-
include/arm_ffa_priv.h | 24 +-
include/arm_ffa_runtime.h | 189 +++++++++++++
test/dm/ffa.c | 6 +-
10 files changed, 564 insertions(+), 120 deletions(-)
create mode 100644 drivers/firmware/arm-ffa/arm-ffa-runtime.c
create mode 100644 include/arm_ffa_runtime.h
diff --git a/drivers/firmware/arm-ffa/Kconfig b/drivers/firmware/arm-ffa/Kconfig
index d75f8b53fd8..1be9adeb1db 100644
--- a/drivers/firmware/arm-ffa/Kconfig
+++ b/drivers/firmware/arm-ffa/Kconfig
@@ -17,6 +17,9 @@ config ARM_FFA_TRANSPORT
The FF-A support in U-Boot is based on FF-A specification v1.0 and uses SMC32
calling convention.
+ The FF-A bus also provides a runtime layer to keep a minimal set of FF-A
+ operations available after ExitBootServices().
+
FF-A specification:
https://developer.arm.com/documentation/den0077/a/?lang=en
@@ -40,3 +43,11 @@ config ARM_FFA_TRANSPORT
Secure World (sandbox_ffa.c).
For more details about the FF-A support, please refer to doc/arch/arm64.ffa.rst
+
+config ARM_FFA_RT_MODE
+ bool "Enable FF-A runtime support"
+ depends on ARM_FFA_TRANSPORT && EFI_LOADER
+ default y
+ help
+ Enable the FF-A runtime layer, keeping a minimal set of FF-A
+ operations available after ExitBootServices().
diff --git a/drivers/firmware/arm-ffa/Makefile b/drivers/firmware/arm-ffa/Makefile
index 318123a7f42..9deb59ba640 100644
--- a/drivers/firmware/arm-ffa/Makefile
+++ b/drivers/firmware/arm-ffa/Makefile
@@ -1,12 +1,12 @@
# SPDX-License-Identifier: GPL-2.0+
#
-# Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# Copyright 2022-2023, 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
#
# Authors:
# Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
# build the generic FF-A methods
-obj-y += arm-ffa-uclass.o
+obj-y += arm-ffa-uclass.o arm-ffa-runtime.o
ifeq ($(CONFIG_SANDBOX),y)
# build the FF-A sandbox emulator and driver
obj-y += ffa-emul-uclass.o sandbox_ffa.o
diff --git a/drivers/firmware/arm-ffa/arm-ffa-runtime.c b/drivers/firmware/arm-ffa/arm-ffa-runtime.c
new file mode 100644
index 00000000000..82c75da7d4b
--- /dev/null
+++ b/drivers/firmware/arm-ffa/arm-ffa-runtime.c
@@ -0,0 +1,293 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ *
+ * Authors:
+ * Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+ */
+
+#include <arm_ffa_runtime.h>
+#include <arm_ffa_priv.h>
+#include <log.h>
+#include <asm/global_data.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Error mapping declarations */
+
+int __ffa_runtime_data ffa_to_std_errmap[MAX_NUMBER_FFA_ERR] = {
+ [NOT_SUPPORTED] = -EOPNOTSUPP,
+ [INVALID_PARAMETERS] = -EINVAL,
+ [NO_MEMORY] = -ENOMEM,
+ [BUSY] = -EBUSY,
+ [INTERRUPTED] = -EINTR,
+ [DENIED] = -EACCES,
+ [RETRY] = -EAGAIN,
+ [ABORTED] = -ECANCELED,
+};
+
+static __ffa_runtime_data struct ffa_priv_runtime ffa_priv_rt = {0};
+
+/* Arm FF-A driver runtime operations */
+static const __ffa_runtime_data struct ffa_bus_ops_runtime ffa_ops_rt = {
+ .sync_send_receive = ffa_msg_send_direct_req_hdlr_runtime,
+};
+
+#define ffa_get_ops_runtime() (&ffa_ops_rt)
+#define ffa_get_priv_runtime() (&ffa_priv_rt)
+
+#if CONFIG_IS_ENABLED(ARM_FFA_RT_MODE)
+static void EFIAPI ffa_rt_exit_boot_services_notify(struct efi_event *event,
+ void *context)
+{
+ struct ffa_priv *priv = context;
+
+ if (priv)
+ ffa_copy_runtime_priv(&priv->rt);
+ else
+ log_err("FF-A: Entering RT mode without FF-A runtime data information\n");
+
+ ffa_enable_runtime_context();
+}
+
+/**
+ * ffa_setup_efi_exit_boot_services_event() - register ExitBootServices event
+ * @priv: pointer to the FF-A private data
+ *
+ * Register an EFI event that enables the FF-A runtime context when
+ * ExitBootServices() is invoked.
+ *
+ * Return: 0 on success, -EPERM on failure to create the event.
+ */
+int ffa_setup_efi_exit_boot_services_event(struct ffa_priv *priv)
+{
+ efi_status_t efi_ret;
+ struct efi_event *evt = NULL;
+
+ efi_ret = efi_create_event(EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
+ ffa_rt_exit_boot_services_notify, priv,
+ &efi_guid_event_group_exit_boot_services,
+ &evt);
+ if (efi_ret != EFI_SUCCESS) {
+ log_err("FF-A: cannot install ExitBootServices event %p, err (%lu)\n",
+ evt, efi_ret);
+ return -EPERM;
+ }
+
+ return 0;
+}
+#endif
+
+/**
+ * ffa_copy_runtime_priv() - copy runtime data into resident storage
+ * @priv: pointer to the runtime private data
+ *
+ * Copy boot-time runtime data into the resident runtime storage to be used
+ * after ExitBootServices().
+ */
+void ffa_copy_runtime_priv(const struct ffa_priv_runtime *priv)
+{
+ struct ffa_priv_runtime *priv_rt = ffa_get_priv_runtime();
+
+ if (priv)
+ *priv_rt = *priv;
+}
+
+/**
+ * ffa_enable_runtime_context() - Enable FF-A runtime context
+ *
+ * This function marks the FF-A runtime environment as ready for use by
+ * EFI runtime services. It is called when ExitBootServices() is invoked,
+ * after the FF-A bus device has successfully probed and U-Boots FF-A
+ * endpoint ID has been discovered and stored in the runtime private data
+ * structure.
+ *
+ * The FF-A runtime flag allows the EFI runtime layer to verify that the
+ * FF-A transport was initialized during the boot phase and that all
+ * runtime-safe FF-A operations may now be used after ExitBootServices().
+ *
+ */
+void ffa_enable_runtime_context(void)
+{
+ struct ffa_priv_runtime *priv_rt = ffa_get_priv_runtime();
+
+ priv_rt->use_ffa_runtime = true;
+}
+
+/**
+ * ffa_get_status_runtime_context() - Query FF-A runtime readiness
+ *
+ * This helper returns whether the FF-A runtime environment has been
+ * enabled during the boot phase. Runtime FF-A operations must check this
+ * flag before attempting any FF-A access, as the U-Boot driver model
+ * (DM/uclass) is no longer available after ExitBootServices().
+ *
+ * The runtime context becomes enabled when ffa_enable_runtime_context()
+ * is called, typically after the FF-A bus device has probed and the
+ * endpoint ID has been discovered and stored in the runtime private
+ * data structure.
+ *
+ * Return:
+ * true FF-A runtime support is ready
+ * false FF-A runtime environment is not ready
+ */
+bool __ffa_runtime ffa_get_status_runtime_context(void)
+{
+ struct ffa_priv_runtime *priv_rt = ffa_get_priv_runtime();
+
+ return priv_rt->use_ffa_runtime;
+}
+
+/**
+ * ffa_to_std_errno() - convert FF-A error code to standard error code
+ * @ffa_errno: Error code returned by the FF-A ABI
+ *
+ * Map the given FF-A error code as specified
+ * by the spec to a u-boot standard error code.
+ *
+ * Return:
+ *
+ * The standard error code on success. . Otherwise, failure
+ */
+int __ffa_runtime ffa_to_std_errno(int ffa_errno)
+{
+ int err_idx = -ffa_errno;
+
+ /* Map the FF-A error code to the standard u-boot error code */
+ if (err_idx > 0 && err_idx < MAX_NUMBER_FFA_ERR)
+ return ffa_to_std_errmap[err_idx];
+ return -EINVAL;
+}
+
+/**
+ * ffa_invoke_msg_send_direct_req() - Invokes FFA_MSG_SEND_DIRECT_{REQ,RESP}
+ * @endpoint_id: u-boot endpoint id
+ * @dst_part_id: destination partition ID
+ * @msg: pointer to the message data preallocated by the client (in/out)
+ * @is_smc64: select 64-bit or 32-bit FF-A ABI
+ *
+ * This function invokes FFA_MSG_SEND_DIRECT_{REQ,RESP} FF-A functions.
+ *
+ * FFA_MSG_SEND_DIRECT_REQ is used to send the data to the secure partition.
+ * The response from the secure partition is handled by reading the
+ * FFA_MSG_SEND_DIRECT_RESP arguments.
+ *
+ * The maximum size of the data that can be exchanged is 40 bytes which is
+ * sizeof(struct ffa_send_direct_data) as defined by the FF-A specification 1.0
+ * in the section relevant to FFA_MSG_SEND_DIRECT_{REQ,RESP}
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, error on failure
+ */
+int __ffa_runtime ffa_invoke_msg_send_direct_req(u16 endpoint_id, u16 dst_part_id,
+ struct ffa_send_direct_data *msg, bool is_smc64)
+{
+ int ffa_errno;
+ u64 req_mode;
+ ffa_value_t ffa_args_rt;
+ ffa_value_t ffa_res_rt;
+
+ if (is_smc64) {
+ req_mode = FFA_SMC_64(FFA_MSG_SEND_DIRECT_REQ);
+ } else {
+ req_mode = FFA_SMC_32(FFA_MSG_SEND_DIRECT_REQ);
+ }
+
+ efi_memset_runtime(&ffa_args_rt, 0, sizeof(ffa_args_rt));
+ efi_memset_runtime(&ffa_res_rt, 0, sizeof(ffa_res_rt));
+ ffa_args_rt.a0 = req_mode;
+ ffa_args_rt.a1 = PREP_SELF_ENDPOINT_ID(endpoint_id) |
+ PREP_PART_ENDPOINT_ID(dst_part_id);
+ ffa_args_rt.a2 = 0;
+ ffa_args_rt.a3 = msg->data0;
+ ffa_args_rt.a4 = msg->data1;
+ ffa_args_rt.a5 = msg->data2;
+ ffa_args_rt.a6 = msg->data3;
+ ffa_args_rt.a7 = msg->data4;
+
+ invoke_ffa_fn_runtime(&ffa_args_rt, &ffa_res_rt);
+
+ while (ffa_res_rt.a0 == FFA_SMC_32(FFA_INTERRUPT) ||
+ ffa_res_rt.a0 == FFA_SMC_64(FFA_INTERRUPT)) {
+ efi_memset_runtime(&ffa_args_rt, 0, sizeof(ffa_args_rt));
+ ffa_args_rt.a0 = (ffa_res_rt.a0 == FFA_SMC_64(FFA_INTERRUPT)) ?
+ FFA_SMC_64(FFA_RUN) : FFA_SMC_32(FFA_RUN);
+ ffa_args_rt.a1 = ffa_res_rt.a1;
+
+ invoke_ffa_fn_runtime(&ffa_args_rt, &ffa_res_rt);
+ }
+ if (ffa_res_rt.a0 == FFA_SMC_32(FFA_SUCCESS) ||
+ ffa_res_rt.a0 == FFA_SMC_64(FFA_SUCCESS)) {
+ /* Message sent with no response */
+ return 0;
+ }
+
+ if (ffa_res_rt.a0 == FFA_SMC_32(FFA_MSG_SEND_DIRECT_RESP) ||
+ ffa_res_rt.a0 == FFA_SMC_64(FFA_MSG_SEND_DIRECT_RESP)) {
+ /* Message sent with response extract the return data */
+ msg->data0 = ffa_res_rt.a3;
+ msg->data1 = ffa_res_rt.a4;
+ msg->data2 = ffa_res_rt.a5;
+ msg->data3 = ffa_res_rt.a6;
+ msg->data4 = ffa_res_rt.a7;
+ return 0;
+ }
+
+ ffa_errno = ffa_res_rt.a2;
+ return ffa_to_std_errno(ffa_errno);
+}
+
+/**
+ * ffa_msg_send_direct_req_hdlr_runtime() - Runtime implementation of
+ * FFA_MSG_SEND_DIRECT_{REQ,RESP} handler function
+ * @dst_part_id: destination partition ID
+ * @msg: pointer to the message data preallocated by the client (in/out)
+ * @is_smc64: select 64-bit or 32-bit FF-A ABI
+ *
+ * This function calls the ffa_invoke_msg_send_direct_req() function which
+ * invokes FFA_MSG_SEND_DIRECT_{REQ,RESP} FF-A functions.
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, failure
+ */
+int __ffa_runtime ffa_msg_send_direct_req_hdlr_runtime(u16 dst_part_id,
+ struct ffa_send_direct_data *msg,
+ bool is_smc64)
+{
+ struct ffa_priv_runtime *priv_rt = ffa_get_priv_runtime();
+
+ return ffa_invoke_msg_send_direct_req(priv_rt->id, dst_part_id, msg, is_smc64);
+}
+
+/**
+ * ffa_sync_send_receive_runtime() - Runtime implementation of
+ * ffa_sync_send_receive()
+ * @dst_part_id: destination partition ID
+ * @msg: pointer to the message data preallocated by the client (in/out)
+ * @is_smc64: select 64-bit or 32-bit FF-A ABI
+ *
+ * Please see ffa_msg_send_direct_req_hdlr_runtime() description for more details.
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, failure
+ */
+int __ffa_runtime ffa_sync_send_receive_runtime(u16 dst_part_id,
+ struct ffa_send_direct_data *msg,
+ bool is_smc64)
+{
+ const struct ffa_bus_ops_runtime *ops_rt = ffa_get_ops_runtime();
+
+ if (!ffa_get_status_runtime_context())
+ return -EPERM;
+
+ if (!ops_rt->sync_send_receive)
+ return -ENOSYS;
+
+ return ops_rt->sync_send_receive(dst_part_id, msg, is_smc64);
+}
diff --git a/drivers/firmware/arm-ffa/arm-ffa-uclass.c b/drivers/firmware/arm-ffa/arm-ffa-uclass.c
index 597b4e994b4..f769e0e9b05 100644
--- a/drivers/firmware/arm-ffa/arm-ffa-uclass.c
+++ b/drivers/firmware/arm-ffa/arm-ffa-uclass.c
@@ -1,12 +1,13 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2022-2023, 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * Copyright 2022-2023, 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* Authors:
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
#include <arm_ffa.h>
#include <arm_ffa_priv.h>
+#include <arm_ffa_runtime.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
@@ -21,19 +22,6 @@
DECLARE_GLOBAL_DATA_PTR;
-/* Error mapping declarations */
-
-int ffa_to_std_errmap[MAX_NUMBER_FFA_ERR] = {
- [NOT_SUPPORTED] = -EOPNOTSUPP,
- [INVALID_PARAMETERS] = -EINVAL,
- [NO_MEMORY] = -ENOMEM,
- [BUSY] = -EBUSY,
- [INTERRUPTED] = -EINTR,
- [DENIED] = -EACCES,
- [RETRY] = -EAGAIN,
- [ABORTED] = -ECANCELED,
-};
-
static struct ffa_abi_errmap err_msg_map[FFA_ERRMAP_COUNT] = {
[FFA_ID_TO_ERRMAP_ID(FFA_VERSION)] = {
{
@@ -123,27 +111,6 @@ static struct ffa_abi_errmap err_msg_map[FFA_ERRMAP_COUNT] = {
},
};
-/**
- * ffa_to_std_errno() - convert FF-A error code to standard error code
- * @ffa_errno: Error code returned by the FF-A ABI
- *
- * Map the given FF-A error code as specified
- * by the spec to a u-boot standard error code.
- *
- * Return:
- *
- * The standard error code on success. . Otherwise, failure
- */
-static int ffa_to_std_errno(int ffa_errno)
-{
- int err_idx = -ffa_errno;
-
- /* Map the FF-A error code to the standard u-boot error code */
- if (err_idx > 0 && err_idx < MAX_NUMBER_FFA_ERR)
- return ffa_to_std_errmap[err_idx];
- return -EINVAL;
-}
-
/**
* ffa_print_error_log() - print the error log corresponding to the selected FF-A ABI
* @ffa_id: FF-A ABI ID
@@ -233,7 +200,7 @@ int ffa_get_version_hdlr(struct udevice *dev)
if (dev) {
uc_priv = dev_get_uclass_priv(dev);
if (uc_priv)
- uc_priv->fwk_version = res.a0;
+ uc_priv->rt.fwk_version = res.a0;
}
return 0;
@@ -267,8 +234,8 @@ static int ffa_get_endpoint_id(struct udevice *dev)
}, &res);
if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) {
- uc_priv->id = GET_SELF_ENDPOINT_ID((u32)res.a2);
- log_debug("FF-A endpoint ID is %u\n", uc_priv->id);
+ uc_priv->rt.id = GET_SELF_ENDPOINT_ID((u32)res.a2);
+ log_debug("FF-A endpoint ID is %u\n", uc_priv->rt.id);
return 0;
}
@@ -490,7 +457,7 @@ int ffa_unmap_rxtx_buffers_hdlr(struct udevice *dev)
invoke_ffa_fn((ffa_value_t){
.a0 = FFA_SMC_32(FFA_RXTX_UNMAP),
- .a1 = PREP_SELF_ENDPOINT_ID(uc_priv->id),
+ .a1 = PREP_SELF_ENDPOINT_ID(uc_priv->rt.id),
}, &res);
if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) {
@@ -880,16 +847,8 @@ static int ffa_cache_partitions_info(struct udevice *dev)
* @msg: pointer to the message data preallocated by the client (in/out)
* @is_smc64: select 64-bit or 32-bit FF-A ABI
*
- * Implement FFA_MSG_SEND_DIRECT_{REQ,RESP}
- * FF-A functions.
- *
- * FFA_MSG_SEND_DIRECT_REQ is used to send the data to the secure partition.
- * The response from the secure partition is handled by reading the
- * FFA_MSG_SEND_DIRECT_RESP arguments.
- *
- * The maximum size of the data that can be exchanged is 40 bytes which is
- * sizeof(struct ffa_send_direct_data) as defined by the FF-A specification 1.0
- * in the section relevant to FFA_MSG_SEND_DIRECT_{REQ,RESP}
+ * This function calls the ffa_invoke_msg_send_direct_req() function which
+ * invokes FFA_MSG_SEND_DIRECT_{REQ,RESP} FF-A functions.
*
* Return:
*
@@ -898,9 +857,6 @@ static int ffa_cache_partitions_info(struct udevice *dev)
int ffa_msg_send_direct_req_hdlr(struct udevice *dev, u16 dst_part_id,
struct ffa_send_direct_data *msg, bool is_smc64)
{
- ffa_value_t res = {0};
- int ffa_errno;
- u64 req_mode, resp_mode;
struct ffa_priv *uc_priv;
uc_priv = dev_get_uclass_priv(dev);
@@ -909,50 +865,7 @@ int ffa_msg_send_direct_req_hdlr(struct udevice *dev, u16 dst_part_id,
if (!uc_priv->partitions.count || !uc_priv->partitions.descs)
return -ENODEV;
- if (is_smc64) {
- req_mode = FFA_SMC_64(FFA_MSG_SEND_DIRECT_REQ);
- resp_mode = FFA_SMC_64(FFA_MSG_SEND_DIRECT_RESP);
- } else {
- req_mode = FFA_SMC_32(FFA_MSG_SEND_DIRECT_REQ);
- resp_mode = FFA_SMC_32(FFA_MSG_SEND_DIRECT_RESP);
- }
-
- invoke_ffa_fn((ffa_value_t){
- .a0 = req_mode,
- .a1 = PREP_SELF_ENDPOINT_ID(uc_priv->id) |
- PREP_PART_ENDPOINT_ID(dst_part_id),
- .a2 = 0,
- .a3 = msg->data0,
- .a4 = msg->data1,
- .a5 = msg->data2,
- .a6 = msg->data3,
- .a7 = msg->data4,
- }, &res);
-
- while (res.a0 == FFA_SMC_32(FFA_INTERRUPT))
- invoke_ffa_fn((ffa_value_t){
- .a0 = FFA_SMC_32(FFA_RUN),
- .a1 = res.a1,
- }, &res);
-
- if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) {
- /* Message sent with no response */
- return 0;
- }
-
- if (res.a0 == resp_mode) {
- /* Message sent with response extract the return data */
- msg->data0 = res.a3;
- msg->data1 = res.a4;
- msg->data2 = res.a5;
- msg->data3 = res.a6;
- msg->data4 = res.a7;
-
- return 0;
- }
-
- ffa_errno = res.a2;
- return ffa_to_std_errno(ffa_errno);
+return ffa_invoke_msg_send_direct_req(uc_priv->rt.id, dst_part_id, msg, is_smc64);
}
/**
@@ -1008,7 +921,7 @@ static int ffa_setup_and_transmit(struct udevice *dev, u32 func_id,
mem_region->tag = args->tag;
mem_region->flags = args->flags;
- mem_region->sender_id = uc_priv->id;
+ mem_region->sender_id = uc_priv->rt.id;
/*
* These attributes are only valid for FFA_MEM_SHARE.
@@ -1322,6 +1235,7 @@ int ffa_memory_reclaim(struct udevice *dev, u64 g_handle, u32 flags)
static int ffa_do_probe(struct udevice *dev)
{
int ret;
+ struct ffa_priv *uc_priv = dev_get_uclass_priv(dev);
ret = ffa_get_version_hdlr(dev);
if (ret)
@@ -1345,6 +1259,11 @@ static int ffa_do_probe(struct udevice *dev)
return ret;
}
+ if (IS_ENABLED(CONFIG_ARM_FFA_RT_MODE)) {
+ ret = ffa_setup_efi_exit_boot_services_event(uc_priv);
+ if (ret)
+ return ret;
+ }
return 0;
}
diff --git a/drivers/firmware/arm-ffa/arm-ffa.c b/drivers/firmware/arm-ffa/arm-ffa.c
index de36f5647d2..0d451c0ddc7 100644
--- a/drivers/firmware/arm-ffa/arm-ffa.c
+++ b/drivers/firmware/arm-ffa/arm-ffa.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2022-2023, 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * Copyright 2022-2023, 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* Authors:
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
@@ -8,6 +8,7 @@
#include <arm_ffa.h>
#include <arm_ffa_priv.h>
+#include <arm_ffa_runtime.h>
#include <dm.h>
#include <log.h>
#include <asm/global_data.h>
@@ -28,6 +29,19 @@ void invoke_ffa_fn(ffa_value_t args, ffa_value_t *res)
arm_smccc_1_2_smc(&args, res);
}
+/**
+ * invoke_ffa_fn_runtime() - Runtime-safe SMC wrapper
+ * @args: FF-A ABI arguments to be copied to Xn registers
+ * @res: FF-A ABI return values copied from Xn registers
+ *
+ * Calls the SMCCC SMC 1.2 helper from EFI runtime context. This wrapper
+ * is marked __ffa_runtime so it remains available after ExitBootServices().
+ */
+void __ffa_runtime invoke_ffa_fn_runtime(ffa_value_t *args, ffa_value_t *res)
+{
+ arm_smccc_1_2_smc(args, res);
+}
+
/**
* arm_ffa_discover() - perform FF-A discovery
* @dev: The Arm FF-A bus device (arm_ffa)
diff --git a/drivers/firmware/arm-ffa/ffa-emul-uclass.c b/drivers/firmware/arm-ffa/ffa-emul-uclass.c
index a630392b6d1..531ecb12f3a 100644
--- a/drivers/firmware/arm-ffa/ffa-emul-uclass.c
+++ b/drivers/firmware/arm-ffa/ffa-emul-uclass.c
@@ -758,6 +758,18 @@ void invoke_ffa_fn(ffa_value_t args, ffa_value_t *res)
sandbox_arm_ffa_smccc_smc(&args, res);
}
+/**
+ * invoke_ffa_fn_runtime() - Runtime-safe SMC wrapper
+ * @args: FF-A ABI arguments to be copied to Xn registers
+ * @res: FF-A ABI return data to be copied from Xn registers
+ *
+ * Calls the emulated SMC call.
+ */
+void invoke_ffa_fn_runtime(ffa_value_t *args, ffa_value_t *res)
+{
+ sandbox_arm_ffa_smccc_smc(args, res);
+}
+
/**
* ffa_emul_find() - Find the FF-A emulator
* @dev: the sandbox FF-A device (sandbox-arm-ffa)
diff --git a/include/arm_ffa.h b/include/arm_ffa.h
index 1229e6e3d02..f19a9759e55 100644
--- a/include/arm_ffa.h
+++ b/include/arm_ffa.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * Copyright 2022-2023, 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * Copyright 2022-2023, 2025-2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* Authors:
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
@@ -195,21 +195,13 @@ int ffa_sync_send_receive(struct udevice *dev, u16 dst_part_id,
/**
* ffa_msg_send_direct_req_hdlr() - FFA_MSG_SEND_DIRECT_{REQ,RESP} handler function
- * @dev: The arm_ffa bus device
+ * @dev: The FF-A bus device
* @dst_part_id: destination partition ID
* @msg: pointer to the message data preallocated by the client (in/out)
* @is_smc64: select 64-bit or 32-bit FF-A ABI
*
- * This function implements FFA_MSG_SEND_DIRECT_{REQ,RESP}
- * FF-A functions.
- *
- * FFA_MSG_SEND_DIRECT_REQ is used to send the data to the secure partition.
- * The response from the secure partition is handled by reading the
- * FFA_MSG_SEND_DIRECT_RESP arguments.
- *
- * The maximum size of the data that can be exchanged is 40 bytes which is
- * sizeof(struct ffa_send_direct_data) as defined by the FF-A specification 1.0
- * in the section relevant to FFA_MSG_SEND_DIRECT_{REQ,RESP}
+ * This function calls the ffa_invoke_msg_send_direct_req() function which
+ * invokes FFA_MSG_SEND_DIRECT_{REQ,RESP} FF-A functions.
*
* Return:
*
diff --git a/include/arm_ffa_priv.h b/include/arm_ffa_priv.h
index 54196199ce3..73eba942e3b 100644
--- a/include/arm_ffa_priv.h
+++ b/include/arm_ffa_priv.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * Copyright 2022-2023, 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * Copyright 2022-2023, 2025-2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* Authors:
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
@@ -202,11 +202,26 @@ struct ffa_partitions {
};
/**
- * struct ffa_priv - the driver private data structure
+ * struct ffa_priv_runtime - the driver's private runtime data structure
*
+ * @use_ffa_runtime: Whether FF-A runtime is available to use or not
* @fwk_version: FF-A framework version
- * @emul: FF-A sandbox emulator
* @id: u-boot endpoint ID
+ *
+ * The device private runtime data structure containing all the
+ * data read from secure world.
+ */
+struct ffa_priv_runtime {
+ bool use_ffa_runtime;
+ u32 fwk_version;
+ u16 id;
+};
+
+/**
+ * struct ffa_priv - the driver private data structure
+ *
+ * @rt: Runtime data captured at boot time
+ * @emul: FF-A sandbox emulator
* @partitions: The partitions descriptors structure
* @pair: The RX/TX buffers pair
*
@@ -214,9 +229,8 @@ struct ffa_partitions {
* data read from secure world.
*/
struct ffa_priv {
- u32 fwk_version;
+ struct ffa_priv_runtime rt;
struct udevice *emul;
- u16 id;
struct ffa_partitions partitions;
struct ffa_rxtxpair pair;
};
diff --git a/include/arm_ffa_runtime.h b/include/arm_ffa_runtime.h
new file mode 100644
index 00000000000..b6ddda68f4b
--- /dev/null
+++ b/include/arm_ffa_runtime.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ *
+ * Authors:
+ * Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+ */
+
+#ifndef __ARM_FFA_RUNTIME_H
+#define __ARM_FFA_RUNTIME_H
+
+#include <linux/types.h>
+#include <arm_ffa.h>
+#include <arm_ffa_priv.h>
+#include <efi_loader.h>
+
+/**
+ * __ffa_runtime - controls whether functions are
+ * available after calling the EFI ExitBootServices service.
+ * Functions tagged with these keywords are resident (available at boot time and
+ * at runtime)
+ */
+#if CONFIG_IS_ENABLED(ARM_FFA_RT_MODE)
+#define __ffa_runtime_data __efi_runtime_data
+#define __ffa_runtime __efi_runtime
+#else
+#define __ffa_runtime_data
+#define __ffa_runtime
+#endif
+
+/**
+ * invoke_ffa_fn_runtime() - Runtime-safe SMC wrapper
+ * @args: FF-A ABI arguments to be copied to Xn registers
+ * @res: FF-A ABI return values copied from Xn registers
+ *
+ * Calls low level SMC implementation. This wrapper
+ * is marked __ffa_runtime so it remains available after ExitBootServices().
+ */
+void __ffa_runtime invoke_ffa_fn_runtime(ffa_value_t *args, ffa_value_t *res);
+
+/**
+ * struct ffa_bus_ops_runtime - Operations for FF-A runtime
+ * @sync_send_receive: callback for the FFA_MSG_SEND_DIRECT_REQ
+ *
+ * The data structure providing all the runtime operations supported by the driver.
+ * This structure is an EFI runtime resident.
+ */
+struct ffa_bus_ops_runtime {
+ int (*sync_send_receive)(u16 dst_part_id, struct ffa_send_direct_data *msg,
+ bool is_smc64);
+};
+
+/**
+ * ffa_enable_runtime_context() - Enable FF-A runtime context
+ *
+ * This function marks the FF-A runtime environment as ready for use by
+ * EFI runtime services. It is called when ExitBootServices() is invoked,
+ * after the FF-A bus device has successfully probed and U-Boots FF-A
+ * endpoint ID has been discovered and stored in the runtime private data
+ * structure.
+ *
+ * The FF-A runtime flag allows the EFI runtime layer to verify that the
+ * FF-A transport was initialized during the boot phase and that all
+ * runtime-safe FF-A operations may now be used after ExitBootServices().
+ *
+ */
+void ffa_enable_runtime_context(void);
+
+/**
+ * ffa_copy_runtime_priv() - copy runtime data into resident storage
+ * @priv: pointer to the runtime private data
+ *
+ * Copy boot-time runtime data into the resident runtime storage to be used
+ * after ExitBootServices().
+ */
+void ffa_copy_runtime_priv(const struct ffa_priv_runtime *priv);
+
+/**
+ * ffa_setup_efi_exit_boot_services_event() - register ExitBootServices event
+ * @priv: pointer to the FF-A private data
+ *
+ * Register an EFI event that enables the FF-A runtime context when
+ * ExitBootServices() is invoked.
+ *
+ * Return: 0 on success, -EPERM on failure to create the event.
+ */
+#if CONFIG_IS_ENABLED(ARM_FFA_RT_MODE)
+int ffa_setup_efi_exit_boot_services_event(struct ffa_priv *priv);
+#else
+static inline int ffa_setup_efi_exit_boot_services_event(struct ffa_priv *priv)
+{
+ return 0;
+}
+#endif
+
+/**
+ * ffa_get_status_runtime_context() - Query FF-A runtime readiness
+ *
+ * This helper returns whether the FF-A runtime environment has been
+ * enabled during the boot phase. Runtime FF-A operations must check this
+ * flag before attempting any FF-A access, as the U-Boot driver model
+ * (DM/uclass) is no longer available after ExitBootServices().
+ *
+ * The runtime context becomes enabled when ffa_enable_runtime_context()
+ * is called, typically after the FF-A bus device has probed and the
+ * endpoint ID has been discovered and stored in the runtime private
+ * data structure.
+ *
+ * Return:
+ * true FF-A runtime support is ready
+ * false FF-A runtime environment is not ready
+ */
+bool __ffa_runtime ffa_get_status_runtime_context(void);
+
+/**
+ * ffa_to_std_errno() - convert FF-A error code to standard error code
+ * @ffa_errno: Error code returned by the FF-A ABI
+ *
+ * Map the given FF-A error code as specified
+ * by the spec to a u-boot standard error code.
+ *
+ * Return:
+ *
+ * The standard error code on success. . Otherwise, failure
+ */
+int __ffa_runtime ffa_to_std_errno(int ffa_errno);
+
+/**
+ * ffa_sync_send_receive_runtime() - Runtime implementation of
+ * ffa_sync_send_receive()
+ * @dst_part_id: destination partition ID
+ * @msg: pointer to the message data preallocated by the client (in/out)
+ * @is_smc64: select 64-bit or 32-bit FF-A ABI
+ *
+ * Please see ffa_msg_send_direct_req_hdlr_runtime() description for more details.
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, failure
+ */
+int __ffa_runtime ffa_sync_send_receive_runtime(u16 dst_part_id,
+ struct ffa_send_direct_data *msg,
+ bool is_smc64);
+
+/**
+ * ffa_invoke_msg_send_direct_req() - Invokes FFA_MSG_SEND_DIRECT_{REQ,RESP}
+ * @endpoint_id: u-boot endpoint id
+ * @dst_part_id: destination partition ID
+ * @msg: pointer to the message data preallocated by the client (in/out)
+ * @is_smc64: select 64-bit or 32-bit FF-A ABI
+ *
+ * This function invokes FFA_MSG_SEND_DIRECT_{REQ,RESP} FF-A functions.
+ *
+ * FFA_MSG_SEND_DIRECT_REQ is used to send the data to the secure partition.
+ * The response from the secure partition is handled by reading the
+ * FFA_MSG_SEND_DIRECT_RESP arguments.
+ *
+ * The maximum size of the data that can be exchanged is 40 bytes which is
+ * sizeof(struct ffa_send_direct_data) as defined by the FF-A specification 1.0
+ * in the section relevant to FFA_MSG_SEND_DIRECT_{REQ,RESP}
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, error on failure
+ */
+int __ffa_runtime ffa_invoke_msg_send_direct_req(u16 endpoint_id, u16 dst_part_id,
+ struct ffa_send_direct_data *msg,
+ bool is_smc64);
+
+/**
+ * ffa_msg_send_direct_req_hdlr_runtime() - Runtime implementation of
+ * FFA_MSG_SEND_DIRECT_{REQ,RESP} handler function
+ * @dst_part_id: destination partition ID
+ * @msg: pointer to the message data preallocated by the client (in/out)
+ * @is_smc64: select 64-bit or 32-bit FF-A ABI
+ *
+ * This function calls the ffa_invoke_msg_send_direct_req() function which
+ * invokes FFA_MSG_SEND_DIRECT_{REQ,RESP} FF-A functions.
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, failure
+ */
+int __ffa_runtime ffa_msg_send_direct_req_hdlr_runtime(u16 dst_part_id,
+ struct ffa_send_direct_data *msg,
+ bool is_smc64);
+
+#endif
diff --git a/test/dm/ffa.c b/test/dm/ffa.c
index f4a6716cfd8..1240bb4141a 100644
--- a/test/dm/ffa.c
+++ b/test/dm/ffa.c
@@ -2,7 +2,7 @@
/*
* Functional tests for UCLASS_FFA class
*
- * Copyright 2022-2023, 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * Copyright 2022-2023, 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* Authors:
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
@@ -27,14 +27,14 @@ static int check_fwk_version(struct ffa_priv *uc_priv, struct unit_test_state *u
func_data.data0 = &fwk_version;
func_data.data0_size = sizeof(fwk_version);
ut_assertok(sandbox_query_ffa_emul_state(FFA_VERSION, &func_data));
- ut_asserteq(uc_priv->fwk_version, fwk_version);
+ ut_asserteq(uc_priv->rt.fwk_version, fwk_version);
return 0;
}
static int check_endpoint_id(struct ffa_priv *uc_priv, struct unit_test_state *uts)
{
- ut_asserteq(0, uc_priv->id);
+ ut_asserteq(0, uc_priv->rt.id);
return 0;
}
@@ -0,0 +1,478 @@
From dd992d82e9958786bd8367a8b7018648d217d552 Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Thu, 20 Nov 2025 22:19:01 +0000
Subject: [PATCH 43/53] efi_loader: add FF-A runtime support in EFI variable
TEE driver
Enable MM variable services over FF-A after ExitBootServices
This patch extends lib/efi_loader/efi_variable_tee.c to support FF-A
communication with the secure world during EFI runtime. It enables EFI
runtime variable access and MM communication using FF-A transport when
ExitBootServices() has already been called.
Key changes:
------------
- Introduce runtime-safe implementations for MM communication,
notification, and variable access using FF-A driver.
- Introduce communication-buffer helper (get_comm_buf()) that switches
between dynamic allocation (boot phase) and the fixed FF-A shared
buffer (runtime phase).
- Mark persistent data and code with __efi_runtime and
__efi_runtime_data attributes.
- Use direct physical address mapping for shared buffers since
U-Boot operates with 1:1 physical-to-virtual mapping.
- Only per-buffer cache maintenance is performed at runtime,
as whole D-cache invalidation would violate the OS coherency model
after ExitBootServices().
- Add runtime-phase tracking (efi_runtime_enabled).
The change reuses the statically reserved shared buffer, replaces
allocations with __efi_runtime copies, and updates the runtime service
table so EFI variable runtime calls reach the secure partition via FF-A.
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
lib/efi_loader/efi_variable_tee.c | 331 ++++++++++++++++++++++++++++--
1 file changed, 319 insertions(+), 12 deletions(-)
diff --git a/lib/efi_loader/efi_variable_tee.c b/lib/efi_loader/efi_variable_tee.c
index 6a1fa39bb6f..e4d97dc55ab 100644
--- a/lib/efi_loader/efi_variable_tee.c
+++ b/lib/efi_loader/efi_variable_tee.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 2019 Linaro Ltd. <sughosh.ganu@linaro.org>
* Copyright (C) 2019 Linaro Ltd. <ilias.apalodimas@linaro.org>
- * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * Copyright 2022-2023, 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* Authors:
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
@@ -14,6 +14,7 @@
#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT)
#include <arm_ffa.h>
+#include <arm_ffa_runtime.h>
#endif
#include <cpu_func.h>
#include <dm.h>
@@ -34,20 +35,47 @@
#define MM_DENIED (-3)
#define MM_NO_MEMORY (-5)
+static const int __efi_runtime_rodata mm_sp_errmap[] = {
+ [-MM_NOT_SUPPORTED] = -EINVAL,
+ [-MM_INVALID_PARAMETER] = -EPERM,
+ [-MM_DENIED] = -EACCES,
+ [-MM_NO_MEMORY] = -EBUSY,
+};
+
static const char *mm_sp_svc_uuid = MM_SP_UUID;
-static u16 mm_sp_id;
+static u16 __efi_runtime_data mm_sp_id;
#endif
+static void *__efi_runtime_data ffa_shared_buf;
+static const efi_guid_t __efi_runtime_rodata mm_var_guid_runtime =
+ EFI_MM_VARIABLE_GUID;
+
extern struct efi_var_file __efi_runtime_data *efi_var_buf;
-static efi_uintn_t max_buffer_size; /* comm + var + func + data */
-static efi_uintn_t max_payload_size; /* func + data */
+static efi_uintn_t __efi_runtime_data max_buffer_size; /* comm + var + func + data */
+static efi_uintn_t __efi_runtime_data max_payload_size; /* func + data */
static const u16 __efi_runtime_rodata pk[] = u"PK";
+static bool __efi_runtime_data efi_runtime_enabled;
struct mm_connection {
struct udevice *tee;
u32 session;
};
+/**
+ * efi_is_runtime_enabled() - Indicate whether the system is in the UEFI runtime phase
+ *
+ * This helper returns whether the firmware has transitioned into the
+ * UEFI runtime phase, meaning that ExitBootServices() has been invoked.
+ *
+ * Return:
+ * true - The system is operating in UEFI runtime mode.
+ * false - The system is still in the boot services phase.
+ */
+static bool __efi_runtime efi_is_runtime_enabled(void)
+{
+ return efi_runtime_enabled;
+}
+
/**
* get_connection() - Retrieve OP-TEE session for a specific UUID.
*
@@ -169,6 +197,28 @@ static efi_status_t optee_mm_communicate(void *comm_buf, ulong dsize)
}
#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT)
+/**
+ * ffa_map_sp_event_runtime() - Map MM SP response to errno (runtime-safe)
+ * @sp_event_ret: MM SP return code from ffa_notify_mm_sp_runtime()
+ *
+ * Convert the MM SP return code into a standard U-Boot errno. This helper
+ * is marked __efi_runtime to ensure it is safe to call after
+ * ExitBootServices().
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static __efi_runtime int ffa_map_sp_event_runtime(int sp_event_ret)
+{
+ int idx = -sp_event_ret;
+
+ if (sp_event_ret == MM_SUCCESS)
+ return 0;
+ if (idx > 0 && idx < (int)ARRAY_SIZE(mm_sp_errmap) &&
+ mm_sp_errmap[idx])
+ return mm_sp_errmap[idx];
+ return -EACCES;
+}
+
/**
* ffa_notify_mm_sp() - Announce there is data in the shared buffer
*
@@ -225,6 +275,35 @@ static int ffa_notify_mm_sp(void)
return ret;
}
+/**
+ * ffa_notify_mm_sp_runtime() - Runtime implementation of
+ * ffa_notify_mm_sp()
+ *
+ * Notify the MM partition in the trusted world that
+ * data is available in the shared buffer.
+ * This is a blocking call during which trusted world has exclusive access
+ * to the MM shared buffer.
+ *
+ * Return:
+ *
+ * 0 on success
+ */
+static int __efi_runtime ffa_notify_mm_sp_runtime(void)
+{
+ struct ffa_send_direct_data msg = {0};
+ int ret;
+ int sp_event_ret;
+
+ msg.data0 = CONFIG_FFA_SHARED_MM_BUF_OFFSET;
+
+ ret = ffa_sync_send_receive_runtime(mm_sp_id, &msg, 1);
+ if (ret)
+ return ret;
+
+ ret = ffa_map_sp_event_runtime(sp_event_ret);
+ return ret;
+}
+
/**
* ffa_discover_mm_sp_id() - Query the MM partition ID
*
@@ -360,6 +439,116 @@ static efi_status_t ffa_mm_communicate(void *comm_buf, ulong comm_buf_size)
return efi_ret;
}
+/**
+ * ffa_mm_communicate_runtime() - Runtime implementation of ffa_mm_communicate()
+ * @comm_buf: locally allocated communication buffer used for rx/tx
+ * @comm_buf_size: communication buffer size
+ *
+ * Issue a door bell event to notify the MM partition (SP) running in OP-TEE
+ * that there is data to read from the shared buffer.
+ * Communication with the MM SP is performed using FF-A transport.
+ * On the event, MM SP can read the data from the buffer and
+ * update the MM shared buffer with response data.
+ * The response data is copied back to the communication buffer.
+ *
+ * Return:
+ *
+ * EFI status code
+ */
+static efi_status_t __efi_runtime ffa_mm_communicate_runtime(void *comm_buf,
+ ulong comm_buf_size)
+{
+ ulong tx_data_size;
+ int ffa_ret;
+ efi_status_t efi_ret;
+ struct efi_mm_communicate_header *mm_hdr;
+
+ if (!comm_buf)
+ return EFI_INVALID_PARAMETER;
+
+ /* Discover MM partition ID at boot time */
+ if (!mm_sp_id)
+ return EFI_UNSUPPORTED;
+
+ mm_hdr = (struct efi_mm_communicate_header *)comm_buf;
+ tx_data_size = mm_hdr->message_len + sizeof(efi_guid_t) + sizeof(size_t);
+
+ if (comm_buf_size != tx_data_size || tx_data_size > CONFIG_FFA_SHARED_MM_BUF_SIZE)
+ return EFI_INVALID_PARAMETER;
+
+ /*
+ * Shared buffer cache maintenance for FF-A / OP-TEE communication:
+ *
+ * NS -> S (request path):
+ *
+ * The non-secure side populates the shared buffer. If the buffer is cached
+ * in NS, the updated bytes may reside in dirty D-cache lines and not yet be
+ * visible in DDR. Since the secure world typically reads the shared buffer
+ * directly from DDR (e.g. with caches disabled / non-coherent mapping), we
+ * must clean the corresponding cache lines to the Point of Coherency (PoC)
+ * before entering secure world.
+ *
+ * S -> NS (response path):
+ *
+ * The secure world may update the same shared buffer in DDR. After returning
+ * to non-secure, any cached copies of that region in NS may be stale. We
+ * therefore invalidate the shared buffer range after the FF-A call to drop
+ * those lines and force subsequent reads to fetch the latest data from DDR.
+ *
+ * Note: Whole-cache invalidation must not be used in EFI runtime context.
+ * After ExitBootServices(), the OS owns the cache hierarchy; global invalidation
+ * could drop OS dirty lines and violate the OS coherency model. Always operate
+ * on the shared buffer range only.
+ */
+ if (IS_ENABLED(CONFIG_ARM64))
+ flush_dcache_range((unsigned long)comm_buf,
+ (unsigned long)((u8 *)comm_buf +
+ CONFIG_FFA_SHARED_MM_BUF_SIZE));
+
+ /* Announce there is data in the shared buffer */
+
+ ffa_ret = ffa_notify_mm_sp_runtime();
+
+ if (IS_ENABLED(CONFIG_ARM64))
+ invalidate_dcache_range((unsigned long)comm_buf,
+ (unsigned long)((u8 *)comm_buf +
+ CONFIG_FFA_SHARED_MM_BUF_SIZE));
+
+ switch (ffa_ret) {
+ case 0: {
+ ulong rx_data_size;
+
+ rx_data_size = ((struct efi_mm_communicate_header *)comm_buf)->message_len +
+ sizeof(efi_guid_t) +
+ sizeof(size_t);
+
+ if (rx_data_size > comm_buf_size) {
+ efi_ret = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ efi_ret = EFI_SUCCESS;
+ break;
+ }
+ case -EINVAL:
+ efi_ret = EFI_DEVICE_ERROR;
+ break;
+ case -EPERM:
+ efi_ret = EFI_INVALID_PARAMETER;
+ break;
+ case -EACCES:
+ efi_ret = EFI_ACCESS_DENIED;
+ break;
+ case -EBUSY:
+ efi_ret = EFI_OUT_OF_RESOURCES;
+ break;
+ default:
+ efi_ret = EFI_ACCESS_DENIED;
+ }
+
+ return efi_ret;
+}
+
/**
* get_mm_comms() - detect the available MM transport
*
@@ -386,6 +575,27 @@ static enum mm_comms_select get_mm_comms(void)
return MM_COMMS_FFA;
}
+
+/**
+ * get_mm_comms_runtime() - detect the available MM transport at runtime
+ *
+ * Make sure the FF-A bus is available at runtime and ready
+ * for use.
+ *
+ * Return:
+ *
+ * MM_COMMS_FFA or MM_COMMS_UNDEFINED
+ */
+static enum mm_comms_select __efi_runtime get_mm_comms_runtime(void)
+{
+ bool ret;
+
+ ret = efi_is_runtime_enabled();
+ if (!ret)
+ return MM_COMMS_UNDEFINED;
+
+ return MM_COMMS_FFA;
+}
#endif
/**
@@ -433,9 +643,86 @@ static efi_status_t mm_communicate(u8 *comm_buf, efi_uintn_t dsize)
return var_hdr->ret_status;
}
+/**
+ * mm_communicate_runtime() - Runtime implementation of mm_communicate()
+ *
+ * @comm_buf: locally allocated communication buffer
+ * @dsize: buffer size
+ *
+ * The SP (also called partition) can be any MM SP such as StandAlonneMM or smm-gateway.
+ * The comm_buf format is the same for both partitions.
+ * When using the u-boot OP-TEE driver, StandAlonneMM is supported.
+ * When using the u-boot FF-A driver, any MM SP is supported.
+ *
+ * Return: status code
+ */
+static efi_status_t __efi_runtime mm_communicate_runtime(u8 *comm_buf, efi_uintn_t dsize)
+{
+ efi_status_t ret = EFI_UNSUPPORTED;
+ struct efi_mm_communicate_header *mm_hdr;
+ struct smm_variable_communicate_header *var_hdr;
+ enum mm_comms_select mm_comms;
+
+ dsize += MM_COMMUNICATE_HEADER_SIZE + MM_VARIABLE_COMMUNICATE_SIZE;
+ mm_hdr = (struct efi_mm_communicate_header *)comm_buf;
+ var_hdr = (struct smm_variable_communicate_header *)mm_hdr->data;
+
+ if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT)) {
+ mm_comms = get_mm_comms_runtime();
+ if (mm_comms == MM_COMMS_FFA)
+ ret = ffa_mm_communicate_runtime(comm_buf, dsize);
+ }
+
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ return var_hdr->ret_status;
+}
+
+/**
+ * get_comm_buf() - Obtain a communication buffer for MM/FF-A exchange
+ * @payload_size: size of the payload that will be appended to the
+ * MM communication header
+ * This helper returns a buffer suitable for constructing an
+ * EFI_MM_COMMUNICATE message. During the boot phase a new buffer is
+ * dynamically allocated. After ExitBootServices(), dynamic
+ * allocation is no longer permitted, and all runtime communication must
+ * use the statically reserved FF-A shared buffer.
+ *
+ * Return:
+ * Pointer to a valid communication buffer on success,
+ * NULL if allocation fails during the boot phase.
+ */
+static __efi_runtime u8 *get_comm_buf(efi_uintn_t payload_size)
+{
+ u8 *comm_buf;
+
+ /* After ExitBootServices(), dynamic allocation is no longer permitted.
+ * Use the predefined FF-A shared buffer at runtime; otherwise allocate
+ * a fresh buffer during the boot phase.
+ */
+ if (efi_is_runtime_enabled()) {
+ if (IS_ENABLED(CONFIG_ARM_FFA_RT_MODE)) {
+ comm_buf = ffa_shared_buf;
+ if (!comm_buf)
+ return NULL;
+ efi_memset_runtime(comm_buf, 0, CONFIG_FFA_SHARED_MM_BUF_SIZE);
+ } else {
+ return NULL;
+ }
+ } else {
+ comm_buf = calloc(1, MM_COMMUNICATE_HEADER_SIZE +
+ MM_VARIABLE_COMMUNICATE_SIZE +
+ payload_size);
+ if (!comm_buf)
+ return NULL;
+ }
+ return comm_buf;
+}
+
/**
* setup_mm_hdr() - Allocate a buffer for StandAloneMM and initialize the
- * header data.
+ * header data. It is runtime safe.
*
* @dptr: pointer address of the corresponding StandAloneMM
* function
@@ -444,10 +731,9 @@ static efi_status_t mm_communicate(u8 *comm_buf, efi_uintn_t dsize)
* @ret: EFI return code
* Return: buffer or NULL
*/
-static u8 *setup_mm_hdr(void **dptr, efi_uintn_t payload_size,
- efi_uintn_t func, efi_status_t *ret)
+static __efi_runtime u8 *setup_mm_hdr(void **dptr, efi_uintn_t payload_size,
+ efi_uintn_t func, efi_status_t *ret)
{
- const efi_guid_t mm_var_guid = EFI_MM_VARIABLE_GUID;
struct efi_mm_communicate_header *mm_hdr;
struct smm_variable_communicate_header *var_hdr;
u8 *comm_buf;
@@ -465,16 +751,15 @@ static u8 *setup_mm_hdr(void **dptr, efi_uintn_t payload_size,
return NULL;
}
- comm_buf = calloc(1, MM_COMMUNICATE_HEADER_SIZE +
- MM_VARIABLE_COMMUNICATE_SIZE +
- payload_size);
+ comm_buf = get_comm_buf(payload_size);
if (!comm_buf) {
*ret = EFI_OUT_OF_RESOURCES;
return NULL;
}
mm_hdr = (struct efi_mm_communicate_header *)comm_buf;
- guidcpy(&mm_hdr->header_guid, &mm_var_guid);
+ efi_memcpy_runtime(&mm_hdr->header_guid, &mm_var_guid_runtime,
+ sizeof(mm_hdr->header_guid));
mm_hdr->message_len = MM_VARIABLE_COMMUNICATE_SIZE + payload_size;
var_hdr = (struct smm_variable_communicate_header *)mm_hdr->data;
@@ -982,6 +1267,9 @@ void efi_variables_boot_exit_notify(void)
efi_get_next_variable_name_runtime;
efi_runtime_services.set_variable = efi_set_variable_runtime;
efi_update_table_header_crc32(&efi_runtime_services.hdr);
+
+ /* Set efi_runtime_enabled as true after ExitBootServices */
+ efi_runtime_enabled = true;
}
/**
@@ -993,6 +1281,25 @@ efi_status_t efi_init_variables(void)
{
efi_status_t ret;
+ if (IS_ENABLED(CONFIG_ARM_FFA_RT_MODE)) {
+ /*
+ * The FF-A shared buffer is accessed by EFI runtime services, so it must
+ * be marked as runtime memory in the EFI memory map.
+ */
+ ffa_shared_buf = (void *)CONFIG_FFA_SHARED_MM_BUF_ADDR;
+ ret = efi_add_memory_map(CONFIG_FFA_SHARED_MM_BUF_ADDR,
+ CONFIG_FFA_SHARED_MM_BUF_SIZE,
+ EFI_RUNTIME_SERVICES_DATA);
+ if (ret != EFI_SUCCESS) {
+ log_err("EFI: failed to add FF-A shared buffer to runtime map (%lu)\n",
+ ret);
+ return ret;
+ }
+ log_info("EFI: FF-A shared buffer runtime map: addr=0x%lx size=0x%lx\n",
+ (ulong)CONFIG_FFA_SHARED_MM_BUF_ADDR,
+ (ulong)CONFIG_FFA_SHARED_MM_BUF_SIZE);
+ }
+
/* Create a cached copy of the variables that will be enabled on ExitBootServices() */
ret = efi_var_mem_init();
if (ret != EFI_SUCCESS)
@@ -0,0 +1,418 @@
From 119d43911b72f8c90b09e91b727d33d21d539c49 Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Thu, 11 Dec 2025 15:28:39 +0000
Subject: [PATCH 44/53] efi_loader: enable EFI runtime
SetVariable()/GetVariable() using FF-A transport
Route EFI runtime variable APIs through FF-A MM communication
This patch implements full EFI Runtime Variable Services (GetVariable,
SetVariable, GetNextVariableName, and QueryVariableInfo) using the
FF-A/MM communication backend. Once ExitBootServices() has been invoked,
all variable operations now use the runtime-safe FF-A transport instead
of the boot-time communication paths.
Key changes:
============
- Add runtime-safe variable property handling via FF-A MM SP.
- Add runtime versions of variable access and property operations.
- Replace all standard memory operations with EFI-runtime-safe variants.
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
lib/charset.c | 2 +-
lib/efi_loader/efi_variable_tee.c | 322 +++++++++++++++++++++++++++++-
2 files changed, 318 insertions(+), 6 deletions(-)
diff --git a/lib/charset.c b/lib/charset.c
index 182c92a50c4..738ad1352de 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -407,7 +407,7 @@ size_t __efi_runtime u16_strnlen(const u16 *in, size_t count)
return i;
}
-size_t u16_strsize(const void *in)
+size_t __efi_runtime u16_strsize(const void *in)
{
return (u16_strlen(in) + 1) * sizeof(u16);
}
diff --git a/lib/efi_loader/efi_variable_tee.c b/lib/efi_loader/efi_variable_tee.c
index e4d97dc55ab..30687c21b8e 100644
--- a/lib/efi_loader/efi_variable_tee.c
+++ b/lib/efi_loader/efi_variable_tee.c
@@ -859,6 +859,38 @@ out:
return ret;
}
+static efi_status_t __efi_runtime set_property_int_runtime(const u16 *variable_name,
+ efi_uintn_t name_size,
+ const efi_guid_t *vendor,
+ struct var_check_property *var_property)
+{
+ struct smm_variable_var_check_property *smm_property;
+ efi_uintn_t payload_size;
+ u8 *comm_buf = NULL;
+ efi_status_t ret;
+
+ payload_size = sizeof(*smm_property) + name_size;
+ if (payload_size > max_payload_size) {
+ ret = EFI_INVALID_PARAMETER;
+ return ret;
+ }
+ comm_buf = setup_mm_hdr((void **)&smm_property, payload_size,
+ SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET,
+ &ret);
+ if (!comm_buf)
+ return ret;
+
+ efi_memcpy_runtime(&smm_property->guid, vendor, sizeof(*vendor));
+ smm_property->name_size = name_size;
+ efi_memcpy_runtime(&smm_property->property, var_property,
+ sizeof(smm_property->property));
+ efi_memcpy_runtime(smm_property->name, variable_name, name_size);
+
+ ret = mm_communicate_runtime(comm_buf, payload_size);
+
+ return ret;
+}
+
static efi_status_t get_property_int(const u16 *variable_name,
efi_uintn_t name_size,
const efi_guid_t *vendor,
@@ -904,6 +936,49 @@ out:
return ret;
}
+static efi_status_t __efi_runtime get_property_int_runtime(const u16 *variable_name,
+ efi_uintn_t name_size,
+ const efi_guid_t *vendor,
+ struct var_check_property *var_property)
+{
+ struct smm_variable_var_check_property *smm_property;
+ efi_uintn_t payload_size;
+ u8 *comm_buf = NULL;
+ efi_status_t ret;
+
+ efi_memset_runtime(var_property, 0, sizeof(*var_property));
+ payload_size = sizeof(*smm_property) + name_size;
+ if (payload_size > max_payload_size) {
+ ret = EFI_INVALID_PARAMETER;
+ return ret;
+ }
+ comm_buf = setup_mm_hdr((void **)&smm_property, payload_size,
+ SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET,
+ &ret);
+ if (!comm_buf)
+ return ret;
+
+ efi_memcpy_runtime(&smm_property->guid, vendor, sizeof(smm_property->guid));
+ smm_property->name_size = name_size;
+ efi_memcpy_runtime(smm_property->name, variable_name, name_size);
+
+ ret = mm_communicate_runtime(comm_buf, payload_size);
+ /*
+ * Currently only R/O property is supported in StMM.
+ * Variables that are not set to R/O will not set the property in StMM
+ * and the call will return EFI_NOT_FOUND. We are setting the
+ * properties to 0x0 so checking against that is enough for the
+ * EFI_NOT_FOUND case.
+ */
+ if (ret == EFI_NOT_FOUND)
+ ret = EFI_SUCCESS;
+ if (ret != EFI_SUCCESS)
+ return ret;
+ efi_memcpy_runtime(var_property, &smm_property->property, sizeof(*var_property));
+
+ return ret;
+}
+
efi_status_t efi_get_variable_int(const u16 *variable_name,
const efi_guid_t *vendor,
u32 *attributes, efi_uintn_t *data_size,
@@ -991,6 +1066,92 @@ out:
return ret;
}
+efi_status_t __efi_runtime efi_get_variable_runtime(u16 *variable_name,
+ const efi_guid_t *vendor,
+ u32 *attributes,
+ efi_uintn_t *data_size,
+ void *data)
+{
+ struct var_check_property var_property;
+ struct smm_variable_access *var_acc;
+ efi_uintn_t payload_size;
+ efi_uintn_t name_size;
+ efi_uintn_t tmp_dsize;
+ u8 *comm_buf = NULL;
+ efi_status_t ret, tmp;
+
+ if (!variable_name || !vendor || !data_size) {
+ ret = EFI_INVALID_PARAMETER;
+ return ret;
+ }
+
+ /* Check payload size */
+ name_size = u16_strsize(variable_name);
+ if (name_size > max_payload_size - MM_VARIABLE_ACCESS_HEADER_SIZE) {
+ ret = EFI_INVALID_PARAMETER;
+ return ret;
+ }
+
+ /* Trim output buffer size */
+ tmp_dsize = *data_size;
+ if (name_size + tmp_dsize >
+ max_payload_size - MM_VARIABLE_ACCESS_HEADER_SIZE) {
+ tmp_dsize = max_payload_size -
+ MM_VARIABLE_ACCESS_HEADER_SIZE -
+ name_size;
+ }
+
+ /* Get communication buffer and initialize header */
+ payload_size = MM_VARIABLE_ACCESS_HEADER_SIZE + name_size + tmp_dsize;
+ comm_buf = setup_mm_hdr((void **)&var_acc, payload_size,
+ SMM_VARIABLE_FUNCTION_GET_VARIABLE, &ret);
+ if (!comm_buf)
+ return ret;
+
+ /* Fill in contents */
+ efi_memcpy_runtime(&var_acc->guid, vendor, sizeof(var_acc->guid));
+ var_acc->data_size = tmp_dsize;
+ var_acc->name_size = name_size;
+ var_acc->attr = attributes ? *attributes : 0;
+ efi_memcpy_runtime(var_acc->name, variable_name, name_size);
+
+ /* Communicate */
+ ret = mm_communicate_runtime(comm_buf, payload_size);
+ if (ret != EFI_SUCCESS && ret != EFI_BUFFER_TOO_SMALL)
+ return ret;
+
+ /* Update with reported data size for trimmed case */
+ *data_size = var_acc->data_size;
+
+ /* Copy the data if ret is EFI_SUCCESS */
+ if (ret == EFI_SUCCESS) {
+ if (data)
+ efi_memcpy_runtime(data, (u8 *)var_acc->name + var_acc->name_size,
+ var_acc->data_size);
+ else
+ ret = EFI_INVALID_PARAMETER;
+ }
+
+ /*
+ * UEFI > 2.7 needs the attributes set even if the buffer is
+ * smaller
+ */
+ if (attributes) {
+ tmp = get_property_int_runtime(variable_name, name_size, vendor,
+ &var_property);
+ if (tmp != EFI_SUCCESS) {
+ ret = tmp;
+ return ret;
+ }
+ *attributes = var_acc->attr;
+ if (var_property.property &
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY)
+ *attributes |= EFI_VARIABLE_READ_ONLY;
+ }
+
+ return ret;
+}
+
efi_status_t efi_get_next_variable_name_int(efi_uintn_t *variable_name_size,
u16 *variable_name,
efi_guid_t *guid)
@@ -1055,6 +1216,68 @@ out:
return ret;
}
+efi_status_t __efi_runtime efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size,
+ u16 *variable_name,
+ efi_guid_t *guid)
+{
+ struct smm_variable_getnext *var_getnext;
+ efi_uintn_t payload_size;
+ efi_uintn_t out_name_size;
+ efi_uintn_t in_name_size;
+ u8 *comm_buf = NULL;
+ efi_status_t ret;
+
+ if (!variable_name_size || !variable_name || !guid) {
+ ret = EFI_INVALID_PARAMETER;
+ return ret;
+ }
+
+ out_name_size = *variable_name_size;
+ in_name_size = u16_strsize(variable_name);
+
+ if (out_name_size < in_name_size) {
+ ret = EFI_INVALID_PARAMETER;
+ return ret;
+ }
+
+ if (in_name_size > max_payload_size - MM_VARIABLE_GET_NEXT_HEADER_SIZE) {
+ ret = EFI_INVALID_PARAMETER;
+ return ret;
+ }
+
+ /* Trim output buffer size */
+ if (out_name_size > max_payload_size - MM_VARIABLE_GET_NEXT_HEADER_SIZE)
+ out_name_size = max_payload_size - MM_VARIABLE_GET_NEXT_HEADER_SIZE;
+
+ payload_size = MM_VARIABLE_GET_NEXT_HEADER_SIZE + out_name_size;
+ comm_buf = setup_mm_hdr((void **)&var_getnext, payload_size,
+ SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME,
+ &ret);
+ if (!comm_buf)
+ return ret;
+
+ /* Fill in contents */
+ efi_memcpy_runtime(&var_getnext->guid, guid, sizeof(*guid));
+ var_getnext->name_size = out_name_size;
+ efi_memcpy_runtime(var_getnext->name, variable_name, in_name_size);
+ efi_memset_runtime((u8 *)var_getnext->name + in_name_size, 0x0,
+ out_name_size - in_name_size);
+
+ /* Communicate */
+ ret = mm_communicate_runtime(comm_buf, payload_size);
+ if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
+ /* Update with reported data size for trimmed case */
+ *variable_name_size = var_getnext->name_size;
+ }
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ efi_memcpy_runtime(guid, &var_getnext->guid, sizeof(*guid));
+ efi_memcpy_runtime(variable_name, var_getnext->name, var_getnext->name_size);
+
+ return ret;
+}
+
efi_status_t efi_set_variable_int(const u16 *variable_name,
const efi_guid_t *vendor, u32 attributes,
efi_uintn_t data_size, const void *data,
@@ -1197,11 +1420,11 @@ out:
*
* @attributes: bitmask to select variables to be
* queried
- * @maximum_variable_storage_size: maximum size of storage area for the
+ * @max_variable_storage_size: maximum size of storage area for the
* selected variable types
- * @remaining_variable_storage_size: remaining size of storage are for the
+ * @remain_variable_storage_size: remaining size of storage are for the
* selected variable types
- * @maximum_variable_size: maximum size of a variable of the
+ * @max_variable_size: maximum size of a variable of the
* selected type
* Return: status code
*/
@@ -1210,7 +1433,33 @@ efi_query_variable_info_runtime(u32 attributes, u64 *max_variable_storage_size,
u64 *remain_variable_storage_size,
u64 *max_variable_size)
{
- return EFI_UNSUPPORTED;
+ struct smm_variable_query_info *mm_query_info;
+ efi_uintn_t payload_size;
+ efi_status_t ret;
+ u8 *comm_buf;
+
+ if (!max_variable_storage_size ||
+ !remain_variable_storage_size ||
+ !max_variable_size || !attributes)
+ return EFI_INVALID_PARAMETER;
+
+ payload_size = sizeof(*mm_query_info);
+ comm_buf = setup_mm_hdr((void **)&mm_query_info, payload_size,
+ SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO,
+ &ret);
+ if (!comm_buf)
+ return ret;
+
+ mm_query_info->attr = attributes;
+ ret = mm_communicate_runtime(comm_buf, payload_size);
+ if (ret != EFI_SUCCESS)
+ return ret;
+ *max_variable_storage_size = mm_query_info->max_variable_storage;
+ *remain_variable_storage_size =
+ mm_query_info->remaining_variable_storage;
+ *max_variable_size = mm_query_info->max_variable_size;
+
+ return ret;
}
/**
@@ -1228,7 +1477,70 @@ efi_set_variable_runtime(u16 *variable_name, const efi_guid_t *guid,
u32 attributes, efi_uintn_t data_size,
const void *data)
{
- return EFI_UNSUPPORTED;
+ efi_status_t ret, mm_communicate_ret = EFI_SUCCESS;
+ struct var_check_property var_property;
+ struct smm_variable_access *var_acc;
+ efi_uintn_t payload_size;
+ efi_uintn_t name_size;
+ u8 *comm_buf = NULL;
+ bool ro;
+
+ if (!variable_name || variable_name[0] == 0 || !guid)
+ return EFI_INVALID_PARAMETER;
+
+ if (data_size > 0 && !data)
+ return EFI_INVALID_PARAMETER;
+
+ /* Check payload size */
+ name_size = u16_strsize(variable_name);
+ payload_size = MM_VARIABLE_ACCESS_HEADER_SIZE + name_size + data_size;
+ if (payload_size > max_payload_size)
+ return EFI_INVALID_PARAMETER;
+
+ ro = !!(attributes & EFI_VARIABLE_READ_ONLY);
+ attributes &= EFI_VARIABLE_MASK;
+
+ ret = get_property_int_runtime(variable_name, name_size, guid,
+ &var_property);
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ /*
+ * Allocate the buffer early, before switching to RW (if needed)
+ * so we won't need to account for any failures in reading/setting
+ * the properties, if the allocation fails
+ */
+ comm_buf = setup_mm_hdr((void **)&var_acc, payload_size,
+ SMM_VARIABLE_FUNCTION_SET_VARIABLE, &ret);
+ if (!comm_buf)
+ return ret;
+
+ if (var_property.property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY)
+ return EFI_WRITE_PROTECTED;
+
+ /* Fill in contents */
+ efi_memcpy_runtime(&var_acc->guid, guid, sizeof(*guid));
+ var_acc->data_size = data_size;
+ var_acc->name_size = name_size;
+ var_acc->attr = attributes;
+ efi_memcpy_runtime(var_acc->name, variable_name, name_size);
+ efi_memcpy_runtime((u8 *)var_acc->name + name_size, data, data_size);
+
+ /* Communicate */
+ ret = mm_communicate_runtime(comm_buf, payload_size);
+ if (ret != EFI_SUCCESS)
+ mm_communicate_ret = ret;
+
+ if (ro && !(var_property.property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY)) {
+ var_property.revision = VAR_CHECK_VARIABLE_PROPERTY_REVISION;
+ var_property.property |= VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY;
+ var_property.attributes = attributes;
+ var_property.minsize = 1;
+ var_property.maxsize = var_acc->data_size;
+ ret = set_property_int_runtime(variable_name, name_size, guid, &var_property);
+ }
+
+ return (mm_communicate_ret == EFI_SUCCESS) ? ret : mm_communicate_ret;
}
/**
@@ -0,0 +1,103 @@
From 5c2b1f517c97f3349108bfd9fef9aac40ba236ac Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Fri, 12 Dec 2025 10:59:47 +0000
Subject: [PATCH 45/53] efi_loader: move runtime GetVariable() helpers to
efi_variable.c
Consolidate runtime GetVariable helpers to avoid duplicates
The functions efi_get_variable_runtime() and
efi_get_next_variable_name_runtime() were implemented in
efi_variable_tee.c as part of the FF-A runtime variable handling work.
However, default implementations for these same runtime helpers also
exist in efi_var_common.c. This results in duplicate symbol definitions.
To resolve the conflict and centralize the runtime API, this patch moves
the default implementations of the two runtime GetVariable() helpers
from efi_var_common.c to efi_variable.c. This ensures that:
- only a single definition of each runtime helper exists,
- backend-specific implementations can override these cleanly,
- the EFI runtime variable service table continues to reference the
correct functions.
No functional changes are introduced; this is a structural cleanup to
avoid build-time conflicts and consolidate EFI runtime variable support
in the appropriate file.
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
lib/efi_loader/efi_var_common.c | 24 ------------------------
lib/efi_loader/efi_variable.c | 24 ++++++++++++++++++++++++
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c
index 4b34a58b4cf..0eaf89112e6 100644
--- a/lib/efi_loader/efi_var_common.c
+++ b/lib/efi_loader/efi_var_common.c
@@ -172,30 +172,6 @@ efi_status_t EFIAPI efi_query_variable_info(
return EFI_EXIT(ret);
}
-efi_status_t __efi_runtime EFIAPI
-efi_get_variable_runtime(u16 *variable_name, const efi_guid_t *guid,
- u32 *attributes, efi_uintn_t *data_size, void *data)
-{
- efi_status_t ret;
-
- ret = efi_get_variable_mem(variable_name, guid, attributes, data_size,
- data, NULL, EFI_VARIABLE_RUNTIME_ACCESS);
-
- /* Remove EFI_VARIABLE_READ_ONLY flag */
- if (attributes)
- *attributes &= EFI_VARIABLE_MASK;
-
- return ret;
-}
-
-efi_status_t __efi_runtime EFIAPI
-efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size,
- u16 *variable_name, efi_guid_t *guid)
-{
- return efi_get_next_variable_name_mem(variable_name_size, variable_name,
- guid, EFI_VARIABLE_RUNTIME_ACCESS);
-}
-
/**
* efi_set_secure_state - modify secure boot state variables
* @secure_boot: value of SecureBoot
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index f3533f4def3..a688c6da58d 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -566,6 +566,30 @@ efi_set_variable_runtime(u16 *variable_name, const efi_guid_t *vendor,
return EFI_SUCCESS;
}
+efi_status_t __efi_runtime EFIAPI
+efi_get_variable_runtime(u16 *variable_name, const efi_guid_t *guid,
+ u32 *attributes, efi_uintn_t *data_size, void *data)
+{
+ efi_status_t ret;
+
+ ret = efi_get_variable_mem(variable_name, guid, attributes, data_size,
+ data, NULL, EFI_VARIABLE_RUNTIME_ACCESS);
+
+ /* Remove EFI_VARIABLE_READ_ONLY flag */
+ if (attributes)
+ *attributes &= EFI_VARIABLE_MASK;
+
+ return ret;
+}
+
+efi_status_t __efi_runtime EFIAPI
+efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size,
+ u16 *variable_name, efi_guid_t *guid)
+{
+ return efi_get_next_variable_name_mem(variable_name_size, variable_name,
+ guid, EFI_VARIABLE_RUNTIME_ACCESS);
+}
+
/**
* efi_variables_boot_exit_notify() - notify ExitBootServices() is called
*/
@@ -0,0 +1,38 @@
From 4c8504fe21f91bf462486afdfe4113f8bbc9f930 Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Sun, 11 Jan 2026 20:34:13 +0000
Subject: [PATCH 46/53] corstone1000: enable bootefi selftest
Enable UEFI selftest command in Corstone-1000 defconfig
Turn on CONFIG_CMD_BOOTEFI_SELFTEST in the Corstone-1000 defconfig
so the board can run the built-in UEFI self-test suite during
development and validation.
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
configs/corstone1000_defconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig
index 350607892fa..8de2f9bd440 100644
--- a/configs/corstone1000_defconfig
+++ b/configs/corstone1000_defconfig
@@ -41,6 +41,8 @@ CONFIG_SYS_PROMPT="corstone1000# "
# CONFIG_CMD_CONSOLE is not set
CONFIG_CMD_FWU_METADATA=y
CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_BOOTEFI_HELLO is not set
+CONFIG_CMD_BOOTEFI_SELFTEST=y
# CONFIG_CMD_XIMG is not set
CONFIG_CMD_NVEDIT_EFI=y
CONFIG_CMD_GPT=y
@@ -79,6 +81,7 @@ CONFIG_SYSRESET=y
CONFIG_SYSRESET_PSCI=y
CONFIG_TEE=y
CONFIG_OPTEE=y
+# CONFIG_CMD_POWEROFF is not set
CONFIG_USB=y
CONFIG_USB_ISP1760=y
CONFIG_VIRTIO_MMIO=y
@@ -0,0 +1,176 @@
From 85edddc46913a19ce9e2dd0cb802a2dac60c9b9d Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Sun, 11 Jan 2026 20:36:45 +0000
Subject: [PATCH 47/53] efi: selftest: add runtime variable tests with
non-volatile storage
Extend runtime variable tests for persistent storage
Previously, EFI selftesting of runtime variables was only supported
under CONFIG_EFI_RT_VOLATILE_STORE, which uses VarToFile to simulate
non-volatile variable storage. This commit adds new test cases that
exercise runtime variable operations for persistent storage.
Features tested:
- Creation of runtime-accessible variables (set)
- Retrieval of runtime variables (get)
- Deletion using SetVariable() with size = 0
- Append operation using EFI_VARIABLE_APPEND_WRITE
This improves EFI compliance validation for non-volatile runtime storage
scenarios and ensures proper attribute enforcement and variable
management.
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
.../efi_selftest_variables_runtime.c | 108 +++++++++++++++++-
1 file changed, 105 insertions(+), 3 deletions(-)
diff --git a/lib/efi_selftest/efi_selftest_variables_runtime.c b/lib/efi_selftest/efi_selftest_variables_runtime.c
index 379c4f9c47b..7c14b9fefd4 100644
--- a/lib/efi_selftest/efi_selftest_variables_runtime.c
+++ b/lib/efi_selftest/efi_selftest_variables_runtime.c
@@ -3,6 +3,7 @@
* efi_selftest_variables_runtime
*
* Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ * Copyright (c) 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* This unit test checks the runtime services for variables after
* ExitBootServices():
@@ -40,7 +41,13 @@ static int setup(const efi_handle_t img_handle,
/**
* execute() - execute unit test
*
- * As runtime support is not implmented expect EFI_UNSUPPORTED to be returned.
+ * For EFI variables in non-volatile storage, these tests have to be executed in two phases
+ * 1. During first phase, run these tests and it creates EFI variable in persistent storage.
+ * 2. Then reboot and run the test again to verify if the variable created above is still
+ * available in non-volatile storage. If available, validate the EFI variable, append
+ * it, and validate it again. If validation is successful, delete the same variable.
+ *
+ * Return: EFI_ST_SUCCESS on success, EFI_ST_FAILURE on failure
*/
static int execute(void)
{
@@ -57,6 +64,80 @@ static int execute(void)
u64 max_storage, rem_storage, max_size;
int test_ret;
+ /* Compare the value of EFI variable if it already exists in non volatile storage */
+ if (!IS_ENABLED(CONFIG_EFI_RT_VOLATILE_STORE)) {
+ len = sizeof(v) / 2;
+ ret = runtime->get_variable(u"efi_st_var0", &guid_vendor0,
+ &attr, &len, data);
+ if (ret == EFI_SUCCESS) {
+ efi_st_printf("EFI Variable efi_st_var0 found. Executing Second Phase\n");
+ if (len != sizeof(v) / 2) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+ if (memcmp(data, v, len)) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Append an existing variable */
+ append_len = sizeof(v) - len;
+ ret = runtime->set_variable(u"efi_st_var0", &guid_vendor0,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_APPEND_WRITE |
+ EFI_VARIABLE_NON_VOLATILE,
+ append_len, (v + len));
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("SetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ len = sizeof(v);
+ ret = runtime->get_variable(u"efi_st_var0", &guid_vendor0,
+ &attr, &len, data);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ if (len != sizeof(v)) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ if (memcmp(data, v, len)) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Delete it by setting the size to 0 */
+ ret = runtime->set_variable(u"efi_st_var0", &guid_vendor0,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE,
+ 0, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("SetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ ret = runtime->get_variable(u"efi_st_var0", &guid_vendor0,
+ &attr, &len, data);
+ if (ret != EFI_NOT_FOUND) {
+ efi_st_error("GetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ return EFI_ST_SUCCESS;
+ } else {
+ if (ret == EFI_NOT_FOUND) {
+ efi_st_printf("EFI Variable efi_st_var0 not found. "
+ "Executing First Phase\n");
+ }
+ }
+ }
+
memset(v2, 0x1, sizeof(v2));
if (IS_ENABLED(CONFIG_EFI_VARIABLE_FILE_STORE)) {
@@ -70,7 +151,7 @@ static int execute(void)
ret = runtime->query_variable_info(EFI_VARIABLE_BOOTSERVICE_ACCESS,
&max_storage, &rem_storage,
&max_size);
- if (ret != EFI_UNSUPPORTED) {
+ if (ret != EFI_ST_SUCCESS) {
efi_st_error("QueryVariableInfo failed\n");
return EFI_ST_FAILURE;
}
@@ -286,7 +367,28 @@ static int execute(void)
return EFI_ST_FAILURE;
}
} else {
- if (ret != EFI_UNSUPPORTED) {
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("SetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Delete it by setting the size to 0 */
+ ret = runtime->set_variable(u"efi_st_var0", &guid_vendor0,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ 0, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("SetVariable failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Add an 8byte aligned variable */
+ ret = runtime->set_variable(u"efi_st_var0", &guid_vendor0,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE,
+ sizeof(v) / 2, v);
+ if (ret != EFI_SUCCESS) {
efi_st_error("SetVariable failed\n");
return EFI_ST_FAILURE;
}
@@ -0,0 +1,163 @@
From d12b38b7af88fdb37487d5196e214c8a4ad561fc Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Wed, 14 Jan 2026 13:55:02 +0000
Subject: [PATCH 48/53] test: dm: add sandbox FF-A runtime transport tests
Exercise FF-A runtime helpers via sandbox DM tests
Add driver-model unit tests that exercise the FF-A runtime helpers on
sandbox. The new tests reuse the sandbox emulator to validate both the
positive direct-request flow and failure handling, priming the emulator
state so the runtime path can be executed.
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
arch/sandbox/include/asm/sandbox_arm_ffa.h | 16 ++++-
test/dm/Makefile | 3 +-
test/dm/ffa_runtime.c | 82 ++++++++++++++++++++++
3 files changed, 99 insertions(+), 2 deletions(-)
create mode 100644 test/dm/ffa_runtime.c
diff --git a/arch/sandbox/include/asm/sandbox_arm_ffa.h b/arch/sandbox/include/asm/sandbox_arm_ffa.h
index be2790f4960..a20eb159b73 100644
--- a/arch/sandbox/include/asm/sandbox_arm_ffa.h
+++ b/arch/sandbox/include/asm/sandbox_arm_ffa.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * Copyright 2022-2023, 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* Authors:
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
@@ -26,6 +26,20 @@
#define SANDBOX_SP3_ID 0x6452
#define SANDBOX_SP4_ID 0x7814
+/*
+ * The sandbox FF-A emulator uses fixed, synthetic execution-context counts and
+ * property bitfields for each partition.
+ */
+#define SANDBOX_SP1_EXEC_CTXT 0x5687
+#define SANDBOX_SP2_EXEC_CTXT 0x9587
+#define SANDBOX_SP3_EXEC_CTXT 0x7687
+#define SANDBOX_SP4_EXEC_CTXT 0x1487
+
+#define SANDBOX_SP1_PROPERTIES 0x89325621
+#define SANDBOX_SP2_PROPERTIES 0x45325621
+#define SANDBOX_SP3_PROPERTIES 0x23325621
+#define SANDBOX_SP4_PROPERTIES 0x70325621
+
/* Invalid service UUID (no matching SP) */
#define SANDBOX_SERVICE3_UUID "55d532ed-0942-e699-722d-c09ca798d9cd"
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 474e77a2151..218b0b1411f 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2013 Google, Inc
-# Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# Copyright 2022-2023, 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
# Tests for particular subsystems - when enabling driver model for a new
# subsystem you must add sandbox tests here.
@@ -95,6 +95,7 @@ obj-$(CONFIG_ACPI_PMC) += pmc.o
obj-$(CONFIG_DM_PMIC) += pmic.o
obj-$(CONFIG_DM_PWM) += pwm.o
obj-$(CONFIG_ARM_FFA_TRANSPORT) += ffa.o
+obj-$(CONFIG_ARM_FFA_TRANSPORT) += ffa_runtime.o
obj-$(CONFIG_QFW) += qfw.o
obj-$(CONFIG_RAM) += ram.o
obj-y += regmap.o
diff --git a/test/dm/ffa_runtime.c b/test/dm/ffa_runtime.c
new file mode 100644
index 00000000000..4ba859fa314
--- /dev/null
+++ b/test/dm/ffa_runtime.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Functional tests for FF-A runtime helpers
+ *
+ * Copyright 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ *
+ * Authors:
+ * Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+ */
+
+#include <dm.h>
+#include <dm/test.h>
+#include <asm/sandbox_arm_ffa.h>
+#include <asm/sandbox_arm_ffa_priv.h>
+#include <arm_ffa_runtime.h>
+#include <test/ut.h>
+
+static int ffa_runtime_get_sp_id(struct unit_test_state *uts, u16 *sp_id)
+{
+ struct ffa_partition_desc *descs;
+ u32 count;
+ struct udevice *dev;
+ const char *svc_uuid = SANDBOX_SERVICE1_UUID;
+
+ ut_assertok(uclass_first_device_err(UCLASS_FFA, &dev));
+ ut_assertok(ffa_partition_info_get(dev, svc_uuid, &count, &descs));
+ ut_assert(count > 0);
+
+ *sp_id = descs[0].info.id;
+ return 0;
+}
+
+static int dm_test_ffa_runtime_ack(struct unit_test_state *uts)
+{
+ struct ffa_send_direct_data msg = {0};
+ u16 sp_id;
+ u8 cnt;
+
+ ut_assertok(ffa_runtime_get_sp_id(uts, &sp_id));
+
+ ffa_copy_runtime_priv(&(struct ffa_priv_runtime){
+ .id = NS_PHYS_ENDPOINT_ID,
+ });
+ ffa_enable_runtime_context();
+
+ /* Ensure runtime context is available before attempting runtime-only paths */
+ ut_assert(ffa_get_status_runtime_context());
+
+ /* Runtime messaging should reuse the sandbox emulator and return 0xff pattern */
+ ut_assertok(ffa_sync_send_receive_runtime(sp_id, &msg, true));
+ for (cnt = 0; cnt < sizeof(struct ffa_send_direct_data) / sizeof(u64); cnt++)
+ ut_asserteq_64(-1UL, ((u64 *)&msg)[cnt]);
+
+ /* Validate FF-A error to errno translation helpers */
+ ut_asserteq(-EINVAL, ffa_to_std_errno(-INVALID_PARAMETERS));
+ ut_asserteq(-EOPNOTSUPP, ffa_to_std_errno(-NOT_SUPPORTED));
+
+ return 0;
+}
+DM_TEST(dm_test_ffa_runtime_ack, UTF_SCAN_FDT | UTF_CONSOLE);
+
+static int dm_test_ffa_runtime_nack(struct unit_test_state *uts)
+{
+ struct ffa_send_direct_data msg = {0};
+ u16 sp_id;
+
+ ut_assertok(ffa_runtime_get_sp_id(uts, &sp_id));
+
+ ffa_copy_runtime_priv(&(struct ffa_priv_runtime){
+ .id = NS_PHYS_ENDPOINT_ID,
+ });
+ ffa_enable_runtime_context();
+
+ /* Ensure runtime context is available before attempting runtime-only paths */
+ ut_assert(ffa_get_status_runtime_context());
+
+ /* Invalid partition IDs must be rejected and mapped to -EINVAL */
+ ut_asserteq(-EINVAL, ffa_sync_send_receive_runtime(0, &msg, true));
+
+ return 0;
+}
+DM_TEST(dm_test_ffa_runtime_nack, UTF_SCAN_FDT | UTF_CONSOLE);
@@ -0,0 +1,96 @@
From 6e707fe6a0120a3a6aa7954a250293162a441b21 Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Thu, 15 Jan 2026 10:57:48 +0000
Subject: [PATCH 49/53] sandbox: ffa: share synthetic partition metadata via
macros
Reuse sandbox FF-A partition constants in emulator tests
Allow the sandbox FF-A emulator test to use execution-context and property
constants defined in sandbox_arm_ffa.h
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
drivers/firmware/arm-ffa/ffa-emul-uclass.c | 36 ++++++++++++++++------
1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/drivers/firmware/arm-ffa/ffa-emul-uclass.c b/drivers/firmware/arm-ffa/ffa-emul-uclass.c
index 531ecb12f3a..33d38d37ddb 100644
--- a/drivers/firmware/arm-ffa/ffa-emul-uclass.c
+++ b/drivers/firmware/arm-ffa/ffa-emul-uclass.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2022-2023, 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * Copyright 2022-2023, 2025-2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* Authors:
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
@@ -22,41 +22,57 @@ DECLARE_GLOBAL_DATA_PTR;
/* The partitions (SPs) table */
static struct ffa_partition_desc sandbox_partitions[SANDBOX_PARTITIONS_CNT] = {
{
- .info = { .id = SANDBOX_SP1_ID, .exec_ctxt = 0x5687, .properties = 0x89325621 },
+ .info = {
+ .id = SANDBOX_SP1_ID,
+ .exec_ctxt = SANDBOX_SP1_EXEC_CTXT,
+ .properties = SANDBOX_SP1_PROPERTIES,
+ },
.sp_uuid = {
.a1 = SANDBOX_SERVICE1_UUID_A1,
.a2 = SANDBOX_SERVICE1_UUID_A2,
.a3 = SANDBOX_SERVICE1_UUID_A3,
.a4 = SANDBOX_SERVICE1_UUID_A4,
- }
+ },
},
{
- .info = { .id = SANDBOX_SP3_ID, .exec_ctxt = 0x7687, .properties = 0x23325621 },
+ .info = {
+ .id = SANDBOX_SP2_ID,
+ .exec_ctxt = SANDBOX_SP2_EXEC_CTXT,
+ .properties = SANDBOX_SP2_PROPERTIES,
+ },
.sp_uuid = {
.a1 = SANDBOX_SERVICE2_UUID_A1,
.a2 = SANDBOX_SERVICE2_UUID_A2,
.a3 = SANDBOX_SERVICE2_UUID_A3,
.a4 = SANDBOX_SERVICE2_UUID_A4,
- }
+ },
},
{
- .info = { .id = SANDBOX_SP2_ID, .exec_ctxt = 0x9587, .properties = 0x45325621 },
+ .info = {
+ .id = SANDBOX_SP3_ID,
+ .exec_ctxt = SANDBOX_SP3_EXEC_CTXT,
+ .properties = SANDBOX_SP3_PROPERTIES,
+ },
.sp_uuid = {
.a1 = SANDBOX_SERVICE1_UUID_A1,
.a2 = SANDBOX_SERVICE1_UUID_A2,
.a3 = SANDBOX_SERVICE1_UUID_A3,
.a4 = SANDBOX_SERVICE1_UUID_A4,
- }
+ },
},
{
- .info = { .id = SANDBOX_SP4_ID, .exec_ctxt = 0x1487, .properties = 0x70325621 },
+ .info = {
+ .id = SANDBOX_SP4_ID,
+ .exec_ctxt = SANDBOX_SP4_EXEC_CTXT,
+ .properties = SANDBOX_SP4_PROPERTIES,
+ },
.sp_uuid = {
.a1 = SANDBOX_SERVICE2_UUID_A1,
.a2 = SANDBOX_SERVICE2_UUID_A2,
.a3 = SANDBOX_SERVICE2_UUID_A3,
.a4 = SANDBOX_SERVICE2_UUID_A4,
- }
- }
+ },
+ },
};
@@ -0,0 +1,176 @@
From a4d871a16513e86290aaa2304f0195e533200937 Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Wed, 25 Feb 2026 14:40:19 +0000
Subject: [PATCH 50/53] doc: arm64: document FF-A runtime path for EFI
variables
Document how EFI runtime variables use FF-A MM communication
Describe the FF-A runtime layer on arm64 and how EFI variable
runtime services use the FF-A transport and shared MM buffer.
Also clarify armffa command scope and link to the FF-A doc.
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
doc/arch/arm64.ffa.rst | 92 +++++++++++++++++++++++++++++++++++++---
doc/usage/cmd/armffa.rst | 11 +++++
2 files changed, 96 insertions(+), 7 deletions(-)
diff --git a/doc/arch/arm64.ffa.rst b/doc/arch/arm64.ffa.rst
index d2c4fb49f79..53218cd9c96 100644
--- a/doc/arch/arm64.ffa.rst
+++ b/doc/arch/arm64.ffa.rst
@@ -15,10 +15,10 @@ application in S-EL0, or a Trusted OS in S-EL1.
The U-Boot FF-A support (the bus) implements the interfaces to communicate
with partitions in the Secure world aka Secure partitions (SPs).
-The FF-A support specifically focuses on communicating with SPs that
-isolate portions of EFI runtime services that must run in a protected
-environment which is inaccessible by the Host OS or Hypervisor.
-Examples of such services are set/get variables.
+U-Boot's FF-A bus support exposes an optional transport that EFI runtime
+services can use to communicate with Secure Partitions. Through this
+interface, EFI services (such as variable access) can request or exchange
+data with the Secure World using FF-A.
The FF-A support uses the SMC ABIs defined by the FF-A specification to:
@@ -26,13 +26,13 @@ The FF-A support uses the SMC ABIs defined by the FF-A specification to:
- Access an SP's service through communication protocols
e.g. EFI MM communication protocol
-At this stage of development only EFI boot-time services are supported.
-Runtime support will be added in future developments.
-
The U-Boot FF-A support provides the following parts:
- A Uclass driver providing generic FF-A methods.
- An Arm FF-A device driver providing Arm-specific methods and reusing the Uclass methods.
+- An optional runtime FF-A transport (toggled via CONFIG_ARM_FFA_RT_MODE) that is
+ resident after ExitBootServices() and enables EFI runtime variable services
+ via FF-A helpers and a shared MM communication buffer.
- A sandbox emulator for Arm FF-A, emulates the FF-A side of the Secure World and provides
FF-A ABIs inspection methods.
- An FF-A sandbox device driver for FF-A communication with the emulated Secure World.
@@ -69,6 +69,12 @@ CONFIG_ARM_FFA_TRANSPORT
When using an Arm 64-bit platform, the Arm FF-A driver will be used.
When using sandbox, the sandbox FF-A emulator and FF-A sandbox driver will be used.
+CONFIG_ARM_FFA_RT_MODE
+ Enables the FF-A runtime transport. This option depends on
+ CONFIG_ARM_FFA_TRANSPORT and CONFIG_EFI_LOADER, and is enabled by default.
+ When enabled, a minimal set of FF-A operations remains available after
+ ExitBootServices().
+
FF-A ABIs under the hood
------------------------
@@ -158,6 +164,77 @@ they want to use (32-bit vs 64-bit). Selecting the protocol means using
the 32-bit or 64-bit version of FFA_MSG_SEND_DIRECT_{REQ, RESP}.
The calling convention between U-Boot and the secure world stays the same: SMC32.
+FF-A runtime support for EFI variables
+--------------------------------------
+
+U-Boot provides an FF-A runtime transport to keep a minimal set of FF-A operations
+available after ExitBootServices(). This runtime transport is enabled with
+CONFIG_ARM_FFA_RT_MODE. The runtime helpers and data are marked with
+``__efi_runtime`` / ``__efi_runtime_data`` through the
+``__ffa_runtime`` / ``__ffa_runtime_data`` aliases in
+``include/arm_ffa_runtime.h``.
+
+Runtime context is enabled at ExitBootServices(), and the following prerequisites
+are prepared during FF-A bus probe:
+
+- The U-Boot FF-A endpoint ID is discovered at boot time with FFA_ID_GET and
+ stored in the runtime private data.
+- An ExitBootServices() event is registered by the runtime transport to enable
+ the runtime context with ffa_enable_runtime_context() when EFI transitions
+ to runtime.
+
+At runtime, the driver model is no longer available. Runtime users should
+use the runtime interface ffa_sync_send_receive_runtime(), which internally
+verifies the runtime context before issuing FF-A calls.
+
+EFI variable services over FF-A
+-------------------------------
+
+When CONFIG_EFI_MM_COMM_TEE and CONFIG_ARM_FFA_TRANSPORT are enabled, U-Boot
+routes EFI variable services to an MM Secure Partition (SP) over FF-A.
+The MM SP is discovered at boot time using FFA_PARTITION_INFO_GET and its
+partition ID is cached in runtime data.
+
+The data path uses a shared MM communication buffer and a door-bell style
+direct message:
+
+- The communication buffer is located at CONFIG_FFA_SHARED_MM_BUF_ADDR and
+ sized by CONFIG_FFA_SHARED_MM_BUF_SIZE.
+- CONFIG_FFA_SHARED_MM_BUF_OFFSET is sent in the FF-A direct message payload
+ to indicate where the data begins.
+- The buffer is filled by memcpy(), the cache is flushed before notifying the
+ MM SP, and later the buffer is reused directly with only the shared-buffer
+ range invalidated (invalidate_dcache_range()) to avoid whole-cache
+ invalidation.
+
+After ExitBootServices(), EFI SetVariable()/GetVariable() call paths use the
+runtime MM communication helpers:
+
+- get_comm_buf() switches to the static shared buffer
+- mm_communicate_runtime() selects FF-A transport when the runtime context
+ is enabled
+- ffa_mm_communicate_runtime() issues FFA_MSG_SEND_DIRECT_{REQ,RESP} through
+ ffa_sync_send_receive_runtime()
+
+Configuration notes
+-------------------
+
+Enable FF-A transport and MM communication:
+
+- CONFIG_ARM_FFA_TRANSPORT
+- CONFIG_ARM_FFA_RT_MODE
+- CONFIG_EFI_MM_COMM_TEE
+
+CONFIG_ARM_FFA_RT_MODE is enabled by default. It turns on MM communication for
+EFI runtime and may be disabled when EFI services over FF-A are not required
+after ExitBootServices().
+
+Configure the shared MM communication buffer:
+
+- CONFIG_FFA_SHARED_MM_BUF_ADDR
+- CONFIG_FFA_SHARED_MM_BUF_SIZE
+- CONFIG_FFA_SHARED_MM_BUF_OFFSET
+
Requirements for user drivers
-----------------------------
@@ -260,6 +337,7 @@ For example, when using FF-A with Corstone-1000, debug logs enabled, the output
Contributors
------------
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+ * Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
.. _`FF-A v1.0 specification`: https://documentation-service.arm.com/static/5fb7e8a6ca04df4095c1d65e
.. _`SMC Calling Convention v1.2 specification`: https://documentation-service.arm.com/static/5f8edaeff86e16515cdbe4c6
diff --git a/doc/usage/cmd/armffa.rst b/doc/usage/cmd/armffa.rst
index 4f41e3393fd..5dcc3047a45 100644
--- a/doc/usage/cmd/armffa.rst
+++ b/doc/usage/cmd/armffa.rst
@@ -39,6 +39,17 @@ The command also allows to gather secure partitions information and ping these
The command is also helpful in testing the communication with secure partitions.
+Notes
+-----
+
+armffa is a boot-time test command. It relies on the FF-A driver model device
+(UCLASS_FFA) and is not intended for EFI runtime use after
+ExitBootServices().
+
+armffa does not provide EFI variable operations. For more information about
+using EFI runtime SetVariable() and GetVariable() over FF-A please see
+:doc:`../../arch/arm64.ffa`.
+
Example
-------
@@ -0,0 +1,47 @@
From d595e579413e8bcf1f65be25f3da340abb5d2c2b Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Wed, 1 Apr 2026 13:37:35 +0100
Subject: [PATCH 51/53] doc: bootefi: note two-phase runtime variables selftest
Explain how the runtime variable selftest runs in two phases
Document that the "variables at runtime" selftest runs in two
phases when CONFIG_EFI_RT_VOLATILE_STORE is not enabled, and
show how to select it with efi_selftest.
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
doc/usage/cmd/bootefi.rst | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/doc/usage/cmd/bootefi.rst b/doc/usage/cmd/bootefi.rst
index 7c5448586b7..91aebf1a4b5 100644
--- a/doc/usage/cmd/bootefi.rst
+++ b/doc/usage/cmd/bootefi.rst
@@ -160,6 +160,16 @@ environment variable to match one of the listed identifiers
Some of the tests execute the ExitBootServices() UEFI boot service and will not
return to the command line but require a board reset.
+The test *variables at runtime* runs in two phases when
+CONFIG_EFI_RT_VOLATILE_STORE is not enabled. Run it once to create a
+runtime-accessible variable in non-volatile storage, reboot, then run it
+again to validate, append, and delete that variable.
+
+::
+
+ => setenv efi_selftest 'variables at runtime'
+ => bootefi selftest
+
Configuration
-------------
@@ -167,6 +177,8 @@ To use the *bootefi* command you must specify CONFIG_CMD_BOOTEFI=y.
The *bootefi bootmgr* sub-command requries CMD_BOOTEFI_BOOTMGR=y.
The *bootefi hello* sub-command requries CMD_BOOTEFI_HELLO=y.
The *bootefi selftest* sub-command depends on CMD_BOOTEFI_SELFTEST=y.
+The *variables at runtime* selftest runs in two phases when
+CONFIG\_EFI\_RT\_VOLATILE\_STORE is not enabled.
See also
--------
@@ -0,0 +1,75 @@
From 00b68d1c3dd2d182545bcacc668dbb2f637c94c1 Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Fri, 10 Apr 2026 13:50:25 +0100
Subject: [PATCH 52/53] efi_loader: align FF-A cache maintenance with runtime
path
Match boot-time FF-A cache handling to runtime behavior
The boot-time FF-A MM communication path used invalidate_dcache_all()
after copying the message into the shared buffer. This differs from the
runtime path, which performs range-based maintenance to avoid global cache
operations.
Update ffa_mm_communicate() to use the same pattern as the runtime helper:
clean the shared buffer range before the SMC and invalidate the same range
after the response. This keeps boot-time and runtime behavior consistent
and avoids whole-cache invalidation.
Upstream-Status: Submitted [cover letter: https://lore.kernel.org/u-boot/20260424173151.371134-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
lib/efi_loader/efi_variable_tee.c | 33 ++++++++++++++++++++++++-------
1 file changed, 26 insertions(+), 7 deletions(-)
diff --git a/lib/efi_loader/efi_variable_tee.c b/lib/efi_loader/efi_variable_tee.c
index 30687c21b8e..df509a435b1 100644
--- a/lib/efi_loader/efi_variable_tee.c
+++ b/lib/efi_loader/efi_variable_tee.c
@@ -389,19 +389,38 @@ static efi_status_t ffa_mm_communicate(void *comm_buf, ulong comm_buf_size)
memcpy(virt_shared_buf, comm_buf, tx_data_size);
/*
- * The secure world might have cache disabled for
- * the device region used for shared buffer (which is the case for Optee).
- * In this case, the secure world reads the data from DRAM.
- * Let's flush the cache so the DRAM is updated with the latest data.
+ * Shared buffer cache maintenance for FF-A / OP-TEE communication:
+ *
+ * NS -> S (request path):
+ *
+ * The non-secure side populates the shared buffer. If the buffer is cached
+ * in NS, the updated bytes may reside in dirty D-cache lines and not yet be
+ * visible in DDR. Since the secure world typically reads the shared buffer
+ * directly from DDR (e.g. with caches disabled / non-coherent mapping), we
+ * must clean the corresponding cache lines to the Point of Coherency (PoC)
+ * before entering secure world.
+ *
+ * S -> NS (response path):
+ *
+ * The secure world may update the same shared buffer in DDR. After returning
+ * to non-secure, any cached copies of that region in NS may be stale. We
+ * therefore invalidate the shared buffer range after the FF-A call to drop
+ * those lines and force subsequent reads to fetch the latest data from DDR.
*/
-#ifdef CONFIG_ARM64
- invalidate_dcache_all();
-#endif
+ if (IS_ENABLED(CONFIG_ARM64))
+ flush_dcache_range((unsigned long)virt_shared_buf,
+ (unsigned long)virt_shared_buf +
+ CONFIG_FFA_SHARED_MM_BUF_SIZE);
/* Announce there is data in the shared buffer */
ffa_ret = ffa_notify_mm_sp();
+ if (IS_ENABLED(CONFIG_ARM64))
+ invalidate_dcache_range((unsigned long)virt_shared_buf,
+ (unsigned long)virt_shared_buf +
+ CONFIG_FFA_SHARED_MM_BUF_SIZE);
+
switch (ffa_ret) {
case 0: {
ulong rx_data_size;
@@ -0,0 +1,50 @@
From 1be3bcbc0c7efc36b8fbac7ef0f8c8375dc6770d Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Sat, 18 Apr 2026 14:26:28 +0100
Subject: [PATCH 53/53] efi_loader: fix AllocatePages overlap status
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Return EFI_NOT_FOUND for EFI_ALLOCATE_ADDRESS overlap
When efi_allocate_pages() is called with EFI_ALLOCATE_ADDRESS, UEFI
expects EFI_NOT_FOUND if the requested address range is already
allocated or unavailable. U-Boot currently returns
EFI_OUT_OF_RESOURCES when efi_update_memory_map() detects an overlap
after a successful lmb_alloc_mem(), which does not match
EFI_ALLOCATE_ADDRESS semantics.
Return EFI_NOT_FOUND for EFI_ALLOCATE_ADDRESS requests that fail due
to an overlapping EFI memory descriptor, while keeping
EFI_OUT_OF_RESOURCES for other allocation types.
The UEFI specification [1] specifies that
EFI_BOOT_SERVICES.AllocatePages must return EFI_NOT_FOUND when the
requested address range is unavailable or already allocated;
EFI_OUT_OF_RESOURCES applies to nonaddressspecific allocation
failures.
[1] https://uefi.org/specs/UEFI/2.10_A/07_Services_Boot_Services.html
Upstream-Status: Submitted [https://lore.kernel.org/u-boot/20260427150530.3156000-1-harsimransingh.tungal@arm.com/]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
lib/efi_loader/efi_memory.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index b77c2f980cc..63cf1a7277f 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -510,7 +510,9 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
/* Map would overlap, bail out */
lmb_free(addr, (u64)pages << EFI_PAGE_SHIFT, flags);
unmap_sysmem((void *)(uintptr_t)efi_addr);
- return EFI_OUT_OF_RESOURCES;
+ if (type == EFI_ALLOCATE_ADDRESS)
+ return EFI_NOT_FOUND;
+ return EFI_OUT_OF_RESOURCES;
}
*memory = efi_addr;
@@ -0,0 +1,37 @@
From 0da9650a3ed86e63c6a9621d7a9195eb3a75a233 Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Fri, 17 Apr 2026 13:41:07 +0100
Subject: [PATCH] corstone1000-a320: enable bootefi selftest
Turn on CONFIG_CMD_BOOTEFI_SELFTEST in the Corstone-1000 defconfig
so the board can run the built-in UEFI self-test suite during
development and validation.
Upstream-Status: Pending [Will be submitted upstream with the
pending Cortex-A320 related U-Boot changes]
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
configs/corstone1000-a320_defconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/configs/corstone1000-a320_defconfig b/configs/corstone1000-a320_defconfig
index d0ae1e745db..c4dcd1790cc 100644
--- a/configs/corstone1000-a320_defconfig
+++ b/configs/corstone1000-a320_defconfig
@@ -41,6 +41,8 @@ CONFIG_SYS_PROMPT="corstone1000# "
# CONFIG_CMD_CONSOLE is not set
CONFIG_CMD_FWU_METADATA=y
CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_BOOTEFI_HELLO is not set
+CONFIG_CMD_BOOTEFI_SELFTEST=y
# CONFIG_CMD_XIMG is not set
CONFIG_CMD_NVEDIT_EFI=y
CONFIG_CMD_GPT=y
@@ -76,6 +78,7 @@ CONFIG_SYSRESET=y
CONFIG_SYSRESET_PSCI=y
CONFIG_TEE=y
CONFIG_OPTEE=y
+# CONFIG_CMD_POWEROFF is not set
CONFIG_USB=y
CONFIG_USB_ISP1760=y
CONFIG_VIRTIO_MMIO=y
@@ -1,4 +1,4 @@
From 67b2bcd428a13d14d4311bd1122e664f391af4d4 Mon Sep 17 00:00:00 2001
From 469d6ae6f7f0e6356457a50ab490b56e423e4e50 Mon Sep 17 00:00:00 2001
From: Diego Sueiro <diego.sueiro@arm.com>
Date: Wed, 4 Oct 2023 06:29:12 +0100
Subject: [PATCH] vexpress64: Imply CONFIG_ARM64_CRC32 by default
@@ -15,7 +15,7 @@ Signed-off-by: Diego Sueiro <diego.sueiro@arm.com>
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/board/armltd/vexpress64/Kconfig b/board/armltd/vexpress64/Kconfig
index 9ef3fa1b379f..1a0e0a5018d8 100644
index 9ef3fa1b379..1a0e0a5018d 100644
--- a/board/armltd/vexpress64/Kconfig
+++ b/board/armltd/vexpress64/Kconfig
@@ -24,6 +24,7 @@ config VEXPRESS64_BASE_MODEL
@@ -27,7 +27,7 @@ index 9ef3fa1b379f..1a0e0a5018d8 100644
choice
prompt "VExpress64 board variant"
diff --git a/include/configs/vexpress_aemv8.h b/include/configs/vexpress_aemv8.h
index 5eee13b3fc01..5c271d239501 100644
index fc4727b4a38..01310ca0454 100644
--- a/include/configs/vexpress_aemv8.h
+++ b/include/configs/vexpress_aemv8.h
@@ -172,7 +172,7 @@
@@ -39,9 +39,9 @@ index 5eee13b3fc01..5c271d239501 100644
" setenv bootargs;" \
" abootimg addr ${boot_addr_r};" \
" abootimg get dtb --index=0 fdt_addr_r;" \
@@ -181,13 +181,14 @@
@@ -180,13 +180,14 @@
"else" \
" if load hostfs - ${kernel_addr_r} ${kernel_name}; then" \
" setenv fdt_high 0xffffffffffffffff;" \
" setenv initrd_high 0xffffffffffffffff;" \
- " if test -n load hostfs - ${fdt_addr_r} ${fdtfile}; then" \
- " fdt move $fdtcontroladdr $fdt_addr_r;" \
@@ -1,4 +1,4 @@
From ddf8928e53830ddce9dc5383143dcab75b4a4cfb Mon Sep 17 00:00:00 2001
From 9622b33133ddcd2da42fe41a6e5e52d7c7d5ccf8 Mon Sep 17 00:00:00 2001
From: Jon Mason <jdmason@kudzu.us>
Date: Mon, 19 Dec 2022 11:36:04 -0500
Subject: [PATCH] configs: vexpress: modify to boot compressed initramfs
@@ -10,10 +10,10 @@ Upstream-Status: Inappropriate
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/configs/vexpress_aemv8.h b/include/configs/vexpress_aemv8.h
index 5eee13b3fc01..82dff260c30c 100644
index fc4727b4a38..2c83189923f 100644
--- a/include/configs/vexpress_aemv8.h
+++ b/include/configs/vexpress_aemv8.h
@@ -213,8 +213,10 @@
@@ -212,8 +212,10 @@
#define VEXPRESS_RAMDISK_ADDR 0x8fe00000
#define EXTRA_ENV_NAMES \
@@ -9,6 +9,9 @@ COMPATIBLE_MACHINE = "rdn2"
SRC_URI_EDK2 = "gitsm://gitlab.arm.com/infra-solutions/reference-design/platsw/edk2.git;protocol=https"
SRC_URI_EDK2_PLATFORMS = "git://gitlab.arm.com/infra-solutions/reference-design/platsw/edk2-platforms.git;protocol=https"
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append = " file://0001-Changes-in-acpica-20260408-are-now-causing-issues-wi.patch;patchdir=edk2-platforms"
SRCBRANCH_edk2 = "refinfra"
SRCBRANCH_edk2_platforms = "refinfra"
@@ -9,6 +9,9 @@ COMPATIBLE_MACHINE = "rdv2"
SRC_URI_EDK2 = "gitsm://gitlab.arm.com/infra-solutions/reference-design/platsw/edk2.git;protocol=https"
SRC_URI_EDK2_PLATFORMS = "git://gitlab.arm.com/infra-solutions/reference-design/platsw/edk2-platforms.git;protocol=https"
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append = " file://0001-Changes-in-acpica-20260408-are-now-causing-issues-wi.patch;patchdir=edk2-platforms"
SRCBRANCH_edk2 = "refinfra"
SRCBRANCH_edk2_platforms = "refinfra"
@@ -0,0 +1,24 @@
From 5929e3d0b92d6ae72b2c7c79ca1543d4c2e23e98 Mon Sep 17 00:00:00 2001
From: Jon Mason <jon.mason@arm.com>
Date: Mon, 4 May 2026 14:40:05 -0400
Subject: [PATCH] Changes in acpica 20260408 are now causing issues with the
Printf in SsdrEvents.asl. Since this is probably for debug, remove it.
Upstream-Status: Inappropriate
Signed-off-by: Jon Mason <jon.mason@arm.com>
---
Platform/ARM/SgiPkg/AcpiTables/SsdtEvents.asl | 1 -
1 file changed, 1 deletion(-)
diff --git a/Platform/ARM/SgiPkg/AcpiTables/SsdtEvents.asl b/Platform/ARM/SgiPkg/AcpiTables/SsdtEvents.asl
index 58efe62c93ea..61489513f61b 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/SsdtEvents.asl
+++ b/Platform/ARM/SgiPkg/AcpiTables/SsdtEvents.asl
@@ -56,7 +56,6 @@ DefinitionBlock("SsdtEvent.aml", "SSDT", 2, "ARMLTD", "ARMSGI", EFI_ACPI_ARM_OEM
/* Event handler for pin0 */
Method (_L00) {
- Printf ("GPIO0 Pin0 Toggled")
Store (1, INC0)
}
@@ -1,6 +1,7 @@
# These machines cannot run in product as they are virtual
# platforms, so allow ssh-pregen-hostkeys to be used.
COMPATIBLE_MACHINE:corstone1000-fvp = "corstone1000-fvp"
COMPATIBLE_MACHINE:corstone1000 = "corstone1000-fvp"
COMPATIBLE_MACHINE:corstone1000:cortexa320 = "corstone1000-a320-fvp"
COMPATIBLE_MACHINE:fvp-base = "fvp-base"
COMPATIBLE_MACHINE:sbsa-ref = "sbsa-ref"
@@ -3,8 +3,8 @@ FILESEXTRAPATHS:prepend:corstone1000 := "${THISDIR}/corstone1000/psa-apitest:"
include ts-arm-platforms.inc
SRC_URI:append:corstone1000 = " \
file://0001-corstone1000-port-crypto-config.patch;patchdir=../psatest \
file://0002-corstone1000-Disable-obsolete-algorithms.patch;patchdir=../psatest \
file://0003-corstone1000-Disable-SHA512-384.patch;patchdir=../psatest \
file://0004-Remove-RSA-support.patch;patchdir=../psatest \
file://0001-corstone1000-port-crypto-config.patch;patchdir=../ts/ts-external/psatest \
file://0002-corstone1000-Disable-obsolete-algorithms.patch;patchdir=../ts/ts-external/psatest \
file://0003-corstone1000-Disable-SHA512-384.patch;patchdir=../ts/ts-external/psatest \
file://0004-Remove-RSA-support.patch;patchdir=../ts/ts-external/psatest \
"
@@ -2,11 +2,12 @@ SUMMARY = "CORSTONE1000 external systems communications tests"
DESCRIPTION = "This is a Linux userspace tool to test the communication between Corstone1000 cores"
HOMEPAGE = "https://git.linaro.org/landing-teams/working/arm/test-apps.git"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://license.md;md5=e44b2531cd6ffe9dece394dbe988d9a0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=e44b2531cd6ffe9dece394dbe988d9a0"
SRC_URI = "git://git.gitlab.arm.com/arm-reference-solutions/corstone1000/applications.git;protocol=https;branch=master"
SRCREV = "2945cd92f7c6dbe4999ee72cd5cf1e2615eedba7"
PV .= "+git"
SRC_URI = "git://gitlab.arm.com/arm-reference-solutions/corstone1000/applications.git;protocol=https;branch=master"
SRCREV = "ab79333697875666f397a3a70ee5da15a6eba4b5"
UPSTREAM_CHECK_COMMITS = "1"
COMPATIBLE_MACHINE = "corstone1000"
@@ -11,11 +11,11 @@ LICENSE = "GPL-3.0-with-GCC-exception & GPL-3.0-only"
LIC_FILES_CHKSUM:aarch64 = "file://share/doc/gcc/Copying.html;md5=90014a59d1783b37a10240d4d0002c6e"
LIC_FILES_CHKSUM:x86-64 = "file://share/doc/gcc/Copying.html;md5=90014a59d1783b37a10240d4d0002c6e"
SRC_URI = "https://developer.arm.com/-/media/Files/downloads/gnu/${PV}/binrel/arm-gnu-toolchain-${PV}-${HOST_ARCH}-${BINNAME}.tar.xz;name=gcc-${HOST_ARCH}"
SRC_URI[gcc-aarch64.sha256sum] = "46195685b6aec1077e3f1b7706b43a6aa1fef4d8d3bff3a411b7dad1c5b1196b"
SRC_URI[gcc-x86_64.sha256sum] = "66f7ce7c1bf662f589a4caf440812375f3cd8000a033ccf0971127a0726d6921"
SRC_URI = "https://gitlab.arm.com/api/v4/projects/tooling%2Fgnu-toolchains-for-arm/packages/generic/gnu-toolchain/${PV}/arm-gnu-toolchain-${PV}-${HOST_ARCH}-${BINNAME}.tar.xz;name=gcc-${HOST_ARCH}"
SRC_URI[gcc-aarch64.sha256sum] = "a1c6fdda8b479ea3e235d38dc0994790b840648b60e9fbaf88c82ca117a7a2df"
SRC_URI[gcc-x86_64.sha256sum] = "1b07847728d455f18895f1ebd5d71a40f2ccb7cb3a84ca9a874d7f961a318ce4"
S = "${UNPACKDIR}/arm-gnu-toolchain-${PV}-${HOST_ARCH}-${BINNAME}"
UPSTREAM_CHECK_URI = "https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads"
UPSTREAM_CHECK_REGEX = "arm-gnu-toolchain-(?P<pver>\d+\.\d*\.[A-z]*\d*).*-${HOST_ARCH}-${BINNAME}\.tar\.\w+"
UPSTREAM_CHECK_URI = "https://gitlab.arm.com/tooling/gnu-toolchains-for-arm/-/branches"
UPSTREAM_CHECK_REGEX = "releases/(?P<pver>.+)\?"
@@ -11,11 +11,11 @@ LICENSE = "GPL-3.0-with-GCC-exception & GPL-3.0-only"
LIC_FILES_CHKSUM:aarch64 = "file://share/doc/gcc/Copying.html;md5=90014a59d1783b37a10240d4d0002c6e"
LIC_FILES_CHKSUM:x86-64 = "file://share/doc/gcc/Copying.html;md5=90014a59d1783b37a10240d4d0002c6e"
SRC_URI = "https://developer.arm.com/-/media/Files/downloads/gnu/${PV}/binrel/arm-gnu-toolchain-${PV}-${HOST_ARCH}-${BINNAME}.tar.xz;name=gcc-${HOST_ARCH}"
SRC_URI[gcc-aarch64.sha256sum] = "d061559d814b205ed30c5b7c577c03317ec447ca51cd5a159d26b12a5bbeb20c"
SRC_URI[gcc-x86_64.sha256sum] = "597893282ac8c6ab1a4073977f2362990184599643b4c5ee34870a8215783a16"
SRC_URI = "https://gitlab.arm.com/api/v4/projects/tooling%2Fgnu-toolchains-for-arm/packages/generic/gnu-toolchain/${PV}/arm-gnu-toolchain-${PV}-${HOST_ARCH}-${BINNAME}.tar.xz;name=gcc-${HOST_ARCH}"
SRC_URI[gcc-aarch64.sha256sum] = "06979e0c8171de58e5dc2a2b2019330a290f30930f27728af98a83e1a7369b3a"
SRC_URI[gcc-x86_64.sha256sum] = "563bebb2b97d53382b956d6ee1fe61e2cae26699901417234a37df505ef9b5fa"
S = "${UNPACKDIR}/arm-gnu-toolchain-${PV}-${HOST_ARCH}-${BINNAME}"
UPSTREAM_CHECK_URI = "https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads"
UPSTREAM_CHECK_REGEX = "arm-gnu-toolchain-(?P<pver>\d+\.\d*\.[A-z]*\d*).*-${HOST_ARCH}-${BINNAME}\.tar\.\w+"
UPSTREAM_CHECK_URI = "https://gitlab.arm.com/tooling/gnu-toolchains-for-arm/-/branches"
UPSTREAM_CHECK_REGEX = "releases/(?P<pver>.+)\?"
@@ -18,6 +18,8 @@ IMAGE_FSTYPES += "wic wic.qcow2"
WKS_FILE ?= "qemuarm.wks"
WKS_FILE_DEPENDS = "trusted-firmware-a"
#FIXME - in 2.15.0, new logic for pen hold the SMP cores was added, which breaks this platform. Hold this back until it can be resolved.
PREFERRED_VERSION_trusted-firmware-a ?= "2.14.%"
IMAGE_BOOT_FILES = "${KERNEL_IMAGETYPE}"
MACHINE_FEATURES += "optee-ftpm"
@@ -96,3 +96,6 @@ do_install() {
INSANE_SKIP:${PN}-dbg += "arch"
INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
INHIBIT_PACKAGE_STRIP = "1"
CVE_PRODUCT = "arm:scp-firmware \
arm:scp_firmware"
@@ -6,9 +6,9 @@ SRC_URI_TRUSTED_FIRMWARE_A ?= "git://review.trustedfirmware.org/TF-A/trusted-fir
SRC_URI = "${SRC_URI_TRUSTED_FIRMWARE_A};branch=${SRCBRANCH}"
LIC_FILES_CHKSUM = "file://docs/license.rst;md5=6ed7bace7b0bc63021c6eba7b524039e"
# Use cot-dt2c from TF-A v2.14.1
SRCREV = "e82c7ced9e76aea35b176e608d67dfe5ebe1c569"
SRCBRANCH = "lts-v2.14"
# Use cot-dt2c from TF-A v2.15.0
SRCREV = "da738d5eae93af342fdc4995dd3c05acb4c9d757"
SRCBRANCH = "master"
inherit python_poetry_core
@@ -0,0 +1,41 @@
From 042dcbc95249a2311e8a784fa7193299aa2ad651 Mon Sep 17 00:00:00 2001
From: Jon Mason <jon.mason@arm.com>
Date: Sat, 30 May 2026 10:24:53 -0400
Subject: [PATCH] Fix GCC errors in test_psci_stat.c
With the latest GCC, we're seeing the errors:
| tftf/tests/runtime_services/standard_service/psci/api_tests/psci_stat/test_psci_stat.c: In function 'test_psci_stats_cpu_off':
| tftf/tests/runtime_services/standard_service/psci/api_tests/psci_stat/test_psci_stat.c:681:23: error: variable 'off_cpu_count' set but not used [-Werror=unused-but-set-variable=]
| 681 | int cpu_node, off_cpu_count = 0, ret;
| | ^~~~~~~~~~~~~
| tftf/tests/runtime_services/standard_service/psci/api_tests/psci_stat/test_psci_stat.c: In function 'test_psci_stats_system_suspend':
| tftf/tests/runtime_services/standard_service/psci/api_tests/psci_stat/test_psci_stat.c:800:23: error: variable 'off_cpu_count' set but not used [-Werror=unused-but-set-variable=]
| 800 | int cpu_node, off_cpu_count = 0;
| | ^~~~~~~~~~~~~
This is because assert is being #ifdef'ed out and thus the variable is
never being used. Add '-Wno-unused-but-set-variable' to the Makefile to
workaround the issue.
See https://github.com/TrustedFirmware-A/tf-a-tests/issues/4
Signed-off-by: Jon Mason <jon.mason@arm.com>
Upstream-Status: Pending
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 9d222acc30b4..806329382da5 100644
--- a/Makefile
+++ b/Makefile
@@ -277,7 +277,7 @@ GCC_ASFLAGS_aarch64 := -mgeneral-regs-only ${march64-directive}
GCC_WARNINGS += -nostdinc -ffreestanding -Wall -Werror \
-Wmissing-include-dirs $(GCC_CFLAGS_$(ARCH)) \
- -std=gnu99 -Os
+ -Wno-unused-but-set-variable -std=gnu99 -Os
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
GCC_CFLAGS += $(call cc_option, --param=min-pagesize=0)
@@ -1,531 +0,0 @@
From f5c206b8d9019d8112e55ac8da1936c79c7d2ce7 Mon Sep 17 00:00:00 2001
From: Soby Mathew <soby.mathew@arm.com>
Date: Fri, 15 Nov 2024 17:11:24 +0000
Subject: [PATCH] fix(realm): make PCIe tests default for testing
This patch moves the PCIe DOE test to the default realm world
testsuite.
Also fixes some build issues and hardens the PCIe functions.
Note that FVP_Base_RevC model needs to have the following
options enabled for the PCIe tests to work :
-C pci.pcie_rc.ahci0.endpoint.doe_supported=1
-C pci.pcie_rc.ahci0.endpoint.ide_supported=1
Change-Id: Icfd6b68799b0bacb44299c6a3cf99a3c425f833d
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
Upstream-Status: Backport [2c2810f79e57e78d77899084b5439cbdd1aaa464]
---
docs/porting/optional-mods.rst | 12 ++++++
include/lib/pcie/pcie.h | 9 ++--
include/plat/common/platform.h | 10 ++++-
lib/pcie/pcie.c | 41 ++++++++++++++-----
plat/arm/fvp/fvp_pcie.c | 4 +-
plat/arm/fvp/include/platform_pcie.h | 2 -
plat/arm/fvp/plat_setup.c | 2 -
plat/arm/fvp/platform.mk | 9 ++--
plat/common/plat_common.c | 8 +++-
tftf/tests/doe_tests/doe_helpers.c | 11 +++--
tftf/tests/doe_tests/doe_helpers.h | 2 +
tftf/tests/doe_tests/test_doe.c | 9 +++-
.../realm_payload/host_realm_simd_common.h | 2 +-
tftf/tests/tests-pcie-doe.mk | 22 ----------
tftf/tests/tests-pcie-doe.xml | 14 -------
tftf/tests/tests-realm-payload.mk | 14 ++++++-
tftf/tests/tests-realm-payload.xml | 7 +++-
17 files changed, 105 insertions(+), 73 deletions(-)
delete mode 100644 tftf/tests/tests-pcie-doe.mk
delete mode 100644 tftf/tests/tests-pcie-doe.xml
diff --git a/docs/porting/optional-mods.rst b/docs/porting/optional-mods.rst
index a88d682..7fc3813 100644
--- a/docs/porting/optional-mods.rst
+++ b/docs/porting/optional-mods.rst
@@ -50,6 +50,18 @@ The default implementation uses the ARM watchdog peripheral (`SP805`_) to
generate a watchdog timeout interrupt. This interrupt remains deliberately
unserviced, which eventually asserts the reset signal.
+Function : plat_pcie_get_info_table()
+----------------------------
+
+::
+
+ Argument : void
+ Return : struct pcie_info_table *
+
+This function returns the pointer to `pcie_info_table` structure
+correponding to the platform. This needs to be implemented
+only if the platform want to run PCIe related tests.
+
--------------
*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/include/lib/pcie/pcie.h b/include/lib/pcie/pcie.h
index aa3911f..3ce6986 100644
--- a/include/lib/pcie/pcie.h
+++ b/include/lib/pcie/pcie.h
@@ -11,6 +11,9 @@
#include <stdint.h>
#include <utils_def.h>
+/* platforms need to ensure that number of entries is less that this value */
+#define MAX_PCIE_INFO_ENTRIES 5
+
typedef struct {
unsigned long ecam_base; /* ECAM base address */
unsigned int segment_num; /* Segment number of this ECAM */
@@ -18,10 +21,10 @@ typedef struct {
unsigned int end_bus_num; /* Last bus number */
} pcie_info_block_t;
-typedef struct {
+struct pcie_info_table{
unsigned int num_entries; /* Number of entries */
- pcie_info_block_t block[];
-} pcie_info_table_t;
+ pcie_info_block_t block[MAX_PCIE_INFO_ENTRIES];
+};
typedef struct {
uint32_t bdf;
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index c8b785c..1a51823 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -193,4 +193,12 @@ static inline uint32_t get_current_core_id(void)
return platform_get_core_pos(read_mpidr_el1() & MPID_MASK);
}
+/* Forward declaration */
+struct pcie_info_table;
+
+/*
+ * Retrieve platform PCIe information.
+ */
+const struct pcie_info_table *plat_pcie_get_info_table(void);
+
#endif /* __PLATFORM_H__ */
diff --git a/lib/pcie/pcie.c b/lib/pcie/pcie.c
index c3906d5..5f8c97f 100644
--- a/lib/pcie/pcie.c
+++ b/lib/pcie/pcie.c
@@ -11,13 +11,12 @@
#include <mmio.h>
#include <pcie.h>
#include <pcie_spec.h>
+#include <platform.h>
#include <tftf_lib.h>
-#include <platform_pcie.h>
-
#define PCIE_DEBUG VERBOSE
-const pcie_info_table_t *g_pcie_info_table;
+const struct pcie_info_table *g_pcie_info_table;
pcie_device_bdf_table_t *g_pcie_bdf_table;
pcie_device_bdf_table_t pcie_bdf_table[PCIE_DEVICE_BDF_TABLE_SZ];
@@ -256,6 +255,8 @@ uint32_t pcie_get_rootport(uint32_t bdf, uint32_t *rp_bdf)
return 1;
}
+ assert(g_pcie_bdf_table != NULL);
+
while (index < g_pcie_bdf_table->num_entries) {
*rp_bdf = g_pcie_bdf_table->device[index++].bdf;
@@ -294,6 +295,8 @@ static uint32_t pcie_populate_device_rootport(void)
uint32_t bdf, rp_bdf;
pcie_device_bdf_table_t *bdf_tbl_ptr = g_pcie_bdf_table;
+ assert(bdf_tbl_ptr != NULL);
+
for (unsigned int tbl_index = 0; tbl_index < bdf_tbl_ptr->num_entries;
tbl_index++) {
bdf = bdf_tbl_ptr->device[tbl_index].bdf;
@@ -317,6 +320,8 @@ static uint32_t pcie_populate_device_rootport(void)
*/
pcie_device_bdf_table_t *pcie_get_bdf_table(void)
{
+ assert(g_pcie_bdf_table != NULL);
+
return g_pcie_bdf_table;
}
@@ -336,6 +341,8 @@ void pcie_create_device_bdf_table(void)
assert(g_pcie_bdf_table != NULL);
g_pcie_bdf_table->num_entries = 0;
+
+ assert(g_pcie_info_table != NULL);
assert(g_pcie_info_table->num_entries != 0);
for (ecam_index = 0; ecam_index < g_pcie_info_table->num_entries; ecam_index++) {
@@ -420,6 +427,8 @@ uintptr_t pcie_get_ecam_base(uint32_t bdf)
uint32_t reg_value;
uintptr_t ecam_base = 0;
+ assert(g_pcie_info_table != NULL);
+
while (ecam_index < g_pcie_info_table->num_entries) {
/* Derive ECAM specific information */
const pcie_info_block_t *block = &g_pcie_info_table->block[ecam_index];
@@ -462,13 +471,15 @@ void pcie_print_device_info(void)
uint32_t ecam_index = 0;
uint32_t ecam_base, ecam_start_bus, ecam_end_bus;
pcie_device_bdf_table_t *bdf_tbl_ptr = g_pcie_bdf_table;
- uint32_t num_rciep = 0, num_rcec = 0;
- uint32_t num_iep = 0, num_irp = 0;
- uint32_t num_ep = 0, num_rp = 0;
- uint32_t num_dp = 0, num_up = 0;
- uint32_t num_pcie_pci = 0, num_pci_pcie = 0;
+ uint32_t num_rciep __unused = 0, num_rcec __unused = 0;
+ uint32_t num_iep __unused = 0, num_irp __unused = 0;
+ uint32_t num_ep __unused = 0, num_rp __unused = 0;
+ uint32_t num_dp __unused = 0, num_up __unused = 0;
+ uint32_t num_pcie_pci __unused = 0, num_pci_pcie __unused = 0;
uint32_t bdf_counter;
+ assert(bdf_tbl_ptr != NULL);
+
if (bdf_tbl_ptr->num_entries == 0) {
INFO("BDF Table: No RCiEP or iEP found\n");
return;
@@ -525,6 +536,8 @@ void pcie_print_device_info(void)
INFO("Number of PCI/PCIe Bridge: %u\n", num_pci_pcie);
INFO("Number of PCIe/PCI Bridge: %u\n", num_pcie_pci);
+ assert(g_pcie_info_table != NULL);
+
while (ecam_index < g_pcie_info_table->num_entries) {
/* Derive ECAM specific information */
@@ -540,7 +553,7 @@ void pcie_print_device_info(void)
while (tbl_index < bdf_tbl_ptr->num_entries) {
uint32_t seg_num, bus_num, dev_num, func_num;
- uint32_t device_id, vendor_id, reg_value;
+ uint32_t device_id __unused, vendor_id __unused, reg_value;
uint32_t bdf, dev_ecam_base;
bdf = bdf_tbl_ptr->device[tbl_index++].bdf;
@@ -588,12 +601,18 @@ void pcie_create_info_table(void)
INFO("Creating PCIe info table\n");
g_pcie_info_table = plat_pcie_get_info_table();
+ if (g_pcie_info_table == NULL) {
+ ERROR("PCIe info not returned by platform\n");
+ panic();
+ }
+
g_pcie_bdf_table = pcie_bdf_table;
num_ecam = g_pcie_info_table->num_entries;
INFO("Number of ECAM regions : %u\n", num_ecam);
- if (num_ecam == 0) {
- return;
+ if ((num_ecam == 0) || (num_ecam > MAX_PCIE_INFO_ENTRIES)) {
+ ERROR("PCIe info entries invalid\n");
+ panic();
}
pcie_create_device_bdf_table();
pcie_print_device_info();
diff --git a/plat/arm/fvp/fvp_pcie.c b/plat/arm/fvp/fvp_pcie.c
index 0569832..c43e42d 100644
--- a/plat/arm/fvp/fvp_pcie.c
+++ b/plat/arm/fvp/fvp_pcie.c
@@ -11,7 +11,7 @@
CASSERT(PLATFORM_NUM_ECAM != 0, PLATFORM_NUM_ECAM_is_zero);
-const pcie_info_table_t fvp_pcie_cfg = {
+const struct pcie_info_table fvp_pcie_cfg = {
.num_entries = PLATFORM_NUM_ECAM,
.block[0] = {
PLATFORM_PCIE_ECAM_BASE_ADDR_0,
@@ -21,7 +21,7 @@ const pcie_info_table_t fvp_pcie_cfg = {
}
};
-const pcie_info_table_t *plat_pcie_get_info_table(void)
+const struct pcie_info_table *plat_pcie_get_info_table(void)
{
return &fvp_pcie_cfg;
}
diff --git a/plat/arm/fvp/include/platform_pcie.h b/plat/arm/fvp/include/platform_pcie.h
index c76c7d9..4b3a0e9 100644
--- a/plat/arm/fvp/include/platform_pcie.h
+++ b/plat/arm/fvp/include/platform_pcie.h
@@ -19,6 +19,4 @@
#define PLATFORM_PCIE_START_BUS_NUM_0 0x0
#define PLATFORM_PCIE_END_BUS_NUM_0 0xFF
-const pcie_info_table_t *plat_pcie_get_info_table(void);
-
#endif /* PLATFORM_PCIE_H */
diff --git a/plat/arm/fvp/plat_setup.c b/plat/arm/fvp/plat_setup.c
index e6e4244..69cb0a1 100644
--- a/plat/arm/fvp/plat_setup.c
+++ b/plat/arm/fvp/plat_setup.c
@@ -35,9 +35,7 @@ static const mmap_region_t mmap[] = {
#if USE_NVM
MAP_REGION_FLAT(FLASH_BASE, FLASH_SIZE, MT_DEVICE | MT_RW | MT_NS),
#endif
-#if USE_PCIE
MAP_REGION_FLAT(PCIE_CONFIG_BASE, PCIE_CONFIG_SIZE, MT_DEVICE | MT_RW | MT_NS),
-#endif
MAP_REGION_FLAT(DRAM_BASE, TFTF_BASE - DRAM_BASE, MT_MEMORY | MT_RW | MT_NS),
{0}
};
diff --git a/plat/arm/fvp/platform.mk b/plat/arm/fvp/platform.mk
index 7a2850f..ee30721 100644
--- a/plat/arm/fvp/platform.mk
+++ b/plat/arm/fvp/platform.mk
@@ -90,12 +90,8 @@ $(eval $(call add_define,NS_BL2U_DEFINES,PA_SIZE))
$(eval $(call add_define,TFTF_DEFINES,PA_SIZE))
$(eval $(call add_define,REALM_DEFINES,PA_SIZE))
-ifeq ($(TESTS),pcie-doe)
-USE_PCIE=1
-$(eval $(call add_define,TFTF_DEFINES,USE_PCIE))
-endif
-
-PLAT_INCLUDES += -Iplat/arm/fvp/include/
+PLAT_INCLUDES += -Iplat/arm/fvp/include/ \
+ -Iinclude/lib/pcie/
PLAT_SOURCES := drivers/arm/gic/arm_gic_v2v3.c \
drivers/arm/gic/gic_v2.c \
@@ -104,6 +100,7 @@ PLAT_SOURCES := drivers/arm/gic/arm_gic_v2v3.c \
drivers/arm/timer/private_timer.c \
drivers/arm/timer/system_timer.c \
plat/arm/fvp/${ARCH}/plat_helpers.S \
+ plat/arm/fvp/fvp_pcie.c \
plat/arm/fvp/fvp_pwr_state.c \
plat/arm/fvp/fvp_topology.c \
plat/arm/fvp/fvp_mem_prot.c \
diff --git a/plat/common/plat_common.c b/plat/common/plat_common.c
index c43ae12..a4195c3 100644
--- a/plat/common/plat_common.c
+++ b/plat/common/plat_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -24,6 +24,7 @@
#pragma weak tftf_plat_enable_mmu
#pragma weak tftf_plat_reset
#pragma weak plat_get_prot_regions
+#pragma weak plat_pcie_get_info_table
#if IMAGE_TFTF
@@ -148,3 +149,8 @@ const mem_region_t *plat_get_prot_regions(int *nelem)
*nelem = 0;
return NULL;
}
+
+const struct pcie_info_table *plat_pcie_get_info_table(void)
+{
+ return NULL;
+}
diff --git a/tftf/tests/doe_tests/doe_helpers.c b/tftf/tests/doe_tests/doe_helpers.c
index 28b6a86..911fbd0 100644
--- a/tftf/tests/doe_tests/doe_helpers.c
+++ b/tftf/tests/doe_tests/doe_helpers.c
@@ -13,12 +13,15 @@
#include <pcie_doe.h>
#include <spdm.h>
-#include <platform_pcie.h>
-
void pcie_init(void)
{
+ static bool is_init;
+
/* Create PCIe table and enumeration */
- pcie_create_info_table();
+ if (!is_init) {
+ pcie_create_info_table();
+ is_init = true;
+ }
}
/*
@@ -113,7 +116,7 @@ int get_spdm_version(uint32_t bdf, uint32_t doe_cap_base)
sizeof(ver_resp->version_number_entry_count));
while (entry_count-- != 0) {
- spdm_version_number_t ver = *ver_ptr++;
+ spdm_version_number_t ver __unused = *ver_ptr++;
INFO("SPDM v%llu.%llu.%llu.%llu\n",
EXTRACT(SPDM_VER_MAJOR, ver),
diff --git a/tftf/tests/doe_tests/doe_helpers.h b/tftf/tests/doe_tests/doe_helpers.h
index 08137e3..d0fc5c8 100644
--- a/tftf/tests/doe_tests/doe_helpers.h
+++ b/tftf/tests/doe_tests/doe_helpers.h
@@ -8,6 +8,8 @@
#ifndef DOE_HELPERS_H
#define DOE_HELPERS_H
+#include <stdint.h>
+
void pcie_init(void);
int find_doe_device(uint32_t *bdf_ptr, uint32_t *cap_base_ptr);
int doe_discovery(uint32_t bdf, uint32_t doe_cap_base);
diff --git a/tftf/tests/doe_tests/test_doe.c b/tftf/tests/doe_tests/test_doe.c
index 6eb5079..cc852fa 100644
--- a/tftf/tests/doe_tests/test_doe.c
+++ b/tftf/tests/doe_tests/test_doe.c
@@ -10,6 +10,13 @@
#define SKIP_TEST_IF_DOE_NOT_SUPPORTED() \
do { \
+ /* Test PCIe DOE only for RME */ \
+ if (!get_armv9_2_feat_rme_support()) { \
+ tftf_testcase_printf("FEAT_RME not supported\n"); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ \
+ pcie_init(); \
if (find_doe_device(&bdf, &doe_cap_base) != 0) { \
tftf_testcase_printf("PCIe DOE not supported\n"); \
return TEST_RESULT_SKIPPED; \
@@ -21,8 +28,6 @@ test_result_t doe_discovery_test(void)
uint32_t bdf, doe_cap_base;
int ret;
- pcie_init();
-
SKIP_TEST_IF_DOE_NOT_SUPPORTED();
ret = doe_discovery(bdf, doe_cap_base);
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.h b/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.h
index 377c85b..6ab45c3 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.h
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.h
@@ -4,7 +4,7 @@
*/
#ifndef HOST_REALM_COMMON_H
-#define HOST_REALM_COMMON_h
+#define HOST_REALM_COMMON_H
#define NS_NORMAL_SVE 0x1U
#define NS_STREAMING_SVE 0x2U
diff --git a/tftf/tests/tests-pcie-doe.mk b/tftf/tests/tests-pcie-doe.mk
deleted file mode 100644
index 14bc9cf..0000000
--- a/tftf/tests/tests-pcie-doe.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2024, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-TESTS_SOURCES += \
- $(addprefix plat/arm/fvp/, \
- fvp_pcie.c \
- )
-
-TESTS_SOURCES += \
- $(addprefix tftf/tests/doe_tests/, \
- doe_helpers.c \
- test_doe.c \
- )
-
-TESTS_SOURCES += \
- $(addprefix lib/pcie/, \
- pcie.c \
- pcie_doe.c \
- )
diff --git a/tftf/tests/tests-pcie-doe.xml b/tftf/tests/tests-pcie-doe.xml
deleted file mode 100644
index ed8b7cb..0000000
--- a/tftf/tests/tests-pcie-doe.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- Copyright (c) 2024, Arm Limited. All rights reserved.
-
- SPDX-License-Identifier: BSD-3-Clause
--->
-
-<testsuites>
- <testsuite name="PCI Data Object Exchange" description="Check PCI DOE support">
- <testcase name="PCI DOE Discovery" function="doe_discovery_test" />
- <testcase name="SPDM Get Version" function="spdm_version_test" />
- </testsuite>
-</testsuites>
diff --git a/tftf/tests/tests-realm-payload.mk b/tftf/tests/tests-realm-payload.mk
index ae4b20a..4da8e3e 100644
--- a/tftf/tests/tests-realm-payload.mk
+++ b/tftf/tests/tests-realm-payload.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -44,4 +44,16 @@ TESTS_SOURCES += \
$(addprefix lib/extensions/fpu/, \
fpu.c \
)
+
+TESTS_SOURCES += \
+ $(addprefix tftf/tests/doe_tests/, \
+ doe_helpers.c \
+ test_doe.c \
+ )
+
+TESTS_SOURCES += \
+ $(addprefix lib/pcie/, \
+ pcie.c \
+ pcie_doe.c \
+ )
endif
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index 3c0dda4..d99a6b9 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ Copyright (c) 2021-2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
-->
@@ -126,5 +126,10 @@
function="host_test_non_lpa2_realm_on_lpa2plat" />
<testcase name="Test Realm creation with LPA2 enabled but FEAT_LPA2 absent on platform"
function="host_test_lpa2_realm_on_non_lpa2plat" />
+ <!-- Test case related to PCIE-DOE -->
+ <testcase name="PCI DOE Discovery"
+ function="doe_discovery_test" />
+ <testcase name="SPDM Get Version"
+ function="spdm_version_test" />
</testsuite>
</testsuites>
--
2.34.1
@@ -1,33 +0,0 @@
From f5b2fa90e0c0324f31e72429e7a7382f49a25912 Mon Sep 17 00:00:00 2001
From: Shen Jiamin <shen_jiamin@comp.nus.edu.sg>
Date: Wed, 24 Jul 2024 18:58:55 +0800
Subject: [PATCH] fix(zynqmp): handle secure SGI at EL1 for OP-TEE
OP-TEE requires SGIs to be handled at S-EL1. The
Makefile was not properly setting the flag
GICV2_G0_FOR_EL3 to 0 when the SPD is OP-TEE.
Change-Id: I256afa37ddf4ad4a154c43d51807de670c3689bb
Signed-off-by: Shen Jiamin <shen_jiamin@comp.nus.edu.sg>
---
plat/xilinx/zynqmp/platform.mk | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Upstream-Status: Backport
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index c340009d0..22eceb621 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -21,7 +21,7 @@ ENABLE_LTO := 1
EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
# pncd SPD requires secure SGI to be handled at EL1
-ifeq (${SPD}, $(filter ${SPD},pncd tspd))
+ifeq (${SPD}, $(filter ${SPD},pncd tspd opteed))
ifeq (${ZYNQMP_WDT_RESTART},1)
$(error "Error: ZYNQMP_WDT_RESTART and SPD=pncd are incompatible")
endif
--
2.34.1
@@ -1,33 +0,0 @@
From b91c651e6d596cfe27448b19c8fb2f1168493827 Mon Sep 17 00:00:00 2001
From: Mikko Rapeli <mikko.rapeli@linaro.org>
Date: Mon, 15 Jan 2024 09:26:56 +0000
Subject: [PATCH] qemu_measured_boot.c: ignore TPM error and continue with boot
If firmware is configured with TPM support but it's missing
on HW, e.g. swtpm not started and/or configured with qemu,
then continue booting. Missing TPM is not a fatal error.
Enables testing boot without TPM device to see that
missing TPM is detected further up the SW stack and correct
fallback actions are taken.
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/36514]
Signed-off-by: Mikko Rapeli <mikko.rapeli@linaro.org>
---
plat/qemu/qemu/qemu_measured_boot.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c
index 76a4da17e6a9..ec7f44d3720d 100644
--- a/plat/qemu/qemu/qemu_measured_boot.c
+++ b/plat/qemu/qemu/qemu_measured_boot.c
@@ -80,7 +80,8 @@ void bl2_plat_mboot_finish(void)
* Note: In QEMU platform, OP-TEE uses nt_fw_config to get the
* secure Event Log buffer address.
*/
- panic();
+ ERROR("Ignoring TPM errors, continuing without\n");
+ return;
}
/* Copy Event Log to Non-secure memory */
@@ -1,33 +0,0 @@
# Firmware Image Package (FIP)
# It is a packaging format used by TF-A to package the
# firmware images in a single binary.
DESCRIPTION = "fiptool - Trusted Firmware tool for packaging"
LICENSE = "BSD-3-Clause"
SRC_URI_TRUSTED_FIRMWARE_A ?= "git://review.trustedfirmware.org/TF-A/trusted-firmware-a;protocol=https"
SRC_URI = "${SRC_URI_TRUSTED_FIRMWARE_A};destsuffix=fiptool-${PV};branch=${SRCBRANCH}"
LIC_FILES_CHKSUM = "file://docs/license.rst;md5=83b7626b8c7a37263c6a58af8d19bee1"
# Use fiptool from TF-A v2.12.10
SRCREV = "9487b105dcf18d057c6aeb405f9eaa1079c8fe6e"
SRCBRANCH = "lts-v2.12"
DEPENDS += "openssl-native"
inherit native
EXTRA_OEMAKE = "V=1 HOSTCC='${BUILD_CC}' OPENSSL_DIR=${STAGING_DIR_NATIVE}/${prefix_native}"
do_compile () {
# This is still needed to have the native fiptool executing properly by
# setting the RPATH
sed -i '/^LDOPTS/ s,$, \$\{BUILD_LDFLAGS},' ${S}/tools/fiptool/Makefile
sed -i '/^INCLUDE_PATHS/ s,$, \$\{BUILD_CFLAGS},' ${S}/tools/fiptool/Makefile
oe_runmake fiptool
}
do_install () {
install -D -p -m 0755 tools/fiptool/fiptool ${D}${bindir}/fiptool
}
@@ -9,8 +9,8 @@ SRC_URI_TRUSTED_FIRMWARE_A ?= "git://review.trustedfirmware.org/TF-A/trusted-fir
SRC_URI = "${SRC_URI_TRUSTED_FIRMWARE_A};destsuffix=fiptool-${PV};branch=${SRCBRANCH}"
LIC_FILES_CHKSUM = "file://docs/license.rst;md5=6ed7bace7b0bc63021c6eba7b524039e"
# Use fiptool from TF-A v2.14.1
SRCREV = "e82c7ced9e76aea35b176e608d67dfe5ebe1c569"
# Use fiptool from TF-A v2.14.2
SRCREV = "aa1793fff49a1b5a6a877c278a0df0a188e2b1f2"
SRCBRANCH = "lts-v2.14"
DEPENDS += "openssl-native"
@@ -7,11 +7,11 @@ LICENSE = "BSD-3-Clause"
SRC_URI_TRUSTED_FIRMWARE_A ?= "git://review.trustedfirmware.org/TF-A/trusted-firmware-a;protocol=https"
SRC_URI = "${SRC_URI_TRUSTED_FIRMWARE_A};destsuffix=fiptool-${PV};branch=${SRCBRANCH}"
LIC_FILES_CHKSUM = "file://docs/license.rst;md5=b2c740efedc159745b9b31f88ff03dde"
LIC_FILES_CHKSUM = "file://docs/license.rst;md5=6ed7bace7b0bc63021c6eba7b524039e"
# Use fiptool from TF-A v2.10.30
SRCREV = "d57b81079003e1647ed4181057c5784c7e3b1c3e"
SRCBRANCH = "lts-v2.10"
# Use fiptool from TF-A v2.15.0
SRCREV = "da738d5eae93af342fdc4995dd3c05acb4c9d757"
SRCBRANCH = "master"
DEPENDS += "openssl-native"
@@ -1,56 +0,0 @@
DESCRIPTION = "Trusted Firmware-A tests(aka TFTF)"
LICENSE = "BSD-3-Clause & NCSA"
LIC_FILES_CHKSUM += "file://docs/license.rst;md5=6175cc0aa2e63b6d21a32aa0ee7d1b4a"
inherit deploy
COMPATIBLE_MACHINE ?= "invalid"
SRC_URI_TRUSTED_FIRMWARE_A_TESTS ?= "git://review.trustedfirmware.org/TF-A/tf-a-tests;protocol=https"
SRC_URI = "${SRC_URI_TRUSTED_FIRMWARE_A_TESTS};branch=${SRCBRANCH} \
file://0001-fix-realm-make-PCIe-tests-default-for-testing.patch \
"
SRCBRANCH = "lts-v2.12"
SRCREV = "3650d9cdfaa8eda20eba4b0c366c7c213a356557"
EXTRA_OEMAKE += "USE_NVM=0"
EXTRA_OEMAKE += "SHELL_COLOR=1"
EXTRA_OEMAKE += "DEBUG=1"
# Modify mode based on debug or release mode
TFTF_MODE ?= "debug"
# Platform must be set for each machine
TFA_PLATFORM ?= "invalid"
EXTRA_OEMAKE += "ARCH=aarch64"
EXTRA_OEMAKE += "LOG_LEVEL=50"
B = "${WORKDIR}/build"
# Add platform parameter
EXTRA_OEMAKE += "BUILD_BASE=${B} PLAT=${TFA_PLATFORM}"
# Requires CROSS_COMPILE set by hand as there is no configure script
export CROSS_COMPILE = "${TARGET_PREFIX}"
LDFLAGS[unexport] = "1"
do_compile() {
oe_runmake -C ${S} tftf
}
do_compile[cleandirs] = "${B}"
FILES:${PN} = "/firmware/tftf.bin"
SYSROOT_DIRS += "/firmware"
do_install() {
install -d -m 755 ${D}/firmware
install -m 0644 ${B}/${TFA_PLATFORM}/${TFTF_MODE}/tftf.bin ${D}/firmware/tftf.bin
}
do_deploy() {
cp -rf ${D}/firmware/* ${DEPLOYDIR}/
}
addtask deploy after do_install
@@ -12,6 +12,8 @@ SRC_URI = "${SRC_URI_TRUSTED_FIRMWARE_A_TESTS};branch=${SRCBRANCH}"
SRCBRANCH = "master"
SRCREV = "3b3d800133081b48482b1205a32671b82bc2b640"
SRC_URI += "file://0001-Fix-GCC-errors-in-test_psci_stat.c.patch"
EXTRA_OEMAKE += "USE_NVM=0"
EXTRA_OEMAKE += "SHELL_COLOR=1"
EXTRA_OEMAKE += "DEBUG=1"
@@ -9,8 +9,10 @@ COMPATIBLE_MACHINE ?= "invalid"
SRC_URI_TRUSTED_FIRMWARE_A_TESTS ?= "git://review.trustedfirmware.org/TF-A/tf-a-tests;protocol=https"
SRC_URI = "${SRC_URI_TRUSTED_FIRMWARE_A_TESTS};branch=${SRCBRANCH}"
SRCBRANCH = "lts-v2.10"
SRCREV = "ad8e3c9506abc6fd093c9753c8e201ddc2daa270"
SRCBRANCH = "master"
SRCREV = "bd08278493028d3c33936f61f406169a7f0deb9f"
SRC_URI += "file://0001-Fix-GCC-errors-in-test_psci_stat.c.patch"
EXTRA_OEMAKE += "USE_NVM=0"
EXTRA_OEMAKE += "SHELL_COLOR=1"
@@ -38,23 +38,10 @@ TFA_ARM_SPMC_MANIFEST_DTS ?= ""
# Build for debug (set TFA_DEBUG to 1 to activate)
TFA_DEBUG ?= "${FIRMWARE_DEBUG_BUILD}"
B = "${WORKDIR}/build"
# Set to 1 if the platform has LTO enabled
TFA_LTO ?= ""
# mbed TLS support (set TFA_MBEDTLS to 1 to activate)
TFA_MBEDTLS ?= "0"
# sub-directory in which mbedtls will be downloaded
TFA_MBEDTLS_DIR ?= "mbedtls"
# This should be set to MBEDTLS download URL if MBEDTLS is needed
SRC_URI_MBEDTLS ??= ""
# This should be set to MBEDTLS LIC FILES checksum
LIC_FILES_CHKSUM_MBEDTLS ??= ""
# add MBEDTLS to our sources if activated
SRC_URI:append = " ${@bb.utils.contains('TFA_MBEDTLS', '1', '${SRC_URI_MBEDTLS}', '', d)}"
# Update license variables
LICENSE:append = "${@bb.utils.contains('TFA_MBEDTLS', '1', ' & Apache-2.0', '', d)}"
LIC_FILES_CHKSUM:append = "${@bb.utils.contains('TFA_MBEDTLS', '1', ' ${LIC_FILES_CHKSUM_MBEDTLS}', '', d)}"
# add mbed TLS to version
SRCREV_FORMAT:append = "${@bb.utils.contains('TFA_MBEDTLS', '1', '_mbedtls', '', d)}"
B = "${WORKDIR}/build"
# U-boot support (set TFA_UBOOT to 1 to activate)
# When U-Boot support is activated BL33 is activated with u-boot.bin file
@@ -106,7 +93,7 @@ def remove_options_tail (in_string):
from itertools import takewhile
return ' '.join(takewhile(lambda x: not x.startswith('-'), in_string.split(' ')))
EXTRA_OEMAKE += "LD='${@remove_options_tail(d.getVar('LD'))}'"
EXTRA_OEMAKE += "${@'' if d.getVar('TFA_LTO') else "'LD=" + remove_options_tail(d.getVar('LD')) + "'"}"
EXTRA_OEMAKE += "CC='${@remove_options_tail(d.getVar('CC'))}'"
@@ -128,9 +115,6 @@ EXTRA_OEMAKE += "${@'SPMD_SPM_AT_SEL2=${TFA_SPMD_SPM_AT_SEL2}' if d.getVar('TFA_
# Handle TFA_DEBUG parameter
EXTRA_OEMAKE += "${@bb.utils.contains('TFA_DEBUG', '1', 'DEBUG=${TFA_DEBUG}', '', d)}"
# Handle MBEDTLS
EXTRA_OEMAKE += "${@bb.utils.contains('TFA_MBEDTLS', '1', 'MBEDTLS_DIR=${TFA_MBEDTLS_DIR}', '', d)}"
# Uboot support
DEPENDS += " ${@bb.utils.contains('TFA_UBOOT', '1', 'u-boot', '', d)}"
do_compile[depends] += " ${@bb.utils.contains('TFA_UBOOT', '1', 'u-boot:do_deploy', '', d)}"
@@ -242,4 +226,5 @@ INSANE_SKIP:${PN}-dbg += "buildpaths"
CVE_PRODUCT = "arm:arm-trusted-firmware \
arm:trusted_firmware-a \
arm:arm_trusted_firmware \
arm_trusted_firmware_project:arm_trusted_firmware"
arm_trusted_firmware_project:arm_trusted_firmware \
trustedfirmware:trusted_firmware-a"
@@ -1,21 +0,0 @@
require recipes-bsp/trusted-firmware-a/trusted-firmware-a.inc
# TF-A v2.10.30
SRCREV_tfa = "d57b81079003e1647ed4181057c5784c7e3b1c3e"
SRCBRANCH = "lts-v2.10"
LIC_FILES_CHKSUM += "file://docs/license.rst;md5=b2c740efedc159745b9b31f88ff03dde"
# in TF-A src, docs/getting_started/prerequisites.rst lists the expected version mbedtls
# mbedtls-3.6.4
SRCBRANCH_MBEDTLS = "mbedtls-3.6"
SRC_URI_MBEDTLS = "git://github.com/Mbed-TLS/mbedtls;name=mbedtls;protocol=https;destsuffix=${BB_GIT_DEFAULT_DESTSUFFIX}/mbedtls;branch=${SRCBRANCH_MBEDTLS}"
SRCREV_mbedtls = "c765c831e5c2a0971410692f92f7a81d6ec65ec2"
LIC_FILES_CHKSUM_MBEDTLS = "file://mbedtls/LICENSE;md5=379d5819937a6c2f1ef1630d341e026d"
# continue to boot also without TPM
SRC_URI += "\
file://0001-qemu_measured_boot.c-ignore-TPM-error-and-continue-w.patch \
file://0001-fix-zynqmp-handle-secure-SGI-at-EL1-for-OP-TEE.patch \
"

Some files were not shown because too many files have changed in this diff Show More