mirror of
https://git.yoctoproject.org/meta-arm
synced 2026-10-16 17:47:07 +00:00
Compare commits
88
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49a410f6d2 | ||
|
|
52a0a3656d | ||
|
|
231cfdefd2 | ||
|
|
c0a3d1ab0e | ||
|
|
7ad49af445 | ||
|
|
a5bc7b39ec | ||
|
|
3a97808a24 | ||
|
|
02a2fa9662 | ||
|
|
b8f83d0670 | ||
|
|
954c8d5fee | ||
|
|
130e764b78 | ||
|
|
dc85142cae | ||
|
|
77efb76ff2 | ||
|
|
7f9ee424de | ||
|
|
57d9235d97 | ||
|
|
5e9a3230e7 | ||
|
|
351ba71364 | ||
|
|
063652ff6a | ||
|
|
629d62bcaa | ||
|
|
9cbedaf381 | ||
|
|
9414135734 | ||
|
|
ade09d3a60 | ||
|
|
fede80de4c | ||
|
|
e54d151854 | ||
|
|
b0ff16aba4 | ||
|
|
c6f7492f4a | ||
|
|
86b180b091 | ||
|
|
170b7e2a1c | ||
|
|
683f9680f8 | ||
|
|
c9b21728ab | ||
|
|
b08f6b0b5e | ||
|
|
fba4a2d12b | ||
|
|
fd397fc751 | ||
|
|
5ff5de465a | ||
|
|
3f9a9c8c38 | ||
|
|
167661762b | ||
|
|
0bb23ce40d | ||
|
|
dc8a847b6b | ||
|
|
28606c7215 | ||
|
|
b4fbbaf196 | ||
|
|
c2a169b18e | ||
|
|
ea93de35ae | ||
|
|
82711f1a48 | ||
|
|
451dfc3712 | ||
|
|
9607ed4eee | ||
|
|
94e19cb2b9 | ||
|
|
589e16aebc | ||
|
|
793354dbf2 | ||
|
|
c6febbdd02 | ||
|
|
847af9c082 | ||
|
|
3681201897 | ||
|
|
9014a4e935 | ||
|
|
200ccaa637 | ||
|
|
cef3e3a22c | ||
|
|
dd460eb29d | ||
|
|
66c46946f5 | ||
|
|
f1098681f4 | ||
|
|
8df56513d9 | ||
|
|
d718d02774 | ||
|
|
c5df984862 | ||
|
|
22de042eaf | ||
|
|
fe60f0804e | ||
|
|
dea9d913d8 | ||
|
|
c53fcf76e2 | ||
|
|
ab0930aa96 | ||
|
|
9aaee17adb | ||
|
|
d0b93e582c | ||
|
|
e2e63f20b5 | ||
|
|
81f5a92193 | ||
|
|
02d361b435 | ||
|
|
f23b86a59c | ||
|
|
6e6567869f | ||
|
|
6ab14ea640 | ||
|
|
3c07303388 | ||
|
|
ce5b4c4b0a | ||
|
|
e04ac672d5 | ||
|
|
33cc743536 | ||
|
|
dd2437f8d6 | ||
|
|
7ea8654517 | ||
|
|
faaa3b84a4 | ||
|
|
3f14fc635c | ||
|
|
120782d5fe | ||
|
|
1843e9e2eb | ||
|
|
da39013db9 | ||
|
|
4112fda50b | ||
|
|
f3a2db0561 | ||
|
|
3aa085566e | ||
|
|
85bd24f7b0 |
No files matched your search
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -7,12 +7,12 @@ distro: poky
|
||||
|
||||
defaults:
|
||||
repos:
|
||||
branch: wrynose
|
||||
branch: blacksail
|
||||
|
||||
repos:
|
||||
bitbake:
|
||||
url: https://git.openembedded.org/bitbake
|
||||
branch: "2.18"
|
||||
branch: "2.20"
|
||||
layers:
|
||||
bitbake: disabled
|
||||
|
||||
|
||||
@@ -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.%"
|
||||
@@ -6,6 +6,7 @@ header:
|
||||
repos:
|
||||
meta-secure-core:
|
||||
url: https://github.com/Wind-River/meta-secure-core.git
|
||||
branch: master
|
||||
layers:
|
||||
meta-secure-core-common:
|
||||
meta-signing-key:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
@@ -5,25 +5,21 @@ distro: poky
|
||||
|
||||
defaults:
|
||||
repos:
|
||||
branch: wrynose
|
||||
branch: master
|
||||
|
||||
repos:
|
||||
bitbake:
|
||||
url: https://git.openembedded.org/bitbake
|
||||
branch: "2.18"
|
||||
commit: 22021758e66737bcf68dfd2b74adc6a0cb1d42d9
|
||||
layers:
|
||||
bitbake: disabled
|
||||
|
||||
core:
|
||||
url: https://git.openembedded.org/openembedded-core
|
||||
commit: 06dd66e6220e5ce4ed4b9af4d8231ae5f0a8ce80
|
||||
layers:
|
||||
meta:
|
||||
|
||||
meta-yocto:
|
||||
url: https://git.yoctoproject.org/meta-yocto
|
||||
commit: 8251bdad5fda780a000fb41e6eda82eadf0fa39e
|
||||
layers:
|
||||
meta-poky:
|
||||
|
||||
@@ -35,7 +31,7 @@ repos:
|
||||
|
||||
meta-openembedded:
|
||||
url: https://git.openembedded.org/meta-openembedded
|
||||
commit: 9af4488d46cb4fd4c0d2d64820c86225ebd6ac71
|
||||
# commit: 461d85a1831318747af5abe86da193bcde3fd9b4
|
||||
layers:
|
||||
meta-oe:
|
||||
meta-python:
|
||||
@@ -43,7 +39,7 @@ repos:
|
||||
|
||||
meta-secure-core:
|
||||
url: https://github.com/wind-river/meta-secure-core.git
|
||||
commit: 07a99ae241acd488a2feda1ededf87dc70dfde80
|
||||
# commit: 59d7e90542947c342098863b9998693ac79352b0
|
||||
layers:
|
||||
meta-secure-core-common:
|
||||
meta-signing-key:
|
||||
|
||||
@@ -9,7 +9,7 @@ BBFILE_COLLECTIONS += "meta-arm-bsp"
|
||||
BBFILE_PATTERN_meta-arm-bsp = "^${LAYERDIR}/"
|
||||
BBFILE_PRIORITY_meta-arm-bsp = "5"
|
||||
|
||||
LAYERSERIES_COMPAT_meta-arm-bsp = "wrynose"
|
||||
LAYERSERIES_COMPAT_meta-arm-bsp = "blacksail"
|
||||
|
||||
LAYERDEPENDS_meta-arm-bsp = "core meta-arm"
|
||||
# This won't be used by layerindex-fetch, but works everywhere else
|
||||
|
||||
@@ -60,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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -5,19 +5,20 @@ require ${TUNE_FILE}
|
||||
MACHINEOVERRIDES =. "corstone1000:"
|
||||
|
||||
# TF-M
|
||||
PREFERRED_VERSION_trusted-firmware-m ?= "2.2.%"
|
||||
PREFERRED_VERSION_trusted-firmware-m ?= "2.3.%"
|
||||
PREFERRED_VERSION_trusted-firmware-m-scripts-native ?= "2.3.%"
|
||||
|
||||
# TF-A
|
||||
TFA_PLATFORM = "corstone1000"
|
||||
PREFERRED_VERSION_trusted-firmware-a ?= "2.14.%"
|
||||
PREFERRED_VERSION_tf-a-tests ?= "2.14.%"
|
||||
PREFERRED_VERSION_trusted-firmware-a ?= "2.15.%"
|
||||
PREFERRED_VERSION_tf-a-tests ?= "2.15.%"
|
||||
|
||||
TFA_BL2_BINARY = "bl2-corstone1000.bin"
|
||||
TFA_FIP_BINARY = "fip-corstone1000.bin"
|
||||
|
||||
# optee
|
||||
PREFERRED_VERSION_optee-os ?= "4.9.%"
|
||||
PREFERRED_VERSION_optee-client ?= "4.9.%"
|
||||
PREFERRED_VERSION_optee-os ?= "4.10.%"
|
||||
PREFERRED_VERSION_optee-client ?= "4.10.%"
|
||||
|
||||
# Trusted Services
|
||||
TS_PLATFORM = "arm/corstone1000"
|
||||
@@ -26,7 +27,7 @@ TS_SP_SE_PROXY_CONFIG = "corstone1000"
|
||||
MACHINE_FEATURES += "ts-smm-gateway ts-se-proxy"
|
||||
|
||||
# U-Boot
|
||||
PREFERRED_VERSION_u-boot ?= "2025.10"
|
||||
PREFERRED_VERSION_u-boot ?= "2026.07"
|
||||
MACHINE_FEATURES += "efi"
|
||||
EFI_PROVIDER ?= "grub-efi"
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
|
||||
@@ -192,20 +192,11 @@ The following payloads can be individually updated:
|
||||
|
||||
### Generate capsules {.reference}
|
||||
|
||||
[EDK II's]($edk2_repository) `GenerateCapsule` tool is used to generate capsules and is built automatically
|
||||
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`.
|
||||
Capsules are generated by running the `image_uefi_capsule` task for
|
||||
`corstone1000-flash-firmware-image`. The task uses EDK II's `GenerateCapsule`
|
||||
tool and creates the capsule metadata JSON automatically from the recipe settings.
|
||||
|
||||
:::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.
|
||||
|
||||
The capsule's default metadata passed can be found in the `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/images/corstone1000-flash-firmware-image.bb`
|
||||
The capsule's default metadata can be found in the `${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/images/corstone1000-flash-firmware-image.bb`
|
||||
and `${WORKSPACE}/meta-arm/kas/corstone1000-image-configuration.yml` files.
|
||||
|
||||
#### Valid full capsule {.reference}
|
||||
@@ -222,116 +213,39 @@ To generate a capsule that updates only a single component, explicitly set the f
|
||||
|
||||
The partial capsule is also valid, but sets the firmware version to 7 only for the BL2 component, indicating that no other components should be updated.
|
||||
|
||||
Use the following commands to generate the `capsule_config.json` file, which is required by the EDK2 tool for capsule creation:
|
||||
|
||||
```
|
||||
cd ${WORKSPACE}
|
||||
|
||||
python3 meta-arm/meta-arm/scripts/generate_capsule_json_multiple.py \
|
||||
--selected_components DUMMY_START BL2 DUMMY_END \
|
||||
--components DUMMY_START BL2 TFM_S FIP INITRAMFS DUMMY_END \
|
||||
--fw_versions 0 7 0 0 0 0 \
|
||||
--guids \
|
||||
6f784cbf-7938-5c23-8d6e-24d2f1410fa9 \
|
||||
${BL2_GUID} ${TFM_S_GUID} ${FIP_GUID} ${INITRAMFS_GUID} \
|
||||
b57e432b-a250-5c73-93e3-90205e64baba \
|
||||
--hardware_instances 1 1 1 1 1 1 \
|
||||
--lowest_supported_versions 5 5 5 5 5 5 \
|
||||
--monotonic_counts 1 1 1 1 1 1 \
|
||||
--payloads \
|
||||
build/tmp/work/corstone1000_a320_fvp-poky-linux-musl/corstone1000-flash-firmware-image/1.0/sources/corstone1000-flash-firmware-image-1.0/dummy.bin \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/trusted-firmware-m/bl2_signed.bin \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/trusted-firmware-m/tfm_s_signed.bin \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/signed_fip.bin \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/Image.gz-initramfs-corstone1000-a320-fvp.bin \
|
||||
build/tmp/work/corstone1000_a320_fvp-poky-linux-musl/corstone1000-flash-firmware-image/1.0/sources/corstone1000-flash-firmware-image-1.0/dummy.bin \
|
||||
--update_image_indexes 5 1 2 3 4 6 \
|
||||
--private_keys \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
--certificates \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
--output capsule_config.json
|
||||
```
|
||||
|
||||
Run the command below to generate the partial capsule:
|
||||
|
||||
```
|
||||
./build/tmp/sysroots-components/aarch64/edk2-basetools-native/usr/bin/edk2-BaseTools/BinWrappers/PosixLike/GenerateCapsule \
|
||||
-e \
|
||||
-j capsule_config.json \
|
||||
--capflag PersistAcrossReset \
|
||||
-o corstone1000-a320-fvp-partial-v7.uefi.capsule
|
||||
cd ${WORKSPACE}
|
||||
kas shell meta-arm/kas/corstone1000-a320-fvp.yml:meta-arm/ci/debug.yml -c '
|
||||
echo "CAPSULE_VERSION = \"7\"" >> conf/local.conf
|
||||
echo "CAPSULE_LOWEST_SUPPORTED_VERSION = \"7\"" >> conf/local.conf
|
||||
echo "CAPSULE_SELECTED_COMPONENTS = \"BL2\"" >> conf/local.conf
|
||||
bitbake corstone1000-flash-firmware-image -c image_uefi_capsule
|
||||
'
|
||||
```
|
||||
|
||||
The partial capsule will be located in the `${WORKSPACE}` directory.
|
||||
The partial capsule will be located at
|
||||
`${WORKSPACE}/build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000-a320-fvp-v7.uefi.capsule`.
|
||||
|
||||
#### Invalid capsule {.reference}
|
||||
#### Rollback capsule {.reference}
|
||||
|
||||
Generate a capsule with firmware version metadata for all payloads set lower than that of a valid capsule.
|
||||
The valid capsule has a default firmware version of 6 for all payloads, while the simulated invalid capsule has the firmware version set to 5 for all payloads.
|
||||
|
||||
Use the following commands to generate the `capsule_config.json` file, which is required by the EDK2 tool for capsule creation:
|
||||
Run the command below to generate the rollback capsule:
|
||||
|
||||
```
|
||||
cd ${WORKSPACE}
|
||||
|
||||
python3 meta-arm/meta-arm/scripts/generate_capsule_json_multiple.py \
|
||||
--selected_components DUMMY_START BL2 TFM_S FIP INITRAMFS DUMMY_END \
|
||||
--components DUMMY_START BL2 TFM_S FIP INITRAMFS DUMMY_END \
|
||||
--fw_versions 5 5 5 5 5 5 \
|
||||
--guids \
|
||||
6f784cbf-7938-5c23-8d6e-24d2f1410fa9 \
|
||||
${BL2_GUID} ${TFM_S_GUID} ${FIP_GUID} ${INITRAMFS_GUID} \
|
||||
b57e432b-a250-5c73-93e3-90205e64baba \
|
||||
--hardware_instances 1 1 1 1 1 1 \
|
||||
--lowest_supported_versions 5 5 5 5 5 5 \
|
||||
--monotonic_counts 1 1 1 1 1 1 \
|
||||
--payloads \
|
||||
build/tmp/work/corstone1000_a320_fvp-poky-linux-musl/corstone1000-flash-firmware-image/1.0/sources/corstone1000-flash-firmware-image-1.0/dummy.bin \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/trusted-firmware-m/bl2_signed.bin \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/trusted-firmware-m/tfm_s_signed.bin \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/signed_fip.bin \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/Image.gz-initramfs-corstone1000-a320-fvp.bin \
|
||||
build/tmp/work/corstone1000_a320_fvp-poky-linux-musl/corstone1000-flash-firmware-image/1.0/sources/corstone1000-flash-firmware-image-1.0/dummy.bin \
|
||||
--update_image_indexes 5 1 2 3 4 6 \
|
||||
--private_keys \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_key.key \
|
||||
--certificates \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000_capsule_cert.crt \
|
||||
--output capsule_config.json
|
||||
kas shell meta-arm/kas/corstone1000-a320-fvp.yml:meta-arm/ci/debug.yml -c '
|
||||
echo "CAPSULE_VERSION = \"5\"" >> conf/local.conf
|
||||
echo "CAPSULE_LOWEST_SUPPORTED_VERSION = \"5\"" >> conf/local.conf
|
||||
bitbake corstone1000-flash-firmware-image -c image_uefi_capsule
|
||||
'
|
||||
```
|
||||
|
||||
Run the command below to generate the invalid capsule:
|
||||
|
||||
```
|
||||
./build/tmp/sysroots-components/aarch64/edk2-basetools-native/usr/bin/edk2-BaseTools/BinWrappers/PosixLike/GenerateCapsule \
|
||||
-e \
|
||||
-j capsule_config.json \
|
||||
--capflag PersistAcrossReset \
|
||||
-o corstone1000-a320-fvp-v5.uefi.capsule
|
||||
```
|
||||
|
||||
The invalid capsule will be located in the `${WORKSPACE}` directory.
|
||||
The rollback capsule will be located at
|
||||
`${WORKSPACE}/build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000-a320-fvp-v5.uefi.capsule`.
|
||||
|
||||
### Transfer capsules to target {.reference}
|
||||
|
||||
@@ -369,8 +283,8 @@ as opposed to the on-disk method (delivery of capsules using a file on a mass st
|
||||
|
||||
```
|
||||
sudo cp ${WORKSPACE}/build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000-a320-fvp-v6.uefi.capsule /mnt/ir-acs-live-image-generic-arm64/
|
||||
sudo cp ${WORKSPACE}/corstone1000-a320-fvp-v5.uefi.capsule /mnt/ir-acs-live-image-generic-arm64/
|
||||
sudo cp ${WORKSPACE}/corstone1000-a320-fvp-partial-v7.uefi.capsule /mnt/ir-acs-live-image-generic-arm64/
|
||||
sudo cp ${WORKSPACE}/build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000-a320-fvp-v5.uefi.capsule /mnt/ir-acs-live-image-generic-arm64/
|
||||
sudo cp ${WORKSPACE}/build/tmp/deploy/images/corstone1000-a320-fvp/corstone1000-a320-fvp-v7.uefi.capsule /mnt/ir-acs-live-image-generic-arm64/
|
||||
sync
|
||||
```
|
||||
|
||||
@@ -401,7 +315,7 @@ To run the test:
|
||||
cd ${WORKSPACE} && tmux
|
||||
```
|
||||
|
||||
2. Run the FVP within `tmux` with the IR prebuilt image which now also contains the two capsules:
|
||||
2. Run the FVP within `tmux` with the IR prebuilt image which now also contains the three capsules:
|
||||
|
||||
```
|
||||
kas shell meta-arm/kas/corstone1000-a320-fvp.yml:meta-arm/ci/debug.yml \
|
||||
@@ -526,7 +440,7 @@ Do not terminate FVP between the positive full capsule update and partial capsul
|
||||
|
||||
#### Positive partial capsule update {.reference}
|
||||
|
||||
Follow the steps for the [Positive full capsule update test], ensuring you use `corstone1000-a320-fvp-partial-v7.uefi.capsule` instead of `corstone1000-a320-fvp-v6.uefi.capsule`.
|
||||
Follow the steps for the [Positive full capsule update test], ensuring you use `corstone1000-a320-fvp-v7.uefi.capsule` instead of `corstone1000-a320-fvp-v6.uefi.capsule`.
|
||||
|
||||
Once the system has fully booted again, read [Verifying firmware versions with ESRT] to confirm that the firmware version reflects the updated capsule.
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ 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` |
|
||||
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-bsp/trusted-firmware-a/trusted-firmware-a_2.15.0.bb` |
|
||||
|
||||
#### Trusted Services {.reference}
|
||||
|
||||
@@ -91,7 +91,7 @@ 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` |
|
||||
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-security/optee/optee-os_4.10.0.bb` |
|
||||
|
||||
#### U-Boot {.reference}
|
||||
|
||||
@@ -103,7 +103,7 @@ Table: U-Boot components
|
||||
| --------- | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| 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` |
|
||||
| Recipe | `${WORKSPACE}/core/meta/recipes-bsp/u-boot/u-boot_2026.07.bb` |
|
||||
|
||||
#### Linux {.reference}
|
||||
|
||||
@@ -135,7 +135,7 @@ 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` |
|
||||
| Recipe | `${WORKSPACE}/meta-arm/meta-arm/recipes-bsp/trusted-firmware-m/trusted-firmware-m_2.3.0.bb` |
|
||||
|
||||
## Build {.reference}
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -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.1.bb`` |
|
||||
| Recipe | ``${WORKSPACE}/meta-arm/meta-arm/recipes-bsp/trusted-firmware-a/trusted-firmware-a_2.15.0.bb`` |
|
||||
+----------+-------------------------------------------------------------------------------------------------------+
|
||||
|
||||
`Trusted Services <https://trusted-services.readthedocs.io/en/latest/index.html>`__
|
||||
@@ -130,11 +131,11 @@ Host Processor Components
|
||||
`OP-TEE <https://git.trustedfirmware.org/OP-TEE/optee_os.git>`__
|
||||
================================================================
|
||||
|
||||
+----------+------------------------------------------------------------------------------------------+
|
||||
| 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`` |
|
||||
+----------+------------------------------------------------------------------------------------------+
|
||||
+----------+-------------------------------------------------------------------------------------------+
|
||||
| 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.10.0.bb`` |
|
||||
+----------+-------------------------------------------------------------------------------------------+
|
||||
|
||||
`U-Boot <https://github.com/u-boot/u-boot.git>`__
|
||||
=================================================
|
||||
@@ -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.10.bb`` |
|
||||
| Recipe | ``${WORKSPACE}/core/meta/recipes-bsp/u-boot/u-boot_2026.07.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.2.bb`` |
|
||||
| Recipe | ``${WORKSPACE}/meta-arm/meta-arm/recipes-bsp/trusted-firmware-m/trusted-firmware-m_2.3.0.bb`` |
|
||||
+----------+-------------------------------------------------------------------------------------------------------+
|
||||
|
||||
************************************
|
||||
@@ -210,13 +211,22 @@ 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}``.
|
||||
|
||||
@@ -439,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
|
||||
@@ -864,14 +878,15 @@ The results can be fetched from the `acs_results` folder in the ``BOOT`` partiti
|
||||
|
||||
.. 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}
|
||||
|
||||
#####################################################
|
||||
|
||||
@@ -927,20 +942,11 @@ The following payloads can be individually updated:
|
||||
Generate Capsules
|
||||
*****************
|
||||
|
||||
`EDK II's <edk2-repository_>`__ ``GenerateCapsule`` tool is used to generate capsules and is built automatically
|
||||
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``.
|
||||
Capsules are generated by running the ``image_uefi_capsule`` task for
|
||||
``corstone1000-flash-firmware-image``. The task uses EDK II's ``GenerateCapsule``
|
||||
tool and creates the capsule metadata JSON automatically from the recipe settings.
|
||||
|
||||
.. 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.
|
||||
|
||||
The capsule's default metadata passed can be found in the ``${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/images/corstone1000-flash-firmware-image.bb``
|
||||
The capsule's default metadata can be found in the ``${WORKSPACE}/meta-arm/meta-arm-bsp/recipes-bsp/images/corstone1000-flash-firmware-image.bb``
|
||||
and ``${WORKSPACE}/meta-arm/kas/corstone1000-image-configuration.yml`` files.
|
||||
|
||||
Valid Full Capsule
|
||||
@@ -959,118 +965,40 @@ To generate a capsule that updates only a single component, explicitly set the f
|
||||
|
||||
The **partial capsule** is also valid, but sets the firmware version to **7** **only** for the **BL2** component, indicating that no other components should be updated.
|
||||
|
||||
Use the following commands to generate the `capsule_config.json` file, which is required by the EDK2 tool for capsule creation:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cd ${WORKSPACE}
|
||||
|
||||
python3 meta-arm/meta-arm/scripts/generate_capsule_json_multiple.py \
|
||||
--selected_components DUMMY_START BL2 DUMMY_END \
|
||||
--components DUMMY_START BL2 TFM_S FIP INITRAMFS DUMMY_END \
|
||||
--fw_versions 0 7 0 0 0 0 \
|
||||
--guids \
|
||||
6f784cbf-7938-5c23-8d6e-24d2f1410fa9 \
|
||||
${BL2_GUID} ${TFM_S_GUID} ${FIP_GUID} ${INITRAMFS_GUID} \
|
||||
b57e432b-a250-5c73-93e3-90205e64baba \
|
||||
--hardware_instances 1 1 1 1 1 1 \
|
||||
--lowest_supported_versions 5 5 5 5 5 5 \
|
||||
--monotonic_counts 1 1 1 1 1 1 \
|
||||
--payloads \
|
||||
build/tmp/work/corstone1000_${TARGET}-poky-linux-musl/corstone1000-flash-firmware-image/1.0/sources/corstone1000-flash-firmware-image-1.0/dummy.bin \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/trusted-firmware-m/bl2_signed.bin \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/trusted-firmware-m/tfm_s_signed.bin \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/signed_fip.bin \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/Image.gz-initramfs-corstone1000-${TARGET}.bin \
|
||||
build/tmp/work/corstone1000_${TARGET}-poky-linux-musl/corstone1000-flash-firmware-image/1.0/sources/corstone1000-flash-firmware-image-1.0/dummy.bin \
|
||||
--update_image_indexes 5 1 2 3 4 6 \
|
||||
--private_keys \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
--certificates \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
--output capsule_config.json
|
||||
|
||||
Run the command below to generate the partial capsule:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
./build/tmp/sysroots-components/aarch64/edk2-basetools-native/usr/bin/edk2-BaseTools/BinWrappers/PosixLike/GenerateCapsule \
|
||||
-e \
|
||||
-j capsule_config.json \
|
||||
--capflag PersistAcrossReset \
|
||||
-o corstone1000-${TARGET}-partial-v7.uefi.capsule
|
||||
cd ${WORKSPACE}
|
||||
kas shell meta-arm/kas/corstone1000-${TARGET}.yml:meta-arm/ci/debug.yml -c '
|
||||
echo "CAPSULE_VERSION = \"7\"" >> conf/local.conf
|
||||
echo "CAPSULE_LOWEST_SUPPORTED_VERSION = \"7\"" >> conf/local.conf
|
||||
echo "CAPSULE_SELECTED_COMPONENTS = \"BL2\"" >> conf/local.conf
|
||||
bitbake corstone1000-flash-firmware-image -c image_uefi_capsule
|
||||
'
|
||||
|
||||
The partial capsule will be located in the ``${WORKSPACE}`` directory.
|
||||
The partial capsule will be located at
|
||||
``${WORKSPACE}/build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000-${TARGET}-v7.uefi.capsule``.
|
||||
|
||||
Invalid Capsule
|
||||
===============
|
||||
Rollback Capsule
|
||||
================
|
||||
|
||||
Generate a capsule with firmware version metadata for all payloads set lower than that of a valid capsule.
|
||||
The valid capsule has a default firmware version of 6 for all payloads, while the simulated invalid capsule has the firmware version set to 5 for all payloads.
|
||||
|
||||
Use the following commands to generate the `capsule_config.json` file, which is required by the EDK2 tool for capsule creation:
|
||||
Run the command below to generate the rollback capsule:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cd ${WORKSPACE}
|
||||
kas shell meta-arm/kas/corstone1000-${TARGET}.yml:meta-arm/ci/debug.yml -c '
|
||||
echo "CAPSULE_VERSION = \"5\"" >> conf/local.conf
|
||||
echo "CAPSULE_LOWEST_SUPPORTED_VERSION = \"5\"" >> conf/local.conf
|
||||
bitbake corstone1000-flash-firmware-image -c image_uefi_capsule
|
||||
'
|
||||
|
||||
python3 meta-arm/meta-arm/scripts/generate_capsule_json_multiple.py \
|
||||
--selected_components DUMMY_START BL2 TFM_S FIP INITRAMFS DUMMY_END \
|
||||
--components DUMMY_START BL2 TFM_S FIP INITRAMFS DUMMY_END \
|
||||
--fw_versions 5 5 5 5 5 5 \
|
||||
--guids \
|
||||
6f784cbf-7938-5c23-8d6e-24d2f1410fa9 \
|
||||
${BL2_GUID} ${TFM_S_GUID} ${FIP_GUID} ${INITRAMFS_GUID} \
|
||||
b57e432b-a250-5c73-93e3-90205e64baba \
|
||||
--hardware_instances 1 1 1 1 1 1 \
|
||||
--lowest_supported_versions 5 5 5 5 5 5 \
|
||||
--monotonic_counts 1 1 1 1 1 1 \
|
||||
--payloads \
|
||||
build/tmp/work/corstone1000_${TARGET}-poky-linux-musl/corstone1000-flash-firmware-image/1.0/sources/corstone1000-flash-firmware-image-1.0/dummy.bin \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/trusted-firmware-m/bl2_signed.bin \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/trusted-firmware-m/tfm_s_signed.bin \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/signed_fip.bin \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/Image.gz-initramfs-corstone1000-${TARGET}.bin \
|
||||
build/tmp/work/corstone1000_${TARGET}-poky-linux-musl/corstone1000-flash-firmware-image/1.0/sources/corstone1000-flash-firmware-image-1.0/dummy.bin \
|
||||
--update_image_indexes 5 1 2 3 4 6 \
|
||||
--private_keys \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_key.key \
|
||||
--certificates \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000_capsule_cert.crt \
|
||||
--output capsule_config.json
|
||||
|
||||
|
||||
Run the command below to generate the invalid capsule:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
./build/tmp/sysroots-components/aarch64/edk2-basetools-native/usr/bin/edk2-BaseTools/BinWrappers/PosixLike/GenerateCapsule \
|
||||
-e \
|
||||
-j capsule_config.json \
|
||||
--capflag PersistAcrossReset \
|
||||
-o corstone1000-${TARGET}-v5.uefi.capsule
|
||||
|
||||
The invalid capsule will be located in the ``${WORKSPACE}`` directory.
|
||||
The rollback capsule will be located at
|
||||
``${WORKSPACE}/build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000-${TARGET}-v5.uefi.capsule``.
|
||||
|
||||
***************************
|
||||
Transfer Capsules to Target
|
||||
@@ -1079,76 +1007,48 @@ Transfer Capsules to Target
|
||||
The capsule delivery process described below is the direct method (usage of capsules from the ACS image)
|
||||
as opposed to the on-disk method (delivery of capsules using a file on a mass storage device).
|
||||
|
||||
MPS3
|
||||
====
|
||||
|
||||
#. Prepare a USB drive as explained in `this <mps3-instructions-for-acs-image_>`_ section.
|
||||
|
||||
#. Copy the capsule files to the root directory of the ``BOOT`` partition in the USB drive.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cp ${WORKSPACE}/build/tmp/deploy/images/corstone1000-mps3/corstone1000-mps3-v6.uefi.capsule /dev/sdc/BOOT/
|
||||
cp ${WORKSPACE}/corstone1000-mps3-v5.uefi.capsule /dev/sdc/EFI/BOOT/
|
||||
cp ${WORKSPACE}/corstone1000-mps3-partial-v7.uefi.capsule /dev/sdc/EFI/BOOT/
|
||||
sync
|
||||
|
||||
.. 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}/build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000-${TARGET}-v5.uefi.capsule \
|
||||
${ACS_STAGED_IMAGE}:1/corstone1000-${TARGET}-v5.uefi.capsule
|
||||
wic cp ${WORKSPACE}/build/tmp/deploy/images/corstone1000-${TARGET}/corstone1000-${TARGET}-v7.uefi.capsule \
|
||||
${ACS_STAGED_IMAGE}:1/corstone1000-${TARGET}-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
|
||||
@@ -1172,7 +1072,7 @@ Positive Full Capsule Update Test
|
||||
|
||||
- MPS3:
|
||||
|
||||
#. Plug the prepared USB drive which has the IR prebuilt image and two capsules to the MPS3.
|
||||
#. Plug the prepared USB drive which has the IR prebuilt image and three capsules to the MPS3.
|
||||
#. Power cycle the MPS3.
|
||||
|
||||
- FVP:
|
||||
@@ -1183,17 +1083,18 @@ Positive Full Capsule Update Test
|
||||
|
||||
cd ${WORKSPACE} && tmux
|
||||
|
||||
#. Run the FVP within ``tmux`` with the IR prebuilt image which now also contains the two capsules:
|
||||
#. Run the FVP within ``tmux`` with the IR prebuilt image which now also contains the three capsules:
|
||||
|
||||
.. 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).
|
||||
@@ -1214,7 +1115,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:
|
||||
|
||||
@@ -1327,7 +1228,7 @@ Positive Partial Capsule Update Test
|
||||
====================================
|
||||
|
||||
Follow the steps for the `positive full capsule update test <positive-full-capsule-update-test_>`__ ensuring you use
|
||||
``corstone1000-${TARGET}-partial-v7.uefi.capsule`` instead of ``corstone1000-${TARGET}-v6.uefi.capsule``.
|
||||
``corstone1000-${TARGET}-v7.uefi.capsule`` instead of ``corstone1000-${TARGET}-v6.uefi.capsule``.
|
||||
|
||||
Once the system has fully booted again, `read the ESRT <verifying-firmware-versions-via-esrt_>`__ to
|
||||
confirm that the firmware version reflects the updated capsule.
|
||||
@@ -1368,7 +1269,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:
|
||||
|
||||
@@ -1683,6 +1584,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.
|
||||
|
||||
@@ -1903,19 +1808,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
|
||||
****************************
|
||||
@@ -2226,33 +2129,75 @@ For more information about this, see the following resources:
|
||||
- `Authenticated Debug Access Control Specification <https://developer.arm.com/documentation/den0101/latest/>`__
|
||||
- `Arm Corstone-1000 for MPS3 Application Note AN550, Chapter 7 <https://developer.arm.com/documentation/dai0550/latest/>`__
|
||||
|
||||
The Secure Debug Manager API is implemented in the `Secure Debug Manager (PSA-ADAC / SDC-600) <secure-debug-manager-repo-readme_>`__ repository.
|
||||
This repository also contains the necessary files for the Arm Development Studio support.
|
||||
The build and integration instructions can be found in its `README <secure-debug-manager-repo-readme_>`__.
|
||||
#. Install `Arm Development Studio <arm-ds-website_>`__ 2026.1, or Arm
|
||||
Development Studio Platinum 2026.b. These releases contain a built-in
|
||||
PSA-ADAC Secure Debug Manager.
|
||||
|
||||
The `Secure Debug Manager (PSA-ADAC / SDC-600)` repository also contains the private key and chain certificate to be used during the tests.
|
||||
The private key's public pair is provisioned into the One-Time Programmable memory in TrustedFirmware-M.
|
||||
These are dummy keys that should not be used in production.
|
||||
|
||||
To test the Secure Debug feature, you'll need a debug probe from the `Arm ULINKpro family <arm-ulink-pro-website_>`__
|
||||
and `Arm Development Studio <arm-ds-website_>`__ versions 2022.2, 2022.c, or 2023.a.
|
||||
|
||||
|
||||
#. Clone the `Secure Debug Manager (PSA-ADAC / SDC-600)` repository to your workspace.
|
||||
#. Clone the `Secure Debug Manager
|
||||
<https://github.com/ARM-software/secure-debug-manager>`__
|
||||
repository to obtain the dummy test credentials.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cd ${WORKSPACE}
|
||||
git clone https://github.com/ARM-software/secure-debug-manager.git
|
||||
|
||||
#. Navigate into the repository directory and checkout the specific commit in the listing below.
|
||||
Only the example private key and certificate chain are needed from this
|
||||
repository.
|
||||
|
||||
The public key corresponding to these credentials is provisioned into the
|
||||
TrustedFirmware-M One-Time Programmable memory. The supplied credentials
|
||||
are test credentials and must not be used in production.
|
||||
|
||||
#. Create a user configuration database based on the Arm Development Studio
|
||||
Corstone-1000 database. The following example assumes that Arm Development
|
||||
Studio Platinum 2026.b is installed in ``/opt/arm``:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cd ${WORKSPACE}/secure-debug-manager
|
||||
git checkout b30d6496ca749123e86b39b161b9f70ef76106d6
|
||||
export ARMDS_INSTALL_DIR=/opt/arm/developmentstudio_platinum-2026.b
|
||||
export CS1000_ADAC_DB=${WORKSPACE}/armds-cs1000-adac611
|
||||
|
||||
#. Follow the instructions in the `Secure Debug Manager (PSA-ADAC / SDC-600)'s README <secure-debug-manager-repo-readme_>`__ for the development machine setup.
|
||||
mkdir -p "${CS1000_ADAC_DB}/Boards/Arm_Development_Boards"
|
||||
cp -a \
|
||||
"${ARMDS_INSTALL_DIR}/sw/debugger/configdb/Boards/Arm Development Boards/MPS3_Corstone_1000" \
|
||||
"${CS1000_ADAC_DB}/Boards/Arm_Development_Boards/MPS3_Corstone_1000_ADAC_611"
|
||||
cp -a "${ARMDS_INSTALL_DIR}/sw/debugger/configdb/Include" "${CS1000_ADAC_DB}/"
|
||||
cp -a "${ARMDS_INSTALL_DIR}/sw/debugger/configdb/Schemas" "${CS1000_ADAC_DB}/"
|
||||
cp -a "${ARMDS_INSTALL_DIR}/sw/debugger/configdb/ATP" "${CS1000_ADAC_DB}/"
|
||||
|
||||
If Arm Development Studio is installed elsewhere, change
|
||||
``ARMDS_INSTALL_DIR`` accordingly.
|
||||
|
||||
#. Enable the built-in PSA-ADAC Secure Debug Manager in the copied database.
|
||||
In
|
||||
``${CS1000_ADAC_DB}/Boards/Arm_Development_Boards/MPS3_Corstone_1000_ADAC_611/project_types.xml``,
|
||||
add the following element alongside the existing ``dtsl_config`` parameter:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<secure_debug_manager type="adac_sdc600" manifest="CDB://../../../ATP/manifest.xml" device="CSAPBCOM" reset_type="nSRST"/>
|
||||
|
||||
This selects the built-in PSA-ADAC implementation, its authentication-token
|
||||
provider, the SDC-600 communication device, and the board reset signal.
|
||||
|
||||
#. Describe the Corstone-1000 debug port as DPv3. In
|
||||
``${CS1000_ADAC_DB}/Boards/Arm_Development_Boards/MPS3_Corstone_1000_ADAC_611/MPS3_Corstone_1000.sdf``,
|
||||
add the following item to the ``<device_info>`` block of the ``ARMCS-DP``
|
||||
device:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<device_info_item name="DP_VERSION">DPv3</device_info_item>
|
||||
|
||||
DPv3 is required so that Arm Development Studio uses the ADIv6 debug-port
|
||||
addressing needed to reach ``CSAPBCOM``.
|
||||
|
||||
In the same file, give the copied platform a unique title:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<platform_info info_url="" manufacturer="Arm" title="MPS3_Corstone_1000_ADAC_611"/>
|
||||
|
||||
#. Rebuild the software stack with Secure Debug.
|
||||
|
||||
@@ -2272,11 +2217,60 @@ and `Arm Development Studio <arm-ds-website_>`__ versions 2022.2, 2022.c, or 202
|
||||
IComPortInit : 383 : warn : init : IComPortInit: Blocked reading LPH2RA
|
||||
|
||||
|
||||
#. Connect the debug probe to the MPS3 using the 20-pin 1.27mm connector with the ``CS_20W_1.27MM silkscreen`` label.
|
||||
#. Open a new Arm Development Studio IDE window and add the user configuration
|
||||
database.
|
||||
|
||||
#. Create a debug configuration in Arm Development Studio as described in the `Secure Debug Manager (PSA-ADAC / SDC-600)'s README <secure-debug-manager-armds-integration_>`__.
|
||||
#. Select ``Window`` > ``Preferences``.
|
||||
#. Expand ``Arm DS`` and select ``Configuration Database``.
|
||||
#. Select ``Add``.
|
||||
#. Enter a descriptive name, such as ``Corstone-1000 Secure Debug``.
|
||||
The name does not affect the connection.
|
||||
#. Set ``Location`` to ``${WORKSPACE}/armds-cs1000-adac611``.
|
||||
#. Select ``OK`` to close the ``Add configuration database location`` dialog.
|
||||
#. Select ``Rebuild database``.
|
||||
#. Select ``Apply and Close``.
|
||||
|
||||
#. Connect the debuger to the target using the debug configuration.
|
||||
#. Create the Arm Development Studio hardware connection.
|
||||
|
||||
#. Select ``Create a debug connection...``.
|
||||
#. Select ``Hardware Connection``, then select ``Next``.
|
||||
#. Enter a descriptive debug connection name, then select ``Next``.
|
||||
The name does not affect the connection.
|
||||
#. In ``Target Selection``, select ``MPS3_Corstone_1000_ADAC_611``.
|
||||
#. Select ``Finish``.
|
||||
|
||||
#. Configure one of the following external debug connections.
|
||||
|
||||
To use an external `ULINKpro D <arm-ulink-pro-d-website_>`__ probe:
|
||||
|
||||
#. Connect the ULINKpro D probe to the MPS3 connector labelled
|
||||
``CS_20W_1.27MM``.
|
||||
#. Select ``Arm`` > ``MPS3_Corstone_1000_ADAC_611`` >
|
||||
``Bare Metal Debug`` > ``Cortex-M0+``.
|
||||
#. For ``Target Connection``, select ``ULINKpro D``.
|
||||
#. Select ``Browse...``, select the detected ULINKpro D probe, and then
|
||||
select ``Select``.
|
||||
#. Select ``JTAG/SWJ``, set the debug clock to ``500 kHz``, and select
|
||||
``Connect only``.
|
||||
|
||||
To use an external `DSTREAM <arm-dstream-website_>`__ probe:
|
||||
|
||||
#. Connect the DSTREAM probe to the MPS3 connector labelled
|
||||
``CS_20W_1.27MM``.
|
||||
#. Select ``Arm`` > ``MPS3_Corstone_1000_ADAC_611`` >
|
||||
``Bare Metal Debug`` > ``Cortex-M0+``.
|
||||
#. For ``Target Connection``, select ``DSTREAM``.
|
||||
#. Select ``Browse...``, select the detected DSTREAM probe, and then select
|
||||
``Select``.
|
||||
#. Select ``JTAG/SWJ``, set the debug clock to ``500 kHz``, and select
|
||||
``Connect only``.
|
||||
|
||||
In both cases, use ``Cortex-M0+`` because Secure Debug runs in the Secure
|
||||
Enclave. Do not select the host ``Cortex-A35`` connection.
|
||||
|
||||
#. Select ``Debug``. Arm Development Studio resets the target using ``nSRST``
|
||||
and the built-in Secure Debug Manager communicates with ``CSAPBCOM`` to
|
||||
perform authentication.
|
||||
|
||||
#. Provide the paths to the private key and trust chain certificate when asked by Arm Development Studio Console.
|
||||
|
||||
@@ -2285,21 +2279,21 @@ and `Arm Development Studio <arm-ds-website_>`__ versions 2022.2, 2022.c, or 202
|
||||
...
|
||||
|
||||
Please provide private key file path:
|
||||
Enter file path > ${WORKSPACE}\secure-debug-manager\example\data\keys\EcdsaP256Key-3.pem
|
||||
Enter file path > ${WORKSPACE}/secure-debug-manager/example/data/keys/EcdsaP256Key-3.pem
|
||||
|
||||
Please provide trust chain file path:
|
||||
Enter file path > ${WORKSPACE}\secure-debug-manager\example\data\chains\chain.EcdsaP256-3
|
||||
Enter file path > ${WORKSPACE}/secure-debug-manager/example/data/chains/chain.EcdsaP256-3
|
||||
|
||||
...
|
||||
|
||||
#. When successful authenticated, Arm Development Studio will connect to the running MPS3 and the debug features can be used.
|
||||
The following prompt should appear in the Secure Enclave terminal (``ttyUSB1``):
|
||||
#. After authentication succeeds, verify that the image continues booting and
|
||||
is not left waiting inside the Secure Debug authentication flow.
|
||||
Authentication alone is not sufficient to pass the test. Confirm that the
|
||||
Host terminal reaches the Linux login prompt:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
...
|
||||
boot_platform_init: Corstone-1000 Secure Debug is a success.
|
||||
...
|
||||
corstone1000-mps3 login:
|
||||
|
||||
|
||||
--------------
|
||||
@@ -2307,9 +2301,8 @@ and `Arm Development Studio <arm-ds-website_>`__ versions 2022.2, 2022.c, or 202
|
||||
*Copyright (c) 2022-2026, Arm Limited. All rights reserved.*
|
||||
|
||||
.. _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-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
|
||||
.. _arm-ulink-pro-d-website: https://www.arm.com/products/development-tools/debug-probes/ulink-pro
|
||||
.. _arm-dstream-website: https://www.arm.com/products/development-tools/debug-probes/dstream-st
|
||||
.. _edk2-repository: https://github.com/tianocore/edk2
|
||||
@@ -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
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
arch_timer: Failed to initialize memory-mapped timer.
|
||||
PCI: OF: of_root node is NULL, cannot create PCI host bridge node
|
||||
_OSC: platform retains control of PCIe features (AE_ERROR)
|
||||
@@ -1,2 +1,3 @@
|
||||
arch_timer: Failed to initialize memory-mapped timer.
|
||||
PCI: OF: of_root node is NULL, cannot create PCI host bridge node
|
||||
_OSC: platform retains control of PCIe features (AE_ERROR)
|
||||
+7
-6
@@ -1,17 +1,18 @@
|
||||
SUMMARY = "External system Cortex-M3 Firmware"
|
||||
DESCRIPTION = "Firmware to be loaded and run in External System Harness in\
|
||||
support to the main application CPU."
|
||||
HOMEPAGE = "https://git.linaro.org/landing-teams/working/arm/external-system.git"
|
||||
HOMEPAGE = "https://gitlab.arm.com/arm-reference-solutions/corstone1000/external_system/rtx"
|
||||
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 \
|
||||
LICENSE = "Apache-2.0 AND BSD-3-Clause"
|
||||
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,9 +160,10 @@ 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"
|
||||
TFM_IMAGE_SIGN_PSA_KEY_IDS = "2147451244"
|
||||
RE_IMAGE_OFFSET = "0x1000"
|
||||
|
||||
do_sign_images() {
|
||||
|
||||
@@ -12,19 +12,27 @@ PACKAGE_ARCH = "${MACHINE_ARCH}"
|
||||
|
||||
COMPATIBLE_MACHINE = "juno"
|
||||
|
||||
LINARO_RELEASE = "19.06"
|
||||
|
||||
SRC_URI = "http://releases.linaro.org/members/arm/platforms/${LINARO_RELEASE}/juno-latest-oe-uboot.zip;subdir=${S} \
|
||||
file://images-r0.txt \
|
||||
file://images-r1.txt \
|
||||
file://images-r2.txt \
|
||||
SRC_URI = " \
|
||||
file://mbb_v151.ebf \
|
||||
file://io_b118.bit \
|
||||
file://tapid.arm \
|
||||
file://pms_v103.bin \
|
||||
file://pms_v104.bin \
|
||||
file://pms_v105.bin \
|
||||
file://mb-board.txt \
|
||||
file://site1-HBI0262B-board.txt \
|
||||
file://site1-HBI0262C-board.txt \
|
||||
file://site1-HBI0262D-board.txt \
|
||||
file://site1-images.txt \
|
||||
file://hdlcdclk.dat \
|
||||
file://startup.nsh \
|
||||
file://selftest \
|
||||
file://config.txt \
|
||||
file://uEnv.txt \
|
||||
"
|
||||
SRC_URI[md5sum] = "01b662b81fa409d55ff298238ad24003"
|
||||
SRC_URI[sha256sum] = "b8a3909bb3bc4350a8771b863193a3e33b358e2a727624a77c9ecf13516cec82"
|
||||
|
||||
FIRMWARE_DIR = "juno-firmware-${LINARO_RELEASE}"
|
||||
S = "${UNPACKDIR}/${FIRMWARE_DIR}"
|
||||
FIRMWARE_DIR = "juno-firmware"
|
||||
S = "${UNPACKDIR}"
|
||||
|
||||
inherit deploy nopackages
|
||||
|
||||
@@ -34,23 +42,63 @@ do_compile[noexec] = "1"
|
||||
# The ${D} is used as a temporary directory and we don't generate any
|
||||
# packages for this recipe.
|
||||
do_install() {
|
||||
cp -a ${S} ${D}/
|
||||
install -d ${D}/${FIRMWARE_DIR}/
|
||||
cp -f ${UNPACKDIR}/config.txt ${D}/${FIRMWARE_DIR}/
|
||||
|
||||
# Files in the MB directory are mostly the same, except for the PMS file and references to the PMS file by name
|
||||
install -d ${D}/${FIRMWARE_DIR}/MB/HBI0262B/
|
||||
cp -f ${UNPACKDIR}/mbb_v151.ebf ${D}/${FIRMWARE_DIR}/MB/HBI0262B/
|
||||
cp -f ${UNPACKDIR}/io_b118.bit ${D}/${FIRMWARE_DIR}/MB/HBI0262B/
|
||||
cp -f ${UNPACKDIR}/tapid.arm ${D}/${FIRMWARE_DIR}/MB/HBI0262B/
|
||||
cp -f ${UNPACKDIR}/pms_v103.bin ${D}/${FIRMWARE_DIR}/MB/HBI0262B/
|
||||
cp -f ${UNPACKDIR}/mb-board.txt ${D}/${FIRMWARE_DIR}/MB/HBI0262B/board.txt
|
||||
|
||||
install -d ${D}/${FIRMWARE_DIR}/MB/HBI0262C/
|
||||
cp -f ${UNPACKDIR}/mbb_v151.ebf ${D}/${FIRMWARE_DIR}/MB/HBI0262C/
|
||||
cp -f ${UNPACKDIR}/io_b118.bit ${D}/${FIRMWARE_DIR}/MB/HBI0262C/
|
||||
cp -f ${UNPACKDIR}/tapid.arm ${D}/${FIRMWARE_DIR}/MB/HBI0262C/
|
||||
cp -f ${UNPACKDIR}/pms_v104.bin ${D}/${FIRMWARE_DIR}/MB/HBI0262C/
|
||||
sed 's/pms_v103/pms_v104/g' ${UNPACKDIR}/mb-board.txt > ${D}/${FIRMWARE_DIR}/MB/HBI0262C/board.txt
|
||||
|
||||
install -d ${D}/${FIRMWARE_DIR}/MB/HBI0262D/
|
||||
cp -f ${UNPACKDIR}/mbb_v151.ebf ${D}/${FIRMWARE_DIR}/MB/HBI0262D/
|
||||
cp -f ${UNPACKDIR}/io_b118.bit ${D}/${FIRMWARE_DIR}/MB/HBI0262D/
|
||||
cp -f ${UNPACKDIR}/tapid.arm ${D}/${FIRMWARE_DIR}/MB/HBI0262D/
|
||||
cp -f ${UNPACKDIR}/pms_v105.bin ${D}/${FIRMWARE_DIR}/MB/HBI0262D/
|
||||
sed 's/pms_v103/pms_v105/g' ${UNPACKDIR}/mb-board.txt > ${D}/${FIRMWARE_DIR}/MB/HBI0262D/board.txt
|
||||
|
||||
# The SITE1 image files are mostly the same except for the DTB they reference
|
||||
install -d ${D}/${FIRMWARE_DIR}/SITE1/HBI0262B/
|
||||
cp -f ${UNPACKDIR}/site1-HBI0262B-board.txt ${D}/${FIRMWARE_DIR}/SITE1/HBI0262B/board.txt
|
||||
cp -f ${UNPACKDIR}/site1-images.txt ${D}/${FIRMWARE_DIR}/SITE1/HBI0262B/images.txt
|
||||
|
||||
install -d ${D}/${FIRMWARE_DIR}/SITE1/HBI0262C/
|
||||
cp -f ${UNPACKDIR}/site1-HBI0262C-board.txt ${D}/${FIRMWARE_DIR}/SITE1/HBI0262C/board.txt
|
||||
sed 's/juno\.dtb/juno-r1.dtb/g' ${UNPACKDIR}/site1-images.txt > ${D}/${FIRMWARE_DIR}/SITE1/HBI0262C/images.txt
|
||||
|
||||
install -d ${D}/${FIRMWARE_DIR}/SITE1/HBI0262D/
|
||||
cp -f ${UNPACKDIR}/site1-HBI0262D-board.txt ${D}/${FIRMWARE_DIR}/SITE1/HBI0262D/board.txt
|
||||
sed 's/juno\.dtb/juno-r2.dtb/g' ${UNPACKDIR}/site1-images.txt > ${D}/${FIRMWARE_DIR}/SITE1/HBI0262D/images.txt
|
||||
|
||||
# The files in SOFTWARE are listed in the SITE1 board.txt file by name
|
||||
install -d ${D}/${FIRMWARE_DIR}/SOFTWARE/
|
||||
cp -f ${RECIPE_SYSROOT}/firmware/trusted-firmware-a/fip.bin \
|
||||
${D}/${FIRMWARE_DIR}/SOFTWARE/fip.bin
|
||||
|
||||
cp -f ${RECIPE_SYSROOT}/firmware/trusted-firmware-a/bl1.bin \
|
||||
${D}/${FIRMWARE_DIR}/SOFTWARE/bl1.bin
|
||||
|
||||
cp -f ${RECIPE_SYSROOT}/firmware/trusted-firmware-a/fip.bin \
|
||||
${D}/${FIRMWARE_DIR}/SOFTWARE/fip.bin
|
||||
cp -f ${UNPACKDIR}/hdlcdclk.dat ${D}/${FIRMWARE_DIR}/SOFTWARE/
|
||||
|
||||
cp -f ${RECIPE_SYSROOT}/firmware/scp-firmware/scp_romfw_bypass.bin \
|
||||
${D}/${FIRMWARE_DIR}/SOFTWARE/scp_bl1.bin
|
||||
|
||||
cp -f ${UNPACKDIR}/startup.nsh ${D}/${FIRMWARE_DIR}/SOFTWARE/
|
||||
cp -f ${UNPACKDIR}/selftest ${D}/${FIRMWARE_DIR}/SOFTWARE/
|
||||
dd if=/dev/zero of="${D}/${FIRMWARE_DIR}/SOFTWARE/blank.img" bs=1024 count=192 status=none
|
||||
|
||||
# u-boot environment file
|
||||
cp -f ${UNPACKDIR}/uEnv.txt ${D}/${FIRMWARE_DIR}/SOFTWARE/
|
||||
|
||||
# Juno images list file
|
||||
cp -f ${UNPACKDIR}/images-r0.txt ${D}/${FIRMWARE_DIR}/SITE1/HBI0262B/images.txt
|
||||
cp -f ${UNPACKDIR}/images-r1.txt ${D}/${FIRMWARE_DIR}/SITE1/HBI0262C/images.txt
|
||||
cp -f ${UNPACKDIR}/images-r2.txt ${D}/${FIRMWARE_DIR}/SITE1/HBI0262D/images.txt
|
||||
}
|
||||
|
||||
do_deploy() {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
TITLE: V2M-Juno Configuration File
|
||||
|
||||
[CONFIGURATION]
|
||||
AUTORUN: TRUE ;Auto Run from power on
|
||||
TESTMENU: FALSE ;MB Peripheral Test Menu
|
||||
|
||||
UPDATE: FALSE ;Force JTAG and FPGA update to DBs
|
||||
VERIFY: FALSE ;Force FPGA verify to DBs
|
||||
|
||||
DVIMODE: VGA ;VGA or SVGA or XGA or SXGA or UXGA
|
||||
|
||||
MBLOG: FALSE ;LOG MB MICRO in run mode FALSE/UART0/UART1
|
||||
DBLOG: FALSE ;LOG DB MICRO in run mode FALSE/UART1 (when MBLOG is not UART1)
|
||||
|
||||
USERSWITCH: 00000000 ;UserSwitch[7:0] in binary
|
||||
CONFSWITCH: 00000000 ;Configuration Switch[7:0] in binary, Core[0:1] Cluster[2]
|
||||
ASSERTNPOR: TRUE ;External resets assert nPOR
|
||||
WDTRESET: RESETMB ;Watchdog reset options NONE/RESETMB/RESETDB
|
||||
|
||||
PCIMASTER: DB1 ;Port Failover DB1/SL3
|
||||
MASTERSITE: DB1 ;Boot Master DB1/SL3
|
||||
|
||||
REMOTE: NONE ;Selects remote command via USB or FTP NONE/USB/FTP
|
||||
|
||||
MCCMACADDRESS: 0xFFFFFFFFFFFF ;MCC MAC Address (must be even MAC address)
|
||||
SMCMACADDRESS: 0xFFFFFFFFFFFF ;SMC MAC Address
|
||||
|
||||
HOSTNAME: V2M-JUNO-A2 ;Host name for FTP [15 characters max]
|
||||
Binary file not shown.
@@ -1,71 +0,0 @@
|
||||
TITLE: Versatile Express Images Configuration File
|
||||
|
||||
[IMAGES]
|
||||
TOTALIMAGES: 10 ;Number of Images (Max: 32)
|
||||
|
||||
NOR0UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR0ADDRESS: 0x00000000 ;Image Flash Address
|
||||
NOR0FILE: \SOFTWARE\fip.bin ;Image File Name
|
||||
NOR0LOAD: 00000000 ;Image Load Address
|
||||
NOR0ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR1UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR1ADDRESS: 0x03EC0000 ;Image Flash Address
|
||||
NOR1FILE: \SOFTWARE\bl1.bin ;Image File Name
|
||||
NOR1LOAD: 00000000 ;Image Load Address
|
||||
NOR1ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR2UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR2ADDRESS: 0x00500000 ;Image Flash Address
|
||||
NOR2FILE: \SOFTWARE\Image ;Image File Name
|
||||
NOR2NAME: norkern ;Rename kernel to norkern
|
||||
NOR2LOAD: 00000000 ;Image Load Address
|
||||
NOR2ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR3UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR3ADDRESS: 0x03000000 ;Image Flash Address
|
||||
NOR3FILE: \SOFTWARE\juno-r1.dtb ;Image File Name
|
||||
NOR3NAME: board.dtb ;Specify target filename to preserve file extension
|
||||
NOR3LOAD: 00000000 ;Image Load Address
|
||||
NOR3ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR4UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR4ADDRESS: 0x030C0000 ;Image Flash Address
|
||||
NOR4FILE: \SOFTWARE\hdlcdclk.dat ;Image File Name
|
||||
NOR4LOAD: 00000000 ;Image Load Address
|
||||
NOR4ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR5UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR5ADDRESS: 0x03E40000 ;Image Flash Address
|
||||
NOR5FILE: \SOFTWARE\scp_bl1.bin ;Image File Name
|
||||
NOR5LOAD: 00000000 ;Image Load Address
|
||||
NOR5ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR6UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR6ADDRESS: 0x0BF00000 ;Image Flash Address
|
||||
NOR6FILE: \SOFTWARE\startup.nsh ;Image File Name
|
||||
NOR6NAME: startup.nsh
|
||||
NOR6LOAD: 00000000 ;Image Load Address
|
||||
NOR6ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR7UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR7ADDRESS: 0x0BFC0000 ;Image Flash Address
|
||||
NOR7FILE: \SOFTWARE\blank.img ;Image File Name
|
||||
NOR7NAME: BOOTENV
|
||||
NOR7LOAD: 00000000 ;Image Load Address
|
||||
NOR7ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR8UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR8ADDRESS: 0x03100000 ;Image Flash Address
|
||||
NOR8FILE: \SOFTWARE\selftest ;Image File Name
|
||||
NOR8LOAD: 00000000 ;Image Load Address
|
||||
NOR8ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR9UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR9ADDRESS: 0x03180000 ;Image Flash Address
|
||||
NOR9NAME: uEnv.txt
|
||||
NOR9FILE: \SOFTWARE\uEnv.txt ;Image File Name
|
||||
NOR9LOAD: 00000000 ;Image Load Address
|
||||
NOR9ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
TITLE: Versatile Express Images Configuration File
|
||||
|
||||
[IMAGES]
|
||||
TOTALIMAGES: 10 ;Number of Images (Max: 32)
|
||||
|
||||
NOR0UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR0ADDRESS: 0x00000000 ;Image Flash Address
|
||||
NOR0FILE: \SOFTWARE\fip.bin ;Image File Name
|
||||
NOR0LOAD: 00000000 ;Image Load Address
|
||||
NOR0ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR1UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR1ADDRESS: 0x03EC0000 ;Image Flash Address
|
||||
NOR1FILE: \SOFTWARE\bl1.bin ;Image File Name
|
||||
NOR1LOAD: 00000000 ;Image Load Address
|
||||
NOR1ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR2UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR2ADDRESS: 0x00500000 ;Image Flash Address
|
||||
NOR2FILE: \SOFTWARE\Image ;Image File Name
|
||||
NOR2NAME: norkern ;Rename kernel to norkern
|
||||
NOR2LOAD: 00000000 ;Image Load Address
|
||||
NOR2ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR3UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR3ADDRESS: 0x03000000 ;Image Flash Address
|
||||
NOR3FILE: \SOFTWARE\juno-r2.dtb ;Image File Name
|
||||
NOR3NAME: board.dtb ;Specify target filename to preserve file extension
|
||||
NOR3LOAD: 00000000 ;Image Load Address
|
||||
NOR3ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR4UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR4ADDRESS: 0x030C0000 ;Image Flash Address
|
||||
NOR4FILE: \SOFTWARE\hdlcdclk.dat ;Image File Name
|
||||
NOR4LOAD: 00000000 ;Image Load Address
|
||||
NOR4ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR5UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR5ADDRESS: 0x03E40000 ;Image Flash Address
|
||||
NOR5FILE: \SOFTWARE\scp_bl1.bin ;Image File Name
|
||||
NOR5LOAD: 00000000 ;Image Load Address
|
||||
NOR5ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR6UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR6ADDRESS: 0x0BF00000 ;Image Flash Address
|
||||
NOR6FILE: \SOFTWARE\startup.nsh ;Image File Name
|
||||
NOR6NAME: startup.nsh
|
||||
NOR6LOAD: 00000000 ;Image Load Address
|
||||
NOR6ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR7UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR7ADDRESS: 0x0BFC0000 ;Image Flash Address
|
||||
NOR7FILE: \SOFTWARE\blank.img ;Image File Name
|
||||
NOR7NAME: BOOTENV
|
||||
NOR7LOAD: 00000000 ;Image Load Address
|
||||
NOR7ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR8UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR8ADDRESS: 0x03100000 ;Image Flash Address
|
||||
NOR8FILE: \SOFTWARE\selftest ;Image File Name
|
||||
NOR8LOAD: 00000000 ;Image Load Address
|
||||
NOR8ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
NOR9UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
|
||||
NOR9ADDRESS: 0x03180000 ;Image Flash Address
|
||||
NOR9NAME: uEnv.txt
|
||||
NOR9FILE: \SOFTWARE\uEnv.txt ;Image File Name
|
||||
NOR9LOAD: 00000000 ;Image Load Address
|
||||
NOR9ENTRY: 00000000 ;Image Entry Point
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
BOARD: HBI0262
|
||||
TITLE: MotherBoard Configuration File
|
||||
|
||||
[MCCS]
|
||||
MBBIOS: mbb_v151.ebf ;MB BIOS IMAGE
|
||||
|
||||
[FPGAS]
|
||||
MBIOFPGA: io_b118.bit ;MB IOFPGA
|
||||
|
||||
[PMIC]
|
||||
MBPMIC: pms_v103.bin ;MB PMIC
|
||||
|
||||
[OSCCLKS]
|
||||
TOTALOSCCLKS: 11
|
||||
OSC0: 50.0 ;OSC0 Juno SYSREFCLK (System clock)
|
||||
OSC1: 50.0 ;OSC1 Juno AONREFCLK (Always On)
|
||||
OSC2: 50.0 ;OSC2 Juno PXLREFCLK (HS pixel clock)
|
||||
OSC3: 47.5 ;OSC3 Juno PXCLKIN (LS pixel clock)
|
||||
OSC4: 2.11 ;OSC4 Juno I2SCLK (Audio)
|
||||
OSC5: 50.0 ;OSC5 Juno SMCMCLK (Static memory)
|
||||
OSC6: 50.0 ;OSC6 Juno CA53 REF_CLK (RSVD)
|
||||
OSC7: 50.0 ;OSC7 Juno CA57 REF_CLK (RSVD)
|
||||
OSC8: 50.0 ;OSC8 Juno GPU REF_CLK (RSVD)
|
||||
OSC9: 30.0 ;OSC9 IOFPGA BOOT (RSVD)
|
||||
OSC10: 24.0 ;OSC10 IOFPGA UART (RSVD)
|
||||
OSC11: 7.37 ;OSC11 Juno UARTCLK (UART clock)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
BOARD: HBI0262
|
||||
TITLE: V2M-Juno DevChip Configuration File
|
||||
|
||||
[SCC REGISTERS]
|
||||
TOTALSCCS: 12 ;Total Number of SCC registers
|
||||
SCC: 0x054 0x0007FFFE ;Enable non-secure DMA operations
|
||||
SCC: 0x05C 0x00FE001E ;Enable default GPU Texture Formats
|
||||
SCC: 0x100 0x003F1000 ;A57 PLL Register 0 (800MHz)
|
||||
SCC: 0x104 0x0001F300 ;A57 PLL Register 1
|
||||
SCC: 0x108 0x00371000 ;A53 PLL Register 0 (700MHz)
|
||||
SCC: 0x10C 0x0001B300 ;A53 PLL Register 1
|
||||
SCC: 0x118 0x003F1000 ;SYS PLL Register 0 (1600MHz)
|
||||
SCC: 0x11C 0x0001F100 ;SYS PLL Register 1
|
||||
SCC: 0x0F8 0x0BEC0000 ;BL1 entry point
|
||||
SCC: 0x0FC 0xABE40000 ;BL0 entry point
|
||||
|
||||
SCC: 0x00C 0x000000C2 ;Clock Control, TMIF2XCLK, Register 0xC1 = default
|
||||
;[3:0] CLKSEL : 0 Output gated, 1 AON_REF_CLK, 2 SYSCLK
|
||||
;[7:4] CLKDIV : Clock divider -1 (0 give a division of 1)
|
||||
SCC: 0x010 0x000000C2 ;Clock Control, TSIF2XCLK, Register 0xC1 = default
|
||||
;[3:0] CLKSEL : 0 Output gated, 1 AON_REF_CLK, 2 SYSCLK
|
||||
;[7:4] CLKDIV : Clock divider -1 (0 give a division of 1)
|
||||
@@ -0,0 +1,24 @@
|
||||
BOARD: HBI0262
|
||||
TITLE: V2M-Juno DevChip Configuration File
|
||||
|
||||
[SCC REGISTERS]
|
||||
TOTALSCCS: 13 ;Total Number of SCC registers
|
||||
SCC: 0x054 0x0007FFFE ;Enable non-secure DMA operations
|
||||
SCC: 0x05C 0x00FE001E ;Enable default GPU Texture Formats
|
||||
SCC: 0x100 0x003F1000 ;A57 PLL Register 0 (800MHz)
|
||||
SCC: 0x104 0x0001F300 ;A57 PLL Register 1
|
||||
SCC: 0x108 0x00331000 ;A53 PLL Register 0 (650MHz)
|
||||
SCC: 0x10C 0x00019300 ;A53 PLL Register 1
|
||||
SCC: 0x118 0x003F1000 ;SYS PLL Register 0 (1600MHz)
|
||||
SCC: 0x11C 0x0001F100 ;SYS PLL Register 1
|
||||
SCC: 0x0F8 0x0BEC0000 ;BL1 entry point
|
||||
SCC: 0x0FC 0xABE40000 ;BL0 entry point
|
||||
|
||||
SCC: 0xA14 0x00000000 ;PCLKDBG_CONTROL DIV=1
|
||||
|
||||
SCC: 0x00C 0x000000C2 ;Clock Control, TMIF2XCLK, Register 0xC1 = default
|
||||
;[3:0] CLKSEL : 0 Output gated, 1 AON_REF_CLK, 2 SYSCLK
|
||||
;[7:4] CLKDIV : Clock divider -1 (0 give a division of 1)
|
||||
SCC: 0x010 0x000000C2 ;Clock Control, TSIF2XCLK, Register 0xC1 = default
|
||||
;[3:0] CLKSEL : 0 Output gated, 1 AON_REF_CLK, 2 SYSCLK
|
||||
;[7:4] CLKDIV : Clock divider -1 (0 give a division of 1)
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
BOARD: HBI0262
|
||||
TITLE: V2M-Juno DevChip Configuration File
|
||||
|
||||
[SCC REGISTERS]
|
||||
TOTALSCCS: 13 ;Total Number of SCC registers
|
||||
SCC: 0x054 0x0007FFFE ;Enable non-secure DMA operations
|
||||
SCC: 0x05C 0x00FE001E ;Enable default GPU Texture Formats
|
||||
SCC: 0x100 0x00271000 ;A72 PLL Register 0 (1000MHz)
|
||||
SCC: 0x104 0x00013100 ;A72 PLL Register 1
|
||||
SCC: 0x108 0x003F1000 ;A53 PLL Register 0 (800MHz)
|
||||
SCC: 0x10C 0x0001F300 ;A53 PLL Register 1
|
||||
SCC: 0x118 0x003F1000 ;SYS PLL Register 0 (1600MHz)
|
||||
SCC: 0x11C 0x0001F100 ;SYS PLL Register 1
|
||||
SCC: 0x0F8 0x0BEC0000 ;BL1 entry point
|
||||
SCC: 0x0FC 0xABE40000 ;BL0 entry point
|
||||
|
||||
SCC: 0xA14 0x00000000 ;PCLKDBG_CONTROL DIV=1
|
||||
|
||||
SCC: 0x00C 0x000000C2 ;Clock Control, TMIF2XCLK, Register 0xC1 = default
|
||||
;[3:0] CLKSEL : 0 Output gated, 1 AON_REF_CLK, 2 SYSCLK
|
||||
;[7:4] CLKDIV : Clock divider -1 (0 give a division of 1)
|
||||
SCC: 0x010 0x000000C2 ;Clock Control, TSIF2XCLK, Register 0xC1 = default
|
||||
;[3:0] CLKSEL : 0 Output gated, 1 AON_REF_CLK, 2 SYSCLK
|
||||
;[7:4] CLKDIV : Clock divider -1 (0 give a division of 1)
|
||||
File renamed without changes.
@@ -0,0 +1,4 @@
|
||||
echo -off
|
||||
echo Juno startup.nsh from NOR flash
|
||||
echo Example command to start the kernel:
|
||||
echo norkern dtb=board.dtb initrd=ramdisk.img console=ttyAMA0,115200n8 root=/dev/sda2 rw rootwait earlyprintk=pl011,0x7ff80000 debug user_debug=31 androidboot.hardware=juno loglevel=9 sky2.mac_address=0xAA,0xBB,0xCC,0xDD,0xEE,0xFF
|
||||
@@ -0,0 +1,97 @@
|
||||
# ARM TAP controller IR register lengths file
|
||||
#
|
||||
# Copyright (C) 2008 ARM Limited. All rights reserved.
|
||||
#
|
||||
# This file contains a definition of the devices names, ID codes, ID code mask
|
||||
# and IR lengths for devices used on ARM boards. This file is read by the
|
||||
# progcards_usb.exe program and used to determine if a device ID is valid and
|
||||
# the corresponding IR length. A device that is not recognized will be display
|
||||
# as 'UNKOWN' and device details should be added to this file.
|
||||
#
|
||||
# DEVICE NAME ID CODE ID MASK IR LENGTH
|
||||
# ------------- ---------- ---------- ---------
|
||||
|
||||
# XILINX PLDs
|
||||
|
||||
XC9572 0x09504093 0x0FFFFFFF 8
|
||||
XC9536XL 0x29602093 0x0FFFFFFF 8
|
||||
XC9572XL 0x09604093 0x0FFFFFFF 8
|
||||
XC95288XL 0x09616093 0x0FFFFFFF 8
|
||||
XCR3256XL 0xF494FFFF 0x0FFF8001 4
|
||||
XC4036XLA 0x00224093 0x00FFFFFF 3
|
||||
XC4062XLA 0x00230093 0x00FFFFFF 3
|
||||
XC4085XLA 0x00238093 0x00FFFFFF 3
|
||||
XC2C32A 0x06E1C093 0x0FFF0FFF 8
|
||||
XC2C64A 0x06E5D093 0x0FFF0FFF 8
|
||||
XC2C128 0x06D8A093 0x0FFF0FFF 8
|
||||
XC2C256 0x16D4c093 0x0FFF0FFF 8
|
||||
XC2C384 0x06D5C093 0x0FFF0FFF 8
|
||||
|
||||
# XILINX FPGAs
|
||||
|
||||
XCV600 0x10630093 0x00FFFFFF 5
|
||||
XCV600E 0x90A30093 0x00FFFFFF 5
|
||||
XCV1000 0x40640093 0x0FFFFFFF 5
|
||||
XCV2000E 0xF0A50093 0x0FFFFFFF 5
|
||||
XC2V2000 0x01038093 0x0FFFFFFF 6
|
||||
XC2V6000 0x31060093 0x0FFFFFFF 6
|
||||
XC2V8000 0x01070093 0x0FFFFFFF 6
|
||||
XC4VLX40 0x316A4093 0x0FFFFFFF 10
|
||||
XC4VLX160 0x01718093 0x0FFFFFFF 10
|
||||
XC4VLX200 0x01734093 0x0FFFFFFF 10
|
||||
XC5VLX50T 0x02A96093 0x0FFFFFFF 10
|
||||
XC5VLX110 0x228D6093 0x0FFFFFFF 10
|
||||
XC5VLX330 0x2295C093 0x0FFFFFFF 10
|
||||
XC2S200E 0x20A1C093 0x0FFFFFFF 5
|
||||
XC2S300E 0x90A20093 0x0FFFFFFF 5
|
||||
XC3S200A 0x02218093 0x0FFFFFFF 6
|
||||
XC3S4000 0x01448093 0x0FFFFFFF 6
|
||||
XC6SLX45 0x04008093 0x0FFFFFFF 6
|
||||
|
||||
# ARM
|
||||
|
||||
ARM7TDMI 0x3F0F0F0F 0xFFFFFFFF 4
|
||||
ARM7TDMI-r4 0x40700F0F 0xFFFFFFFF 4
|
||||
ARM720T 0x0F0F0F0F 0xFFFFFFFF 4
|
||||
ARM920T 0x10920F0F 0xFFFFFFFF 4
|
||||
ARM926EJ-S 0x07926F0F 0xFFFFFFFF 4
|
||||
ARM940T 0x1F0F0F0F 0xFFFFFFFF 4
|
||||
ARM10200 0x00A20F0F 0xFFFFFFFF 4
|
||||
ARMFLASH 0x0F0E5F2F 0xFFFFFFFF 5
|
||||
ARMDBT 0x00000F0F 0xFFFFFFFF 5
|
||||
PWP926EJ-S_BS2 0x0F21FF0F 0xFFFFFFFF 2
|
||||
ARM_BS2_ 0x0F203F0F 0xFFFFFFFF 2
|
||||
ARM1136J-Sr0_BS2 0x0F21DF0F 0xFFFFFFFF 2
|
||||
ARM11MPCore_BS5 0x17536021 0xFFFFFFFF 5
|
||||
PXP1176JZF_BS2 0x0F2258EF 0xFFFFFFFF 2
|
||||
CORTEXA8 0x0F423477 0xFFFFFFFF 4
|
||||
CORTEXA9 0x08226021 0xFFFFFFFF 4
|
||||
|
||||
# ALTERA
|
||||
|
||||
EPM3032A 0x170320DD 0xFFFFFFFF 10
|
||||
EPM7256AE 0x172560DD 0xFFFFFFFF 10
|
||||
EPM7512AE 0x175120DD 0xFFFFFFFF 10
|
||||
EPM1270 0x020A30DD 0xFFFFFFFF 10
|
||||
EP20K1000E 0x090000DD 0xFFFFFFFF 10
|
||||
EP2S180F 0x020960DD 0xFFFFFFFF 10
|
||||
|
||||
# Misc
|
||||
|
||||
ispClock5520 0x00150043 0xFFFFFFFF 8
|
||||
ispClock5620 0x00160043 0xFFFFFFFF 8
|
||||
ispClock5610V 0x00161043 0xFFFFFFFF 8
|
||||
ispClock5610AV 0x00166043 0xFFFFFFFF 8
|
||||
ISSP 0x0F0F0F0F 0x0FFFFFFF 5
|
||||
Mali200 0x10400477 0xFFFFFFFF 2
|
||||
PLX6520 0x3197839B 0xFFFFFFFF 5
|
||||
PLX8114 0x21FB239B 0xFFFFFFFF 5
|
||||
PLX8518 0x1214639B 0xFFFFFFFF 5
|
||||
PLX8518 0x4214639B 0xFFFFFFFF 5
|
||||
|
||||
STM32TMC 0x16410041 0x0FFF0FFF 5
|
||||
STM32CM3 0x3BA00477 0x0FFFFFFF 4
|
||||
IDT89HPES32H8 0x08035067 0xFFFFFFFF 6
|
||||
IDT89H16NT16 0x28090067 0xFFFFFFFF 6
|
||||
NX5000_BYPASS 0x14951185 0xFFFFFFFF 4
|
||||
NX5000_FC1152 0x03387589 0xFFFFFFFF 4
|
||||
-231
@@ -1,231 +0,0 @@
|
||||
From 4e23e72e65481fe917d8a0af355b3b7669d5acb6 Mon Sep 17 00:00:00 2001
|
||||
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
|
||||
Date: Thu, 7 Aug 2025 10:05:02 +0000
|
||||
Subject: [PATCH] plat: corstone1000: add Cortex-A320 support
|
||||
|
||||
Introduce `CORSTONE1000_CORTEX_A320` to enable Cortex-A320 on
|
||||
Corstone-1000 while keeping Cortex-A35 as the default. When the
|
||||
define is enabled, the build switches from `cortex_a35.S` to
|
||||
`cortex_a320.S`, maintaining compatibility with existing A35-based
|
||||
designs.
|
||||
|
||||
Also add Normal-World mappings for the Ethos-U85 NPU and its SRAM
|
||||
on Cortex-A320 platforms so U-Boot and other non-secure software
|
||||
can safely access these regions:
|
||||
|
||||
* **Ethos-U85 registers**: base `0x1A050000`, size `0x00004000` (16 KB),
|
||||
attrs `MT_DEVICE | MT_RW | MT_NS`
|
||||
* **Non-secure SRAM**: base `0x02400000`, size `0x00400000` (4 MB),
|
||||
attrs `MT_MEMORY | MT_RW | MT_NS`
|
||||
|
||||
Enable GICv3 with GIC-600 when building for Cortex-A320 (retain
|
||||
GICv2/GIC-400 for Cortex-A35):
|
||||
|
||||
* Update `plat_my_core_pos()` and `plat_arm_calc_core_pos()` to use
|
||||
the Cortex-A320 MPIDR_EL1 affinity layout.
|
||||
* Add an A320-specific core-position routine in assembly guarded by
|
||||
`CORSTONE1000_CORTEX_A320`.
|
||||
* Switch to the GICv3 driver with GIC-600 extensions: update GIC base
|
||||
addresses, use GICv3 APIs, and set `USE_GIC_DRIVER=3`,
|
||||
`GICV3_SUPPORT_GIC600=1`, `GIC_ENABLE_V4_EXTN=1`.
|
||||
|
||||
These changes prepare the platform for Cortex-A320 integration and
|
||||
ensure correct GIC configuration and secondary-core bring-up, while
|
||||
preserving A35 behavior.
|
||||
|
||||
Upstream-Status: Submitted (https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/45729)
|
||||
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Signed-off-by: Michael Safwat <michael.safwat@arm.com>
|
||||
---
|
||||
.../common/corstone1000_helpers.S | 35 ++++++++++++++++++-
|
||||
.../corstone1000/common/corstone1000_plat.c | 4 +++
|
||||
.../corstone1000/common/corstone1000_pm.c | 8 +++++
|
||||
.../common/include/platform_def.h | 26 ++++++++++++++
|
||||
plat/arm/board/corstone1000/platform.mk | 11 ++++++
|
||||
5 files changed, 83 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/plat/arm/board/corstone1000/common/corstone1000_helpers.S b/plat/arm/board/corstone1000/common/corstone1000_helpers.S
|
||||
index a4ca9fe98223..665dbc61a92e 100644
|
||||
--- a/plat/arm/board/corstone1000/common/corstone1000_helpers.S
|
||||
+++ b/plat/arm/board/corstone1000/common/corstone1000_helpers.S
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2021-2024 Arm Limited and Contributors. All rights reserved.
|
||||
+ * Copyright (c) 2021-2025 Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
@@ -13,6 +13,39 @@
|
||||
.globl plat_is_my_cpu_primary
|
||||
.globl plat_arm_calc_core_pos
|
||||
|
||||
+#ifdef CORSTONE1000_CORTEX_A320
|
||||
+ .globl plat_my_core_pos
|
||||
+
|
||||
+func plat_my_core_pos
|
||||
+ mrs x0, mpidr_el1
|
||||
+ b plat_arm_calc_core_pos
|
||||
+endfunc plat_my_core_pos
|
||||
+
|
||||
+func plat_arm_calc_core_pos
|
||||
+ /* Aff0 is always 0 for Cortex-A320
|
||||
+ MPIDR format: https://developer.arm.com/documentation/109551/0001/AArch64-registers/AArch64-Identification-registers-summary/MPIDR-EL1--Multiprocessor-Affinity-Register?lang=en
|
||||
+ */
|
||||
+ /* Extract Aff1 (core ID) */
|
||||
+ ubfx x1, x0, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
|
||||
+
|
||||
+ /* Extract Aff2 (cluster lower bits) */
|
||||
+ ubfx x2, x0, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
|
||||
+
|
||||
+ /* Extract Aff3 (cluster upper bits) */
|
||||
+ ubfx x3, x0, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS
|
||||
+
|
||||
+ /* cluster_id = (Aff3 << 8) | Aff2 */
|
||||
+ lsl x3, x3, #MPIDR_AFFINITY_BITS
|
||||
+ orr x3, x3, x2
|
||||
+
|
||||
+ /* core_pos = core_id + (cluster_id * FVP_MAX_CPUS_PER_CLUSTER) */
|
||||
+ mov x4, #CORSTONE1000_MAX_CPUS_PER_CLUSTER
|
||||
+ madd x0, x3, x4, x1
|
||||
+
|
||||
+ ret
|
||||
+endfunc plat_arm_calc_core_pos
|
||||
+#endif
|
||||
+
|
||||
/* --------------------------------------------------------------------
|
||||
* void plat_secondary_cold_boot_setup (void);
|
||||
*
|
||||
diff --git a/plat/arm/board/corstone1000/common/corstone1000_plat.c b/plat/arm/board/corstone1000/common/corstone1000_plat.c
|
||||
index e388c82f311b..d34e80b29bb0 100644
|
||||
--- a/plat/arm/board/corstone1000/common/corstone1000_plat.c
|
||||
+++ b/plat/arm/board/corstone1000/common/corstone1000_plat.c
|
||||
@@ -26,6 +26,10 @@ const mmap_region_t plat_arm_mmap[] = {
|
||||
ARM_MAP_NS_DRAM1,
|
||||
CORSTONE1000_MAP_DEVICE,
|
||||
CORSTONE1000_EXTERNAL_FLASH,
|
||||
+#ifdef CORSTONE1000_CORTEX_A320
|
||||
+ ARM_MAP_ETHOS_U85,
|
||||
+ ARM_MAP_NONSECURE_SRAM,
|
||||
+#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
diff --git a/plat/arm/board/corstone1000/common/corstone1000_pm.c b/plat/arm/board/corstone1000/common/corstone1000_pm.c
|
||||
index ac808873b9e7..a87697e97f11 100644
|
||||
--- a/plat/arm/board/corstone1000/common/corstone1000_pm.c
|
||||
+++ b/plat/arm/board/corstone1000/common/corstone1000_pm.c
|
||||
@@ -8,7 +8,11 @@
|
||||
#include <plat/arm/common/plat_arm.h>
|
||||
#include <platform_def.h>
|
||||
#include <plat/common/platform.h>
|
||||
+#ifdef CORSTONE1000_CORTEX_A320
|
||||
+#include <drivers/arm/gicv3.h>
|
||||
+#else
|
||||
#include <drivers/arm/gicv2.h>
|
||||
+#endif
|
||||
/*******************************************************************************
|
||||
* Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
|
||||
* platform layer will take care of registering the handlers with PSCI.
|
||||
@@ -24,7 +28,11 @@ static void corstone1000_system_reset(void)
|
||||
* Disable GIC CPU interface to prevent pending interrupt
|
||||
* from waking up the AP from WFI.
|
||||
*/
|
||||
+#ifdef CORSTONE1000_CORTEX_A320
|
||||
+ gicv3_cpuif_disable(plat_my_core_pos());
|
||||
+#else
|
||||
gicv2_cpuif_disable();
|
||||
+#endif
|
||||
|
||||
/* Flush and invalidate data cache */
|
||||
dcsw_op_all(DCCISW);
|
||||
diff --git a/plat/arm/board/corstone1000/common/include/platform_def.h b/plat/arm/board/corstone1000/common/include/platform_def.h
|
||||
index 200383475c80..ffb1e2dec0e1 100644
|
||||
--- a/plat/arm/board/corstone1000/common/include/platform_def.h
|
||||
+++ b/plat/arm/board/corstone1000/common/include/platform_def.h
|
||||
@@ -112,12 +112,19 @@
|
||||
#define ARM_SHARED_RAM_SIZE (SZ_8K) /* 8 KB */
|
||||
#define ARM_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE
|
||||
|
||||
+#ifdef CORSTONE1000_CORTEX_A320
|
||||
+#define TOTAL_SECURE_SRAM_SIZE (SZ_4M)
|
||||
+#define TOTAL_NONSECURE_SRAM_SIZE (SZ_4M)
|
||||
+#define PLAT_ARM_TRUSTED_SRAM_SIZE (TOTAL_SECURE_SRAM_SIZE - \
|
||||
+ ARM_SHARED_RAM_SIZE)
|
||||
+#else
|
||||
/* The remaining Trusted SRAM is used to load the BL images */
|
||||
#define TOTAL_SRAM_SIZE (SZ_4M) /* 4 MB */
|
||||
|
||||
|
||||
#define PLAT_ARM_TRUSTED_SRAM_SIZE (TOTAL_SRAM_SIZE - \
|
||||
ARM_SHARED_RAM_SIZE)
|
||||
+#endif
|
||||
|
||||
#define PLAT_ARM_MAX_BL2_SIZE (180 * SZ_1K) /* 180 KB */
|
||||
|
||||
@@ -208,8 +215,13 @@
|
||||
#define MAX_IO_BLOCK_DEVICES 1
|
||||
|
||||
/* GIC related constants */
|
||||
+#ifdef CORSTONE1000_CORTEX_A320
|
||||
+#define PLAT_ARM_GICD_BASE 0x1C000000
|
||||
+#define PLAT_ARM_GICR_BASE 0x1C040000
|
||||
+#else
|
||||
#define PLAT_ARM_GICD_BASE 0x1C010000
|
||||
#define PLAT_ARM_GICC_BASE 0x1C02F000
|
||||
+#endif
|
||||
|
||||
/* MHUv2 Secure Channel receiver and sender */
|
||||
#define PLAT_SDK700_MHU0_SEND 0x1B800000
|
||||
@@ -334,6 +346,20 @@
|
||||
CORSTONE1000_DEVICE_BASE, \
|
||||
CORSTONE1000_DEVICE_SIZE, \
|
||||
MT_DEVICE | MT_RW | MT_SECURE)
|
||||
+#ifdef CORSTONE1000_CORTEX_A320
|
||||
+#define ARM_ETHOS_U85_BASE UL(0x1A050000)
|
||||
+#define ARM_ETHOS_U85_SIZE UL(0x4000)
|
||||
+#define ARM_MAP_ETHOS_U85 MAP_REGION_FLAT( \
|
||||
+ ARM_ETHOS_U85_BASE, \
|
||||
+ ARM_ETHOS_U85_SIZE, \
|
||||
+ MT_DEVICE | MT_RW | MT_NS)
|
||||
+
|
||||
+#define ARM_NONSECURE_SRAM_BASE (ARM_TRUSTED_SRAM_BASE + TOTAL_SECURE_SRAM_SIZE)
|
||||
+#define ARM_MAP_NONSECURE_SRAM MAP_REGION_FLAT( \
|
||||
+ ARM_NONSECURE_SRAM_BASE, \
|
||||
+ TOTAL_NONSECURE_SRAM_SIZE, \
|
||||
+ MT_MEMORY | MT_RW | MT_NS)
|
||||
+#endif
|
||||
|
||||
#define ARM_IRQ_SEC_PHY_TIMER 29
|
||||
|
||||
diff --git a/plat/arm/board/corstone1000/platform.mk b/plat/arm/board/corstone1000/platform.mk
|
||||
index 65be9c1f5ad7..fe3e94865fca 100644
|
||||
--- a/plat/arm/board/corstone1000/platform.mk
|
||||
+++ b/plat/arm/board/corstone1000/platform.mk
|
||||
@@ -9,7 +9,14 @@ ifeq ($(filter ${TARGET_PLATFORM}, fpga fvp),)
|
||||
$(error TARGET_PLATFORM must be fpga or fvp)
|
||||
endif
|
||||
|
||||
+ifdef CORSTONE1000_CORTEX_A320
|
||||
+CORSTONE1000_CPU_LIBS +=lib/cpus/aarch64/cortex_a320.S
|
||||
+$(eval $(call add_define,CORSTONE1000_CORTEX_A320))
|
||||
+GIC_ENABLE_V4_EXTN := 1
|
||||
+GICV3_SUPPORT_GIC600 := 1
|
||||
+else
|
||||
CORSTONE1000_CPU_LIBS +=lib/cpus/aarch64/cortex_a35.S
|
||||
+endif
|
||||
|
||||
PLAT_INCLUDES := -Iplat/arm/board/corstone1000/common/include \
|
||||
-Iplat/arm/board/corstone1000/include \
|
||||
@@ -43,7 +50,11 @@ $(eval $(call add_define,CORSTONE1000_FVP_MULTICORE))
|
||||
endif
|
||||
endif
|
||||
|
||||
+ifdef CORSTONE1000_CORTEX_A320
|
||||
+USE_GIC_DRIVER := 3
|
||||
+else
|
||||
USE_GIC_DRIVER := 2
|
||||
+endif
|
||||
|
||||
BL2_SOURCES += plat/arm/board/corstone1000/common/corstone1000_security.c \
|
||||
plat/arm/board/corstone1000/common/corstone1000_err.c \
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
From f05f9b75f60697be84217d0957e8864d58ee71bb Mon Sep 17 00:00:00 2001
|
||||
From: Oscar Belshaw <Oscar.Belshaw@arm.com>
|
||||
Date: Tue, 11 Aug 2026 15:40:27 +0100
|
||||
Subject: [PATCH] plat: corstone1000: align BL config mapping
|
||||
|
||||
ARM_FW_CONFIG_BASE starts after the meminfo_t structure and is therefore
|
||||
not page aligned. Translation table mappings require page-aligned base
|
||||
addresses and sizes.
|
||||
|
||||
Map the enclosing page from ARM_SHARED_RAM_BASE while retaining
|
||||
ARM_FW_CONFIG_BASE as the configuration load address. This prevents
|
||||
mmap_add_region_check() from returning -EINVAL during BL2 initialization.
|
||||
|
||||
Only the mapping is widened: the reserved meminfo_t space at the start of
|
||||
shared RAM and the firmware configuration load addresses are unchanged.
|
||||
|
||||
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/54909]
|
||||
|
||||
Signed-off-by: Oscar Belshaw <Oscar.Belshaw@arm.com>
|
||||
|
||||
---
|
||||
.../arm/board/corstone1000/common/include/platform_def.h | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/plat/arm/board/corstone1000/common/include/platform_def.h b/plat/arm/board/corstone1000/common/include/platform_def.h
|
||||
index 382426869b..6673010d2f 100644
|
||||
--- a/plat/arm/board/corstone1000/common/include/platform_def.h
|
||||
+++ b/plat/arm/board/corstone1000/common/include/platform_def.h
|
||||
@@ -334,11 +334,11 @@
|
||||
* Map the region for the optional device tree configuration with read and
|
||||
* write permissions
|
||||
*/
|
||||
-#define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT( \
|
||||
- ARM_FW_CONFIG_BASE, \
|
||||
- (ARM_FW_CONFIG_LIMIT \
|
||||
- - ARM_FW_CONFIG_BASE), \
|
||||
- MT_MEMORY | MT_RW | MT_SECURE)
|
||||
+#define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT( \
|
||||
+ ARM_SHARED_RAM_BASE, \
|
||||
+ (ARM_FW_CONFIG_LIMIT \
|
||||
+ - ARM_SHARED_RAM_BASE), \
|
||||
+ MT_MEMORY | MT_RW | MT_SECURE)
|
||||
|
||||
#define CORSTONE1000_DEVICE_BASE (0x1A000000)
|
||||
#define CORSTONE1000_DEVICE_SIZE (0x26000000)
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
From a9801643d9d4d3f24960c5f24d5f5c3fd4889cc1 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Chapman <alecha05@e142473.arm.com>
|
||||
Date: Tue, 3 Mar 2026 17:00:58 +0000
|
||||
Subject: [PATCH] feat(corestone-1000): make mutlicore support platform generic
|
||||
|
||||
To improve portability, testing coverage, and future platform enablement.
|
||||
|
||||
- Replace FVP-only multicore checks with platform-generic checks.
|
||||
- Add the corresponding TF-M patch to the Corstone-1000 recipe.
|
||||
|
||||
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/49092]
|
||||
Signed-off-by: Alex Chapman <alex.chapman@arm.com>
|
||||
---
|
||||
plat/arm/board/corstone1000/common/corstone1000_helpers.S | 4 ++--
|
||||
plat/arm/board/corstone1000/common/corstone1000_pm.c | 6 +++---
|
||||
plat/arm/board/corstone1000/common/include/platform_def.h | 4 ++--
|
||||
plat/arm/board/corstone1000/platform.mk | 6 ++----
|
||||
4 files changed, 9 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/plat/arm/board/corstone1000/common/corstone1000_helpers.S b/plat/arm/board/corstone1000/common/corstone1000_helpers.S
|
||||
index 665dbc61a..d41df4ebe 100644
|
||||
--- a/plat/arm/board/corstone1000/common/corstone1000_helpers.S
|
||||
+++ b/plat/arm/board/corstone1000/common/corstone1000_helpers.S
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2021-2025 Arm Limited and Contributors. All rights reserved.
|
||||
+ * Copyright (c) 2021-2026 Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
@@ -54,7 +54,7 @@ endfunc plat_arm_calc_core_pos
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func plat_secondary_cold_boot_setup
|
||||
-#if defined(CORSTONE1000_FVP_MULTICORE)
|
||||
+#if defined(CORSTONE1000_MULTICORE)
|
||||
|
||||
/* Calculate the address of our hold entry */
|
||||
bl plat_my_core_pos
|
||||
diff --git a/plat/arm/board/corstone1000/common/corstone1000_pm.c b/plat/arm/board/corstone1000/common/corstone1000_pm.c
|
||||
index a87697e97..2c7a2c67b 100644
|
||||
--- a/plat/arm/board/corstone1000/common/corstone1000_pm.c
|
||||
+++ b/plat/arm/board/corstone1000/common/corstone1000_pm.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
|
||||
+ * Copyright (c) 2021-2026, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
@@ -41,7 +41,7 @@ static void corstone1000_system_reset(void)
|
||||
*watchdog_ctrl_reg = SECURE_WATCHDOG_MASK_ENABLE;
|
||||
}
|
||||
|
||||
-#if defined(CORSTONE1000_FVP_MULTICORE)
|
||||
+#if defined(CORSTONE1000_MULTICORE)
|
||||
int corstone1000_validate_ns_entrypoint(uintptr_t entrypoint)
|
||||
{
|
||||
/*
|
||||
@@ -77,7 +77,7 @@ void corstone1000_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
||||
#endif
|
||||
|
||||
plat_psci_ops_t plat_arm_psci_pm_ops = {
|
||||
-#if defined(CORSTONE1000_FVP_MULTICORE)
|
||||
+#if defined(CORSTONE1000_MULTICORE)
|
||||
.pwr_domain_on = corstone1000_pwr_domain_on,
|
||||
.pwr_domain_on_finish = corstone1000_pwr_domain_on_finish,
|
||||
.validate_ns_entrypoint = corstone1000_validate_ns_entrypoint,
|
||||
diff --git a/plat/arm/board/corstone1000/common/include/platform_def.h b/plat/arm/board/corstone1000/common/include/platform_def.h
|
||||
index ffb1e2dec..4682b8b5d 100644
|
||||
--- a/plat/arm/board/corstone1000/common/include/platform_def.h
|
||||
+++ b/plat/arm/board/corstone1000/common/include/platform_def.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
|
||||
+ * Copyright (c) 2021-2026, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
@@ -266,7 +266,7 @@
|
||||
|
||||
#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
|
||||
|
||||
-#if defined(CORSTONE1000_FVP_MULTICORE)
|
||||
+#if defined(CORSTONE1000_MULTICORE)
|
||||
/* The secondary core entrypoint address points to bl31_warm_entrypoint
|
||||
* and the address size is 8 bytes */
|
||||
#define CORSTONE1000_SECONDARY_CORE_ENTRYPOINT_ADDRESS_SIZE UL(0x8)
|
||||
diff --git a/plat/arm/board/corstone1000/platform.mk b/plat/arm/board/corstone1000/platform.mk
|
||||
index fe3e94865..dee40f3b3 100644
|
||||
--- a/plat/arm/board/corstone1000/platform.mk
|
||||
+++ b/plat/arm/board/corstone1000/platform.mk
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
-# Copyright (c) 2021-2025 Arm Limited and Contributors. All rights reserved.
|
||||
+# Copyright (c) 2021-2026 Arm Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
@@ -44,10 +44,8 @@ $(eval $(call add_define,CORSTONE1000_WITH_BL32))
|
||||
endif
|
||||
|
||||
ENABLE_MULTICORE := 0
|
||||
-ifneq ($(filter ${TARGET_PLATFORM}, fvp),)
|
||||
ifeq (${ENABLE_MULTICORE},1)
|
||||
-$(eval $(call add_define,CORSTONE1000_FVP_MULTICORE))
|
||||
-endif
|
||||
+$(eval $(call add_define,CORSTONE1000_MULTICORE))
|
||||
endif
|
||||
|
||||
ifdef CORSTONE1000_CORTEX_A320
|
||||
--
|
||||
2.43.0
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
From: Oscar Belshaw <Oscar.Belshaw@arm.com>
|
||||
Subject: [PATCH] fix(corstone1000): delay early GPT access
|
||||
|
||||
TF-A 2.15 initializes GPT before MMU setup in the common BL2 boot path.
|
||||
On Corstone1000 MPS3, early memory-mapped flash reads have returned an
|
||||
invalid MBR signature, preventing boot. A 25 ms delay before GPT access
|
||||
has allowed boot and reset tests to complete on the tested configurations.
|
||||
|
||||
Override the weak plat_arm_io_setup hook for Corstone1000 BL2 with
|
||||
RESET_TO_BL2 and ARM_GPT_SUPPORT enabled. Preserve arm_io_setup and its
|
||||
error handling, then wait 25 ms before returning to common GPT setup.
|
||||
|
||||
The common system-counter enable occurs in arm_bl31_platform_setup, and
|
||||
common generic_delay_timer_init occurs after GPT initialization. Enable
|
||||
the system counter here with the same CNTCR configuration used by BL31,
|
||||
then initialize the delay driver before calling mdelay. Driver initialization
|
||||
alone does not enable the hardware counter. Do not reset the counter value;
|
||||
leave the later common initialization unchanged.
|
||||
|
||||
Use the same hook for FPGA, A35 FVP and A320 FVP. Keep the common GPT-before-
|
||||
MMU ordering and reset handling unchanged, without diagnostic flash reads
|
||||
or console output.
|
||||
|
||||
This is a timing workaround, not a hardware readiness check. The underlying
|
||||
cause and any required hardware settling interval remain under investigation;
|
||||
25 ms is the tested delay, not a documented minimum platform requirement.
|
||||
|
||||
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/54910]
|
||||
Signed-off-by: Oscar Belshaw <Oscar.Belshaw@arm.com>
|
||||
---
|
||||
.../corstone1000/common/corstone1000_plat.c | 28 ++++++++++++++++++++
|
||||
1 file changed, 28 insertions(+)
|
||||
|
||||
diff --git a/plat/arm/board/corstone1000/common/corstone1000_plat.c b/plat/arm/board/corstone1000/common/corstone1000_plat.c
|
||||
index d34e80b..1c51145 100644
|
||||
--- a/plat/arm/board/corstone1000/common/corstone1000_plat.c
|
||||
+++ b/plat/arm/board/corstone1000/common/corstone1000_plat.c
|
||||
@@ -6,10 +6,14 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
+#include <arch.h>
|
||||
#include <common/bl_common.h>
|
||||
+#include <common/debug.h>
|
||||
|
||||
+#include <drivers/delay_timer.h>
|
||||
#include <drivers/generic_delay_timer.h>
|
||||
#include <drivers/io/io_storage.h>
|
||||
+#include <lib/mmio.h>
|
||||
#include <plat/common/platform.h>
|
||||
#include <plat/arm/common/arm_fconf_getter.h>
|
||||
#include <plat/arm/common/arm_fconf_io_storage.h>
|
||||
@@ -33,6 +37,30 @@ const mmap_region_t plat_arm_mmap[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
+#define CS1K_GPT_DELAY 25U /* GPT initialization delay in milliseconds. */
|
||||
+
|
||||
+#if defined(IMAGE_BL2) && RESET_TO_BL2 && ARM_GPT_SUPPORT
|
||||
+void plat_arm_io_setup(void)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ err = arm_io_setup();
|
||||
+ if (err < 0) {
|
||||
+ panic();
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Allow time before early memory-mapped flash reads. This is a
|
||||
+ * workaround for invalid GPT reads observed on MPS3; the underlying
|
||||
+ * readiness requirement still needs investigation.
|
||||
+ */
|
||||
+ mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
|
||||
+ CNTCR_FCREQ(0U) | CNTCR_EN);
|
||||
+ generic_delay_timer_init();
|
||||
+ mdelay(CS1K_GPT_DELAY);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static void set_fip_image_source(void)
|
||||
{
|
||||
const struct plat_io_policy *policy;
|
||||
-157
@@ -1,157 +0,0 @@
|
||||
From ff4bb404474a3310654827c36c4ac882eb0344b5 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Safwat <michael.safwat@arm.com>
|
||||
Date: Tue, 26 Aug 2025 11:20:01 +0000
|
||||
Subject: [PATCH] plat: corstone1000: Add Cortex-A320 support
|
||||
|
||||
Switch platform to GICv3 (GIC-600) for Corstone-1000 with Cortex-A320
|
||||
depending on CORSTONE1000_CORTEX_A320:
|
||||
- Define GICD and GICR bases.
|
||||
- Update the platform sources to include the GIC-V3 files.
|
||||
|
||||
Move the NVM offset to prevent overlap with the TFTF firmware,
|
||||
which starts at 0x80000000 (TFTF_BASE).
|
||||
|
||||
Introduce a new skip file tests_to_skip_cortex_a320 to be used when building
|
||||
TF-A-Tests with CORSTONE1000_CORTEX_A320=1. This ensures that tests which
|
||||
are not supported or cause traps on Corstone-1000 with Cortex-A320 are
|
||||
consistently skipped during execution.
|
||||
|
||||
Skipped entries:
|
||||
CPU extensions/AMUv1 suspend/resume
|
||||
CPU extensions/Use trace buffer control Registers
|
||||
|
||||
Signed-off-by: Michael Safwat <michael.safwat@arm.com>
|
||||
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
|
||||
Upstream-Status: Submitted (https://review.trustedfirmware.org/c/TF-A/tf-a-tests/+/42352)
|
||||
---
|
||||
plat/arm/corstone1000/corstone1000_def.h | 12 ++++++++++-
|
||||
plat/arm/corstone1000/include/platform_def.h | 11 +++++-----
|
||||
plat/arm/corstone1000/platform.mk | 20 ++++++++++++++++++
|
||||
.../tests_to_skip_cortex_a320.txt | 21 +++++++++++++++++++
|
||||
4 files changed, 58 insertions(+), 6 deletions(-)
|
||||
create mode 100644 plat/arm/corstone1000/tests_to_skip_cortex_a320.txt
|
||||
|
||||
diff --git a/plat/arm/corstone1000/corstone1000_def.h b/plat/arm/corstone1000/corstone1000_def.h
|
||||
index 3e6f036acc9a..c4fa9a3b5f68 100644
|
||||
--- a/plat/arm/corstone1000/corstone1000_def.h
|
||||
+++ b/plat/arm/corstone1000/corstone1000_def.h
|
||||
@@ -26,13 +26,23 @@
|
||||
* GIC-400 & interrupt handling related constants
|
||||
******************************************************************************/
|
||||
/* GIC memory map */
|
||||
+#ifdef CORSTONE1000_CORTEX_A320
|
||||
+#define GICD_BASE 0x1C000000
|
||||
+#define GICR_BASE 0x1C040000
|
||||
+
|
||||
+/* GIC re-distributor doesn't exits on gic-600, but we still need to
|
||||
+ * provide GICC_BASE as the gic driver needs it
|
||||
+ */
|
||||
+#define GICC_BASE 0x0
|
||||
+#else
|
||||
+
|
||||
#define GICD_BASE 0x1C010000
|
||||
#define GICC_BASE 0x1C02F000
|
||||
/* GIC re-distributor doesn't exits on gic-400, but we still need to
|
||||
* provide GICR_BASE as the gic driver needs it
|
||||
*/
|
||||
#define GICR_BASE 0x0
|
||||
-
|
||||
+#endif
|
||||
/*******************************************************************************
|
||||
* PL011 related constants
|
||||
******************************************************************************/
|
||||
diff --git a/plat/arm/corstone1000/include/platform_def.h b/plat/arm/corstone1000/include/platform_def.h
|
||||
index 91f4cda19a90..2a9e5c4c35bb 100644
|
||||
--- a/plat/arm/corstone1000/include/platform_def.h
|
||||
+++ b/plat/arm/corstone1000/include/platform_def.h
|
||||
@@ -98,12 +98,13 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
- * USE 0x200000 DRAM offset to store TFTF data
|
||||
- *
|
||||
- * Please note that this won't be suitable for all test scenarios and
|
||||
- * for this reason some tests will be disabled in this configuration.
|
||||
+ * When USE_NVM = 0, TFTF_NVM_OFFSET marks the DRAM region
|
||||
+ * used as NVM. This region must not overlap the memory where
|
||||
+ * the TFTF image is loaded. The load address is given by
|
||||
+ * the TFTF_BASE macro. Set TFTF_NVM_OFFSET to leave enough
|
||||
+ * space for the TFTF image.
|
||||
*/
|
||||
-#define TFTF_NVM_OFFSET 0x40000
|
||||
+#define TFTF_NVM_OFFSET 0x80000
|
||||
#define TFTF_NVM_SIZE (128 * SZ_1M) /* 128 MB */
|
||||
|
||||
/*******************************************************************************
|
||||
diff --git a/plat/arm/corstone1000/platform.mk b/plat/arm/corstone1000/platform.mk
|
||||
index cd7a19162bcf..dfdd27abd897 100644
|
||||
--- a/plat/arm/corstone1000/platform.mk
|
||||
+++ b/plat/arm/corstone1000/platform.mk
|
||||
@@ -6,6 +6,16 @@
|
||||
|
||||
PLAT_INCLUDES := -Iplat/arm/corstone1000/include/
|
||||
|
||||
+CORSTONE1000_CORTEX_A320 := 0
|
||||
+ifeq (${CORSTONE1000_CORTEX_A320},1)
|
||||
+PLAT_SOURCES := drivers/arm/timer/private_timer.c \
|
||||
+ drivers/arm/timer/system_timer.c \
|
||||
+ plat/arm/corstone1000/plat_helpers.S \
|
||||
+ plat/arm/corstone1000/corstone1000_pwr_state.c \
|
||||
+ plat/arm/corstone1000/corstone1000_topology.c \
|
||||
+ plat/arm/corstone1000/corstone1000_mem_prot.c \
|
||||
+ plat/arm/corstone1000/plat_setup.c
|
||||
+else
|
||||
PLAT_SOURCES := drivers/arm/timer/private_timer.c \
|
||||
drivers/arm/timer/system_timer.c \
|
||||
plat/arm/corstone1000/plat_helpers.S \
|
||||
@@ -13,6 +23,7 @@ PLAT_SOURCES := drivers/arm/timer/private_timer.c \
|
||||
plat/arm/corstone1000/corstone1000_topology.c \
|
||||
plat/arm/corstone1000/corstone1000_mem_prot.c \
|
||||
plat/arm/corstone1000/plat_setup.c
|
||||
+endif
|
||||
|
||||
PLAT_SUPPORTS_NS_RESET := 1
|
||||
|
||||
@@ -21,6 +32,15 @@ $(eval $(call assert_boolean,PLAT_SUPPORTS_NS_RESET))
|
||||
$(eval $(call add_define,TFTF_DEFINES,PLAT_SUPPORTS_NS_RESET))
|
||||
|
||||
FIRMWARE_UPDATE := 0
|
||||
+
|
||||
+ifeq ($(CORSTONE1000_CORTEX_A320),1)
|
||||
+$(eval $(call add_define,TFTF_DEFINES,CORSTONE1000_CORTEX_A320))
|
||||
+endif
|
||||
+
|
||||
+ifeq (${CORSTONE1000_CORTEX_A320},1)
|
||||
+PLAT_TESTS_SKIP_LIST := plat/arm/corstone1000/tests_to_skip_cortex_a320.txt
|
||||
+else
|
||||
PLAT_TESTS_SKIP_LIST := plat/arm/corstone1000/tests_to_skip.txt
|
||||
+endif
|
||||
|
||||
include plat/arm/common/arm_common.mk
|
||||
diff --git a/plat/arm/corstone1000/tests_to_skip_cortex_a320.txt b/plat/arm/corstone1000/tests_to_skip_cortex_a320.txt
|
||||
new file mode 100644
|
||||
index 000000000000..87b9241daba0
|
||||
--- /dev/null
|
||||
+++ b/plat/arm/corstone1000/tests_to_skip_cortex_a320.txt
|
||||
@@ -0,0 +1,21 @@
|
||||
+Realm payload tests
|
||||
+Realm payload boot
|
||||
+Realm payload multi CPU request
|
||||
+Realm payload Delegate and Undelegate
|
||||
+Multi CPU Realm payload Delegate and Undelegate
|
||||
+Testing delegation fails
|
||||
+Realm testing with SPM tests
|
||||
+PSCI System Suspend Validation
|
||||
+PSCI STAT/Stats test cases after system suspend
|
||||
+IRQ support in TSP/Resume preempted STD SMC after PSCI SYSTEM SUSPEND
|
||||
+PSCI SYSTEM SUSPEND stress tests
|
||||
+Timer framework Validation/Verify the timer interrupt generation
|
||||
+CPU Hotplug/CPU hotplug
|
||||
+PSCI CPU Suspend
|
||||
+PSCI CPU Suspend in OSI mode
|
||||
+PSCI STAT/for valid composite state CPU suspend
|
||||
+FF-A Setup and Discovery/FF-A RXTX remap unmapped region success
|
||||
+FF-A Memory Sharing/Normal World VM retrieve request into SPMC
|
||||
+Boot requirement tests
|
||||
+CPU extensions/AMUv1 suspend/resume
|
||||
+CPU extensions/Use trace buffer control Registers
|
||||
@@ -9,8 +9,3 @@ EXTRA_OEMAKE:append:cortexa320 = " \
|
||||
CORSTONE1000_CORTEX_A320=1 \
|
||||
"
|
||||
TFTF_MODE:corstone1000 = "release"
|
||||
|
||||
FILESEXTRAPATHS:prepend:corstone1000 := "${THISDIR}/files/corstone1000/tf-a-tests:"
|
||||
SRC_URI:append:corstone1000 = " \
|
||||
file://0001-plat-corstone1000-Add-Cortex-A320-support.patch \
|
||||
"
|
||||
@@ -5,13 +5,12 @@ COMPATIBLE_MACHINE = "(corstone1000)"
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/files/corstone1000:"
|
||||
SRC_URI:append = " \
|
||||
file://0001-Fix-FF-A-version-in-SPMC-manifest.patch \
|
||||
file://0002-plat-corstone1000-add-Cortex-A320-support.patch \
|
||||
file://0003-feat-corestone-1000-make-mutlicore-support-platform-.patch \
|
||||
file://0002-plat-corstone1000-align-BL-config-region.patch \
|
||||
file://0003-plat-corstone1000-delay-early-GPT-access.patch \
|
||||
"
|
||||
|
||||
TFA_DEBUG = "1"
|
||||
TFA_UBOOT ?= "1"
|
||||
TFA_MBEDTLS = "1"
|
||||
TFA_BUILD_TARGET = "bl2 bl31 fip"
|
||||
|
||||
# Enabling Secure-EL1 Payload Dispatcher (SPD)
|
||||
|
||||
@@ -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', ' AND 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', ' AND 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"
|
||||
+8
-5
@@ -1,8 +1,8 @@
|
||||
From 4274b94aa0af175e31b8883ec6f2113133608e24 Mon Sep 17 00:00:00 2001
|
||||
From 4cfcc1af5dd1a9aaadcf42a46d5dc769977b4fed Mon Sep 17 00:00:00 2001
|
||||
From: Ali Can Ozaslan <ali.oezaslan@arm.com>
|
||||
Date: Wed, 15 May 2024 12:12:15 +0000
|
||||
Subject: [PATCH] CC312: alignment of cc312 differences between fvp and mps3
|
||||
corstone1000 platforms
|
||||
Subject: [PATCH 01/14] CC312: alignment of cc312 differences between fvp and
|
||||
mps3 corstone1000 platforms
|
||||
|
||||
Configures CC312 mps3 model same as predefined cc312 FVP
|
||||
configuration while keeping debug ports closed.
|
||||
@@ -15,10 +15,10 @@ Upstream-Status: Inappropriate [Requires an aligment cc3xx with mps3 hw and fvp
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c
|
||||
index 31e4332bed64..4b08c02526d3 100644
|
||||
index b43e86988a41..af8181ca815a 100644
|
||||
--- a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c
|
||||
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c
|
||||
@@ -207,6 +207,9 @@ CClibRetCode_t CC_LibInit(CCRndContext_t *rndContext_ptr, CCRndWorkBuff_t *rndW
|
||||
@@ -209,6 +209,9 @@ CClibRetCode_t CC_LibInit(CCRndContext_t *rndContext_ptr, CCRndWorkBuff_t *rndW
|
||||
goto InitErr2;
|
||||
}
|
||||
|
||||
@@ -28,3 +28,6 @@ index 31e4332bed64..4b08c02526d3 100644
|
||||
/* turn off the DFA since Cerberus doen't support it */
|
||||
reg = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
|
||||
CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_FORCE_DFA_ENABLE, reg, 0x0);
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
From f3400c6527e6d0c073215694e19734a6268a6bc9 Mon Sep 17 00:00:00 2001
|
||||
From: Ali Can Ozaslan <ali.oezaslan@arm.com>
|
||||
Date: Wed, 24 Jan 2024 16:10:08 +0000
|
||||
Subject: [PATCH] arm/trusted-firmware-m: disable address warnings into an
|
||||
error
|
||||
|
||||
Signed-off-by: Emekcan Aras <emekcan.aras@arm.com>
|
||||
Signed-off-by: Ali Can Ozaslan <ali.oezaslan@arm.com>
|
||||
Upstream-Status: Inappropriate
|
||||
---
|
||||
toolchain_GNUARM.cmake | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/toolchain_GNUARM.cmake b/toolchain_GNUARM.cmake
|
||||
index 56a220ba8471..af80a2746676 100644
|
||||
--- a/toolchain_GNUARM.cmake
|
||||
+++ b/toolchain_GNUARM.cmake
|
||||
@@ -113,6 +113,7 @@ add_compile_options(
|
||||
-Wno-format
|
||||
-Wno-return-type
|
||||
-Wno-unused-but-set-variable
|
||||
+ -Wno-error=address
|
||||
-c
|
||||
-fdata-sections
|
||||
-ffunction-sections
|
||||
+7
-4
@@ -1,7 +1,7 @@
|
||||
From dae5f3d1ec85e29f44d3f19bec2312607751ec22 Mon Sep 17 00:00:00 2001
|
||||
From a02970f522567169fa1851ab1b5431793e365cb0 Mon Sep 17 00:00:00 2001
|
||||
From: Devaraj Ranganna <devaraj.ranganna@arm.com>
|
||||
Date: Thu, 18 Sep 2025 22:07:38 +0100
|
||||
Subject: [PATCH] Corstone-1000: Enable different DRBG configurations
|
||||
Subject: [PATCH 02/14] Corstone-1000: Enable different DRBG configurations
|
||||
|
||||
The following DRBG configurations are enabled:
|
||||
|
||||
@@ -18,10 +18,10 @@ Signed-off-by: Devaraj Ranganna <devaraj.ranganna@arm.com>
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/cc3xx_config.h b/platform/ext/target/arm/corstone1000/cc3xx_config.h
|
||||
index ac034b17982a..e3f78439861f 100644
|
||||
index 68707f3a2194..8c53cace937c 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/cc3xx_config.h
|
||||
+++ b/platform/ext/target/arm/corstone1000/cc3xx_config.h
|
||||
@@ -90,6 +90,13 @@
|
||||
@@ -100,6 +100,13 @@
|
||||
#error "cc3xx_config: RNG config must select a single DRBG"
|
||||
#endif /* CC3XX_CONFIG_RNG_DRBG_HMAC + CC3XX_CONFIG_RNG_DRBG_CTR + CC3XX_CONFIG_RNG_DRBG_HASH */
|
||||
|
||||
@@ -35,3 +35,6 @@ index ac034b17982a..e3f78439861f 100644
|
||||
/* Whether an external TRNG should be used in place of the standard CC3XX TRNG */
|
||||
/* #define CC3XX_CONFIG_RNG_EXTERNAL_TRNG */
|
||||
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-449
@@ -1,449 +0,0 @@
|
||||
From 9ed08f26cafc2c6e5bf1d5cc04f91ca17d94a1bd Mon Sep 17 00:00:00 2001
|
||||
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
|
||||
Date: Wed, 13 Aug 2025 14:02:57 +0000
|
||||
Subject: [PATCH] Platform: CS1000: Remove unused BL1 files
|
||||
|
||||
These files are not referenced anywhere so removed them to prevent
|
||||
confusion.
|
||||
|
||||
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
|
||||
Upstream-Status: Backport [9a7bdf9ef595196e1e518a27d3c79079aedb5bda]
|
||||
---
|
||||
.../arm/corstone1000/bl1/CMakeLists.txt | 345 ------------------
|
||||
.../arm/corstone1000/bl1/bl1_security_cnt.c | 75 ----
|
||||
2 files changed, 420 deletions(-)
|
||||
delete mode 100644 platform/ext/target/arm/corstone1000/bl1/CMakeLists.txt
|
||||
delete mode 100644 platform/ext/target/arm/corstone1000/bl1/bl1_security_cnt.c
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bl1/CMakeLists.txt b/platform/ext/target/arm/corstone1000/bl1/CMakeLists.txt
|
||||
deleted file mode 100644
|
||||
index d85b0611dd42..000000000000
|
||||
--- a/platform/ext/target/arm/corstone1000/bl1/CMakeLists.txt
|
||||
+++ /dev/null
|
||||
@@ -1,345 +0,0 @@
|
||||
-#-------------------------------------------------------------------------------
|
||||
-# Copyright (c) 2020-2024, Arm Limited. All rights reserved.
|
||||
-#
|
||||
-# SPDX-License-Identifier: BSD-3-Clause
|
||||
-#
|
||||
-#-------------------------------------------------------------------------------
|
||||
-
|
||||
-cmake_minimum_required(VERSION 3.15)
|
||||
-cmake_policy(SET CMP0079 NEW)
|
||||
-
|
||||
-project("BL1 Bootloader" VERSION 0.0.1 LANGUAGES C ASM)
|
||||
-
|
||||
-# BL1 only loads the BL2 image, image number always equals 1
|
||||
-set(BL1_IMAGE_NUMBER 1)
|
||||
-
|
||||
-# Version of BL2 image
|
||||
-set(BL2_IMAGE_VERSION "0.1.0")
|
||||
-
|
||||
-add_executable(bl1)
|
||||
-
|
||||
-set_target_properties(bl1
|
||||
- PROPERTIES
|
||||
- SUFFIX ".axf"
|
||||
- RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
-)
|
||||
-
|
||||
-target_link_options(bl1
|
||||
- PRIVATE
|
||||
- $<$<C_COMPILER_ID:GNU>:-Wl,-Map=${CMAKE_BINARY_DIR}/bin/bl1.map>
|
||||
-)
|
||||
-
|
||||
-add_convert_to_bin_target(bl1)
|
||||
-
|
||||
-# bl2_crypto reused as it is, but it pulls the MCUBOOT_IMAGE_NUMBER=${MCUBOOT_IMAGE_NUMBER}
|
||||
-# configuration, where image number is 3. (Coming from BL2 build). To not to collide with BL1's
|
||||
-# build where image number is 1 mbedcrypto library is separated from the build of other source
|
||||
-# files.
|
||||
-target_link_libraries(bl1
|
||||
- PRIVATE
|
||||
- bl1_main
|
||||
- bl2_crypto
|
||||
- cmsis_stack_override
|
||||
- cmsis
|
||||
-)
|
||||
-
|
||||
-# add_convert_to_bin_target(bl1) requires at least one source file added to bl1. This sources will
|
||||
-# be built with wrong image number macro (value coming from BL2 config), so the start-up files
|
||||
-# added here, as those not use this image number macro.
|
||||
-target_sources(bl1
|
||||
- PRIVATE
|
||||
- $<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}/../Device/Source/startup_corstone1000.c>
|
||||
-)
|
||||
-
|
||||
-# Needed for the GCC startup files
|
||||
-target_include_directories(bl1
|
||||
- PRIVATE
|
||||
- ${CMAKE_SOURCE_DIR}/platform/include
|
||||
- ../Device/Include
|
||||
-)
|
||||
-
|
||||
-# target_add_scatter_file(bl1) cannot be used as it would add the platform_region_defs dependency
|
||||
-# to bl1, again pulling the image number property matching with BL2 build, so scatter setup done
|
||||
-# here by hand.
|
||||
-target_link_options(bl1
|
||||
- PRIVATE
|
||||
- -T $<TARGET_OBJECTS:bl1_scatter>
|
||||
-)
|
||||
-
|
||||
-add_library(bl1_scatter OBJECT)
|
||||
-
|
||||
-add_dependencies(bl1
|
||||
- bl1_scatter
|
||||
- )
|
||||
-
|
||||
-target_sources(bl1_scatter
|
||||
- PRIVATE
|
||||
- ../Device/Source/gcc/corstone1000_bl1.ld
|
||||
-)
|
||||
-
|
||||
-set_source_files_properties(../Device/Source/gcc/corstone1000_bl1.ld
|
||||
- PROPERTIES
|
||||
- LANGUAGE C
|
||||
-)
|
||||
-
|
||||
-target_compile_options(bl1_scatter
|
||||
- PRIVATE
|
||||
- -E
|
||||
- -P
|
||||
- -xc
|
||||
-)
|
||||
-
|
||||
-target_compile_definitions(bl1_scatter
|
||||
- PRIVATE
|
||||
- MCUBOOT_IMAGE_NUMBER=${BL1_IMAGE_NUMBER}
|
||||
- BL1
|
||||
-)
|
||||
-
|
||||
-target_include_directories(bl1_scatter
|
||||
- PRIVATE
|
||||
- ../partition
|
||||
-)
|
||||
-
|
||||
-# Library to spearate build from bl2_mbedcrypto configurations
|
||||
-add_library(bl1_main STATIC)
|
||||
-
|
||||
-target_compile_definitions(bl1_main
|
||||
- PRIVATE
|
||||
- MCUBOOT_IMAGE_NUMBER=${BL1_IMAGE_NUMBER}
|
||||
- BL1
|
||||
- BL2
|
||||
- $<$<BOOL:${PLATFORM_IS_FVP}>:PLATFORM_IS_FVP>
|
||||
-)
|
||||
-
|
||||
-# Configurations based on bl2/CMakeLists.txt
|
||||
-
|
||||
-# Many files are reused form TF-M's bl2 directory
|
||||
-set(BL2_SOURCE ${CMAKE_SOURCE_DIR}/bl2)
|
||||
-
|
||||
-target_sources(bl1_main
|
||||
- PRIVATE
|
||||
- ${BL2_SOURCE}/src/flash_map.c
|
||||
- ./provisioning.c
|
||||
-)
|
||||
-
|
||||
-target_include_directories(bl1_main
|
||||
- PRIVATE
|
||||
- $<BUILD_INTERFACE:${BL2_SOURCE}/include>
|
||||
-)
|
||||
-
|
||||
-# Include path needed for mbedcrypto headers
|
||||
-target_include_directories(bl1_main
|
||||
- PRIVATE
|
||||
- $<BUILD_INTERFACE:${MBEDCRYPTO_PATH}/include>
|
||||
-)
|
||||
-
|
||||
-# Configurations based on bl2/ext/mcuboot/CMakeLists.txt
|
||||
-target_link_libraries(bl1_main
|
||||
- PRIVATE
|
||||
- mcuboot_config
|
||||
- bl2_crypto_config
|
||||
-)
|
||||
-
|
||||
-target_include_directories(bl1_main
|
||||
- PRIVATE
|
||||
- $<BUILD_INTERFACE:${BL2_SOURCE}/ext/mcuboot/include>
|
||||
-)
|
||||
-
|
||||
-target_sources(bl1_main
|
||||
- PRIVATE
|
||||
- ${BL2_SOURCE}/ext/mcuboot/bl2_main.c
|
||||
- ${BL2_SOURCE}/ext/mcuboot/keys.c
|
||||
- ${BL2_SOURCE}/ext/mcuboot/flash_map_legacy.c
|
||||
-)
|
||||
-
|
||||
-# Configurations based on ${MCUBOOT_PATH}/boot/bootutil/CMakeLists.txt
|
||||
-# add_subdirectory("${MCUBOOT_PATH}/boot/bootutil" bootutil) cannot work as we want to define different hal
|
||||
-# functions compared to BL2
|
||||
-target_sources(bl1_main
|
||||
- PRIVATE
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/loader.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/bootutil_misc.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/bootutil_public.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/image_validate.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/image_rsa.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/tlv.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/boot_record.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/swap_scratch.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/swap_move.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/swap_misc.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/encrypted.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/fault_injection_hardening.c
|
||||
- ${MCUBOOT_PATH}/boot/bootutil/src/fault_injection_hardening_delay_rng_mbedtls.c
|
||||
-)
|
||||
-
|
||||
-target_include_directories(bl1_main
|
||||
- PRIVATE
|
||||
- $<BUILD_INTERFACE:${MCUBOOT_PATH}/boot/bootutil/include>
|
||||
- $<BUILD_INTERFACE:${MCUBOOT_PATH}/boot/bootutil/src>
|
||||
- $<BUILD_INTERFACE:${MCUBOOT_PATH}/boot>
|
||||
-)
|
||||
-
|
||||
-# Configurations based on platform/CMakeLists.txt
|
||||
-target_include_directories(bl1_main
|
||||
- PRIVATE
|
||||
- $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/platform/include>
|
||||
- $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/platform/ext/driver>
|
||||
- $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/platform/ext/common>
|
||||
- $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/platform/ext>
|
||||
- $<$<BOOL:${CRYPTO_HW_ACCELERATOR}>:${CMAKE_SOURCE_DIR}/platform/ext/accelerator/interface>
|
||||
-)
|
||||
-
|
||||
-target_sources(bl1_main
|
||||
- PRIVATE
|
||||
- $<$<BOOL:${PLATFORM_DEFAULT_UART_STDOUT}>:${CMAKE_SOURCE_DIR}/platform/ext/common/uart_stdout.c>
|
||||
- $<$<BOOL:${PLATFORM_DEFAULT_NV_COUNTERS}>:${CMAKE_SOURCE_DIR}/platform/ext/common/template/nv_counters.c>
|
||||
- $<$<OR:$<BOOL:${PLATFORM_DEFAULT_NV_COUNTERS}>,$<BOOL:${PLATFORM_DEFAULT_OTP}>>:${CMAKE_SOURCE_DIR}/platform/ext/common/template/flash_otp_nv_counters_backend.c>
|
||||
- $<$<BOOL:${PLATFORM_DEFAULT_OTP}>:${CMAKE_SOURCE_DIR}/platform/ext/common/template/otp_flash.c>
|
||||
-)
|
||||
-
|
||||
-target_link_libraries(bl1_main
|
||||
- PRIVATE
|
||||
- bl2_hal
|
||||
- cmsis
|
||||
-)
|
||||
-
|
||||
-target_compile_definitions(bl1_main
|
||||
- PRIVATE
|
||||
- MCUBOOT_${MCUBOOT_UPGRADE_STRATEGY}
|
||||
- $<$<BOOL:${SYMMETRIC_INITIAL_ATTESTATION}>:SYMMETRIC_INITIAL_ATTESTATION>
|
||||
- $<$<BOOL:${PLATFORM_DEFAULT_NV_COUNTERS}>:PLATFORM_DEFAULT_NV_COUNTERS>
|
||||
- $<$<BOOL:${MCUBOOT_HW_KEY}>:MCUBOOT_HW_KEY>
|
||||
- MCUBOOT_FIH_PROFILE_${MCUBOOT_FIH_PROFILE}
|
||||
- $<$<BOOL:${PLATFORM_DEFAULT_NV_COUNTERS}>:PLATFORM_DEFAULT_NV_COUNTERS>
|
||||
- $<$<BOOL:${PLATFORM_DEFAULT_OTP}>:PLATFORM_DEFAULT_OTP>
|
||||
- $<$<BOOL:${OTP_NV_COUNTERS_RAM_EMULATION}>:OTP_NV_COUNTERS_RAM_EMULATION=1>
|
||||
- $<$<BOOL:${TFM_DUMMY_PROVISIONING}>:TFM_DUMMY_PROVISIONING>
|
||||
- $<$<BOOL:${PLATFORM_DEFAULT_OTP_WRITEABLE}>:OTP_WRITEABLE>
|
||||
-)
|
||||
-
|
||||
-# Configurations based on cc312 cmake files
|
||||
-target_compile_definitions(bl1_main
|
||||
- PRIVATE
|
||||
- $<$<BOOL:${CRYPTO_HW_ACCELERATOR_OTP_STATE}>:CRYPTO_HW_ACCELERATOR_OTP_${CRYPTO_HW_ACCELERATOR_OTP_STATE}>
|
||||
- $<$<BOOL:${CRYPTO_HW_ACCELERATOR}>:CRYPTO_HW_ACCELERATOR>
|
||||
- $<$<BOOL:${ENABLE_FWU_AGENT_DEBUG_LOGS}>:ENABLE_FWU_AGENT_DEBUG_LOGS>
|
||||
-)
|
||||
-
|
||||
-target_include_directories(bl1_main
|
||||
- PRIVATE
|
||||
- $<$<BOOL:${CRYPTO_HW_ACCELERATOR}>:${CMAKE_SOURCE_DIR}/platform/ext/accelerator/cc312>
|
||||
- $<$<BOOL:${CRYPTO_HW_ACCELERATOR}>:${CMAKE_SOURCE_DIR}/lib/ext/cryptocell-312-runtime/shared/include/mbedtls>
|
||||
- $<$<BOOL:${CRYPTO_HW_ACCELERATOR}>:${CMAKE_SOURCE_DIR}/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x>
|
||||
- ../soft_crc
|
||||
-)
|
||||
-
|
||||
-# Configurations based on platform level cmake files
|
||||
-target_sources(bl1_main
|
||||
- PRIVATE
|
||||
- ../CMSIS_Driver/Driver_Flash.c
|
||||
- ../CMSIS_Driver/Driver_USART.c
|
||||
- ../Device/Source/device_definition.c
|
||||
- ../Device/Source/system_core_init.c
|
||||
- ../Native_Driver/firewall.c
|
||||
- ../Native_Driver/uart_pl011_drv.c
|
||||
- ../fw_update_agent/fwu_agent.c
|
||||
- ../soft_crc/soft_crc.c
|
||||
- ../Native_Driver/arm_watchdog_drv.c
|
||||
- ../Native_Driver/watchdog.c
|
||||
- bl1_boot_hal.c
|
||||
- bl1_flash_map.c
|
||||
- bl1_security_cnt.c
|
||||
- flash_map_extended.c
|
||||
- bl1_rotpk.c
|
||||
-)
|
||||
-
|
||||
-if (PLATFORM_IS_FVP)
|
||||
-target_sources(bl1_main
|
||||
- PRIVATE
|
||||
- ${PLATFORM_DIR}/ext/target/arm/drivers/flash/strata/spi_strataflashj3_flash_lib.c
|
||||
- ${PLATFORM_DIR}/ext/target/arm/drivers/flash/cfi/cfi_drv.c
|
||||
-)
|
||||
-else()
|
||||
-target_sources(bl1_main
|
||||
- PRIVATE
|
||||
- ${PLATFORM_DIR}/ext/target/arm/drivers/qspi/xilinx_pg153_axi/xilinx_pg153_axi_qspi_controller_drv.c
|
||||
- ${PLATFORM_DIR}/ext/target/arm/drivers/flash/n25q256a/spi_n25q256a_flash_lib.c
|
||||
- ${PLATFORM_DIR}/ext/target/arm/drivers/flash/sst26vf064b/spi_sst26vf064b_flash_lib.c
|
||||
-)
|
||||
-endif()
|
||||
-
|
||||
-target_include_directories(bl1_main
|
||||
- PRIVATE
|
||||
- ../partition
|
||||
- ../Device/Include
|
||||
- ../.
|
||||
- ../CMSIS_Driver/Config
|
||||
- ../Device/Config
|
||||
- ../Native_Driver
|
||||
- ../fw_update_agent
|
||||
- ${PLATFORM_DIR}/ext/target/arm/drivers/flash/common
|
||||
- ${PLATFORM_DIR}/ext/target/arm/drivers/flash/cfi
|
||||
- ${PLATFORM_DIR}/ext/target/arm/drivers/flash/strata
|
||||
- ${PLATFORM_DIR}/ext/target/arm/drivers/qspi/xilinx_pg153_axi
|
||||
- ${PLATFORM_DIR}/ext/target/arm/drivers/flash/n25q256a
|
||||
- ${PLATFORM_DIR}/ext/target/arm/drivers/flash/sst26vf064b
|
||||
-
|
||||
-)
|
||||
-
|
||||
-############################### SIGNING BL2 image ##################################
|
||||
-
|
||||
-find_package(Python3)
|
||||
-
|
||||
-set(FLASH_AREA_NUM 8)
|
||||
-configure_file(signing_layout.c.in ${CMAKE_CURRENT_BINARY_DIR}/signing_layout.c @ONLY)
|
||||
-add_library(signing_layout_for_bl2 OBJECT ${CMAKE_CURRENT_BINARY_DIR}/signing_layout.c)
|
||||
-
|
||||
-target_compile_options(signing_layout_for_bl2
|
||||
- PRIVATE
|
||||
- $<$<C_COMPILER_ID:GNU>:-E\;-xc>
|
||||
- $<$<C_COMPILER_ID:ARMClang>:-E\;-xc>
|
||||
- $<$<C_COMPILER_ID:IAR>:--preprocess=ns\;$<TARGET_OBJECTS:signing_layout_s>>
|
||||
-)
|
||||
-target_compile_definitions(signing_layout_for_bl2
|
||||
- PRIVATE
|
||||
- MCUBOOT_IMAGE_NUMBER=${BL1_IMAGE_NUMBER}
|
||||
- BL1
|
||||
-)
|
||||
-
|
||||
-target_include_directories(signing_layout_for_bl2
|
||||
- PRIVATE
|
||||
- ../partition
|
||||
-)
|
||||
-
|
||||
-if (CONFIG_TFM_BOOT_STORE_MEASUREMENTS AND CONFIG_TFM_BOOT_STORE_ENCODED_MEASUREMENTS)
|
||||
- set(MCUBOOT_MEASURED_BOOT ON)
|
||||
-endif()
|
||||
-
|
||||
-add_custom_target(bl2_signed_bin
|
||||
- ALL
|
||||
- SOURCES bl2_signed.bin
|
||||
-)
|
||||
-add_custom_command(OUTPUT bl2_signed.bin
|
||||
- DEPENDS $<TARGET_FILE_DIR:bl2>/bl2.bin
|
||||
- DEPENDS bl2_bin signing_layout_for_bl2
|
||||
- WORKING_DIRECTORY ${MCUBOOT_PATH}/scripts
|
||||
-
|
||||
- #Sign secure binary image with provided secret key
|
||||
- COMMAND ${Python3_EXECUTABLE} ${BL2_SOURCE}/ext/mcuboot/scripts/wrapper/wrapper.py
|
||||
- -v ${BL2_IMAGE_VERSION}
|
||||
- --layout $<TARGET_OBJECTS:signing_layout_for_bl2>
|
||||
- -k ${MCUBOOT_KEY_S}
|
||||
- --public-key-format $<IF:$<BOOL:${MCUBOOT_HW_KEY}>,full,hash>
|
||||
- --align 1
|
||||
- --pad
|
||||
- --pad-header
|
||||
- -H 0x400
|
||||
- -s ${MCUBOOT_SECURITY_COUNTER_S}
|
||||
- -d \"\(0,${MCUBOOT_S_IMAGE_MIN_VER}\)\"
|
||||
- $<$<STREQUAL:${MCUBOOT_UPGRADE_STRATEGY},OVERWRITE_ONLY>:--overwrite-only>
|
||||
- $<$<BOOL:${MCUBOOT_ENC_IMAGES}>:-E${MCUBOOT_KEY_ENC}>
|
||||
- $<$<BOOL:${MCUBOOT_MEASURED_BOOT}>:--measured-boot-record>
|
||||
- $<TARGET_FILE_DIR:bl2>/bl2.bin
|
||||
- ${CMAKE_CURRENT_BINARY_DIR}/bl2_signed.bin
|
||||
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/bl2_signed.bin $<TARGET_FILE_DIR:bl2>
|
||||
-)
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bl1/bl1_security_cnt.c b/platform/ext/target/arm/corstone1000/bl1/bl1_security_cnt.c
|
||||
deleted file mode 100644
|
||||
index 32c1481cca11..000000000000
|
||||
--- a/platform/ext/target/arm/corstone1000/bl1/bl1_security_cnt.c
|
||||
+++ /dev/null
|
||||
@@ -1,75 +0,0 @@
|
||||
-/*
|
||||
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
|
||||
- *
|
||||
- * SPDX-License-Identifier: BSD-3-Clause
|
||||
- *
|
||||
- */
|
||||
-
|
||||
-#include "bootutil/security_cnt.h"
|
||||
-#include "tfm_plat_nv_counters.h"
|
||||
-#include "tfm_plat_defs.h"
|
||||
-#include "bootutil/fault_injection_hardening.h"
|
||||
-#include <stdint.h>
|
||||
-#include "tfm_plat_provisioning.h"
|
||||
-#include "fwu_agent.h"
|
||||
-
|
||||
-fih_ret boot_nv_security_counter_init(void)
|
||||
-{
|
||||
- FIH_DECLARE(fih_rc, FIH_FAILURE);
|
||||
-
|
||||
- fih_rc = fih_ret_encode_zero_equality(tfm_plat_init_nv_counter());
|
||||
-
|
||||
- FIH_RET(fih_rc);
|
||||
-}
|
||||
-
|
||||
-fih_ret boot_nv_security_counter_get(uint32_t image_id, fih_int *security_cnt)
|
||||
-{
|
||||
- FIH_DECLARE(fih_rc, FIH_FAILURE);
|
||||
- uint32_t security_cnt_soft;
|
||||
-
|
||||
- /* Check if it's a null-pointer. */
|
||||
- if (!security_cnt) {
|
||||
- FIH_RET(FIH_FAILURE);
|
||||
- }
|
||||
-
|
||||
- if (image_id != 0) {
|
||||
- FIH_RET(FIH_FAILURE);
|
||||
- }
|
||||
-
|
||||
- fih_rc = fih_ret_encode_zero_equality(
|
||||
- tfm_plat_read_nv_counter(PLAT_NV_COUNTER_BL1_0,
|
||||
- sizeof(security_cnt_soft),
|
||||
- (uint8_t *)&security_cnt_soft));
|
||||
- *security_cnt = fih_int_encode(security_cnt_soft);
|
||||
-
|
||||
- FIH_RET(fih_rc);
|
||||
-}
|
||||
-
|
||||
-int32_t boot_nv_security_counter_update(uint32_t image_id,
|
||||
- uint32_t img_security_cnt)
|
||||
-{
|
||||
- enum tfm_plat_err_t err;
|
||||
- enum fwu_agent_error_t fwu_err;
|
||||
-
|
||||
- if (image_id != 0) {
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- if (tfm_plat_provisioning_is_required()) {
|
||||
-
|
||||
- err = tfm_plat_set_nv_counter(PLAT_NV_COUNTER_BL1_0, img_security_cnt);
|
||||
- if (err != TFM_PLAT_ERR_SUCCESS) {
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- } else {
|
||||
-
|
||||
- fwu_err = fwu_stage_nv_counter(FWU_BL2_NV_COUNTER, img_security_cnt);
|
||||
- if (fwu_err != FWU_AGENT_SUCCESS) {
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
From 1d7ab426f171516c15ce8e5223541c62c91ec596 Mon Sep 17 00:00:00 2001
|
||||
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
|
||||
Date: Wed, 13 Aug 2025 14:31:53 +0000
|
||||
Subject: [PATCH] Platform: Corstone1000: Fix BL1 compiler switch and
|
||||
regression test failure
|
||||
|
||||
Introduce a dedicated preprocessor definition (`BL1_BUILD`) added only to the
|
||||
platform_bl1_1 target. This ensures that #if BL1 checks are evaluated correctly
|
||||
based on the actual build configuration.
|
||||
|
||||
Signed-off-by: Michael Safwat <michael.safwat@arm.com>
|
||||
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
|
||||
Upstream-Status: Backport [f25649cc0de56f360069c6128670f7533ba5e14d]
|
||||
---
|
||||
platform/ext/target/arm/corstone1000/CMakeLists.txt | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/CMakeLists.txt b/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
index ff7cf7330a07..66dfb2399503 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
+++ b/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
@@ -146,6 +146,7 @@ target_sources(platform_s
|
||||
rse_comms_permissions_hal.c
|
||||
mem_check_v6m_v7m_hal.c
|
||||
${PLATFORM_DIR}/ext/common/mem_check_v6m_v7m.c
|
||||
+ platform.c
|
||||
)
|
||||
|
||||
if (PLATFORM_IS_FVP)
|
||||
@@ -215,6 +216,13 @@ target_compile_definitions(platform_bl1_1
|
||||
$<$<BOOL:${CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING}>:CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING>
|
||||
MBEDTLS_CONFIG_FILE="${CMAKE_SOURCE_DIR}/lib/ext/mbedcrypto/mbedcrypto_config/tfm_mbedcrypto_config_default.h"
|
||||
MBEDTLS_PSA_CRYPTO_CONFIG_FILE="${CMAKE_SOURCE_DIR}/lib/ext/mbedcrypto/mbedcrypto_config/crypto_config_default.h"
|
||||
+
|
||||
+ # This definition is only added to the bl1_main target. There are
|
||||
+ # files that are shared between the BL1 and TFM_S targets. This flag
|
||||
+ # can be used if the BL1 target needs different implementation than
|
||||
+ # the TFM_S target.
|
||||
+ BL1_BUILD
|
||||
+
|
||||
)
|
||||
|
||||
target_include_directories(platform_bl1_1_interface
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
From d8141d0d445bc5117b21dc684410b115e82d5568 Mon Sep 17 00:00:00 2001
|
||||
From: Devaraj Ranganna <devaraj.ranganna@arm.com>
|
||||
Date: Mon, 22 Sep 2025 12:59:43 +0100
|
||||
Subject: [PATCH 03/14] bl2: corstone-1000: secure debug waiting in CM LCS
|
||||
|
||||
Currently, when the device is in Secure Enable (SE) LCS state,
|
||||
setting the dcu_en register causes a CC-312 reset. Because CC-312 and
|
||||
the device share a power domain, this effectively resets the device.
|
||||
|
||||
Temporarily perform the secure-debug handshake while the device
|
||||
remains in the CM provisioned state. The long-term solution is to
|
||||
complete the secure-debug handshake, reset the device, and apply
|
||||
dcu_en during BL2.
|
||||
|
||||
Upstream-Status: Inappropriate [Need to be redesigned]
|
||||
Signed-off-by: Devaraj Ranganna <devaraj.ranganna@arm.com>
|
||||
Signed-off-by: Ahmed Gomaa <Ahmed.Gomaa@arm.com>
|
||||
---
|
||||
.../arm/corstone1000/bl2/boot_hal_bl2.c | 46 ++++++++++++-------
|
||||
1 file changed, 30 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c b/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c
|
||||
index 9bc0f20e1045..d034efe59f5d 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c
|
||||
@@ -187,7 +187,7 @@ int32_t boot_platform_post_init(void)
|
||||
int32_t result;
|
||||
enum tfm_plat_err_t plat_err;
|
||||
#ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
|
||||
- bool provisioning_required;
|
||||
+ /* bool provisioning_required; */
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTO_HW_ACCELERATOR
|
||||
@@ -204,26 +204,40 @@ int32_t boot_platform_post_init(void)
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
|
||||
- plat_err = tfm_plat_provisioning_is_required(&provisioning_required);
|
||||
+ /*
|
||||
+ * TODO: Currently, when the device is in Secure Enable (SE) LCS state,
|
||||
+ * setting `dcu_en` register causes CC-312 reset, which effectively resets
|
||||
+ * the device as they are both on the same power domain. Therefore,
|
||||
+ * temporarily perform the secure-debug handshake while the device remains
|
||||
+ * in the CM provisioned state.
|
||||
+ *
|
||||
+ * The long-term solution is to complete the secure-debug handshake, reset
|
||||
+ * the device, and apply `dcu_en` during BL2.
|
||||
+ *
|
||||
+ * TF-M 2.3 splits the provisioning check into an error return and a Boolean
|
||||
+ * output value. Keep the complete gate commented while this workaround is
|
||||
+ * required:
|
||||
+ *
|
||||
+ * plat_err = tfm_plat_provisioning_is_required(&provisioning_required);
|
||||
+ * if (plat_err != TFM_PLAT_ERR_SUCCESS) {
|
||||
+ * BOOT_LOG_ERR("Platform provisioning required check failed");
|
||||
+ * FIH_PANIC;
|
||||
+ * }
|
||||
+ *
|
||||
+ * if (!provisioning_required) {
|
||||
+ */
|
||||
+
|
||||
+ plat_err = tfm_plat_otp_read(SECURE_DEBUG_ROTPK_ID, 32, secure_debug_rotpk);
|
||||
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
|
||||
- BOOT_LOG_ERR("Platform provisioning required check failed");
|
||||
- FIH_PANIC;
|
||||
+ return plat_err;
|
||||
}
|
||||
|
||||
- if (!provisioning_required) {
|
||||
-
|
||||
- plat_err = tfm_plat_otp_read(SECURE_DEBUG_ROTPK_ID, 32, secure_debug_rotpk);
|
||||
- if (plat_err != TFM_PLAT_ERR_SUCCESS) {
|
||||
- return plat_err;
|
||||
- }
|
||||
-
|
||||
#ifndef PSA_ADAC_AS_TFM_RUNTIME_SERVICE
|
||||
- result = tfm_to_psa_adac_corstone1000_secure_debug(secure_debug_rotpk, 32);
|
||||
- BOOT_LOG_INF("%s: Corstone-1000 Secure Debug is a %s.\r\n", __func__,
|
||||
- (result == 0) ? "success" : "failure");
|
||||
+ result = tfm_to_psa_adac_corstone1000_secure_debug(secure_debug_rotpk, 32);
|
||||
+ BOOT_LOG_INF("%s: Corstone-1000 Secure Debug is a %s.\r\n", __func__,
|
||||
+ (result == 0) ? "success" : "failure");
|
||||
#endif /* PSA_ADAC_AS_TFM_RUNTIME_SERVICE */
|
||||
-
|
||||
- }
|
||||
+ /* } */
|
||||
#endif /* PLATFORM_PSA_ADAC_SECURE_DEBUG */
|
||||
|
||||
return 0;
|
||||
--
|
||||
2.39.5
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
From 8a30545506d8a7f58f0ad30130593e0f78e8b219 Mon Sep 17 00:00:00 2001
|
||||
From: Jon Mason <jon.mason@arm.com>
|
||||
Date: Mon, 23 Feb 2026 11:53:38 -0500
|
||||
Subject: [PATCH 04/14] Build: fix remaining GCC v14.2 AES type error
|
||||
|
||||
GCC v14.2 diagnoses the incompatible pointer type used when passing
|
||||
the ECB key buffer to bl1_key_to_cc3xx_key(). Cast the uint32_t key
|
||||
buffer to the uint8_t pointer type expected by the helper.
|
||||
|
||||
Upstream-Status: Inappropriate [GCC v14.2 compatibility workaround]
|
||||
|
||||
Signed-off-by: Jon Mason <jon.mason@arm.com>
|
||||
Signed-off-by: Ahmed Gomaa <Ahmed.Gomaa@arm.com>
|
||||
---
|
||||
platform/ext/target/arm/corstone1000/bl1/cc312_rom_crypto.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bl1/cc312_rom_crypto.c b/platform/ext/target/arm/corstone1000/bl1/cc312_rom_crypto.c
|
||||
index 6bc89fe1155c..2008e9641b49 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/bl1/cc312_rom_crypto.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/bl1/cc312_rom_crypto.c
|
||||
@@ -338,7 +338,7 @@ static int32_t aes_256_ecb_encrypt(enum tfm_bl1_key_id_t key_id,
|
||||
return -1;
|
||||
}
|
||||
|
||||
- rc = bl1_key_to_cc3xx_key(key_id, &cc3xx_key_type, key_buf, sizeof(key_buf));
|
||||
+ rc = bl1_key_to_cc3xx_key(key_id, &cc3xx_key_type, (uint8_t *)key_buf, sizeof(key_buf));
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
From fdfbb3b82f62a2d4575a983ebaee14a67130d316 Mon Sep 17 00:00:00 2001
|
||||
From: Ali Can Ozaslan <ali.oezaslan@arm.com>
|
||||
Date: Tue, 15 Oct 2024 12:50:16 +0000
|
||||
Subject: [PATCH] Platform: Corstone1000: Enable FWU partition
|
||||
|
||||
Enable firmware update partition for Corstone-1000 platform.
|
||||
|
||||
Increase the necessary flags to enable firmware update partition.
|
||||
Set TFM_FWU_BOOTLOADER_LIB to use Corstone-1000 specific bootloader
|
||||
configuration. Fix linker issues caused by enablement.
|
||||
|
||||
Upstream-Status: Backport [0107057d1411ec68e374fbd0ddc0e12abd5754ec]
|
||||
Signed-off-by: Ali Can Ozaslan <ali.oezaslan@arm.com>
|
||||
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
|
||||
---
|
||||
platform/ext/target/arm/corstone1000/config.cmake | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/config.cmake b/platform/ext/target/arm/corstone1000/config.cmake
|
||||
index 7a88542a32fc..6d9cb1fea750 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/config.cmake
|
||||
+++ b/platform/ext/target/arm/corstone1000/config.cmake
|
||||
@@ -55,6 +55,10 @@ set(TFM_PARTITION_CRYPTO ON CACHE BOOL "Enable Cryp
|
||||
set(TFM_PARTITION_INITIAL_ATTESTATION ON CACHE BOOL "Enable Initial Attestation partition")
|
||||
set(TFM_PARTITION_INTERNAL_TRUSTED_STORAGE ON CACHE BOOL "Enable Internal Trusted Storage partition")
|
||||
|
||||
+set(TFM_PARTITION_FIRMWARE_UPDATE ON CACHE BOOL "Enable firmware update partition")
|
||||
+set(PLATFORM_HAS_FIRMWARE_UPDATE_SUPPORT ON CACHE BOOL "Wheter the platform has firmware update support")
|
||||
+set(MCUBOOT_DATA_SHARING ON CACHE BOOL "Enable Data Sharing")
|
||||
+set(TFM_FWU_BOOTLOADER_LIB "${CMAKE_CURRENT_LIST_DIR}/bootloader/mcuboot" CACHE STRING "Bootloader configure file for Firmware Update partition")
|
||||
|
||||
if (${CMAKE_BUILD_TYPE} STREQUAL Debug OR ${CMAKE_BUILD_TYPE} STREQUAL RelWithDebInfo)
|
||||
set(ENABLE_FWU_AGENT_DEBUG_LOGS TRUE CACHE BOOL "Enable Firmware update agent debug logs.")
|
||||
+11
-7
@@ -1,20 +1,21 @@
|
||||
From c579565c25937ae9455efe9cc3fbcace84c3e580 Mon Sep 17 00:00:00 2001
|
||||
From 9192041a3e6eec6b9e63dbdbe7fa49581aafa5b2 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Mon, 29 Dec 2025 11:28:47 +0000
|
||||
Subject: [PATCH] plat: cs1k: Removed unused variables
|
||||
Subject: [PATCH 05/14] plat: cs1k: Removed unused variables
|
||||
|
||||
Change-Id: I0dd3ff834c47c58dc833586c74791deca679a3ab
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport
|
||||
Signed-off-by: Ahmed Gomaa <Ahmed.Gomaa@arm.com>
|
||||
---
|
||||
.../arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c | 4 ----
|
||||
1 file changed, 4 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
index cff80b755..83b0bd27d 100644
|
||||
index deb14a9215b5..ed4a9f6804c9 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
@@ -1511,7 +1511,6 @@ static psa_status_t fwu_accept_image(struct fwu_metadata *metadata,
|
||||
@@ -1614,7 +1614,6 @@ static psa_status_t fwu_accept_image(struct fwu_metadata *metadata,
|
||||
uint8_t number)
|
||||
{
|
||||
uint8_t current_state;
|
||||
@@ -22,7 +23,7 @@ index cff80b755..83b0bd27d 100644
|
||||
uint32_t active_bank_index;
|
||||
uint32_t fwu_image_index;
|
||||
psa_status_t ret;
|
||||
@@ -1848,7 +1847,6 @@ static psa_status_t fwu_update_metadata(const psa_fwu_component_t *candidates, u
|
||||
@@ -2160,7 +2159,6 @@ static psa_status_t fwu_update_metadata(const psa_fwu_component_t *candidates, u
|
||||
{
|
||||
int ret;
|
||||
uint32_t active_index;
|
||||
@@ -30,8 +31,8 @@ index cff80b755..83b0bd27d 100644
|
||||
uint32_t previous_active_index;
|
||||
uint8_t fwu_image_index;
|
||||
|
||||
@@ -1864,10 +1862,8 @@ static psa_status_t fwu_update_metadata(const psa_fwu_component_t *candidates, u
|
||||
|
||||
@@ -2175,10 +2173,8 @@ static psa_status_t fwu_update_metadata(const psa_fwu_component_t *candidates, u
|
||||
active_index = _metadata.active_index;
|
||||
if (active_index == BANK_0) {
|
||||
previous_active_index = BANK_1;
|
||||
- bank_offset = BANK_1_PARTITION_OFFSET;
|
||||
@@ -41,3 +42,6 @@ index cff80b755..83b0bd27d 100644
|
||||
} else {
|
||||
FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index);
|
||||
ret = PSA_ERROR_DATA_INVALID;
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-5067
File diff suppressed because it is too large.
Load diff
+7
-3
@@ -1,7 +1,8 @@
|
||||
From ca0d50fc1abbfe165941dc0bd674bb117f236f87 Mon Sep 17 00:00:00 2001
|
||||
From 81813176251a37995390338914f309d8ca72549d Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Mon, 30 Mar 2026 14:06:20 +0100
|
||||
Subject: [PATCH] lib: gpt: Show intent of GUIDs in unittests more clearly
|
||||
Subject: [PATCH 06/14] lib: gpt: Show intent of GUIDs in unittests more
|
||||
clearly
|
||||
|
||||
The standard EFI_GUID macros used in the unittests do not convey the
|
||||
full meaning of the why that particular GUID is used. The new macros can
|
||||
@@ -16,7 +17,7 @@ Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-fi
|
||||
1 file changed, 31 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
index bd161ec74..32dfb8fb2 100644
|
||||
index bd161ec7445b..32dfb8fb2757 100644
|
||||
--- a/lib/gpt/unittests/gpt/test_gpt.c
|
||||
+++ b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
@@ -69,6 +69,13 @@
|
||||
@@ -214,3 +215,6 @@ index bd161ec74..32dfb8fb2 100644
|
||||
TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_read_by_type(&test_type, 0, &entry));
|
||||
|
||||
/* Now, have a non-empty GPT but search for a type that won't exist */
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
From 78231f27db0bbc747902b603bf279dce1707a3cc Mon Sep 17 00:00:00 2001
|
||||
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
|
||||
Date: Mon, 16 Jun 2025 14:44:39 +0100
|
||||
Subject: [PATCH] Platform: Corstone1000: Increase buffer sizes
|
||||
|
||||
Increase PSA_MAX_ASSET_SIZE and CRYPTO_IOVEC_BUFFER_SIZE
|
||||
to accommodate large size EFI variables set by new U-Boot version.
|
||||
|
||||
This change is required to pass ACS tests related to Set/Get
|
||||
EFI variables. These ACS tests started failing after introducing new
|
||||
version of U-Boot, Trusted-Services and Trusted-Firmware-M while
|
||||
implementing PSA FWU support.
|
||||
|
||||
Upstream-Status: Backport [bd80dee733e792eadfd2115f4bfa6bad748e5ce5]
|
||||
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
|
||||
---
|
||||
platform/ext/target/arm/corstone1000/config_tfm_target.h | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/config_tfm_target.h b/platform/ext/target/arm/corstone1000/config_tfm_target.h
|
||||
index 4920f67084d4..cf13712a1806 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/config_tfm_target.h
|
||||
+++ b/platform/ext/target/arm/corstone1000/config_tfm_target.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
|
||||
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
@@ -27,13 +27,13 @@
|
||||
#define ITS_MAX_ASSET_SIZE 2048
|
||||
|
||||
/* The maximum asset size to be stored in the Protected Storage */
|
||||
-#define PS_MAX_ASSET_SIZE 2592
|
||||
+#define PS_MAX_ASSET_SIZE 3500
|
||||
|
||||
/* This is needed to be able to process the EFI variables during PS writes. */
|
||||
#define CRYPTO_ENGINE_BUF_SIZE 0x5000
|
||||
|
||||
/* This is also has to be increased to fit the EFI variables into the iovecs. */
|
||||
-#define CRYPTO_IOVEC_BUFFER_SIZE 6000
|
||||
+#define CRYPTO_IOVEC_BUFFER_SIZE 7200
|
||||
|
||||
/* The Mailbox partition is used as an NS Agent so its stack size is used to
|
||||
* determine the PSP and PSPLIM during the SFN backend initialization. It has to
|
||||
+6
-3
@@ -1,7 +1,7 @@
|
||||
From 229313778bae6ca16d6e3b25437c8e87eddf3084 Mon Sep 17 00:00:00 2001
|
||||
From 02ce1958e127f0bec9bfb86cd3a3e406644e1fce Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Mon, 30 Mar 2026 14:35:45 +0100
|
||||
Subject: [PATCH] lib: gpt: Provide macro identifying free space
|
||||
Subject: [PATCH 07/14] lib: gpt: Provide macro identifying free space
|
||||
|
||||
In the unit tests, it is often required to know where free space on the
|
||||
mocked disk is in order to determine where it is valid to create or move
|
||||
@@ -15,7 +15,7 @@ Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-fi
|
||||
1 file changed, 23 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
index 32dfb8fb2..0ae660336 100644
|
||||
index 32dfb8fb2757..0ae6603368e8 100644
|
||||
--- a/lib/gpt/unittests/gpt/test_gpt.c
|
||||
+++ b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
@@ -58,6 +58,7 @@
|
||||
@@ -155,3 +155,6 @@ index 32dfb8fb2..0ae660336 100644
|
||||
|
||||
/* Fourth, start in the backup header area */
|
||||
TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_move(
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
From 291b717c9ff6124dd132602e84f75f320adbfda1 Mon Sep 17 00:00:00 2001
|
||||
From: Yogesh Wani <yogesh.wani@arm.com>
|
||||
Date: Wed, 30 Apr 2025 14:39:37 +0100
|
||||
Subject: [PATCH] Platform: Corstone1000: Remove duplicate configuration
|
||||
parameters for Corstone-1000
|
||||
|
||||
The PS_NUM_ASSET is duplicated in the cmake.config and the
|
||||
config_tfm_target.h file under Corstone-1000. The commit removes
|
||||
the one from the cmake.config and keeps the one in the header file.
|
||||
|
||||
The whole rationale behind this is for the vendor to be able
|
||||
to override the configuration using the cmake file.
|
||||
|
||||
Upstream-Status: Backport [948cb8e7601dcf1fe822d855c77749287fe6d9bd]
|
||||
Signed-off-by: Yogesh Wani <yogesh.wani@arm.com>
|
||||
---
|
||||
platform/ext/target/arm/corstone1000/config.cmake | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/config.cmake b/platform/ext/target/arm/corstone1000/config.cmake
|
||||
index a923f63ca697..032265cdf4ac 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/config.cmake
|
||||
+++ b/platform/ext/target/arm/corstone1000/config.cmake
|
||||
@@ -74,7 +74,6 @@ endif()
|
||||
# Platform-specific configurations
|
||||
set(CONFIG_TFM_USE_TRUSTZONE OFF)
|
||||
set(TFM_MULTI_CORE_TOPOLOGY ON)
|
||||
-set(PS_NUM_ASSETS "40" CACHE STRING "The maximum number of assets to be stored in the Protected Storage area")
|
||||
|
||||
set(MCUBOOT_USE_PSA_CRYPTO ON CACHE BOOL "Enable the cryptographic abstraction layer to use PSA Crypto APIs")
|
||||
set(MCUBOOT_SIGNATURE_TYPE "EC-P256" CACHE STRING "Algorithm to use for signature validation [RSA-2048, RSA-3072, EC-P256, EC-P384]")
|
||||
+8
-5
@@ -1,7 +1,7 @@
|
||||
From 38daa61f876a6becb3968f1360d403f496634131 Mon Sep 17 00:00:00 2001
|
||||
From 69ee51ca58f8b1460a9ce4649c0e07f21201ff0a Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Mon, 16 Mar 2026 16:46:43 +0000
|
||||
Subject: [PATCH] lib: gpt: Add operation to duplicate entries
|
||||
Subject: [PATCH 08/14] lib: gpt: Add operation to duplicate entries
|
||||
|
||||
Without this new function, callers of the library would have to first
|
||||
read the entry they want to duplicate, then attempt to create a new
|
||||
@@ -20,7 +20,7 @@ Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-fi
|
||||
3 files changed, 201 insertions(+)
|
||||
|
||||
diff --git a/lib/gpt/inc/gpt.h b/lib/gpt/inc/gpt.h
|
||||
index 34ce67580..334a08f41 100644
|
||||
index 34ce675801b3..334a08f41abe 100644
|
||||
--- a/lib/gpt/inc/gpt.h
|
||||
+++ b/lib/gpt/inc/gpt.h
|
||||
@@ -170,6 +170,25 @@ psa_status_t gpt_entry_move(const struct efi_guid_t *guid,
|
||||
@@ -50,7 +50,7 @@ index 34ce67580..334a08f41 100644
|
||||
* \brief Creates a partition entry in the table.
|
||||
*
|
||||
diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c
|
||||
index 0335befa7..920c4ccca 100644
|
||||
index 0335befa7770..920c4ccca78e 100644
|
||||
--- a/lib/gpt/src/gpt.c
|
||||
+++ b/lib/gpt/src/gpt.c
|
||||
@@ -516,6 +516,29 @@ psa_status_t gpt_entry_move(const struct efi_guid_t *guid,
|
||||
@@ -84,7 +84,7 @@ index 0335befa7..920c4ccca 100644
|
||||
const uint64_t start,
|
||||
const uint64_t size,
|
||||
diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
index 0ae660336..5d2c4243f 100644
|
||||
index 0ae6603368e8..5d2c4243f607 100644
|
||||
--- a/lib/gpt/unittests/gpt/test_gpt.c
|
||||
+++ b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
@@ -738,6 +738,165 @@ void test_gpt_defragment_should_succeedWhenNoIOFailure(void)
|
||||
@@ -253,3 +253,6 @@ index 0ae660336..5d2c4243f 100644
|
||||
void test_gpt_entry_create_should_createNewEntry(void)
|
||||
{
|
||||
/* Add an entry. It must not overlap with an existing entry and must also
|
||||
--
|
||||
2.39.5
|
||||
|
||||
+7
-3
@@ -1,7 +1,8 @@
|
||||
From 0dcbef3a0800a2a610b32935a54762d4b42203f1 Mon Sep 17 00:00:00 2001
|
||||
From 4dab128d0da86be6ca09b861dfb157a11345e0e7 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Tue, 17 Mar 2026 11:44:14 +0000
|
||||
Subject: [PATCH] lib: gpt: Consecutively erase blocks when moving partitions
|
||||
Subject: [PATCH 09/14] lib: gpt: Consecutively erase blocks when moving
|
||||
partitions
|
||||
|
||||
An LBA is typically smaller than a flash sector size, so it becomes
|
||||
inefficient to erase block by block and also erases the same sector
|
||||
@@ -21,7 +22,7 @@ Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-fi
|
||||
1 file changed, 75 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c
|
||||
index 920c4ccca..984c8f821 100644
|
||||
index 920c4ccca78e..984c8f82146c 100644
|
||||
--- a/lib/gpt/src/gpt.c
|
||||
+++ b/lib/gpt/src/gpt.c
|
||||
@@ -207,7 +207,7 @@ static psa_status_t read_entry_from_flash(const struct gpt_t *table,
|
||||
@@ -238,3 +239,6 @@ index 920c4ccca..984c8f821 100644
|
||||
memcpy(lba_buf, temp_buf, GPT_HEADER_SIZE);
|
||||
|
||||
return ret;
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-487
@@ -1,487 +0,0 @@
|
||||
From c5bcb737352ad2e1c24cc14a0b8ddf91ad7197b4 Mon Sep 17 00:00:00 2001
|
||||
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
|
||||
Date: Tue, 29 Jul 2025 15:09:45 +0000
|
||||
Subject: [PATCH] plat: corstone1000: Add support for Cortex-A320 variant
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add support for powering on the Cortex-A320 host in the DSU-120T
|
||||
cluster and reserve Host SRAM for the normal world on the
|
||||
Corstone-1000 platform. These changes enable secure-enclave firmware
|
||||
control of the Cortex-A320 power domain and memory access
|
||||
configuration.
|
||||
|
||||
**DSU-120T Power-Policy Unit (PPU) driver**
|
||||
|
||||
* Introduce a minimal driver to program the DSU-120T Power-Policy
|
||||
Units, allowing the secure-enclave firmware to bring the
|
||||
Cortex-A320 host cluster out of reset.
|
||||
* The DSU utility-bus registers are located at:
|
||||
* `0x6091_0000` in the Host memory map.
|
||||
* `0xC091_0000` in the Secure-Enclave memory map.
|
||||
* The FC1 firewall is configured so that only the Secure Enclave may
|
||||
write to this window.
|
||||
* Add new CMake option `CORSTONE1000_DSU_120T` and platform define to
|
||||
enable Cortex-A320 DSU-120T–specific code.
|
||||
|
||||
**Host SRAM allocation**
|
||||
|
||||
* Reserve a 4 MiB block of Host SRAM at `0x0240_0000` for the
|
||||
Cortex-A320 normal world.
|
||||
* Open the same region in the Host-side firewall (CVM, region 2)
|
||||
to allow non-secure access.
|
||||
* This configuration is compiled in when `CORSTONE1000_CORTEX_A320`
|
||||
is defined.
|
||||
|
||||
These updates prepare the Corstone-1000 platform for Cortex-A320
|
||||
integration with proper cluster power management and normal-world
|
||||
memory accessibility.
|
||||
|
||||
Upstream-Status: Submitted (https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/45749)
|
||||
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
|
||||
---
|
||||
.../target/arm/corstone1000/CMakeLists.txt | 31 +++
|
||||
.../Device/Include/platform_base_address.h | 8 +-
|
||||
.../arm/corstone1000/bl1/boot_hal_bl1_1.c | 50 ++++-
|
||||
.../target/arm/corstone1000/dsu-120t/ppu.c | 40 ++++
|
||||
.../target/arm/corstone1000/dsu-120t/ppu.h | 185 ++++++++++++++++++
|
||||
.../arm/corstone1000/tfm_hal_multi_core.c | 28 ++-
|
||||
6 files changed, 339 insertions(+), 3 deletions(-)
|
||||
create mode 100644 platform/ext/target/arm/corstone1000/dsu-120t/ppu.c
|
||||
create mode 100644 platform/ext/target/arm/corstone1000/dsu-120t/ppu.h
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/CMakeLists.txt b/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
index 91bf197d86b7..993c51591fa7 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
+++ b/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
@@ -423,6 +423,37 @@ target_sources(tfm_spm
|
||||
$<$<BOOL:${TFM_S_REG_TEST}>:${CMAKE_CURRENT_SOURCE_DIR}/target_cfg.c>
|
||||
)
|
||||
|
||||
+#========================= DSU-120T ============================================#
|
||||
+if (CORSTONE1000_DSU_120T)
|
||||
+ target_sources(tfm_psa_rot_partition_ns_agent_mailbox
|
||||
+ PUBLIC
|
||||
+ dsu-120t/ppu.c
|
||||
+ )
|
||||
+
|
||||
+ target_compile_definitions(tfm_psa_rot_partition_ns_agent_mailbox
|
||||
+ PUBLIC
|
||||
+ CORSTONE1000_DSU_120T
|
||||
+ )
|
||||
+
|
||||
+ target_compile_definitions(platform_bl1_1
|
||||
+ PUBLIC
|
||||
+ CORSTONE1000_DSU_120T
|
||||
+ )
|
||||
+
|
||||
+ target_include_directories(tfm_psa_rot_partition_ns_agent_mailbox
|
||||
+ PUBLIC
|
||||
+ dsu-120t
|
||||
+ )
|
||||
+endif()
|
||||
+
|
||||
+#========================= Ethos-U NPU =========================================#
|
||||
+if (CORSTONE1000_CORTEX_A320)
|
||||
+ target_compile_definitions(platform_bl1_1
|
||||
+ PUBLIC
|
||||
+ CORSTONE1000_CORTEX_A320
|
||||
+ )
|
||||
+endif()
|
||||
+
|
||||
#========================= tfm_adac ============================================#
|
||||
|
||||
if (${PLATFORM_PSA_ADAC_SECURE_DEBUG})
|
||||
diff --git a/platform/ext/target/arm/corstone1000/Device/Include/platform_base_address.h b/platform/ext/target/arm/corstone1000/Device/Include/platform_base_address.h
|
||||
index 5f9f03ddc610..3908d69bc9bd 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/Device/Include/platform_base_address.h
|
||||
+++ b/platform/ext/target/arm/corstone1000/Device/Include/platform_base_address.h
|
||||
@@ -1,5 +1,7 @@
|
||||
/*
|
||||
- * Copyright (c) 2017-2024 Arm Limited. All rights reserved.
|
||||
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -79,6 +81,10 @@
|
||||
#define CORSTONE1000_HOST_AXI_QSPI_CTRL_REG_BASE_SE_SECURE_FLASH (0x90010000U) /* AXI QSPI Controller for SE FLash */
|
||||
#define CORSTONE1000_HOST_DRAM_UEFI_CAPSULE (0xA0000000U) /* 1.5 GB DDR */
|
||||
|
||||
+#ifdef CORSTONE1000_DSU_120T
|
||||
+#define CORSTONE1000_HOST_DSU_120T_BASE (0xC0910000U) /* DSU-120T PPU */
|
||||
+#endif
|
||||
+
|
||||
/* Map Component definitions to Corstone definitions */
|
||||
#define CC3XX_BASE_S CORSTONE1000_CRYPTO_ACCELERATOR_BASE
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bl1/boot_hal_bl1_1.c b/platform/ext/target/arm/corstone1000/bl1/boot_hal_bl1_1.c
|
||||
index b51a233e9143..1a5e98ad3c35 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/bl1/boot_hal_bl1_1.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/bl1/boot_hal_bl1_1.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
|
||||
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
@@ -48,6 +48,15 @@ REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
|
||||
#define HOST_SE_SECURE_FLASH_BASE_FVP 0x60010000
|
||||
#define HOST_AXI_QSPI_CTRL_REG_BASE_SE_SECURE_FLASH 0x60010000
|
||||
|
||||
+#ifdef CORSTONE1000_DSU_120T
|
||||
+#define HOST_DSU_120T_BASE 0x60910000
|
||||
+#endif
|
||||
+
|
||||
+#ifdef CORSTONE1000_CORTEX_A320
|
||||
+#define HOST_SECURE_SRAM_SIZE 0x400000
|
||||
+#define HOST_NONSECURE_SRAM_BASE (HOST_TRUSTED_RAM_BASE + HOST_SECURE_SRAM_SIZE)
|
||||
+#endif
|
||||
+
|
||||
#define HOST_DRAM_BASE 0x80000000
|
||||
#define HOST_DRAM_UEFI_CAPSULE 0x80000000
|
||||
|
||||
@@ -286,6 +295,25 @@ static void setup_se_firewall(void)
|
||||
fc_enable_regions();
|
||||
#endif
|
||||
|
||||
+#ifdef CORSTONE1000_DSU_120T
|
||||
+#if (PLATFORM_IS_FVP)
|
||||
+ fc_select_region(7);
|
||||
+ fc_disable_regions();
|
||||
+ fc_disable_mpe(RGN_MPE0);
|
||||
+ fc_prog_rgn(RGN_SIZE_16MB, CORSTONE1000_HOST_DSU_120T_BASE);
|
||||
+ fc_prog_rgn_upper_addr(HOST_DSU_120T_BASE);
|
||||
+ fc_enable_addr_trans();
|
||||
+ fc_init_mpl(RGN_MPE0);
|
||||
+
|
||||
+ mpl_rights = (RGN_MPL_SECURE_READ_MASK |
|
||||
+ RGN_MPL_SECURE_WRITE_MASK);
|
||||
+
|
||||
+ fc_enable_mpl(RGN_MPE0, mpl_rights);
|
||||
+ fc_prog_mid(RGN_MPE0, SE_MID);
|
||||
+ fc_enable_mpe(RGN_MPE0);
|
||||
+ fc_enable_regions();
|
||||
+#endif
|
||||
+#endif
|
||||
fc_pe_enable();
|
||||
}
|
||||
|
||||
@@ -369,6 +397,26 @@ static void setup_host_firewall(void)
|
||||
fc_enable_regions();
|
||||
fc_rgn_lock();
|
||||
|
||||
+#ifdef CORSTONE1000_CORTEX_A320
|
||||
+ /* CVM - Non Secure RAM */
|
||||
+ fc_select_region(2);
|
||||
+ fc_disable_regions();
|
||||
+ fc_disable_mpe(RGN_MPE0);
|
||||
+ fc_prog_rgn(RGN_SIZE_4MB, HOST_NONSECURE_SRAM_BASE);
|
||||
+ fc_init_mpl(RGN_MPE0);
|
||||
+
|
||||
+ mpl_rights = (RGN_MPL_ANY_MST_MASK | RGN_MPL_NONSECURE_READ_MASK |
|
||||
+ RGN_MPL_NONSECURE_WRITE_MASK |
|
||||
+ RGN_MPL_NONSECURE_EXECUTE_MASK);
|
||||
+
|
||||
+ fc_enable_mpl(RGN_MPE0, mpl_rights);
|
||||
+ fc_disable_mpl(RGN_MPE0, ~mpl_rights);
|
||||
+
|
||||
+ fc_enable_mpe(RGN_MPE0);
|
||||
+ fc_enable_regions();
|
||||
+ fc_rgn_lock();
|
||||
+#endif
|
||||
+
|
||||
fc_pe_enable();
|
||||
|
||||
/* DDR */
|
||||
diff --git a/platform/ext/target/arm/corstone1000/dsu-120t/ppu.c b/platform/ext/target/arm/corstone1000/dsu-120t/ppu.c
|
||||
new file mode 100644
|
||||
index 000000000000..d6be5982a8dd
|
||||
--- /dev/null
|
||||
+++ b/platform/ext/target/arm/corstone1000/dsu-120t/ppu.c
|
||||
@@ -0,0 +1,40 @@
|
||||
+/*
|
||||
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+#include "ppu.h"
|
||||
+
|
||||
+void PPU_SetPowerPolicy(PPU_TypeDef *ppu, PPU_PowerPolicy_Type policy, bool isDynamic)
|
||||
+{
|
||||
+ uint32_t regval = ppu->PWPR;
|
||||
+
|
||||
+ regval &= ~(PPU_PWPR_PWR_POLICY_Msk | PPU_PWPR_PWR_DYN_EN_Msk);
|
||||
+
|
||||
+ regval |= ((policy << PPU_PWPR_PWR_POLICY_Pos) & PPU_PWPR_PWR_POLICY_Msk);
|
||||
+
|
||||
+ if (isDynamic) {
|
||||
+ regval |= PPU_PWPR_PWR_DYN_EN_Msk;
|
||||
+ }
|
||||
+
|
||||
+ ppu->PWPR = regval;
|
||||
+}
|
||||
+
|
||||
+void PPU_SetOperatingPolicy(PPU_TypeDef *ppu, PPU_OperatingPolicy_Type policy, bool isDynamic)
|
||||
+{
|
||||
+ uint32_t regval = ppu->PWPR;
|
||||
+
|
||||
+ regval &= ~(PPU_PWPR_OP_POLICY_Msk | PPU_PWPR_OP_DYN_EN_Msk);
|
||||
+
|
||||
+ regval |= ((policy << PPU_PWPR_OP_POLICY_Pos) & PPU_PWPR_OP_POLICY_Msk);
|
||||
+
|
||||
+ if (isDynamic) {
|
||||
+ regval |= PPU_PWPR_OP_DYN_EN_Msk;
|
||||
+ }
|
||||
+
|
||||
+ ppu->PWPR = regval;
|
||||
+}
|
||||
+
|
||||
diff --git a/platform/ext/target/arm/corstone1000/dsu-120t/ppu.h b/platform/ext/target/arm/corstone1000/dsu-120t/ppu.h
|
||||
new file mode 100644
|
||||
index 000000000000..05470df9a884
|
||||
--- /dev/null
|
||||
+++ b/platform/ext/target/arm/corstone1000/dsu-120t/ppu.h
|
||||
@@ -0,0 +1,185 @@
|
||||
+/*
|
||||
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ *
|
||||
+ */
|
||||
+#ifndef PPU_H
|
||||
+#define PPU_H
|
||||
+
|
||||
+#include <stdbool.h>
|
||||
+#include <stdint.h>
|
||||
+#include "platform_base_address.h"
|
||||
+
|
||||
+// Bit definition for PPU_PWPR register
|
||||
+#define PPU_PWPR_PWR_POLICY_Pos (0U) // Power mode policy
|
||||
+#define PPU_PWPR_PWR_POLICY_Msk (0xFUL << PPU_PWPR_PWR_POLICY_Pos) // 4 bits
|
||||
+#define PPU_PWPR_PWR_POLICY_OFF (0UL << PPU_PWPR_PWR_POLICY_Pos) // Logic off and RAM off.
|
||||
+#define PPU_PWPR_PWR_POLICY_OFF_EMU (1UL << PPU_PWPR_PWR_POLICY_Pos) // Emulated Off. Logic on with RAM on. This mode is used to emulate the functional condition of OFF without removing
|
||||
+#define PPU_PWPR_PWR_POLICY_MEM_RET (2UL << PPU_PWPR_PWR_POLICY_Pos) // Memory Retention. Logic off with RAM retained.
|
||||
+#define PPU_PWPR_PWR_POLICY_MEM_RET_EMU (3UL << PPU_PWPR_PWR_POLICY_Pos) // Emulated Memory Retention. Logic on with RAM on. This mode is used to emulate the functional condition of
|
||||
+#define PPU_PWPR_PWR_POLICY_FULL_RET (5UL << PPU_PWPR_PWR_POLICY_Pos) // Full Retention. Slice logic off with RAM contents retained.
|
||||
+#define PPU_PWPR_PWR_POLICY_FUNC_RET (7UL << PPU_PWPR_PWR_POLICY_Pos) // Functional Retention. Logic on with L3 Cache and Snoop Filter retained.
|
||||
+#define PPU_PWPR_PWR_POLICY_ON (8UL << PPU_PWPR_PWR_POLICY_Pos) // Logic on with RAM on, cluster is functional.
|
||||
+#define PPU_PWPR_PWR_POLICY_WARM_RST (9UL << PPU_PWPR_PWR_POLICY_Pos) // Warm Reset. Warm reset application with logic and RAM on.
|
||||
+#define PPU_PWPR_PWR_POLICY_DBG_RECOV (10UL << PPU_PWPR_PWR_POLICY_Pos) // Debug Recovery Reset. Warm reset application with logic and RAM on.
|
||||
+#define PPU_PWPR_PWR_DYN_EN_Pos (8U) // Power mode dynamic transition enable.
|
||||
+#define PPU_PWPR_PWR_DYN_EN_Msk (0x1UL << PPU_PWPR_PWR_DYN_EN_Pos) // 1 bit
|
||||
+#define PPU_PWPR_LOCK_EN_Pos (12U) // Lock enable bit for OFF, OFF_EMU, MEM_RET and MEM_RET_EMU power modes.
|
||||
+#define PPU_PWPR_LOCK_EN_Msk (0x1UL << PPU_PWPR_LOCK_EN_Pos) // 1 bit
|
||||
+#define PPU_PWPR_OP_POLICY_Pos (16U) // Operating mode policy
|
||||
+#define PPU_PWPR_OP_POLICY_Msk (0xFUL << PPU_PWPR_OP_POLICY_Pos) // 4 bits
|
||||
+#define PPU_PWPR_OP_POLICY_OPMODE_00 (0UL << PPU_PWPR_OP_POLICY_Pos) // ONE_SLICE_SF_ONLY_ON: One L3 Cache slice is operational, the Cache RAM is powered down.
|
||||
+#define PPU_PWPR_OP_POLICY_OPMODE_01 (1UL << PPU_PWPR_OP_POLICY_Pos) // ONE_SLICE_HALF_RAM_ON: One L3 Cache slice is operational, half of the Cache RAMs are powered on.
|
||||
+#define PPU_PWPR_OP_POLICY_OPMODE_03 (3UL << PPU_PWPR_OP_POLICY_Pos) // ONE_SLICE_FULL_RAM_ON: One L3 Cache slice is operational, all of the Cache RAMs are powered on.
|
||||
+#define PPU_PWPR_OP_POLICY_OPMODE_04 (4UL << PPU_PWPR_OP_POLICY_Pos) // ALL_SLICE_SF_ONLY_ON: All L3 Cache slices are operational, the Cache RAMs in each slice are powered down.
|
||||
+#define PPU_PWPR_OP_POLICY_OPMODE_05 (5UL << PPU_PWPR_OP_POLICY_Pos) // ALL_SLICE_HALF_RAM_ON: All L3 Cache slices are operational, half of the Cache RAMs are powered on.
|
||||
+#define PPU_PWPR_OP_POLICY_OPMODE_07 (7UL << PPU_PWPR_OP_POLICY_Pos) // ALL_SLICE_FULL_RAM_ON: All L3 Cache slices are operational, all of the Cache RAMs are powered on.
|
||||
+#define PPU_PWPR_OP_POLICY_OPMODE_08 (8UL << PPU_PWPR_OP_POLICY_Pos) // HALF_SLICE_SF_ONLY_ON: Half L3 Cache slices are operational, the Cache RAMs in each slice are powered down.
|
||||
+#define PPU_PWPR_OP_POLICY_OPMODE_09 (9UL << PPU_PWPR_OP_POLICY_Pos) // HALF_SLICE_HALF_RAM_ON: Half L3 Cache slices are operational, half of the Cache RAMs are powered on.
|
||||
+#define PPU_PWPR_OP_POLICY_OPMODE_0B (11UL << PPU_PWPR_PWR_POLICY_Pos) // HALF_SLICE_FULL_RAM_ON: Half L3 Cache slices are operational, all of the Cache RAMs are powered on.
|
||||
+#define PPU_PWPR_OP_DYN_EN_Pos (24U) // Operating mode dynamic transition enable.
|
||||
+#define PPU_PWPR_OP_DYN_EN_Msk (0x1UL << PPU_PWPR_OP_DYN_EN_Pos) // 1 bit
|
||||
+
|
||||
+// Bit definition for PPU_PWSR register
|
||||
+#define PPU_PWSR_PWR_STATUS_Pos (0U)
|
||||
+#define PPU_PWSR_PWR_STATUS_Msk (0xFUL << PPU_PWSR_PWR_STATUS_Pos) // 4 bits
|
||||
+#define PPU_PWSR_PWR_STATUS_OFF (0UL << PPU_PWSR_PWR_STATUS_Pos) // Logic off and RAM off.
|
||||
+#define PPU_PWSR_PWR_STATUS_OFF_EMU (1UL << PPU_PWSR_PWR_STATUS_Pos) // Emulated Off. Logic on with RAM on. This mode is used to emulate the functional condition of OFF without removing
|
||||
+#define PPU_PWSR_PWR_STATUS_MEM_RET (2UL << PPU_PWSR_PWR_STATUS_Pos) // Memory Retention. Logic off with RAM retained.
|
||||
+#define PPU_PWSR_PWR_STATUS_MEM_RET_EMU (3UL << PPU_PWSR_PWR_STATUS_Pos) // Emulated Memory Retention. Logic on with RAM on. This mode is used to emulate the functional condition of
|
||||
+#define PPU_PWSR_PWR_STATUS_FULL_RET (5UL << PPU_PWSR_PWR_STATUS_Pos) // Full Retention. Slice logic off with RAM contents retained.
|
||||
+#define PPU_PWSR_PWR_STATUS_FUNC_RET (7UL << PPU_PWSR_PWR_STATUS_Pos) // Functional Retention. Logic on with L3 Cache and Snoop Filter retained.
|
||||
+#define PPU_PWSR_PWR_STATUS_ON (8UL << PPU_PWSR_PWR_STATUS_Pos) // Logic on with RAM on, cluster is functional.
|
||||
+#define PPU_PWSR_PWR_STATUS_WARM_RST (9UL << PPU_PWSR_PWR_STATUS_Pos) // Warm Reset. Warm reset application with logic and RAM on.
|
||||
+#define PPU_PWSR_PWR_STATUS_DBG_RECOV (10UL << PPU_PWSR_PWR_STATUS_Pos) // Debug Recovery Reset. Warm reset application with logic and RAM on.
|
||||
+#define PPU_PWSR_PWR_DYN_STATUS_Pos (8U) // Power mode dynamic transition enable.
|
||||
+#define PPU_PWSR_PWR_DYN_STATUS_Msk (0x1UL << PPU_PWSR_PWR_DYN_STATUS_Pos) // 1 bit
|
||||
+#define PPU_PWSR_LOCK_STATUS_Pos (12U) // Lock enable bit for OFF, OFF_EMU, MEM_RET and MEM_RET_EMU power modes.
|
||||
+#define PPU_PWSR_LOCK_STATUS_Msk (0x1UL << PPU_PWSR_LOCK_STATUS_Pos) // 1 bit
|
||||
+#define PPU_PWSR_OP_STATUS_Pos (16U) // Operating mode policy
|
||||
+#define PPU_PWSR_OP_STATUS_Msk (0xFUL << PPU_PWSR_OP_STATUS_Pos) // 4 bits
|
||||
+#define PPU_PWSR_OP_STATUS_OPMODE_00 (0UL << PPU_PWSR_OP_STATUS_Pos) // ONE_SLICE_SF_ONLY_ON: One L3 Cache slice is operational, only the snoop filter RAM instances are active in the slice
|
||||
+#define PPU_PWSR_OP_STATUS_OPMODE_01 (1UL << PPU_PWSR_OP_STATUS_Pos) // ONE_SLICE_HALF_RAM_ON: One L3 Cache slice is operational, half of the Cache RAMs are powered on.
|
||||
+#define PPU_PWSR_OP_STATUS_OPMODE_03 (3UL << PPU_PWSR_OP_STATUS_Pos) // ONE_SLICE_FULL_RAM_ON: One L3 Cache slice is operational, all of the Cache RAMs are powered on.
|
||||
+#define PPU_PWSR_OP_STATUS_OPMODE_04 (4UL << PPU_PWSR_OP_STATUS_Pos) // ALL_SLICE_SF_ONLY_ON: All L3 Cache slices are operational, the Cache RAMs in each slice are powered down.
|
||||
+#define PPU_PWSR_OP_STATUS_OPMODE_05 (5UL << PPU_PWSR_OP_STATUS_Pos) // ALL_SLICE_HALF_RAM_ON: All L3 Cache slices are operational, half of the Cache RAMs are powered on.
|
||||
+#define PPU_PWSR_OP_STATUS_OPMODE_07 (7UL << PPU_PWSR_OP_STATUS_Pos) // ALL_SLICE_FULL_RAM_ON: All L3 Cache slices are operational, all of the Cache RAMs are powered on.
|
||||
+#define PPU_PWSR_OP_STATUS_OPMODE_08 (8UL << PPU_PWSR_OP_STATUS_Pos) // HALF_SLICE_SF_ONLY_ON: Half L3 Cache slices are operational, the Cache RAMs in each slice are powered down.
|
||||
+#define PPU_PWSR_OP_STATUS_OPMODE_09 (9UL << PPU_PWSR_OP_STATUS_Pos) // HALF_SLICE_HALF_RAM_ON: Half L3 Cache slices are operational, half of the Cache RAMs are powered on.
|
||||
+#define PPU_PWSR_OP_STATUS_OPMODE_0B (11UL << PPU_PWSR_OP_STATUS_Pos) // HALF_SLICE_FULL_RAM_ON: Half L3 Cache slices are operational, all of the Cache RAMs are powered on.
|
||||
+#define PPU_PWSR_OP_DYN_STATUS_Pos (24U) // Operating mode dynamic transition enable.
|
||||
+#define PPU_PWSR_OP_DYN_STATUS_Msk (0x1UL << PPU_PWSR_OP_DYN_STATUS_Pos) // 1 bit
|
||||
+
|
||||
+/*!< PPU memory offsets */
|
||||
+#define DSU_120T_CLUSTER_PPU_OFFSET 0x030000
|
||||
+#define DSU_120T_CORE0_PPU_OFFSET 0x080000
|
||||
+#define DSU_120T_CORE1_PPU_OFFSET 0x180000
|
||||
+#define DSU_120T_CORE2_PPU_OFFSET 0x280000
|
||||
+#define DSU_120T_CORE3_PPU_OFFSET 0x380000
|
||||
+
|
||||
+/*!< PPU memory map */
|
||||
+#define CLUSTER_PPU_BASE (CORSTONE1000_HOST_DSU_120T_BASE + DSU_120T_CLUSTER_PPU_OFFSET)
|
||||
+#define CORE0_PPU_BASE (CORSTONE1000_HOST_DSU_120T_BASE + DSU_120T_CORE0_PPU_OFFSET)
|
||||
+#define CORE1_PPU_BASE (CORSTONE1000_HOST_DSU_120T_BASE + DSU_120T_CORE1_PPU_OFFSET)
|
||||
+#define CORE2_PPU_BASE (CORSTONE1000_HOST_DSU_120T_BASE + DSU_120T_CORE2_PPU_OFFSET)
|
||||
+#define CORE3_PPU_BASE (CORSTONE1000_HOST_DSU_120T_BASE + DSU_120T_CORE3_PPU_OFFSET)
|
||||
+
|
||||
+/*!< PPU declarations */
|
||||
+#define CLUSTER_PPU ((PPU_TypeDef *) CLUSTER_PPU_BASE)
|
||||
+#define CORE0_PPU ((PPU_TypeDef *) CORE0_PPU_BASE)
|
||||
+#define CORE1_PPU ((PPU_TypeDef *) CORE1_PPU_BASE)
|
||||
+#define CORE2_PPU ((PPU_TypeDef *) CORE2_PPU_BASE)
|
||||
+#define CORE3_PPU ((PPU_TypeDef *) CORE3_PPU_BASE)
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ volatile uint32_t PWPR; /*!< PPU Power Policy Register, Address offset: 0x00 */
|
||||
+ volatile uint32_t PMER; /*!< PPU Power Mode Emulation Enable Register, Address offset: 0x04 */
|
||||
+ volatile uint32_t PWSR; /*!< PPU Power Status Register, Address offset: 0x08 */
|
||||
+ volatile uint32_t RESERVED0; /*!< Reserved, Address offset: 0x0C */
|
||||
+ volatile uint32_t DISR; /*!< PPU Device Interface Input Current Status Register, Address offset: 0x10 */
|
||||
+ volatile uint32_t MISR; /*!< PPU Miscellaneous Input Current Status Register, Address offset: 0x14 */
|
||||
+ volatile uint32_t STSR; /*!< PPU Stored Status Register, Address offset: 0x18 */
|
||||
+ volatile uint32_t UNLK; /*!< PPU Unlock Register, Address offset: 0x1C */
|
||||
+ volatile uint32_t PWCR; /*!< PPU Power Configuration Register, Address offset: 0x20 */
|
||||
+ volatile uint32_t PTCR; /*!< PPU Power Mode Transition Register, Address offsets: 0x24 */
|
||||
+ volatile uint32_t RESERVED1[2]; /*!< Reserved: Address offsets 0x28 - 0x2C */
|
||||
+ volatile uint32_t IMR; /*!< PPU Interrupt Mask Register, Address offsets: 0x30 */
|
||||
+ volatile uint32_t AIMR; /*!< PPU Additional Interrupt Mask Register, Address offsets: 0x34 */
|
||||
+ volatile uint32_t ISR; /*!< PPU Interrupt Status Register, Address offsets: 0x38 */
|
||||
+ volatile uint32_t AISR; /*!< PPU Additional Interrupt Status Register, Address offsets: 0x3C */
|
||||
+ volatile uint32_t IESR; /*!< PPU Input Edge Sensitivity Register Address offsets: 0x040 */
|
||||
+ volatile uint32_t OPSR; /*!< PPU Operating Mode Active Edge Sensitivity Register Address offsets: 0x044 */
|
||||
+ volatile uint32_t RESERVED2[2]; /*!< Reserved: Address offsets 0x48 - 0x4C */
|
||||
+ volatile uint32_t FUNRR; /*!< Functional Retention RAM Configuration Register Address offsets: 0x050 */
|
||||
+ volatile uint32_t FULRR; /*!< Full Retention RAM Configuration Register Address offsets: 0x054 */
|
||||
+ volatile uint32_t MEMRR; /*!< Memory Retention RAM Configuration Register Address offsets: 0x058 */
|
||||
+ volatile uint32_t RESERVED3[69]; /*!< Reserved: Address offsets 0x5C - 0x16C */
|
||||
+ volatile uint32_t DCDR0; /*!< Device Control Delay Configuration Register 0 Address offsets: 0x170 */
|
||||
+ volatile uint32_t DCDR1; /*!< Device Control Delay Configuration Register 1 Address offsets: 0x174 */
|
||||
+ volatile uint32_t RESERVED4[910]; /*!< Reserved, offsets 0x178 - 0xFAC */
|
||||
+ volatile uint32_t IDR0; /*!< PPU Identification Register 0, Address offsets: 0xFB0 */
|
||||
+ volatile uint32_t IDR1; /*!< PPU Identification Register 1, Address offsets: 0xFB4 */
|
||||
+ volatile uint32_t RESERVED5[4]; /*!< Reserved, offsets 0xFB8 - 0xFC4 */
|
||||
+ volatile uint32_t IIDR; /*!< PPU Implementation Identification Register, Address offsets: 0xFC8 */
|
||||
+ volatile uint32_t AIDR; /*!< PPU Architecture Identification Register, Address offsets: 0xFCC */
|
||||
+ volatile uint32_t PIDR4; /*!< PPU Peripheral Identification Register 4, Address offsets: 0xFD0 */
|
||||
+ volatile uint32_t PIDR5; /*!< PPU Peripheral Identification Register 5, Address offsets: 0xFD4 */
|
||||
+ volatile uint32_t PIDR6; /*!< PPU Peripheral Identification Register 6, Address offsets: 0xFD8 */
|
||||
+ volatile uint32_t PIDR7; /*!< PPU Peripheral Identification Register 7, Address offsets: 0xFDC */
|
||||
+ volatile uint32_t PIDR0; /*!< PPU Peripheral Identification Register 0, Address offsets: 0xFE0 */
|
||||
+ volatile uint32_t PIDR1; /*!< PPU Peripheral Identification Register 1, Address offsets: 0xFE4 */
|
||||
+ volatile uint32_t PIDR2; /*!< PPU Peripheral Identification Register 2, Address offsets: 0xFE8 */
|
||||
+ volatile uint32_t PIDR3; /*!< PPU Peripheral Identification Register 3, Address offsets: 0xFEC */
|
||||
+ volatile uint32_t CIDR0; /*!< PPU Component Identification Register 0, Address offsets: 0xFF0 */
|
||||
+ volatile uint32_t CIDR1; /*!< PPU Component Identification Register 1, Address offsets: 0xFF4 */
|
||||
+ volatile uint32_t CIDR2; /*!< PPU Component Identification Register 2, Address offsets: 0xFF8 */
|
||||
+ volatile uint32_t CIDR3; /*!< PPU Component Identification Register 3, Address offsets: 0xFFC */
|
||||
+} PPU_TypeDef;
|
||||
+
|
||||
+typedef enum {
|
||||
+ PPU_PWR_MODE_OFF = 0, // Logic off and RAM off.
|
||||
+ PPU_PWR_MODE_OFF_EMU = 1, // Emulated Off. Logic on with RAM on. This mode is used to emulate the functional condition of OFF without removing
|
||||
+ PPU_PWR_MODE_MEM_RET = 2, // Memory Retention. Logic off with RAM retained.
|
||||
+ PPU_PWR_MODE_MEM_RET_EMU = 3, // Emulated Memory Retention. Logic on with RAM on. This mode is used to emulate the functional condition of
|
||||
+ PPU_PWR_MODE_FULL_RET = 5, // Full Retention. Slice logic off with RAM contents retained.
|
||||
+ PPU_PWR_MODE_FUNC_RET = 7, // Functional Retention. Logic on with L3 Cache and Snoop Filter retained.
|
||||
+ PPU_PWR_MODE_ON = 8, // Logic on with RAM on, cluster is functional.
|
||||
+ PPU_PWR_MODE_WARM_RST = 9, // Warm Reset. Warm reset application with logic and RAM on.
|
||||
+ PPU_PWR_MODE_DBG_RECOV = 10 // Debug Recovery Reset. Warm reset application with logic and RAM on.
|
||||
+} PPU_PowerPolicy_Type;
|
||||
+
|
||||
+typedef enum {
|
||||
+ PPU_OP_MODE_ONE_SLICE_SF_ONLY_ON = 0, // One L3 Cache slice is operational, only the snoop filter RAM instances are active in the slice
|
||||
+ PPU_OP_MODE_ONE_SLICE_HALF_RAM_ON = 1, // One L3 Cache slice is operational, half of the Cache RAMs are powered on.
|
||||
+ PPU_OP_MODE_ONE_SLICE_FULL_RAM_ON = 3, // One L3 Cache slice is operational, all of the Cache RAMs are powered on.
|
||||
+ PPU_OP_MODE_ALL_SLICE_SF_ONLY_ON = 4, // All L3 Cache slices are operational, the Cache RAMs in each slice are powered down.
|
||||
+ PPU_OP_MODE_ALL_SLICE_HALF_RAM_ON = 5, // All L3 Cache slices are operational, half of the Cache RAMs are powered on.
|
||||
+ PPU_OP_MODE_ALL_SLICE_FULL_RAM_ON = 7, // All L3 Cache slices are operational, all of the Cache RAMs are powered on.
|
||||
+ PPU_OP_MODE_HALF_SLICE_SF_ONLY_ON = 8, // Half L3 Cache slices are operational, the Cache RAMs in each slice are powered down.
|
||||
+ PPU_OP_MODE_HALF_SLICE_HALF_RAM_ON = 9, // Half L3 Cache slices are operational, half of the Cache RAMs are powered on.
|
||||
+ PPU_OP_MODE_HALF_SLICE_FULL_RAM_ON = 11 // Half L3 Cache slices are operational, all of the Cache RAMs are powered on.
|
||||
+} PPU_OperatingPolicy_Type;
|
||||
+
|
||||
+/**
|
||||
+ * @brief Set the power policy for a given PPU instance.
|
||||
+ * Only modifies PWR_POLICY and PWR_DYN_EN bits.
|
||||
+ * @param ppu: Pointer to the PPU instance (e.g., CLUSTER_PPU, CORE0_PPU1)
|
||||
+ * @param policy: Power mode policy (e.g., PPU_PWR_MODE_ON)
|
||||
+ * @param dynamic: Enable dynamic transitions enabled for power modes, allowing transitions to be initiated by changes on power mode DEVACTIVE inputs if non-zero
|
||||
+ * @retval None
|
||||
+ */
|
||||
+void PPU_SetPowerPolicy(PPU_TypeDef *ppu, PPU_PowerPolicy_Type policy, bool isDynamic);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Set the operating mode policy for a given PPU instance.
|
||||
+* Only modifies OP_POLICY and OP_DYN_EN bits.
|
||||
+ * @param ppu: Pointer to the PPU instance (e.g., CLUSTER_PPU, CORE0_PPU)
|
||||
+ * @param policy: Operating mode policy (e.g., PPU_OP_MODE_ONE_SLICE_SF_ONLY_ON)
|
||||
+ * @param dynamic: Enable dynamic transitions enabled for operating modes, allowing transitions to be initiated by changes on operating mode DEVACTIVE inputs if non-zero
|
||||
+ * @retval None
|
||||
+ */
|
||||
+void PPU_SetOperatingPolicy(PPU_TypeDef *ppu, PPU_OperatingPolicy_Type policy, bool isDynamic);
|
||||
+
|
||||
+#endif /* PPU_H */
|
||||
diff --git a/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c b/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c
|
||||
index d0c6b8d590f9..10c66ac41ad2 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2018-2024 Arm Limited. All rights reserved.
|
||||
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
@@ -11,6 +11,10 @@
|
||||
#include "tfm_hal_multi_core.h"
|
||||
#include "fwu_agent.h"
|
||||
|
||||
+#ifdef CORSTONE1000_DSU_120T
|
||||
+#include "ppu.h"
|
||||
+#endif
|
||||
+
|
||||
#define HOST_SYS_RST_CTRL_OFFSET 0x000
|
||||
#define HOST_CPU_PE0_CONFIG_OFFSET 0x010
|
||||
#define HOST_CPU_PE1_CONFIG_OFFSET 0x020
|
||||
@@ -98,6 +102,28 @@ void tfm_hal_boot_ns_cpu(uintptr_t start_addr)
|
||||
|
||||
(void) start_addr;
|
||||
|
||||
+#ifdef CORSTONE1000_DSU_120T
|
||||
+ /* Power on DSU-120T cluster */
|
||||
+ PPU_SetOperatingPolicy(CLUSTER_PPU, PPU_OP_MODE_ONE_SLICE_SF_ONLY_ON, false);
|
||||
+ PPU_SetPowerPolicy(CLUSTER_PPU, PPU_PWR_MODE_ON, false);
|
||||
+
|
||||
+ /* Power on Cortex-A320 core0 in DSU-120T Cluster */
|
||||
+ PPU_SetOperatingPolicy(CORE0_PPU, PPU_OP_MODE_ONE_SLICE_SF_ONLY_ON, false);
|
||||
+ PPU_SetPowerPolicy(CORE0_PPU, PPU_PWR_MODE_ON, false);
|
||||
+
|
||||
+#if CORSTONE1000_FVP_MULTICORE
|
||||
+ /* Power on all Cortex-A320 cores in DSU-120T Cluster */
|
||||
+ PPU_SetOperatingPolicy(CORE1_PPU, PPU_OP_MODE_ONE_SLICE_SF_ONLY_ON, false);
|
||||
+ PPU_SetPowerPolicy(CORE1_PPU, PPU_PWR_MODE_ON, false);
|
||||
+
|
||||
+ PPU_SetOperatingPolicy(CORE2_PPU, PPU_OP_MODE_ONE_SLICE_SF_ONLY_ON, false);
|
||||
+ PPU_SetPowerPolicy(CORE2_PPU, PPU_PWR_MODE_ON, false);
|
||||
+
|
||||
+ PPU_SetOperatingPolicy(CORE3_PPU, PPU_OP_MODE_ONE_SLICE_SF_ONLY_ON, false);
|
||||
+ PPU_SetPowerPolicy(CORE3_PPU, PPU_PWR_MODE_ON, false);
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
#ifdef EXTERNAL_SYSTEM_SUPPORT
|
||||
/*release EXT SYS out of reset*/
|
||||
tfm_external_system_boot();
|
||||
+6
-3
@@ -1,7 +1,7 @@
|
||||
From 7e2ae2fc4f8ae8a16a24b87d0650c6b4b28fc870 Mon Sep 17 00:00:00 2001
|
||||
From 60608602c55f92c82263775cbe42b221f3ea5f09 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Wed, 8 Apr 2026 17:39:13 +0100
|
||||
Subject: [PATCH] lib: gpt: Clarify API operation
|
||||
Subject: [PATCH 10/14] lib: gpt: Clarify API operation
|
||||
|
||||
The move and duplicate operations both also move or copy (respectively)
|
||||
the partition data, which is not immediately obvious.
|
||||
@@ -14,7 +14,7 @@ Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-fi
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/gpt/inc/gpt.h b/lib/gpt/inc/gpt.h
|
||||
index 334a08f41..c11ecbff2 100644
|
||||
index 334a08f41abe..c11ecbff2619 100644
|
||||
--- a/lib/gpt/inc/gpt.h
|
||||
+++ b/lib/gpt/inc/gpt.h
|
||||
@@ -152,7 +152,7 @@ __attribute__((nonnull(1)))
|
||||
@@ -36,3 +36,6 @@ index 334a08f41..c11ecbff2 100644
|
||||
*
|
||||
* \param[in] old_guid Entry to duplicate.
|
||||
* \param[in] start Starting LBA (0 uses the lowest free LBA possible).
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
From 3a9e209596ca0ae5850ae382c624adf9932b16b4 Mon Sep 17 00:00:00 2001
|
||||
From: Devaraj Ranganna <devaraj.ranganna@arm.com>
|
||||
Date: Mon, 22 Sep 2025 12:48:57 +0100
|
||||
Subject: [PATCH] bl2: corstone-1000: Remove
|
||||
`psa_adac_to_tfm_apply_permissions`
|
||||
|
||||
The API `psa_adac_to_tfm_apply_permissions` is added to `psa-adac`
|
||||
library. Therefore, remove it from
|
||||
`platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c`.
|
||||
|
||||
Upstream-Status: Pending [Not submitted to upstream yet]
|
||||
Signed-off-by: Devaraj Ranganna <devaraj.ranganna@arm.com>
|
||||
---
|
||||
.../arm/corstone1000/bl2/boot_hal_bl2.c | 21 -------------------
|
||||
1 file changed, 21 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c b/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c
|
||||
index 2abcfb5fd39d..8c4eb80d032c 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c
|
||||
@@ -111,27 +111,6 @@ static bool fill_flash_map_with_fip_data(uint8_t boot_index) {
|
||||
#endif /* !TFM_S_REG_TEST */
|
||||
|
||||
#ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
|
||||
-int psa_adac_to_tfm_apply_permissions(uint8_t permissions_mask[16])
|
||||
-{
|
||||
- (void)permissions_mask;
|
||||
-
|
||||
- int ret;
|
||||
- uint32_t dcu_reg_values[4];
|
||||
-
|
||||
- /* Below values provide same access as when platform is in development
|
||||
- life cycle state */
|
||||
- dcu_reg_values[0] = 0xffffe7fc;
|
||||
- dcu_reg_values[1] = 0x800703ff;
|
||||
- dcu_reg_values[2] = 0xffffffff;
|
||||
- dcu_reg_values[3] = 0xffffffff;
|
||||
-
|
||||
- ret = crypto_hw_apply_debug_permissions((uint8_t*)dcu_reg_values, 16);
|
||||
- BOOT_LOG_INF("%s: debug permission apply %s\n\r", __func__,
|
||||
- (ret == 0) ? "success" : "fail");
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
uint8_t secure_debug_rotpk[32];
|
||||
#endif /* PLATFORM_PSA_ADAC_SECURE_DEBUG */
|
||||
|
||||
+8
-5
@@ -1,7 +1,7 @@
|
||||
From f9badce3570bbc89b141c86a6b8a988d90d81f0c Mon Sep 17 00:00:00 2001
|
||||
From b10d50f554745f2f9a2e43c24e1020c4da15a098 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Wed, 8 Apr 2026 17:51:18 +0100
|
||||
Subject: [PATCH] lib: gpt: Add metadata-only API operations
|
||||
Subject: [PATCH 11/14] lib: gpt: Add metadata-only API operations
|
||||
|
||||
Both move and duplicate functions also move or copy (respectively) the
|
||||
partition data. This is not always required, for example if the
|
||||
@@ -17,7 +17,7 @@ Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-fi
|
||||
3 files changed, 473 insertions(+), 120 deletions(-)
|
||||
|
||||
diff --git a/lib/gpt/inc/gpt.h b/lib/gpt/inc/gpt.h
|
||||
index c11ecbff2..c5bddb470 100644
|
||||
index c11ecbff2619..c5bddb4704e7 100644
|
||||
--- a/lib/gpt/inc/gpt.h
|
||||
+++ b/lib/gpt/inc/gpt.h
|
||||
@@ -170,6 +170,25 @@ psa_status_t gpt_entry_move(const struct efi_guid_t *guid,
|
||||
@@ -74,7 +74,7 @@ index c11ecbff2..c5bddb470 100644
|
||||
* \brief Creates a partition entry in the table.
|
||||
*
|
||||
diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c
|
||||
index 984c8f821..d6528f6a5 100644
|
||||
index 984c8f82146c..d6528f6a50ef 100644
|
||||
--- a/lib/gpt/src/gpt.c
|
||||
+++ b/lib/gpt/src/gpt.c
|
||||
@@ -222,9 +222,17 @@ static psa_status_t find_gpt_entry(const struct gpt_t *table,
|
||||
@@ -413,7 +413,7 @@ index 984c8f821..d6528f6a5 100644
|
||||
restore_to.header.array_lba,
|
||||
(restore_from->header.num_partitions +
|
||||
diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
index 5d2c4243f..bd9eb8ba1 100644
|
||||
index 5d2c4243f607..bd9eb8ba1da5 100644
|
||||
--- a/lib/gpt/unittests/gpt/test_gpt.c
|
||||
+++ b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
@@ -897,6 +897,153 @@ void test_gpt_entry_duplicate_should_failWhenTableFull(void)
|
||||
@@ -699,3 +699,6 @@ index 5d2c4243f..bd9eb8ba1 100644
|
||||
void test_gpt_attr_set_should_setAttributes(void)
|
||||
{
|
||||
/* Start with a populated GPT */
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
From 901a63f09369cfbed8eff8c450b8615bd4c361af Mon Sep 17 00:00:00 2001
|
||||
From: Devaraj Ranganna <devaraj.ranganna@arm.com>
|
||||
Date: Mon, 22 Sep 2025 12:59:43 +0100
|
||||
Subject: [PATCH] bl2: corstone-1000: secure debug waiting in CM LCS
|
||||
|
||||
Currently, when the device is in Secure Enable (SE) LCS state, setting
|
||||
`dcu_en` register causes CC-312 reset, which effectively resets the
|
||||
device as they are both on same power domain. Therefore, temporarily
|
||||
disable moving SE enable before waiting for secure debug notification.
|
||||
The device will be in CM provisioned state.
|
||||
|
||||
Long-term solution is to implement a solution similar to RSE, secure
|
||||
debug handshake is completed and then a reset is triggered and `dcu_en`
|
||||
is applied during bl2.
|
||||
|
||||
Upstream-Status: Inappropriate [Need to be redesigned]
|
||||
Signed-off-by: Devaraj Ranganna <devaraj.ranganna@arm.com>
|
||||
---
|
||||
.../ext/target/arm/corstone1000/bl2/boot_hal_bl2.c | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c b/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c
|
||||
index 8c4eb80d032c..bf7b62881ad5 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c
|
||||
@@ -165,7 +165,18 @@ int32_t boot_platform_post_init(void)
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
|
||||
+ /* TODO: Currently, when the device is in Secure Enable (SE) LCS state,
|
||||
+ setting `dcu_en` register causes CC-312 reset, which effectively resets
|
||||
+ the device as they are both on same power domain. Therefore, temporarily
|
||||
+ disable moving SE enable before waiting for secure debug notification.
|
||||
+ The device will be in CM provisioned state.
|
||||
+
|
||||
+ Long-term solution is to implement a solution similar to RSE, secure
|
||||
+ debug handshake is completed and then a reset is triggered and `dcu_en`
|
||||
+ is applied during bl2.
|
||||
+
|
||||
if (!tfm_plat_provisioning_is_required()) {
|
||||
+ */
|
||||
|
||||
plat_err = tfm_plat_otp_read(PLAT_OTP_ID_SECURE_DEBUG_PK, 32, secure_debug_rotpk);
|
||||
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
|
||||
@@ -176,7 +187,7 @@ int32_t boot_platform_post_init(void)
|
||||
BOOT_LOG_INF("%s: Corstone-1000 Secure Debug is a %s.\r\n", __func__,
|
||||
(result == 0) ? "success" : "failure");
|
||||
|
||||
- }
|
||||
+ /*}*/
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
+6
-3
@@ -1,7 +1,7 @@
|
||||
From 60277832aa6d4a205a5b1180f0513de0eb7c84c6 Mon Sep 17 00:00:00 2001
|
||||
From 857a18c00ca3301ed6136333732d4c35e838e51f Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Tue, 17 Mar 2026 11:05:45 +0000
|
||||
Subject: [PATCH] plat: cs1k: Add flash erase protection
|
||||
Subject: [PATCH 12/14] plat: cs1k: Add flash erase protection
|
||||
|
||||
The GPT library deals in blocks, whereas flash deals in sectors. On
|
||||
cs1k, eight blocks make up a sector. So, when the GPT library requests a
|
||||
@@ -23,7 +23,7 @@ Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-fi
|
||||
1 file changed, 39 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/io/io_gpt.c b/platform/ext/target/arm/corstone1000/io/io_gpt.c
|
||||
index 513c77016..f7c3d79d2 100644
|
||||
index 513c770166cc..f7c3d79d272f 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/io/io_gpt.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/io/io_gpt.c
|
||||
@@ -53,6 +53,32 @@ static uint8_t sector_buf[FLASH_SECTOR_SIZE];
|
||||
@@ -96,3 +96,6 @@ index 513c77016..f7c3d79d2 100644
|
||||
}
|
||||
} else {
|
||||
/* Partial erase of final sector */
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-147
@@ -1,147 +0,0 @@
|
||||
From 14fff6df016dad1d76f1eda6f77dde1890836c3c Mon Sep 17 00:00:00 2001
|
||||
From: Anton Komlev <anton.komlev@arm.com>
|
||||
Date: Thu, 11 Sep 2025 17:16:43 +0100
|
||||
Subject: [PATCH] Build: adjust CS1000 platform for GCC v14.2
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The latest GNUARM toolchain is more strict, converting some warnings
|
||||
into errors. This change:
|
||||
- adds missing function prototypes and header files
|
||||
- explicitly typecasts incompatible types in secure side
|
||||
- prevents integer–pointer conversion errors in
|
||||
`tfm_test_suite_extra_s` CMake targets because a number of type
|
||||
mismatch is too high.
|
||||
|
||||
Signed-off-by: Anton Komlev <anton.komlev@arm.com>
|
||||
Change-Id: Ia803ebd5ceeab03ab7c7afc7c79c4e5836e03b26
|
||||
|
||||
Upstream-Status: Backport [05c174df157eac428a3e87a1c40170ed7a74af57]
|
||||
Signed-off-by: Jon Mason <jon.mason@arm.com>
|
||||
---
|
||||
.../ext/target/arm/corstone1000/bl1/boot_hal_bl1_2.c | 1 +
|
||||
.../corstone1000/ci_regression_tests/CMakeLists.txt | 2 ++
|
||||
platform/ext/target/arm/corstone1000/io/io_block.c | 1 +
|
||||
platform/ext/target/arm/corstone1000/io/io_flash.c | 10 +++++-----
|
||||
platform/ext/target/arm/corstone1000/platform.c | 8 ++++----
|
||||
.../target/arm/corstone1000/rse_comms/rse_comms_hal.h | 2 ++
|
||||
6 files changed, 15 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bl1/boot_hal_bl1_2.c b/platform/ext/target/arm/corstone1000/bl1/boot_hal_bl1_2.c
|
||||
index 8d85d2b2c9b8..b81e14e03aa9 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/bl1/boot_hal_bl1_2.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/bl1/boot_hal_bl1_2.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "uart_stdout.h"
|
||||
#include "region_defs.h"
|
||||
#include "tfm_log.h"
|
||||
+#include "cc3xx_init.h"
|
||||
|
||||
#ifdef CRYPTO_HW_ACCELERATOR
|
||||
#include "cc3xx_dev.h"
|
||||
diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/CMakeLists.txt b/platform/ext/target/arm/corstone1000/ci_regression_tests/CMakeLists.txt
|
||||
index 405b2b370237..3b023c813e02 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/ci_regression_tests/CMakeLists.txt
|
||||
+++ b/platform/ext/target/arm/corstone1000/ci_regression_tests/CMakeLists.txt
|
||||
@@ -44,3 +44,5 @@ target_compile_definitions(tfm_test_suite_extra_s
|
||||
TEST_FLASH_PAGE_SIZE=${TEST_FLASH_PAGE_SIZE}
|
||||
TEST_FLASH_PROGRAM_UNIT=${TEST_FLASH_PROGRAM_UNIT}
|
||||
)
|
||||
+
|
||||
+target_compile_options(tfm_test_suite_extra_s PRIVATE -Wno-int-conversion)
|
||||
diff --git a/platform/ext/target/arm/corstone1000/io/io_block.c b/platform/ext/target/arm/corstone1000/io/io_block.c
|
||||
index f7eaf7444c38..a5c021ac5a18 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/io/io_block.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/io/io_block.c
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
+#include <string.h>
|
||||
|
||||
#include "io_defs.h"
|
||||
#include "io_driver.h"
|
||||
diff --git a/platform/ext/target/arm/corstone1000/io/io_flash.c b/platform/ext/target/arm/corstone1000/io/io_flash.c
|
||||
index ff4524e9c575..b90a81a48d82 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/io/io_flash.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/io/io_flash.c
|
||||
@@ -71,7 +71,7 @@ static size_t flash_read(int lba, uintptr_t buf, size_t size, size_t flash_id) {
|
||||
size_t rem = info->sector_count * info->sector_size - offset;
|
||||
size_t cnt = size < rem ? size : rem;
|
||||
|
||||
- return flash_driver->ReadData(offset, buf, cnt);
|
||||
+ return flash_driver->ReadData(offset, (void *)buf, cnt);
|
||||
}
|
||||
|
||||
static size_t flash_write(int lba, const uintptr_t buf, size_t size,
|
||||
@@ -86,7 +86,7 @@ static size_t flash_write(int lba, const uintptr_t buf, size_t size,
|
||||
size_t cnt = size < rem ? size : rem;
|
||||
|
||||
flash_driver->EraseSector(offset);
|
||||
- rc = flash_driver->ProgramData(offset, buf, cnt);
|
||||
+ rc = flash_driver->ProgramData(offset, (const void *)buf, cnt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -143,8 +143,8 @@ static int flash_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) {
|
||||
/* Check if Flash ops functions are defined for this flash */
|
||||
assert(flashs_ops[index].read && flashs_ops[index].write);
|
||||
|
||||
- flash_dev_specs[index] = dev_spec;
|
||||
- flash_driver = flash_dev_specs[index]->flash_driver;
|
||||
+ flash_dev_specs[index] = (io_flash_dev_spec_t *)dev_spec;
|
||||
+ flash_driver = (const ARM_DRIVER_FLASH *)flash_dev_specs[index]->flash_driver;
|
||||
|
||||
block_dev_spec[index].block_size = flash_driver->GetInfo()->sector_size;
|
||||
block_dev_spec[index].buffer.offset = flash_dev_specs[index]->buffer;
|
||||
@@ -153,7 +153,7 @@ static int flash_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) {
|
||||
|
||||
flash_driver->Initialize(NULL);
|
||||
|
||||
- block_dev_connectors[index].dev_open(&block_dev_spec[index], dev_info);
|
||||
+ block_dev_connectors[index].dev_open((uintptr_t)&block_dev_spec[index], dev_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/platform/ext/target/arm/corstone1000/platform.c b/platform/ext/target/arm/corstone1000/platform.c
|
||||
index c686b403ff10..d0f30b72a76d 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/platform.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/platform.c
|
||||
@@ -29,10 +29,10 @@ extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
|
||||
static io_dev_connector_t *flash_dev_con;
|
||||
static uint8_t local_block_flash[FLASH_SECTOR_SIZE];
|
||||
static io_flash_dev_spec_t flash_dev_spec = {
|
||||
- .buffer = local_block_flash,
|
||||
+ .buffer = (uintptr_t)local_block_flash,
|
||||
.bufferlen = FLASH_SECTOR_SIZE,
|
||||
.base_addr = FLASH_BASE_ADDRESS,
|
||||
- .flash_driver = &FLASH_DEV_NAME,
|
||||
+ .flash_driver = (uintptr_t)&FLASH_DEV_NAME,
|
||||
};
|
||||
static io_block_spec_t flash_spec = {
|
||||
.offset = FLASH_BASE_ADDRESS,
|
||||
@@ -41,8 +41,8 @@ static io_block_spec_t flash_spec = {
|
||||
|
||||
static platform_image_source_t platform_image_source[] = {
|
||||
[PLATFORM_GPT_IMAGE] = {
|
||||
- .dev_handle = NULL,
|
||||
- .image_spec = &flash_spec,
|
||||
+ .dev_handle = (uintptr_t)NULL,
|
||||
+ .image_spec = (uintptr_t)&flash_spec,
|
||||
}
|
||||
};
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/rse_comms/rse_comms_hal.h b/platform/ext/target/arm/corstone1000/rse_comms/rse_comms_hal.h
|
||||
index c4676cb2ef74..29be08ddb36e 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/rse_comms/rse_comms_hal.h
|
||||
+++ b/platform/ext/target/arm/corstone1000/rse_comms/rse_comms_hal.h
|
||||
@@ -49,6 +49,8 @@ enum tfm_plat_err_t tfm_multi_core_hal_receive(void *mhu_receiver_dev,
|
||||
*/
|
||||
enum tfm_plat_err_t tfm_multi_core_hal_reply(struct client_request_t *req);
|
||||
|
||||
+int32_t tfm_hal_client_id_translate(void *owner, int32_t client_id_in);
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
From e7fb39d0124f60b624f535bc78745fbf4aac678c 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 13/14] 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 e2219d80a75c..b7282beb232e 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 */
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
From 949ecbcd29660225f42bdfc37bdff4b79917620a Mon Sep 17 00:00:00 2001
|
||||
From: Jon Mason <jon.mason@arm.com>
|
||||
Date: Mon, 23 Feb 2026 11:53:38 -0500
|
||||
Subject: [PATCH] Workaround compile errors in AES
|
||||
|
||||
TF-M commit d7c4850d8ce3abeb2634e85631b4bbadeb343f23 removes support for
|
||||
bl1_aes_256_ctr_decrypt() API. Since backporting that is more involved
|
||||
than we want for this release. Simply do some casting to address the
|
||||
issues until the next release (which will have the commit referenced
|
||||
previously).
|
||||
|
||||
Upstream-Status: Inappropriate
|
||||
Signed-off-by: Jon Mason <jon.mason@arm.com>
|
||||
---
|
||||
platform/ext/target/arm/corstone1000/bl1/cc312_rom_crypto.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bl1/cc312_rom_crypto.c b/platform/ext/target/arm/corstone1000/bl1/cc312_rom_crypto.c
|
||||
index 542fc01bc7a8..5b34d90464eb 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/bl1/cc312_rom_crypto.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/bl1/cc312_rom_crypto.c
|
||||
@@ -328,7 +328,7 @@ fih_int bl1_aes_256_ctr_decrypt(enum tfm_bl1_key_id_t key_id,
|
||||
uint32_t key_buf[32 / sizeof(uint32_t)];
|
||||
fih_int fih_rc;
|
||||
int32_t rc = 0;
|
||||
- const uint8_t *input_key = key_buf;
|
||||
+ const uint8_t *input_key = (const uint8_t *)key_buf;
|
||||
cc3xx_err_t err;
|
||||
|
||||
if (ciphertext_length == 0) {
|
||||
@@ -356,7 +356,7 @@ fih_int bl1_aes_256_ctr_decrypt(enum tfm_bl1_key_id_t key_id,
|
||||
}
|
||||
|
||||
err = cc3xx_lowlevel_aes_init(CC3XX_AES_DIRECTION_DECRYPT, CC3XX_AES_MODE_CTR,
|
||||
- cc3xx_key_type, input_key, CC3XX_AES_KEYSIZE_256,
|
||||
+ cc3xx_key_type, (const uint32_t *)input_key, CC3XX_AES_KEYSIZE_256,
|
||||
(uint32_t *)counter, 16);
|
||||
fih_rc = fih_int_encode_zero_equality(err);
|
||||
if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
|
||||
@@ -388,7 +388,7 @@ static int32_t aes_256_ecb_encrypt(enum tfm_bl1_key_id_t key_id,
|
||||
return -1;
|
||||
}
|
||||
|
||||
- rc = bl1_key_to_cc3xx_key(key_id, &cc3xx_key_type, key_buf, sizeof(key_buf));
|
||||
+ rc = bl1_key_to_cc3xx_key(key_id, &cc3xx_key_type, (uint8_t *)key_buf, sizeof(key_buf));
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
From 3b01281520036b621166d409634dab9b46d01f70 Mon Sep 17 00:00:00 2001
|
||||
From: Ahmed Gomaa <ahmed.gomaa@arm.com>
|
||||
Date: Wed, 2 Sep 2026 12:00:00 +0100
|
||||
Subject: [PATCH 14/14] platform: corstone1000: keep CM during secure debug
|
||||
|
||||
Add a temporary Corstone-1000 Secure Debug workaround that skips runtime
|
||||
TF-M provisioning when Secure Debug is enabled. This keeps the device in
|
||||
the CM lifecycle state and avoids the provisioning reset, allowing the
|
||||
authenticated debug session to remain active.
|
||||
|
||||
Keep this workaround until a reset-safe architecture is implemented to
|
||||
preserve the authenticated DCU_EN value across reset and apply it from BL2.
|
||||
|
||||
Upstream-Status: Inappropriate [temporary platform workaround]
|
||||
Signed-off-by: Ahmed Gomaa <ahmed.gomaa@arm.com>
|
||||
---
|
||||
secure_fw/spm/CMakeLists.txt | 1 +
|
||||
secure_fw/spm/core/main.c | 9 +++++++++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
diff --git a/secure_fw/spm/CMakeLists.txt b/secure_fw/spm/CMakeLists.txt
|
||||
index bf0ab6e99c16..6741c52089de 100644
|
||||
--- a/secure_fw/spm/CMakeLists.txt
|
||||
+++ b/secure_fw/spm/CMakeLists.txt
|
||||
@@ -110,6 +110,7 @@ target_compile_definitions(tfm_spm
|
||||
$<$<STREQUAL:${CONFIG_TFM_BRANCH_PROTECTION_FEAT},BRANCH_PROTECTION_PACRET_LEAF>:BRANCH_PROTECTION_CONTROL=2>
|
||||
$<$<STREQUAL:${CONFIG_TFM_BRANCH_PROTECTION_FEAT},BRANCH_PROTECTION_BTI>:BRANCH_PROTECTION_CONTROL=3>
|
||||
$<$<BOOL:${PLATFORM_PSA_ADAC_SECURE_DEBUG}>:PLATFORM_PSA_ADAC_SECURE_DEBUG>
|
||||
+ $<$<BOOL:${CORSTONE1000_SKIP_PROVISIONING_FOR_DEBUG}>:CORSTONE1000_SKIP_PROVISIONING_FOR_DEBUG>
|
||||
$<$<BOOL:${CONFIG_TFM_REUSE_COPY_AREA_FOR_SP_STACKS}>:CONFIG_TFM_REUSE_COPY_AREA_FOR_SP_STACKS>
|
||||
$<$<BOOL:${TFM_TZ_REENTRANCY_CHECK}>:TFM_TZ_REENTRANCY_CHECK>
|
||||
)
|
||||
diff --git a/secure_fw/spm/core/main.c b/secure_fw/spm/core/main.c
|
||||
index 2bafac0c980e..22090c34efc4 100644
|
||||
--- a/secure_fw/spm/core/main.c
|
||||
+++ b/secure_fw/spm/core/main.c
|
||||
@@ -31,7 +31,9 @@ static fih_ret tfm_core_init(void)
|
||||
{
|
||||
enum tfm_plat_err_t plat_err = TFM_PLAT_ERR_SYSTEM_ERR;
|
||||
FIH_DECLARE(fih_rc, FIH_FAILURE);
|
||||
+#ifndef CORSTONE1000_SKIP_PROVISIONING_FOR_DEBUG
|
||||
bool provisioning_required;
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Access to any peripheral should be performed after programming
|
||||
@@ -65,6 +67,7 @@ static fih_ret tfm_core_init(void)
|
||||
FIH_RET(SPM_ERROR_GENERIC);
|
||||
}
|
||||
|
||||
+#ifndef CORSTONE1000_SKIP_PROVISIONING_FOR_DEBUG
|
||||
/* Perform provisioning. */
|
||||
plat_err = tfm_plat_provisioning_is_required(&provisioning_required);
|
||||
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
|
||||
@@ -77,6 +80,12 @@ static fih_ret tfm_core_init(void)
|
||||
FIH_RET(SPM_ERROR_GENERIC);
|
||||
}
|
||||
}
|
||||
+#else
|
||||
+ /* Temporary workaround: retain CM and avoid the provisioning reset. */
|
||||
+ WARN("Skipping TF-M provisioning for Secure Debug workaround. "
|
||||
+ "Device remains unprovisioned and must not be used in "
|
||||
+ "production.\n");
|
||||
+#endif
|
||||
|
||||
TFM_COVERITY_DEVIATE_LINE(MISRA_C_2023_Rule_2_2, "Parameters can be changed by user and this code will make effect")
|
||||
tfm_plat_provisioning_check_for_dummy_keys();
|
||||
--
|
||||
2.39.5
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
From 3d2bdf81fee8832101fe47b633af5bdee251531a Mon Sep 17 00:00:00 2001
|
||||
From: Michael Safwat <michael.safwat@arm.com>
|
||||
Date: Fri, 13 Mar 2026 12:42:09 +0000
|
||||
Subject: [PATCH] CC312: Add barrier before first AO lock write
|
||||
|
||||
On Corstone-1000 MPS3 with GCC 15.x, TF-M can HardFault in
|
||||
CC_LibInit() on the first HOST_AO_LOCK_BITS write.
|
||||
|
||||
Add a compiler barrier before that write to keep the fix minimal and
|
||||
local to the affected sequence.
|
||||
|
||||
Signed-off-by: Michael Safwat <michael.safwat@arm.com>
|
||||
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/49269]
|
||||
---
|
||||
lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c
|
||||
index 4b08c02526..1e96fcac5b 100644
|
||||
--- a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c
|
||||
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "cc_rnd_common.h"
|
||||
#include "cc_int_general_defs.h"
|
||||
|
||||
+#define CC_COMPILER_BARRIER() __asm volatile("" ::: "memory")
|
||||
+
|
||||
CC_PalMutex CCSymCryptoMutex;
|
||||
CC_PalMutex CCAsymCryptoMutex;
|
||||
CC_PalMutex *pCCRndCryptoMutex;
|
||||
@@ -213,6 +215,7 @@ CClibRetCode_t CC_LibInit(CCRndContext_t *rndContext_ptr, CCRndWorkBuff_t *rndW
|
||||
/* turn off the DFA since Cerberus doen't support it */
|
||||
reg = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
|
||||
CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_FORCE_DFA_ENABLE, reg, 0x0);
|
||||
+ CC_COMPILER_BARRIER();
|
||||
CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS) ,reg );
|
||||
tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF,HOST_AO_LOCK_BITS));
|
||||
if(tempVal != reg) {
|
||||
--
|
||||
2.43.0
|
||||
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
From 9f86d644aa23589e5187f0a22394438cd525d574 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Chapman <alex.chapman@arm.com>
|
||||
Date: Wed, 4 Mar 2026 13:41:59 +0000
|
||||
Subject: [PATCH] Platform: CS1K: make mutlicore support platform generic
|
||||
|
||||
To improve portability, testing coverage, and future platform enablement.
|
||||
|
||||
- Replace FVP-only multicore checks with platform-generic checks.
|
||||
|
||||
Upstream-Status: Backport [71619253e03cc10cdd4527ab7e896e3ec10afabe]
|
||||
Signed-off-by: Alex Chapman <alex.chapman@arm.com>
|
||||
---
|
||||
platform/ext/target/arm/corstone1000/CMakeLists.txt | 4 +---
|
||||
.../target/arm/corstone1000/Device/Config/device_cfg.h | 2 +-
|
||||
platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c | 8 ++++----
|
||||
3 files changed, 6 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/CMakeLists.txt b/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
index 993c51591..a13f16fd7 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
+++ b/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
@@ -407,12 +407,10 @@ target_sources(tfm_psa_rot_partition_ns_agent_mailbox
|
||||
tfm_hal_multi_core.c
|
||||
)
|
||||
|
||||
-if (PLATFORM_IS_FVP)
|
||||
target_compile_definitions(tfm_psa_rot_partition_ns_agent_mailbox
|
||||
PUBLIC
|
||||
- $<$<BOOL:${ENABLE_MULTICORE}>:CORSTONE1000_FVP_MULTICORE>
|
||||
+ $<$<BOOL:${ENABLE_MULTICORE}>:CORSTONE1000_MULTICORE>
|
||||
)
|
||||
-endif()
|
||||
#========================= tfm_spm ============================================#
|
||||
|
||||
target_sources(tfm_spm
|
||||
diff --git a/platform/ext/target/arm/corstone1000/Device/Config/device_cfg.h b/platform/ext/target/arm/corstone1000/Device/Config/device_cfg.h
|
||||
index 544475a86..0c3a9088e 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/Device/Config/device_cfg.h
|
||||
+++ b/platform/ext/target/arm/corstone1000/Device/Config/device_cfg.h
|
||||
@@ -46,7 +46,7 @@
|
||||
#define CFI_S
|
||||
|
||||
/* Total number of host cores */
|
||||
-#if CORSTONE1000_FVP_MULTICORE
|
||||
+#if CORSTONE1000_MULTICORE
|
||||
#define PLATFORM_HOST_MAX_CORE_COUNT 4
|
||||
#else
|
||||
#define PLATFORM_HOST_MAX_CORE_COUNT 1
|
||||
diff --git a/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c b/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c
|
||||
index 10c66ac41..9a785bfa0 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c
|
||||
@@ -62,7 +62,7 @@ void tfm_hal_boot_ns_cpu(uintptr_t start_addr)
|
||||
volatile uint32_t *PE0_CONFIG =
|
||||
(uint32_t *)(CORSTONE1000_HOST_BASE_SYSTEM_CONTROL_BASE
|
||||
+ HOST_CPU_PE0_CONFIG_OFFSET);
|
||||
-#if CORSTONE1000_FVP_MULTICORE
|
||||
+#if CORSTONE1000_MULTICORE
|
||||
volatile uint32_t *PE1_CONFIG =
|
||||
(uint32_t *)(CORSTONE1000_HOST_BASE_SYSTEM_CONTROL_BASE
|
||||
+ HOST_CPU_PE1_CONFIG_OFFSET);
|
||||
@@ -80,7 +80,7 @@ void tfm_hal_boot_ns_cpu(uintptr_t start_addr)
|
||||
#endif
|
||||
/* Select host CPU architecture as AArch64 */
|
||||
*PE0_CONFIG |= AA64nAA32_MASK; /* 0b1 – AArch64 */
|
||||
-#if CORSTONE1000_FVP_MULTICORE
|
||||
+#if CORSTONE1000_MULTICORE
|
||||
*PE1_CONFIG |= AA64nAA32_MASK; /* 0b1 – AArch64 */
|
||||
*PE2_CONFIG |= AA64nAA32_MASK; /* 0b1 – AArch64 */
|
||||
*PE3_CONFIG |= AA64nAA32_MASK; /* 0b1 – AArch64 */
|
||||
@@ -92,7 +92,7 @@ void tfm_hal_boot_ns_cpu(uintptr_t start_addr)
|
||||
/* Clear HOST_SYS_RST_CTRL register to bring host out of RESET */
|
||||
*reset_ctl_reg = 0;
|
||||
|
||||
-#if CORSTONE1000_FVP_MULTICORE
|
||||
+#if CORSTONE1000_MULTICORE
|
||||
/* Wake up secondary cores.
|
||||
* This should be done after bringing the primary core out of reset.*/
|
||||
for (int core_index=1; core_index < PLATFORM_HOST_MAX_CORE_COUNT; core_index++) {
|
||||
@@ -111,7 +111,7 @@ void tfm_hal_boot_ns_cpu(uintptr_t start_addr)
|
||||
PPU_SetOperatingPolicy(CORE0_PPU, PPU_OP_MODE_ONE_SLICE_SF_ONLY_ON, false);
|
||||
PPU_SetPowerPolicy(CORE0_PPU, PPU_PWR_MODE_ON, false);
|
||||
|
||||
-#if CORSTONE1000_FVP_MULTICORE
|
||||
+#if CORSTONE1000_MULTICORE
|
||||
/* Power on all Cortex-A320 cores in DSU-120T Cluster */
|
||||
PPU_SetOperatingPolicy(CORE1_PPU, PPU_OP_MODE_ONE_SLICE_SF_ONLY_ON, false);
|
||||
PPU_SetPowerPolicy(CORE1_PPU, PPU_PWR_MODE_ON, false);
|
||||
--
|
||||
2.43.0
|
||||
-217
@@ -1,217 +0,0 @@
|
||||
From 5fc4f3857739a9fe93819cedc4a8108d33bf8241 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Thu, 27 Nov 2025 10:35:58 +0000
|
||||
Subject: [PATCH] lib: efi_guid: Added EFI GUID library
|
||||
|
||||
This library can be used to generate version 4 UUID/GUIDs according to
|
||||
RFC 4122 by using a PSA crypto driver. A separate header is provided to
|
||||
give access to the struct without the need of a PSA config.
|
||||
|
||||
Change-Id: Ief35b2a4f565889ba2ea0de82e20dc12f6e824e8
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [3bdd2562ebad3115457ea75e58d0554802e12dba]
|
||||
---
|
||||
CMakeLists.txt | 1 +
|
||||
lib/efi_guid/CMakeLists.txt | 26 ++++++++++++
|
||||
lib/efi_guid/inc/efi_guid.h | 36 +++++++++++++++++
|
||||
lib/efi_guid/inc/efi_guid_structs.h | 62 +++++++++++++++++++++++++++++
|
||||
lib/efi_guid/src/efi_guid.c | 33 +++++++++++++++
|
||||
5 files changed, 158 insertions(+)
|
||||
create mode 100644 lib/efi_guid/CMakeLists.txt
|
||||
create mode 100644 lib/efi_guid/inc/efi_guid.h
|
||||
create mode 100644 lib/efi_guid/inc/efi_guid_structs.h
|
||||
create mode 100644 lib/efi_guid/src/efi_guid.c
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 2560dd15e..b120de697 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -44,6 +44,7 @@ project("Trusted Firmware M" VERSION ${TFM_VERSION} LANGUAGES C CXX ASM)
|
||||
|
||||
add_subdirectory(lib/backtrace)
|
||||
add_subdirectory(lib/ext)
|
||||
+add_subdirectory(lib/efi_guid)
|
||||
add_subdirectory(lib/fih)
|
||||
add_subdirectory(lib/tfm_log)
|
||||
add_subdirectory(lib/tfm_log_unpriv)
|
||||
diff --git a/lib/efi_guid/CMakeLists.txt b/lib/efi_guid/CMakeLists.txt
|
||||
new file mode 100644
|
||||
index 000000000..656eb72ea
|
||||
--- /dev/null
|
||||
+++ b/lib/efi_guid/CMakeLists.txt
|
||||
@@ -0,0 +1,26 @@
|
||||
+#-------------------------------------------------------------------------------
|
||||
+# SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
+#
|
||||
+# SPDX-License-Identifier: BSD-3-Clause
|
||||
+#
|
||||
+#-------------------------------------------------------------------------------
|
||||
+
|
||||
+add_library(tfm_efi_guid STATIC)
|
||||
+
|
||||
+target_sources(tfm_efi_guid
|
||||
+ PRIVATE
|
||||
+ src/efi_guid.c
|
||||
+)
|
||||
+
|
||||
+target_include_directories(tfm_efi_guid
|
||||
+ PUBLIC
|
||||
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
|
||||
+ PRIVATE
|
||||
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
+)
|
||||
+
|
||||
+target_link_libraries(tfm_efi_guid
|
||||
+ PUBLIC
|
||||
+ psa_interface
|
||||
+ psa_crypto_config
|
||||
+)
|
||||
diff --git a/lib/efi_guid/inc/efi_guid.h b/lib/efi_guid/inc/efi_guid.h
|
||||
new file mode 100644
|
||||
index 000000000..81f6ad507
|
||||
--- /dev/null
|
||||
+++ b/lib/efi_guid/inc/efi_guid.h
|
||||
@@ -0,0 +1,36 @@
|
||||
+/*
|
||||
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef __TFM_EFI_GUID_H__
|
||||
+#define __TFM_EFI_GUID_H__
|
||||
+
|
||||
+#include "psa/crypto.h"
|
||||
+#include "efi_guid_structs.h"
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+/**
|
||||
+ * \brief Generates a random version 4 UUID/GUID using a PSA crypto driver.
|
||||
+ *
|
||||
+ * \note See RFC 4112 for details on UUID/GUIDs.
|
||||
+ *
|
||||
+ * \note See psa_generate_random for possible failures.
|
||||
+ *
|
||||
+ * \param[out] guid Pointer populated with the generated UUID/GUID.
|
||||
+ *
|
||||
+ * \return PSA_SUCCESS on success or a PSA error code on failure.
|
||||
+ *
|
||||
+ */
|
||||
+psa_status_t efi_guid_generate_random(struct efi_guid_t *guid);
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* __TFM_EFI_GUID_H__ */
|
||||
diff --git a/lib/efi_guid/inc/efi_guid_structs.h b/lib/efi_guid/inc/efi_guid_structs.h
|
||||
new file mode 100644
|
||||
index 000000000..c89e8f692
|
||||
--- /dev/null
|
||||
+++ b/lib/efi_guid/inc/efi_guid_structs.h
|
||||
@@ -0,0 +1,62 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2021, Linaro Limited
|
||||
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef __TFM_EFI_GUID_STRUCTS_H__
|
||||
+#define __TFM_EFI_GUID_STRUCTS_H__
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+#define EFI_GUID_NODE_LEN 6
|
||||
+
|
||||
+/**
|
||||
+ * \brief Representation that makes creating GUIDs slightly easier.
|
||||
+ */
|
||||
+struct efi_guid_t {
|
||||
+ uint32_t time_low; /**< Low 32-bits of timestamp. */
|
||||
+ uint16_t time_mid; /**< Middle 16-bits of timestamp. */
|
||||
+ uint16_t time_hi_and_version; /**< High 12-bits of timestamp with 4-bit version. */
|
||||
+ uint8_t clock_seq_hi_and_reserved; /**< High 4-bits of clock sequence with 4-bit variant. */
|
||||
+ uint8_t clock_seq_low; /**< Low 8-bits of clock sequence. */
|
||||
+ uint8_t node[EFI_GUID_NODE_LEN]; /**< 48-bit spatially unique node identifier. */
|
||||
+};
|
||||
+
|
||||
+static inline int efi_guid_cmp(const struct efi_guid_t *g1,
|
||||
+ const struct efi_guid_t *g2)
|
||||
+{
|
||||
+ return memcmp(g1, g2, sizeof(struct efi_guid_t));
|
||||
+}
|
||||
+
|
||||
+static inline void *efi_guid_cpy(const struct efi_guid_t *src,
|
||||
+ struct efi_guid_t *dst)
|
||||
+{
|
||||
+ return memcpy(dst, src, sizeof(struct efi_guid_t));
|
||||
+}
|
||||
+
|
||||
+/** \brief Helper macro to build an EFI GUID structure from individual values. */
|
||||
+#define MAKE_EFI_GUID(a, b, c, d0, d1, e0, e1, e2, e3, e4, e5) \
|
||||
+ { \
|
||||
+ (a) & 0xffffffff, (b)&0xffff, (c)&0xffff, d0, d1, { \
|
||||
+ (e0), (e1), (e2), (e3), (e4), (e5) \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/** \brief Helper macro to build the EFI GUID 00000000-0000-0000-0000-0000000000. */
|
||||
+#define NULL_GUID \
|
||||
+ MAKE_EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
+ 0x00, 0x00, 0x00)
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* __TFM_EFI_GUID_STRUCTS_H__ */
|
||||
diff --git a/lib/efi_guid/src/efi_guid.c b/lib/efi_guid/src/efi_guid.c
|
||||
new file mode 100644
|
||||
index 000000000..cb8730a51
|
||||
--- /dev/null
|
||||
+++ b/lib/efi_guid/src/efi_guid.c
|
||||
@@ -0,0 +1,33 @@
|
||||
+/*
|
||||
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ */
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#include "psa/crypto.h"
|
||||
+
|
||||
+#include "efi_guid_structs.h"
|
||||
+#include "efi_guid.h"
|
||||
+
|
||||
+psa_status_t efi_guid_generate_random(struct efi_guid_t *guid)
|
||||
+{
|
||||
+ const psa_status_t ret = psa_generate_random((uint8_t *)guid, sizeof(*guid));
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* According to RFC 4122, counting bits from the right:
|
||||
+ * - Bits 6 and 7 of clock_seq_hi_and_reserved need to be set to
|
||||
+ * 0 and 1 respecitively
|
||||
+ * - Bits 12 through 15 of time_hi_and_version need to be set to
|
||||
+ * 0b0100
|
||||
+ */
|
||||
+ guid->clock_seq_hi_and_reserved &= 0x3F;
|
||||
+ guid->clock_seq_hi_and_reserved |= 0x80;
|
||||
+ guid->time_hi_and_version &= 0x0FFF;
|
||||
+ guid->time_hi_and_version |= 0x4000;
|
||||
+
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
-136
@@ -1,136 +0,0 @@
|
||||
From 4a47d926420bfec4a0e687b6ecc4cf52419e4f58 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Thu, 27 Nov 2025 10:37:28 +0000
|
||||
Subject: [PATCH] lib: efi_soft_crc: Added EFI CRC library
|
||||
|
||||
This library can be used to perform CRC32 calculations using the
|
||||
standard CRC32 polynomial specified by the UEFI spec 2.10. It does not
|
||||
use a lookup table to save on memory. The polynomial used is in reverse
|
||||
order to match little-endian machines.
|
||||
|
||||
Change-Id: Ifce5a1cbbb3ab394bc748305be213a8467610015
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [3f2b707eaadef8008f333bd5c519c1b2544458ab]
|
||||
---
|
||||
lib/ext/CMakeLists.txt | 1 +
|
||||
lib/ext/efi_soft_crc/CMakeLists.txt | 18 ++++++++++++++
|
||||
lib/ext/efi_soft_crc/inc/efi_soft_crc.h | 33 +++++++++++++++++++++++++
|
||||
lib/ext/efi_soft_crc/src/efi_soft_crc.c | 32 ++++++++++++++++++++++++
|
||||
4 files changed, 84 insertions(+)
|
||||
create mode 100644 lib/ext/efi_soft_crc/CMakeLists.txt
|
||||
create mode 100644 lib/ext/efi_soft_crc/inc/efi_soft_crc.h
|
||||
create mode 100644 lib/ext/efi_soft_crc/src/efi_soft_crc.c
|
||||
|
||||
diff --git a/lib/ext/CMakeLists.txt b/lib/ext/CMakeLists.txt
|
||||
index 05f6b8f14..1dffbacfb 100644
|
||||
--- a/lib/ext/CMakeLists.txt
|
||||
+++ b/lib/ext/CMakeLists.txt
|
||||
@@ -10,6 +10,7 @@ add_subdirectory(qcbor)
|
||||
add_subdirectory(t_cose)
|
||||
add_subdirectory(mbedcrypto)
|
||||
add_subdirectory(cmsis)
|
||||
+add_subdirectory(efi_soft_crc)
|
||||
if(BL2)
|
||||
add_subdirectory(mcuboot)
|
||||
endif()
|
||||
diff --git a/lib/ext/efi_soft_crc/CMakeLists.txt b/lib/ext/efi_soft_crc/CMakeLists.txt
|
||||
new file mode 100644
|
||||
index 000000000..47fd2d507
|
||||
--- /dev/null
|
||||
+++ b/lib/ext/efi_soft_crc/CMakeLists.txt
|
||||
@@ -0,0 +1,18 @@
|
||||
+#-------------------------------------------------------------------------------
|
||||
+# SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
+#
|
||||
+# SPDX-License-Identifier: BSD-3-Clause
|
||||
+#
|
||||
+#-------------------------------------------------------------------------------
|
||||
+
|
||||
+add_library(tfm_efi_soft_crc STATIC)
|
||||
+
|
||||
+target_sources(tfm_efi_soft_crc
|
||||
+ PRIVATE
|
||||
+ src/efi_soft_crc.c
|
||||
+)
|
||||
+
|
||||
+target_include_directories(tfm_efi_soft_crc
|
||||
+ PUBLIC
|
||||
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
|
||||
+)
|
||||
diff --git a/lib/ext/efi_soft_crc/inc/efi_soft_crc.h b/lib/ext/efi_soft_crc/inc/efi_soft_crc.h
|
||||
new file mode 100644
|
||||
index 000000000..77baa8987
|
||||
--- /dev/null
|
||||
+++ b/lib/ext/efi_soft_crc/inc/efi_soft_crc.h
|
||||
@@ -0,0 +1,33 @@
|
||||
+/*
|
||||
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef __TFM_EFI_SOFT_CRC_H__
|
||||
+#define __TFM_EFI_SOFT_CRC_H__
|
||||
+
|
||||
+#include <stddef.h>
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+/**
|
||||
+ * \brief Updates a CRC32 calculation using ISO 3309 CRC-32.
|
||||
+ *
|
||||
+ * \param[in] old_crc Existing CRC value (0 for the first calculation).
|
||||
+ * \param[in] buf Buffer of bytes to perform the calculation over.
|
||||
+ * \param[in] len Length of \p buf in bytes.
|
||||
+ *
|
||||
+ * \return The calculated CRC32 value.
|
||||
+ */
|
||||
+uint32_t efi_soft_crc32_update(uint32_t old_crc, const uint8_t *buf, size_t len);
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* __TFM_EFI_SOFT_CRC_H__ */
|
||||
diff --git a/lib/ext/efi_soft_crc/src/efi_soft_crc.c b/lib/ext/efi_soft_crc/src/efi_soft_crc.c
|
||||
new file mode 100644
|
||||
index 000000000..041a321cd
|
||||
--- /dev/null
|
||||
+++ b/lib/ext/efi_soft_crc/src/efi_soft_crc.c
|
||||
@@ -0,0 +1,32 @@
|
||||
+/* Copyright (C) 2013 Henry S. Warren Jr. You are free to use, copy,
|
||||
+ * and distribute any of the code on this web site, whether modified
|
||||
+ * by you or not.
|
||||
+ */
|
||||
+
|
||||
+#include "efi_soft_crc.h"
|
||||
+
|
||||
+/* The standard polynomial, in reverse */
|
||||
+#define POLYNOMIAL 0xEDB88320
|
||||
+
|
||||
+/* Algorithmic approach to CRC calculation: avoids lookup tables, slow. Byte
|
||||
+ * reversal is avoided by shifting the crc register right instead of left and
|
||||
+ * by using a reversed 32-bit word to represent the polynomial.
|
||||
+ *
|
||||
+ * Derived from work by Henry S. Warren Jr.
|
||||
+ */
|
||||
+uint32_t efi_soft_crc32_update(uint32_t old_crc32, const uint8_t *buf, size_t len)
|
||||
+{
|
||||
+ register uint32_t crc32 = ~old_crc32;
|
||||
+ uint32_t mask;
|
||||
+
|
||||
+ for ( ; len; --len, ++buf)
|
||||
+ {
|
||||
+ crc32 ^= *buf;
|
||||
+ for (size_t i = 0; i < 8; ++i) {
|
||||
+ mask = -(crc32 & 1);
|
||||
+ crc32 = (crc32 >> 1) ^ (POLYNOMIAL & mask);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ~crc32;
|
||||
+}
|
||||
-1495
File diff suppressed because it is too large.
Load diff
-308
@@ -1,308 +0,0 @@
|
||||
From b3775fd8aa2078e5e86d5cdb4164e6fc31fabbfc Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Wed, 11 Feb 2026 11:16:13 +0000
|
||||
Subject: [PATCH] lib: gpt: Expanded how GPT partition can be identified
|
||||
|
||||
The GUID of a partition is not always known, particularly for tables
|
||||
that have been created outside the control of the user. Therefore,
|
||||
allowing the name or type to be used to identify a partition gives the
|
||||
user greater flexibility. These may not be unique, however, and so must
|
||||
be indexed. A single entry is returned rather than a list so as to not
|
||||
dynamically allocate such memory.
|
||||
|
||||
Change-Id: I7687bfc737b244f6e589c4fe6b61c370daf1b062
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [aede42c1c58b5681fe50bbec3a797f69256d108e]
|
||||
---
|
||||
lib/gpt/inc/gpt.h | 34 +++++++++
|
||||
lib/gpt/src/gpt.c | 68 +++++++++++++++--
|
||||
lib/gpt/unittests/gpt/test_gpt.c | 127 +++++++++++++++++++++++++++++++
|
||||
3 files changed, 223 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/lib/gpt/inc/gpt.h b/lib/gpt/inc/gpt.h
|
||||
index d98abe980..947a6b341 100644
|
||||
--- a/lib/gpt/inc/gpt.h
|
||||
+++ b/lib/gpt/inc/gpt.h
|
||||
@@ -48,6 +48,40 @@ __attribute__((nonnull(1,2)))
|
||||
psa_status_t gpt_entry_read(const struct efi_guid_t *guid,
|
||||
struct partition_entry_t *partition_entry);
|
||||
|
||||
+/**
|
||||
+ * \brief Reads the contents of a partition entry identified by name.
|
||||
+ *
|
||||
+ * \param[in] name Name of the partition to read in unicode.
|
||||
+ * \param[in] index Index to read when multiple entries share the same name.
|
||||
+ * \param[out] partition_entry Populated partition entry on success.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS Success.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_DOES_NOT_EXIST No entry found with the provided name at \p index. For example,
|
||||
+ * \p index was 1 (second entry) but only one entry was found.
|
||||
+ */
|
||||
+__attribute__((nonnull(1,3)))
|
||||
+psa_status_t gpt_entry_read_by_name(const char name[GPT_ENTRY_NAME_LENGTH],
|
||||
+ const uint32_t index,
|
||||
+ struct partition_entry_t *partition_entry);
|
||||
+
|
||||
+/**
|
||||
+ * \brief Reads the contents of a partition entry identified by type.
|
||||
+ *
|
||||
+ * \param[in] type Type of the partition to read.
|
||||
+ * \param[in] index Index to read when multiple entries share the same type.
|
||||
+ * \param[out] partition_entry Populated partition entry on success.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS Success.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_DOES_NOT_EXIST No entry found with the provided type at \p index. For example,
|
||||
+ * \p index was 1 (second entry) but only one entry was found.
|
||||
+ */
|
||||
+__attribute__((nonnull(1,3)))
|
||||
+psa_status_t gpt_entry_read_by_type(const struct efi_guid_t *type,
|
||||
+ const uint32_t index,
|
||||
+ struct partition_entry_t *partition_entry);
|
||||
+
|
||||
/**
|
||||
* \brief Reads the GPT header from the second block (LBA 1).
|
||||
*
|
||||
diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c
|
||||
index 99d735797..1662b81c2 100644
|
||||
--- a/lib/gpt/src/gpt.c
|
||||
+++ b/lib/gpt/src/gpt.c
|
||||
@@ -177,6 +177,8 @@ static inline uint64_t partition_entry_lba(const struct gpt_t *table,
|
||||
static inline uint64_t gpt_entry_per_lba_count(void);
|
||||
static psa_status_t count_used_partitions(const struct gpt_t *table,
|
||||
uint32_t *num_used);
|
||||
+static inline void parse_entry(struct gpt_entry_t *entry,
|
||||
+ struct partition_entry_t *partition_entry);
|
||||
static psa_status_t read_from_flash(uint64_t required_lba);
|
||||
static psa_status_t read_entry_from_flash(const struct gpt_t *table,
|
||||
uint32_t array_index,
|
||||
@@ -190,6 +192,8 @@ static psa_status_t find_gpt_entry(const struct gpt_t *table,
|
||||
uint32_t *array_index);
|
||||
static psa_status_t mbr_load(struct mbr_t *mbr);
|
||||
static bool gpt_entry_cmp_guid(const struct gpt_entry_t *entry, const void *guid);
|
||||
+static bool gpt_entry_cmp_name(const struct gpt_entry_t *entry, const void *name);
|
||||
+static bool gpt_entry_cmp_type(const struct gpt_entry_t *entry, const void *type);
|
||||
|
||||
/* PUBLIC API FUNCTIONS */
|
||||
|
||||
@@ -202,12 +206,37 @@ psa_status_t gpt_entry_read(const struct efi_guid_t *guid,
|
||||
return ret;
|
||||
}
|
||||
|
||||
- partition_entry->start = cached_entry.start;
|
||||
- partition_entry->size = cached_entry.end - cached_entry.start + 1;
|
||||
- memcpy(partition_entry->name, cached_entry.name, GPT_ENTRY_NAME_LENGTH);
|
||||
- partition_entry->attr = cached_entry.attr;
|
||||
- partition_entry->partition_guid = cached_entry.unique_guid;
|
||||
- partition_entry->type_guid = cached_entry.partition_type;
|
||||
+ parse_entry(&cached_entry, partition_entry);
|
||||
+
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+psa_status_t gpt_entry_read_by_name(const char name[GPT_ENTRY_NAME_LENGTH],
|
||||
+ const uint32_t index,
|
||||
+ struct partition_entry_t *partition_entry)
|
||||
+{
|
||||
+ struct gpt_entry_t cached_entry;
|
||||
+ const psa_status_t ret = find_gpt_entry(&primary_gpt, gpt_entry_cmp_name, name, index, &cached_entry, NULL);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ parse_entry(&cached_entry, partition_entry);
|
||||
+
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+psa_status_t gpt_entry_read_by_type(const struct efi_guid_t *type,
|
||||
+ const uint32_t index,
|
||||
+ struct partition_entry_t *partition_entry)
|
||||
+{
|
||||
+ struct gpt_entry_t cached_entry;
|
||||
+ const psa_status_t ret = find_gpt_entry(&primary_gpt, gpt_entry_cmp_type, type, index, &cached_entry, NULL);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ parse_entry(&cached_entry, partition_entry);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
@@ -322,6 +351,18 @@ static inline uint64_t gpt_entry_per_lba_count(void)
|
||||
return num_entries;
|
||||
}
|
||||
|
||||
+/* Copies information from the entry to the user visible structure */
|
||||
+static inline void parse_entry(struct gpt_entry_t *entry,
|
||||
+ struct partition_entry_t *partition_entry)
|
||||
+{
|
||||
+ partition_entry->start = entry->start;
|
||||
+ partition_entry->size = entry->end - entry->start + 1;
|
||||
+ memcpy(partition_entry->name, entry->name, GPT_ENTRY_NAME_LENGTH);
|
||||
+ partition_entry->attr = entry->attr;
|
||||
+ partition_entry->partition_guid = entry->unique_guid;
|
||||
+ partition_entry->type_guid = entry->partition_type;
|
||||
+}
|
||||
+
|
||||
/* Compare the entry with the given guid */
|
||||
static bool gpt_entry_cmp_guid(const struct gpt_entry_t *entry, const void *guid)
|
||||
{
|
||||
@@ -331,6 +372,21 @@ static bool gpt_entry_cmp_guid(const struct gpt_entry_t *entry, const void *guid
|
||||
return efi_guid_cmp(&entry_guid, cmp_guid) == 0;
|
||||
}
|
||||
|
||||
+/* Compare the entry with the given name */
|
||||
+static bool gpt_entry_cmp_name(const struct gpt_entry_t *entry, const void *name)
|
||||
+{
|
||||
+ return memcmp(name, entry->name, GPT_ENTRY_NAME_LENGTH) == 0;
|
||||
+}
|
||||
+
|
||||
+/* Compare the entry with the given type */
|
||||
+static bool gpt_entry_cmp_type(const struct gpt_entry_t *entry, const void *type)
|
||||
+{
|
||||
+ const struct efi_guid_t *cmp_type = (const struct efi_guid_t *)type;
|
||||
+ const struct efi_guid_t entry_type = entry->partition_type;
|
||||
+
|
||||
+ return efi_guid_cmp(&entry_type, cmp_type) == 0;
|
||||
+}
|
||||
+
|
||||
/* Read entry with given GUID from given table and return it if found. */
|
||||
static psa_status_t find_gpt_entry(const struct gpt_t *table,
|
||||
gpt_entry_cmp_t compare,
|
||||
diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
index 325887fae..d6671f3fc 100644
|
||||
--- a/lib/gpt/unittests/gpt/test_gpt.c
|
||||
+++ b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
@@ -381,3 +381,130 @@ void test_gpt_entry_read_should_failWhenEntryNotExisting(void)
|
||||
register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_read(&non_existing, &entry));
|
||||
}
|
||||
+
|
||||
+void test_gpt_entry_read_by_name_should_populateEntry(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Ensure an entry is found, even with repeat names */
|
||||
+ struct partition_entry_t entry;
|
||||
+ struct gpt_entry_t *desired1 = &(test_partition_array[0]);
|
||||
+ struct efi_guid_t test_guid1 = desired1->guid;
|
||||
+ struct efi_guid_t test_type1 = desired1->type;
|
||||
+
|
||||
+ /* Change the name of something else and ensure it is found */
|
||||
+ struct gpt_entry_t *desired2 = &(test_partition_array[1]);
|
||||
+ struct efi_guid_t test_guid2 = desired2->guid;
|
||||
+ struct efi_guid_t test_type2 = desired2->type;
|
||||
+ memcpy(desired2->name, desired1->name, GPT_ENTRY_NAME_LENGTH);
|
||||
+
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_entry_read_by_name(desired1->name, 0, &entry));
|
||||
+
|
||||
+ /* Ensure this is the correct entry */
|
||||
+ TEST_ASSERT_EQUAL(0, efi_guid_cmp(&test_guid1, &(entry.partition_guid)));
|
||||
+ TEST_ASSERT_EQUAL(0, efi_guid_cmp(&test_type1, &(entry.type_guid)));
|
||||
+ TEST_ASSERT_EQUAL(desired1->start, entry.start);
|
||||
+ TEST_ASSERT_EQUAL(desired1->end, entry.start + entry.size - 1);
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL_MEMORY(desired1->name, entry.name, GPT_ENTRY_NAME_LENGTH);
|
||||
+
|
||||
+ /* Do again but the next entry */
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_entry_read_by_name(desired1->name, 1, &entry));
|
||||
+
|
||||
+ /* Ensure this is the correct entry */
|
||||
+ TEST_ASSERT_EQUAL(0, efi_guid_cmp(&test_guid2, &(entry.partition_guid)));
|
||||
+ TEST_ASSERT_EQUAL(0, efi_guid_cmp(&test_type2, &(entry.type_guid)));
|
||||
+ TEST_ASSERT_EQUAL(desired2->start, entry.start);
|
||||
+ TEST_ASSERT_EQUAL(desired2->end, entry.start + entry.size - 1);
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL_MEMORY(desired2->name, entry.name, GPT_ENTRY_NAME_LENGTH);
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_read_by_name_should_failWhenEntryNotExisting(void)
|
||||
+{
|
||||
+ /* Start with an empty GPT */
|
||||
+ setup_empty_gpt();
|
||||
+
|
||||
+ /* Try to read something */
|
||||
+ struct partition_entry_t entry;
|
||||
+ char test_name[GPT_ENTRY_NAME_LENGTH] = {'\0'};
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_read_by_name(test_name, 0, &entry));
|
||||
+
|
||||
+ /* Now, have a non-empty GPT but search for a name that won't exist */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Each entry should be read */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_read_by_name(test_name, 0, &entry));
|
||||
+
|
||||
+ /* Finally, search for the second entry of a name that appears only once */
|
||||
+ memcpy(test_name, test_partition_array[0].name, GPT_ENTRY_NAME_LENGTH);
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_read_by_name(test_name, 1, &entry));
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_read_by_name(test_name, TEST_DEFAULT_NUM_PARTITIONS, &entry));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_read_by_type_should_populateEntry(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Ensure an entry is found, even with repeat types */
|
||||
+ struct partition_entry_t entry;
|
||||
+ struct gpt_entry_t *desired1 = &(test_partition_array[0]);
|
||||
+ struct efi_guid_t test_guid1 = desired1->guid;
|
||||
+ struct efi_guid_t test_type1 = desired1->type;
|
||||
+
|
||||
+ struct gpt_entry_t *desired2 = &(test_partition_array[1]);
|
||||
+ struct efi_guid_t test_guid2 = desired2->guid;
|
||||
+ struct efi_guid_t test_type2 = test_type1;
|
||||
+ desired2->type = test_type2;
|
||||
+
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_entry_read_by_type(&test_type1, 0, &entry));
|
||||
+
|
||||
+ /* Ensure this is the correct entry */
|
||||
+ TEST_ASSERT_EQUAL(0, efi_guid_cmp(&test_guid1, &(entry.partition_guid)));
|
||||
+ TEST_ASSERT_EQUAL(0, efi_guid_cmp(&test_type1, &(entry.type_guid)));
|
||||
+ TEST_ASSERT_EQUAL(desired1->start, entry.start);
|
||||
+ TEST_ASSERT_EQUAL(desired1->end, entry.start + entry.size - 1);
|
||||
+
|
||||
+ /* Name is unicode */
|
||||
+ TEST_ASSERT_EQUAL_MEMORY(desired1->name, entry.name, GPT_ENTRY_NAME_LENGTH);
|
||||
+
|
||||
+ /* Do again but the next entry */
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_entry_read_by_type(&test_type1, 1, &entry));
|
||||
+
|
||||
+ /* Ensure this is the correct entry */
|
||||
+ TEST_ASSERT_EQUAL(0, efi_guid_cmp(&test_guid2, &(entry.partition_guid)));
|
||||
+ TEST_ASSERT_EQUAL(0, efi_guid_cmp(&test_type2, &(entry.type_guid)));
|
||||
+ TEST_ASSERT_EQUAL(desired2->start, entry.start);
|
||||
+ TEST_ASSERT_EQUAL(desired2->end, entry.start + entry.size - 1);
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL_MEMORY(desired2->name, entry.name, GPT_ENTRY_NAME_LENGTH);
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_read_by_type_should_failWhenEntryNotExisting(void)
|
||||
+{
|
||||
+ /* Start with an empty GPT */
|
||||
+ setup_empty_gpt();
|
||||
+
|
||||
+ /* Try to read something */
|
||||
+ struct partition_entry_t entry;
|
||||
+ struct efi_guid_t test_type = MAKE_EFI_GUID(11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_read_by_type(&test_type, 0, &entry));
|
||||
+
|
||||
+ /* Now, have a non-empty GPT but search for a type that won't exist */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Each entry should be read */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_read_by_type(&test_type, 0, &entry));
|
||||
+
|
||||
+ /* Finally, search for the second entry of a type that appears only once */
|
||||
+ struct efi_guid_t existing_type = test_partition_array[0].type;
|
||||
+ efi_guid_cpy(&existing_type, &test_type);
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_read_by_type(&test_type, 1, &entry));
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_read_by_type(&test_type, TEST_DEFAULT_NUM_PARTITIONS, &entry));
|
||||
+}
|
||||
-961
@@ -1,961 +0,0 @@
|
||||
From 02ec696240d0225ed6473ea5b01ec6617d897a41 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Wed, 11 Feb 2026 11:23:31 +0000
|
||||
Subject: [PATCH] lib: gpt: Added operations to modify partitions
|
||||
|
||||
The operations added allow the user to modify existing GPT partitions,
|
||||
apart from moving them; that is, they are all metadata changes. The
|
||||
library also handles updating both primary and backup partition entry
|
||||
arrays and headers after each modification.
|
||||
|
||||
Each modification on an entry is buffered in order to reduce the number
|
||||
of flash erase operations. A simple heuristic of "write on every n
|
||||
operations" is used to prevent infinite buffering. The buffering is most
|
||||
effective when consecutive entries are operated on. If the mapping of
|
||||
LBA to flash sector is not 1:1, the flash driver the platform registers
|
||||
with the library may implement its own buffering for further
|
||||
optimisation.
|
||||
|
||||
Change-Id: Ie358464427d66883e1681497a2630a8ef281e528
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [ab942ecb7cb62bcfe1e5701f3f3adbf1eebd330a]
|
||||
---
|
||||
lib/gpt/CMakeLists.txt | 1 +
|
||||
lib/gpt/inc/gpt.h | 69 +++++
|
||||
lib/gpt/inc/gpt_flash.h | 41 ++-
|
||||
lib/gpt/src/gpt.c | 419 +++++++++++++++++++++++++++++-
|
||||
lib/gpt/unittests/gpt/test_gpt.c | 187 +++++++++++++
|
||||
lib/gpt/unittests/gpt/utcfg.cmake | 2 +
|
||||
6 files changed, 712 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/lib/gpt/CMakeLists.txt b/lib/gpt/CMakeLists.txt
|
||||
index 2b5d6af8f..25d0de9cd 100644
|
||||
--- a/lib/gpt/CMakeLists.txt
|
||||
+++ b/lib/gpt/CMakeLists.txt
|
||||
@@ -37,4 +37,5 @@ target_link_libraries(tfm_gpt
|
||||
tfm_log_headers
|
||||
PRIVATE
|
||||
tfm_efi_guid
|
||||
+ tfm_efi_soft_crc
|
||||
)
|
||||
diff --git a/lib/gpt/inc/gpt.h b/lib/gpt/inc/gpt.h
|
||||
index 947a6b341..6e7bb360e 100644
|
||||
--- a/lib/gpt/inc/gpt.h
|
||||
+++ b/lib/gpt/inc/gpt.h
|
||||
@@ -82,6 +82,75 @@ psa_status_t gpt_entry_read_by_type(const struct efi_guid_t *type,
|
||||
const uint32_t index,
|
||||
struct partition_entry_t *partition_entry);
|
||||
|
||||
+/**
|
||||
+ * \brief Renames a partition entry.
|
||||
+ *
|
||||
+ * \param[in] guid Entry to rename.
|
||||
+ * \param[in] name New unicode name for the entry.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS Success.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_DOES_NOT_EXIST No entry found with the provided GUID.
|
||||
+ * \retval PSA_ERROR_INVALID_ARGUMENT Empty name.
|
||||
+ */
|
||||
+__attribute__((nonnull(1,2)))
|
||||
+psa_status_t gpt_entry_rename(const struct efi_guid_t *guid,
|
||||
+ const char name[GPT_ENTRY_NAME_LENGTH]);
|
||||
+
|
||||
+/**
|
||||
+ * \brief Changes the type of a partition.
|
||||
+ *
|
||||
+ * \param[in] guid Entry to update.
|
||||
+ * \param[in] type New type GUID.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS Success.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_INVALID_ARGUMENT \p type is the null GUID.
|
||||
+ * \retval PSA_ERROR_DOES_NOT_EXIST No entry found with the provided GUID.
|
||||
+ */
|
||||
+__attribute__((nonnull(1,2)))
|
||||
+psa_status_t gpt_entry_change_type(const struct efi_guid_t *guid,
|
||||
+ const struct efi_guid_t *type);
|
||||
+
|
||||
+/**
|
||||
+ * \brief Adds attributes to a partition entry.
|
||||
+ *
|
||||
+ * \param[in] guid Entry to modify.
|
||||
+ * \param[in] attr Attributes to add.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS Success.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_DOES_NOT_EXIST No entry found with the provided GUID.
|
||||
+ */
|
||||
+__attribute__((nonnull(1)))
|
||||
+psa_status_t gpt_attr_add(const struct efi_guid_t *guid, const uint64_t attr);
|
||||
+
|
||||
+/**
|
||||
+ * \brief Removes attributes from a partition entry.
|
||||
+ *
|
||||
+ * \param[in] guid Entry to modify.
|
||||
+ * \param[in] attr Attributes to remove.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS Success.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_DOES_NOT_EXIST No entry found with the provided GUID.
|
||||
+ */
|
||||
+__attribute__((nonnull(1)))
|
||||
+psa_status_t gpt_attr_remove(const struct efi_guid_t *guid, const uint64_t attr);
|
||||
+
|
||||
+/**
|
||||
+ * \brief Sets attributes for a partition entry.
|
||||
+ *
|
||||
+ * \param[in] guid Entry to modify.
|
||||
+ * \param[in] attr Attributes to set.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS Success.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_DOES_NOT_EXIST No entry found with the provided GUID.
|
||||
+ */
|
||||
+__attribute__((nonnull(1)))
|
||||
+psa_status_t gpt_attr_set(const struct efi_guid_t *guid, const uint64_t attr);
|
||||
+
|
||||
/**
|
||||
* \brief Reads the GPT header from the second block (LBA 1).
|
||||
*
|
||||
diff --git a/lib/gpt/inc/gpt_flash.h b/lib/gpt/inc/gpt_flash.h
|
||||
index 2b43390c1..ada5f6932 100644
|
||||
--- a/lib/gpt/inc/gpt_flash.h
|
||||
+++ b/lib/gpt/inc/gpt_flash.h
|
||||
@@ -57,13 +57,48 @@ __attribute__((nonnull(2)))
|
||||
typedef ssize_t (*gpt_flash_read_t)(uint64_t lba,
|
||||
void *buf);
|
||||
|
||||
+/**
|
||||
+ * \brief Function that writes to a logical block address.
|
||||
+ *
|
||||
+ * \param[in] lba Logical block address to write to.
|
||||
+ * \param[in] buf Buffer to write from. Must be at least the size of an LBA.
|
||||
+ *
|
||||
+ * \return Number of bytes written on success or a negative error code on failure.
|
||||
+ * \retval GPT_FLASH_NOT_INIT The flash driver has not been initialised.
|
||||
+ * \retval GPT_FLASH_UNAVAILABLE The flash driver is unavailable.
|
||||
+ * \retval GPT_FLASH_BAD_PARAM \p lba is not a valid address (for example larger than the flash size).
|
||||
+ * \retval GPT_FLASH_GENERIC_ERROR Unspecified error.
|
||||
+ */
|
||||
+__attribute__((nonnull(2)))
|
||||
+typedef ssize_t (*gpt_flash_write_t)(uint64_t lba,
|
||||
+ const void *buf);
|
||||
+
|
||||
+/**
|
||||
+ * \brief Function that erases consecutive logical blocks.
|
||||
+ *
|
||||
+ * \param[in] lba Starting logical block address.
|
||||
+ * \param[in] num_blocks Number of blocks to erase.
|
||||
+ *
|
||||
+ * \return Number of blocks erased on success or a negative error code on failure.
|
||||
+ * \retval GPT_FLASH_NOT_INIT The flash driver has not been initialised.
|
||||
+ * \retval GPT_FLASH_UNAVAILABLE The flash driver is unavailable.
|
||||
+ * \retval GPT_FLASH_BAD_PARAM \p num_blocks is zero.
|
||||
+ * \retval GPT_FLASH_BAD_PARAM One of the requested blocks is invalid (for example,
|
||||
+ * \p lba + \p num_blocks exceeds the flash size).
|
||||
+ * \retval GPT_FLASH_BAD_PARAM \p lba is not a valid address (for example larger than the flash size).
|
||||
+ * \retval GPT_FLASH_GENERIC_ERROR Unspecified error.
|
||||
+ */
|
||||
+typedef ssize_t (*gpt_flash_erase_t)(uint64_t lba, size_t num_blocks);
|
||||
+
|
||||
/**
|
||||
* \brief Interface for interacting with the flash driver.
|
||||
*/
|
||||
struct gpt_flash_driver_t {
|
||||
- gpt_flash_init_t init; /**< Flash initialisation routine. */
|
||||
- gpt_flash_uninit_t uninit; /**< Flash deinitialisation routine. */
|
||||
- gpt_flash_read_t read; /**< Routine used to read a logical block. */
|
||||
+ gpt_flash_init_t init; /**< Flash initialisation routine. */
|
||||
+ gpt_flash_uninit_t uninit; /**< Flash deinitialisation routine. */
|
||||
+ gpt_flash_read_t read; /**< Routine used to read a logical block. */
|
||||
+ gpt_flash_write_t write; /**< Routine used to write a logical block. */
|
||||
+ gpt_flash_erase_t erase; /**< Routine used to erase logical blocks. */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c
|
||||
index 1662b81c2..2cfcdff07 100644
|
||||
--- a/lib/gpt/src/gpt.c
|
||||
+++ b/lib/gpt/src/gpt.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "gpt_flash.h"
|
||||
#include "tfm_log.h"
|
||||
#include "efi_guid_structs.h"
|
||||
+#include "efi_soft_crc.h"
|
||||
|
||||
/* This needs to be defined by the platform and is used by the GPT library as
|
||||
* the number of bytes in a Logical Block Address (LBA)
|
||||
@@ -146,6 +147,15 @@ typedef bool (*gpt_entry_cmp_t)(const struct gpt_entry_t *, const void *);
|
||||
/* The LBA for the backup table */
|
||||
static uint64_t backup_gpt_lba = 0;
|
||||
|
||||
+/* The LBA for the partition array for the backup table. Rather than storing
|
||||
+ * the entire table header in memory, just this is stored so that updates can
|
||||
+ * be done without reading from flash
|
||||
+ */
|
||||
+static uint64_t backup_gpt_array_lba = 0;
|
||||
+
|
||||
+/* CRC for backup header. Because the LBAs differ, so too will the CRC */
|
||||
+static uint32_t backup_crc32 = 0;
|
||||
+
|
||||
/* The flash driver, used to perform I/O */
|
||||
static struct gpt_flash_driver_t *plat_flash_driver = NULL;
|
||||
|
||||
@@ -165,6 +175,9 @@ static uint8_t lba_buf[TFM_GPT_BLOCK_SIZE] = {0};
|
||||
*/
|
||||
static uint64_t cached_lba = 0;
|
||||
|
||||
+/* True if write was buffered */
|
||||
+static bool write_buffered = false;
|
||||
+
|
||||
/* Helper function prototypes */
|
||||
__attribute__((unused))
|
||||
static void print_guid(struct efi_guid_t guid);
|
||||
@@ -174,7 +187,9 @@ __attribute__((unused))
|
||||
static psa_status_t unicode_to_ascii(const char *unicode, char *ascii);
|
||||
static inline uint64_t partition_entry_lba(const struct gpt_t *table,
|
||||
uint32_t array_index);
|
||||
+static inline uint64_t partition_array_last_lba(const struct gpt_t *table);
|
||||
static inline uint64_t gpt_entry_per_lba_count(void);
|
||||
+static inline void swap_headers(const struct gpt_header_t *src, struct gpt_header_t *dst);
|
||||
static psa_status_t count_used_partitions(const struct gpt_t *table,
|
||||
uint32_t *num_used);
|
||||
static inline void parse_entry(struct gpt_entry_t *entry,
|
||||
@@ -184,6 +199,15 @@ static psa_status_t read_entry_from_flash(const struct gpt_t *table,
|
||||
uint32_t array_index,
|
||||
struct gpt_entry_t *entry);
|
||||
static psa_status_t read_table_from_flash(struct gpt_t *table, bool is_primary);
|
||||
+static psa_status_t flush_lba_buf(void);
|
||||
+static psa_status_t write_to_flash(uint64_t lba);
|
||||
+static psa_status_t write_entries_to_flash(uint32_t lbas_into_array, bool no_header_update);
|
||||
+static psa_status_t write_entry(uint32_t array_index,
|
||||
+ const struct gpt_entry_t *entry,
|
||||
+ bool no_header_update);
|
||||
+static psa_status_t write_header_to_flash(const struct gpt_t *table);
|
||||
+static psa_status_t write_headers_to_flash(void);
|
||||
+static psa_status_t update_header(uint32_t num_partitions);
|
||||
static psa_status_t find_gpt_entry(const struct gpt_t *table,
|
||||
gpt_entry_cmp_t compare,
|
||||
const void *attr,
|
||||
@@ -241,16 +265,146 @@ psa_status_t gpt_entry_read_by_type(const struct efi_guid_t *type,
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
+psa_status_t gpt_entry_rename(const struct efi_guid_t *guid, const char name[GPT_ENTRY_NAME_LENGTH])
|
||||
+{
|
||||
+ if (name[0] == '\0') {
|
||||
+ return PSA_ERROR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ struct gpt_entry_t cached_entry;
|
||||
+ uint32_t cached_index;
|
||||
+ const psa_status_t ret = find_gpt_entry(
|
||||
+ &primary_gpt,
|
||||
+ gpt_entry_cmp_guid,
|
||||
+ guid,
|
||||
+ 0,
|
||||
+ &cached_entry,
|
||||
+ &cached_index);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* NOOP if no name change. Prevents header update. */
|
||||
+ if (memcmp(cached_entry.name, name, GPT_ENTRY_NAME_LENGTH) == 0) {
|
||||
+ return PSA_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(cached_entry.name, name, GPT_ENTRY_NAME_LENGTH);
|
||||
+ cached_entry.name[GPT_ENTRY_NAME_LENGTH - 1] = '\0';
|
||||
+ cached_entry.name[GPT_ENTRY_NAME_LENGTH - 2] = '\0';
|
||||
+ return write_entry(cached_index, &cached_entry, false);
|
||||
+}
|
||||
+
|
||||
+psa_status_t gpt_entry_change_type(const struct efi_guid_t *guid, const struct efi_guid_t *type)
|
||||
+{
|
||||
+ struct efi_guid_t null_type = NULL_GUID;
|
||||
+ if (efi_guid_cmp(&null_type, type) == 0) {
|
||||
+ ERROR("Cannot set type to null-GUID; delete instead\n");
|
||||
+ return PSA_ERROR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ struct gpt_entry_t cached_entry;
|
||||
+ uint32_t cached_index;
|
||||
+ const psa_status_t ret = find_gpt_entry(
|
||||
+ &primary_gpt,
|
||||
+ gpt_entry_cmp_guid,
|
||||
+ guid,
|
||||
+ 0,
|
||||
+ &cached_entry,
|
||||
+ &cached_index);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ cached_entry.partition_type = *type;
|
||||
+
|
||||
+ return write_entry(cached_index, &cached_entry, false);
|
||||
+}
|
||||
+
|
||||
+psa_status_t gpt_attr_add(const struct efi_guid_t *guid, const uint64_t attr)
|
||||
+{
|
||||
+ /* This quick check prevents I/O from happening for a no-op */
|
||||
+ if (attr == 0) {
|
||||
+ return PSA_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ struct gpt_entry_t cached_entry;
|
||||
+ uint32_t cached_index;
|
||||
+ const psa_status_t ret = find_gpt_entry(
|
||||
+ &primary_gpt,
|
||||
+ gpt_entry_cmp_guid,
|
||||
+ guid,
|
||||
+ 0,
|
||||
+ &cached_entry,
|
||||
+ &cached_index);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ cached_entry.attr |= attr;
|
||||
+
|
||||
+ return write_entry(cached_index, &cached_entry, false);
|
||||
+}
|
||||
+
|
||||
+psa_status_t gpt_attr_remove(const struct efi_guid_t *guid, const uint64_t attr)
|
||||
+{
|
||||
+ /* This quick check prevents I/O from happening for a no-op */
|
||||
+ if (attr == 0) {
|
||||
+ return PSA_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ struct gpt_entry_t cached_entry;
|
||||
+ uint32_t cached_index;
|
||||
+ const psa_status_t ret = find_gpt_entry(
|
||||
+ &primary_gpt,
|
||||
+ gpt_entry_cmp_guid,
|
||||
+ guid,
|
||||
+ 0,
|
||||
+ &cached_entry,
|
||||
+ &cached_index);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ cached_entry.attr &= ~(attr);
|
||||
+
|
||||
+ return write_entry(cached_index, &cached_entry, false);
|
||||
+}
|
||||
+
|
||||
+psa_status_t gpt_attr_set(const struct efi_guid_t *guid, const uint64_t attr)
|
||||
+{
|
||||
+ struct gpt_entry_t cached_entry;
|
||||
+ uint32_t cached_index;
|
||||
+ const psa_status_t ret = find_gpt_entry(
|
||||
+ &primary_gpt,
|
||||
+ gpt_entry_cmp_guid,
|
||||
+ guid,
|
||||
+ 0,
|
||||
+ &cached_entry,
|
||||
+ &cached_index);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ cached_entry.attr = attr;
|
||||
+
|
||||
+ return write_entry(cached_index, &cached_entry, false);
|
||||
+}
|
||||
+
|
||||
/* Initialises GPT from first block. */
|
||||
psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, uint64_t max_partitions)
|
||||
{
|
||||
cached_lba = 0;
|
||||
+ write_buffered = false;
|
||||
if (max_partitions < GPT_MIN_PARTITIONS) {
|
||||
ERROR("Minimum number of partitions is %d\n", GPT_MIN_PARTITIONS);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
- if (flash_driver->read == NULL) {
|
||||
+ if (flash_driver->read == NULL ||
|
||||
+ flash_driver->write == NULL ||
|
||||
+ flash_driver->erase == NULL)
|
||||
+ {
|
||||
ERROR("I/O functions must be defined\n");
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
@@ -303,6 +457,7 @@ psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, uint64_t max_part
|
||||
if (ret != PSA_SUCCESS) {
|
||||
goto fail_load;
|
||||
}
|
||||
+ backup_gpt_array_lba = backup_gpt.header.array_lba;
|
||||
} else {
|
||||
WARN("Backup GPT location is unknown!\n");
|
||||
}
|
||||
@@ -314,7 +469,9 @@ fail_load:
|
||||
plat_flash_driver = NULL;
|
||||
plat_max_partitions = 0;
|
||||
backup_gpt_lba = 0;
|
||||
+ backup_gpt_array_lba = 0;
|
||||
cached_lba = 0;
|
||||
+ write_buffered = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -324,6 +481,11 @@ psa_status_t gpt_uninit(void)
|
||||
psa_status_t ret = PSA_SUCCESS;
|
||||
|
||||
if (plat_flash_driver) {
|
||||
+ /* Flush the in-memory buffer */
|
||||
+ if (write_buffered) {
|
||||
+ ret = flush_lba_buf();
|
||||
+ }
|
||||
+
|
||||
/* Uninitialise driver if function provided */
|
||||
if (plat_flash_driver->uninit != NULL) {
|
||||
if (plat_flash_driver->uninit() != 0) {
|
||||
@@ -336,7 +498,9 @@ psa_status_t gpt_uninit(void)
|
||||
plat_flash_driver = NULL;
|
||||
plat_max_partitions = 0;
|
||||
backup_gpt_lba = 0;
|
||||
+ backup_gpt_array_lba = 0;
|
||||
cached_lba = 0;
|
||||
+ write_buffered = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -422,6 +586,47 @@ static psa_status_t find_gpt_entry(const struct gpt_t *table,
|
||||
return io_failure ? PSA_ERROR_STORAGE_FAILURE : PSA_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
+/* Updates the header of the GPT based on new number of partitions */
|
||||
+static psa_status_t update_header(uint32_t num_partitions)
|
||||
+{
|
||||
+ primary_gpt.num_used_partitions = num_partitions;
|
||||
+ struct gpt_header_t *header = &(primary_gpt.header);
|
||||
+
|
||||
+ /* Take the CRC of the partition array */
|
||||
+ uint32_t crc = 0;
|
||||
+ for (uint32_t i = 0; i < header->num_partitions; ++i) {
|
||||
+ uint8_t entry_buf[header->entry_size];
|
||||
+ memset(entry_buf, 0, header->entry_size);
|
||||
+ struct gpt_entry_t *entry = (struct gpt_entry_t *)entry_buf;
|
||||
+
|
||||
+ psa_status_t ret = read_entry_from_flash(&primary_gpt, i, entry);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ crc = efi_soft_crc32_update(crc, entry_buf, header->entry_size);
|
||||
+ }
|
||||
+ header->array_crc = crc;
|
||||
+
|
||||
+ /* Calculate new CRC32 for primary header */
|
||||
+ header->header_crc = 0;
|
||||
+ header->header_crc = efi_soft_crc32_update(0, (uint8_t *)header, GPT_HEADER_SIZE);
|
||||
+
|
||||
+ /* Calculate new CRC32 for backup header */
|
||||
+ struct gpt_header_t backup_header = {0};
|
||||
+ swap_headers(header, &backup_header);
|
||||
+ backup_header.header_crc = 0;
|
||||
+ backup_crc32 = efi_soft_crc32_update(0, (uint8_t *)&backup_header, GPT_HEADER_SIZE);
|
||||
+
|
||||
+ /* Write headers */
|
||||
+ const psa_status_t ret = write_headers_to_flash();
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ ERROR("Unable to write headers to flash\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
+
|
||||
/* Load MBR from flash */
|
||||
static psa_status_t mbr_load(struct mbr_t *mbr)
|
||||
{
|
||||
@@ -452,10 +657,16 @@ static psa_status_t mbr_load(struct mbr_t *mbr)
|
||||
*/
|
||||
static psa_status_t read_from_flash(uint64_t required_lba)
|
||||
{
|
||||
- ssize_t ret;
|
||||
-
|
||||
if (required_lba != cached_lba) {
|
||||
- ret = plat_flash_driver->read(required_lba, lba_buf);
|
||||
+ if (write_buffered && cached_lba != 0) {
|
||||
+ psa_status_t ret = flush_lba_buf();
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ write_buffered = false;
|
||||
+
|
||||
+ ssize_t ret = plat_flash_driver->read(required_lba, lba_buf);
|
||||
if (ret != TFM_GPT_BLOCK_SIZE) {
|
||||
ERROR("Unable to read from flash at block 0x%08x%08x\n",
|
||||
(uint32_t)(required_lba >> 32),
|
||||
@@ -477,6 +688,14 @@ static uint64_t inline partition_entry_lba(const struct gpt_t *table,
|
||||
return table->header.array_lba + (array_index / gpt_entry_per_lba_count());
|
||||
}
|
||||
|
||||
+/* Returns the last LBA used by the partition entry array */
|
||||
+static uint64_t inline partition_array_last_lba(const struct gpt_t *table)
|
||||
+{
|
||||
+ return (table->num_used_partitions == 0 ?
|
||||
+ table->header.array_lba :
|
||||
+ partition_entry_lba(table, table->num_used_partitions - 1));
|
||||
+}
|
||||
+
|
||||
/* Returns the number of partition entries used in the array, assuming the
|
||||
* array is not sparse
|
||||
*/
|
||||
@@ -539,6 +758,198 @@ static psa_status_t read_table_from_flash(struct gpt_t *table, bool is_primary)
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
+/* Writes the in-memory LBA buffer to flash, taking care of multiple writes if
|
||||
+ * needed.
|
||||
+ */
|
||||
+static psa_status_t flush_lba_buf(void)
|
||||
+{
|
||||
+ /* Prevent recursive calls, as the various writes below may attempt to
|
||||
+ * flush, particularly those making multiple writes
|
||||
+ */
|
||||
+ static bool in_flush = false;
|
||||
+ if (in_flush) {
|
||||
+ return PSA_SUCCESS;
|
||||
+ }
|
||||
+ in_flush = true;
|
||||
+ write_buffered = false;
|
||||
+ psa_status_t ret = PSA_SUCCESS;
|
||||
+
|
||||
+ /* Commit to flash what is in the buffer. Also update the backup table if
|
||||
+ * the cached LBA was part of the primary table (or vise-versa)
|
||||
+ */
|
||||
+ uint64_t array_size = partition_array_last_lba(&primary_gpt) - primary_gpt.header.array_lba + 1;
|
||||
+
|
||||
+ if (cached_lba == PRIMARY_GPT_LBA || (backup_gpt_lba != 0 && cached_lba == backup_gpt_lba)) {
|
||||
+ /* Write both backup and primary headers */
|
||||
+ ret = write_headers_to_flash();
|
||||
+ } else if (PRIMARY_GPT_ARRAY_LBA <= cached_lba &&
|
||||
+ cached_lba <= partition_array_last_lba(&primary_gpt))
|
||||
+ {
|
||||
+ /* Primary array entry. Write to backup and primary array */
|
||||
+ ret = write_entries_to_flash(cached_lba - PRIMARY_GPT_ARRAY_LBA, false);
|
||||
+ } else if (backup_gpt_array_lba != 0 &&
|
||||
+ backup_gpt_array_lba <= cached_lba &&
|
||||
+ cached_lba <= backup_gpt_array_lba + array_size - 1)
|
||||
+ {
|
||||
+ /* Backup array entry. Write to backup and primary array */
|
||||
+ ret = write_entries_to_flash(cached_lba - backup_gpt_array_lba, false);
|
||||
+ } else {
|
||||
+ /* Shouldn't be possible */
|
||||
+ ERROR("Unknown data in LBA cache, discarding\n");
|
||||
+ }
|
||||
+
|
||||
+ in_flush = false;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* Write to the flash at the specified LBA */
|
||||
+static psa_status_t write_to_flash(uint64_t lba)
|
||||
+{
|
||||
+ if (plat_flash_driver->erase(lba, 1) != 1) {
|
||||
+ ERROR("Unable to erase flash at LBA 0x%08x%08x\n",
|
||||
+ (uint32_t)(lba >> 32),
|
||||
+ (uint32_t)lba);
|
||||
+ return PSA_ERROR_STORAGE_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ if (plat_flash_driver->write(lba, lba_buf) != TFM_GPT_BLOCK_SIZE) {
|
||||
+ ERROR("Unable to program flash at LBA 0x%08x%08x\n",
|
||||
+ (uint32_t)(lba >> 32),
|
||||
+ (uint32_t)lba);
|
||||
+ return PSA_ERROR_STORAGE_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+/* Writes the in-memory buffer to both the primary and backup partition arrays.
|
||||
+ * This should only be used when it is certain that the cached lba is part of
|
||||
+ * either the primary or backup partition array
|
||||
+ */
|
||||
+static psa_status_t write_entries_to_flash(uint32_t lbas_into_array, bool no_header_update)
|
||||
+{
|
||||
+ psa_status_t ret;
|
||||
+
|
||||
+ if (backup_gpt_array_lba != 0) {
|
||||
+ ret = write_to_flash(backup_gpt_array_lba + lbas_into_array);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ ERROR("Unable to write entry to backup partition array\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ } else {
|
||||
+ WARN("Backup array LBA unknown!\n");
|
||||
+ }
|
||||
+
|
||||
+ ret = write_to_flash(PRIMARY_GPT_ARRAY_LBA + lbas_into_array);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ ERROR("Unable to write entry to primary partition array\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Update the header unless the user specifies not to, This might be useful
|
||||
+ * if it is known that multiple entries are being written, such as on removal
|
||||
+ * or defragmentation operations
|
||||
+ */
|
||||
+ if (!no_header_update) {
|
||||
+ return update_header(primary_gpt.num_used_partitions);
|
||||
+ }
|
||||
+
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+/* Writes a GPT entry to flash or the in-memory buffer. The buffer is flushed
|
||||
+ * to both the primary and backup partition entry arrays ocassionally. When the
|
||||
+ * buffer is flushed, the header is updated unless no_header_update is true.
|
||||
+ */
|
||||
+static psa_status_t write_entry(uint32_t array_index,
|
||||
+ const struct gpt_entry_t *entry,
|
||||
+ bool no_header_update)
|
||||
+{
|
||||
+ /* Use this for a very simple, very dumb buffering heuristic. Flush every
|
||||
+ * time an LBA's worth of entries have been written (flush every nth
|
||||
+ * operation).
|
||||
+ */
|
||||
+ static uint32_t num_writes = 0;
|
||||
+
|
||||
+ /* First, ensure the entry is part of the buffered block. In most cases,
|
||||
+ * this will be a no-op
|
||||
+ */
|
||||
+ psa_status_t ret = read_from_flash(partition_entry_lba(&primary_gpt, array_index));
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Copy into buffer */
|
||||
+ uint32_t index_in_lba = array_index % gpt_entry_per_lba_count();
|
||||
+ memcpy(lba_buf + index_in_lba * primary_gpt.header.entry_size, entry, GPT_ENTRY_SIZE);
|
||||
+
|
||||
+ /* Write on every nth operation. */
|
||||
+ if (++num_writes == gpt_entry_per_lba_count()) {
|
||||
+ /* Write the buffer to flash */
|
||||
+ num_writes = 0;
|
||||
+ write_buffered = false;
|
||||
+
|
||||
+ ret = write_entries_to_flash(cached_lba - PRIMARY_GPT_ARRAY_LBA, no_header_update);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ } else {
|
||||
+ write_buffered = true;
|
||||
+ }
|
||||
+
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+/* Writes GPT header to flash. Returns PSA_SUCCESS on success or a PSA error on failure */
|
||||
+static psa_status_t write_header_to_flash(const struct gpt_t *table)
|
||||
+{
|
||||
+ /* Ensure the in-memory LBA buffer has the header. Because the header is
|
||||
+ * also in memory, there is no need to read it again before writing.
|
||||
+ */
|
||||
+ uint8_t temp_buf[GPT_HEADER_SIZE];
|
||||
+ memcpy(temp_buf, lba_buf, GPT_HEADER_SIZE);
|
||||
+ memcpy(lba_buf, &(table->header), GPT_HEADER_SIZE);
|
||||
+ const psa_status_t ret = write_to_flash(table->header.current_lba);
|
||||
+ memcpy(lba_buf, temp_buf, GPT_HEADER_SIZE);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* Writes GPT headers for backup and primary tables to flash. */
|
||||
+static psa_status_t write_headers_to_flash(void)
|
||||
+{
|
||||
+ /* Backup table first, then primary */
|
||||
+ struct gpt_t backup_gpt;
|
||||
+ swap_headers(&(primary_gpt.header), &(backup_gpt.header));
|
||||
+ backup_gpt.header.header_crc = backup_crc32;
|
||||
+ psa_status_t ret = write_header_to_flash(&backup_gpt);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ ERROR("Unable to write backup GPT header\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = write_header_to_flash(&primary_gpt);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ ERROR("Unable to write primary GPT header\n");
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* Copies one header to another and swaps the fields referring to self
|
||||
+ * and alternate headers. This is useful for primary to backup copies
|
||||
+ * and vice-versa.
|
||||
+ */
|
||||
+static inline void swap_headers(const struct gpt_header_t *src, struct gpt_header_t *dst)
|
||||
+{
|
||||
+ memcpy(dst, src, GPT_HEADER_SIZE);
|
||||
+ dst->backup_lba = src->current_lba;
|
||||
+ dst->current_lba = src->backup_lba;
|
||||
+ dst->array_lba = (src->current_lba == PRIMARY_GPT_LBA ?
|
||||
+ backup_gpt_array_lba :
|
||||
+ primary_gpt.header.array_lba);
|
||||
+}
|
||||
+
|
||||
/* Converts unicode string to valid ascii */
|
||||
static psa_status_t unicode_to_ascii(const char *unicode, char *ascii)
|
||||
{
|
||||
diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
index d6671f3fc..1121f7c73 100644
|
||||
--- a/lib/gpt/unittests/gpt/test_gpt.c
|
||||
+++ b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
+#include "mock_efi_soft_crc.h"
|
||||
#include "mock_tfm_log.h"
|
||||
#include "mock_tfm_vprintf.h"
|
||||
|
||||
@@ -133,12 +134,16 @@ struct gpt_header_t {
|
||||
|
||||
static void register_mocked_read(void *buf, size_t num_bytes);
|
||||
static ssize_t test_driver_read(uint64_t lba, void *buf);
|
||||
+static ssize_t test_driver_write(uint64_t lba, const void *buf);
|
||||
+static ssize_t test_driver_erase(uint64_t lba, size_t num_blocks);
|
||||
|
||||
/* LBA driver used in test module */
|
||||
static struct gpt_flash_driver_t mock_driver = {
|
||||
.init = NULL,
|
||||
.uninit = NULL,
|
||||
.read = test_driver_read,
|
||||
+ .write = test_driver_write,
|
||||
+ .erase = test_driver_erase,
|
||||
};
|
||||
|
||||
/* Valid MBR. Only signature is required to be valid */
|
||||
@@ -227,6 +232,17 @@ static ssize_t test_driver_read(uint64_t lba, void *buf)
|
||||
return TEST_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
+/* Driver function that always succeeds in writing all data */
|
||||
+static ssize_t test_driver_write(uint64_t lba, const void *buf)
|
||||
+{
|
||||
+ return TEST_BLOCK_SIZE;
|
||||
+}
|
||||
+
|
||||
+static ssize_t test_driver_erase(uint64_t lba, size_t num_blocks)
|
||||
+{
|
||||
+ return num_blocks;
|
||||
+}
|
||||
+
|
||||
/* Creates backup table from test table and registers a read for it */
|
||||
static void setup_backup_gpt(void)
|
||||
{
|
||||
@@ -285,6 +301,9 @@ void setUp(void)
|
||||
|
||||
test_mbr.partitions[0].os_type = TEST_MBR_TYPE_GPT;
|
||||
|
||||
+ /* Any time this is called, return the same number and ignore the arguments */
|
||||
+ efi_soft_crc32_update_IgnoreAndReturn(test_header.header_crc);
|
||||
+
|
||||
/* Ignore all logging calls */
|
||||
tfm_log_Ignore();
|
||||
|
||||
@@ -337,6 +356,174 @@ void test_gpt_init_should_failWhenFlashDriverNotFullyDefined(void)
|
||||
mock_driver.read = NULL;
|
||||
TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_init(&mock_driver, TEST_MAX_PARTITIONS));
|
||||
mock_driver.read = read_fn;
|
||||
+
|
||||
+ gpt_flash_write_t write_fn = mock_driver.write;
|
||||
+ mock_driver.write = NULL;
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_init(&mock_driver, TEST_MAX_PARTITIONS));
|
||||
+ mock_driver.write = write_fn;
|
||||
+
|
||||
+ gpt_flash_erase_t erase_fn = mock_driver.erase;
|
||||
+ mock_driver.erase = NULL;
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_init(&mock_driver, TEST_MAX_PARTITIONS));
|
||||
+ mock_driver.erase = erase_fn;
|
||||
+}
|
||||
+
|
||||
+void test_gpt_attr_set_should_setAttributes(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Entries are read */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ struct efi_guid_t guid = test_partition_array[0].guid;
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_attr_set(&guid, 0x1));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_attr_set_should_failWhenEntryNotExisting(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Read every entry */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ struct efi_guid_t non_existing = NULL_GUID;
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_attr_set(&non_existing, 0x1));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_attr_remove_should_removeAttributes(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ struct gpt_entry_t *test_entry = &(test_partition_array[0]);
|
||||
+ uint64_t test_attr = 0x1;
|
||||
+ test_entry->attr = test_attr;
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* First entry is read */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ struct efi_guid_t test_guid = test_entry->guid;
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_attr_set(&test_guid, test_attr));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_attr_remove_should_failWhenEntryNotExisting(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Read every entry */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ struct efi_guid_t non_existing = NULL_GUID;
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_attr_remove(&non_existing, 0x1));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_attr_add_should_addAttributes(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ struct gpt_entry_t *test_entry = &(test_partition_array[0]);
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* First entry is read */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ struct efi_guid_t test_guid = test_entry->guid;
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_attr_add(&test_guid, 0x1));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_attr_add_should_failWhenEntryNotExisting(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Read every entry */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ struct efi_guid_t non_existing = NULL_GUID;
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_attr_add(&non_existing, 0x1));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_change_type_should_setNewType(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ struct gpt_entry_t *test_entry = &(test_partition_array[0]);
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* First entry is read */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ struct efi_guid_t test_guid = test_entry->guid;
|
||||
+
|
||||
+ /* Type validation is not a function of the library, as this is OS
|
||||
+ * dependent, so anything will do here.
|
||||
+ */
|
||||
+ struct efi_guid_t new_type = MAKE_EFI_GUID(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_entry_change_type(&test_guid, &new_type));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_change_type_should_failWhenEntryNotExisting(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Read every entry */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ struct efi_guid_t non_existing = NULL_GUID;
|
||||
+ struct efi_guid_t new_type = MAKE_EFI_GUID(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_change_type(&non_existing, &new_type));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_change_type_should_failWhenSettingTypeToNullGuid(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ struct gpt_entry_t *test_entry = &(test_partition_array[0]);
|
||||
+
|
||||
+ /* First entry is read */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ struct efi_guid_t test_guid = test_entry->guid;
|
||||
+ struct efi_guid_t new_type = NULL_GUID;
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_change_type(&test_guid, &new_type));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_rename_should_renameEntry(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ struct gpt_entry_t *test_entry = &(test_partition_array[0]);
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* First entry is read */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ char new_name[GPT_ENTRY_NAME_LENGTH] = {'\0'};
|
||||
+ new_name[0] = 'a';
|
||||
+ struct efi_guid_t test_guid = test_entry->guid;
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_entry_rename(&test_guid, new_name));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_rename_should_failWhenNameIsEmpty(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ struct gpt_entry_t *test_entry = &(test_partition_array[0]);
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Try to change name to an empty string */
|
||||
+ struct efi_guid_t test_guid = test_entry->guid;
|
||||
+ char name[GPT_ENTRY_NAME_LENGTH] = {'\0'};
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_rename(&test_guid, name));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_rename_should_failWhenEntryNotExisting(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Read every entry */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ struct efi_guid_t non_existing = NULL_GUID;
|
||||
+ char new_name[GPT_ENTRY_NAME_LENGTH] = {'\0'};
|
||||
+ new_name[0] = 'a';
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_rename(&non_existing, new_name));
|
||||
}
|
||||
|
||||
void test_gpt_entry_read_should_populateEntry(void)
|
||||
diff --git a/lib/gpt/unittests/gpt/utcfg.cmake b/lib/gpt/unittests/gpt/utcfg.cmake
|
||||
index 37d72d138..620d15b4c 100644
|
||||
--- a/lib/gpt/unittests/gpt/utcfg.cmake
|
||||
+++ b/lib/gpt/unittests/gpt/utcfg.cmake
|
||||
@@ -15,12 +15,14 @@ set(UNIT_TEST_SUITE ${CMAKE_CURRENT_LIST_DIR}/test_gpt.c)
|
||||
list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/interface/include)
|
||||
list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/lib/efi_guid/inc)
|
||||
list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/lib/gpt/inc)
|
||||
+list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/lib/ext/efi_soft_crc/inc)
|
||||
list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/lib/tfm_log/inc)
|
||||
list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/lib/tfm_vprintf/inc)
|
||||
|
||||
# Headers to be mocked
|
||||
list(APPEND MOCK_HEADERS ${TFM_ROOT_DIR}/lib/tfm_log/inc/tfm_log.h)
|
||||
list(APPEND MOCK_HEADERS ${TFM_ROOT_DIR}/lib/tfm_vprintf/inc/tfm_vprintf.h)
|
||||
+list(APPEND MOCK_HEADERS ${TFM_ROOT_DIR}/lib/ext/efi_soft_crc/inc/efi_soft_crc.h)
|
||||
|
||||
# Compile-time definitions
|
||||
list(APPEND UNIT_TEST_COMPILE_DEFS LOG_LEVEL=LOG_LEVEL_VERBOSE)
|
||||
-374
@@ -1,374 +0,0 @@
|
||||
From 7a453edd736c919eccc40eec567e8e97c0597bba Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Tue, 30 Dec 2025 09:13:07 +0000
|
||||
Subject: [PATCH] lib: gpt: Added operation to move entry
|
||||
|
||||
The operation to move or resize an entry is not just a metadata change
|
||||
and actually moves the data the partition entry points to as well.
|
||||
|
||||
Change-Id: Id6b98dcb3d77366db19e453acfbe4af59697eaf6
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [cbab5fd7757e9c06952c15ac7d30b0809b21406c]
|
||||
---
|
||||
lib/gpt/inc/gpt.h | 19 ++++
|
||||
lib/gpt/src/gpt.c | 156 ++++++++++++++++++++++++++++++-
|
||||
lib/gpt/unittests/gpt/test_gpt.c | 128 +++++++++++++++++++++++++
|
||||
3 files changed, 301 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/gpt/inc/gpt.h b/lib/gpt/inc/gpt.h
|
||||
index 6e7bb360e..85f9bed9c 100644
|
||||
--- a/lib/gpt/inc/gpt.h
|
||||
+++ b/lib/gpt/inc/gpt.h
|
||||
@@ -151,6 +151,25 @@ psa_status_t gpt_attr_remove(const struct efi_guid_t *guid, const uint64_t attr)
|
||||
__attribute__((nonnull(1)))
|
||||
psa_status_t gpt_attr_set(const struct efi_guid_t *guid, const uint64_t attr);
|
||||
|
||||
+/**
|
||||
+ * \brief Moves (or resizes) a partition entry.
|
||||
+ *
|
||||
+ * \param[in] guid Entry to move.
|
||||
+ * \param[in] start New start LBA.
|
||||
+ * \param[in] end New end LBA.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS Success.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_DOES_NOT_EXIST No entry found with the provided GUID.
|
||||
+ * \retval PSA_ERROR_INVALID_ARGUMENT Move would overlap with an existing partition.
|
||||
+ * \retval PSA_ERROR_INVALID_ARGUMENT \p end is less than \p start.
|
||||
+ * \retval PSA_ERROR_INVALID_ARGUMENT Part of the partition would move off flash.
|
||||
+ */
|
||||
+__attribute__((nonnull(1)))
|
||||
+psa_status_t gpt_entry_move(const struct efi_guid_t *guid,
|
||||
+ const uint64_t start,
|
||||
+ const uint64_t end);
|
||||
+
|
||||
/**
|
||||
* \brief Reads the GPT header from the second block (LBA 1).
|
||||
*
|
||||
diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c
|
||||
index 2cfcdff07..40b73f3e9 100644
|
||||
--- a/lib/gpt/src/gpt.c
|
||||
+++ b/lib/gpt/src/gpt.c
|
||||
@@ -214,6 +214,10 @@ static psa_status_t find_gpt_entry(const struct gpt_t *table,
|
||||
const uint32_t repeat_index,
|
||||
struct gpt_entry_t *entry,
|
||||
uint32_t *array_index);
|
||||
+static psa_status_t move_lba(const uint64_t old_lba, const uint64_t new_lba);
|
||||
+static psa_status_t move_partition(const uint64_t old_lba,
|
||||
+ const uint64_t new_lba,
|
||||
+ const uint64_t num_blocks);
|
||||
static psa_status_t mbr_load(struct mbr_t *mbr);
|
||||
static bool gpt_entry_cmp_guid(const struct gpt_entry_t *entry, const void *guid);
|
||||
static bool gpt_entry_cmp_name(const struct gpt_entry_t *entry, const void *name);
|
||||
@@ -391,6 +395,111 @@ psa_status_t gpt_attr_set(const struct efi_guid_t *guid, const uint64_t attr)
|
||||
return write_entry(cached_index, &cached_entry, false);
|
||||
}
|
||||
|
||||
+psa_status_t gpt_entry_move(const struct efi_guid_t *guid,
|
||||
+ const uint64_t start,
|
||||
+ const uint64_t end)
|
||||
+{
|
||||
+ if (end < start) {
|
||||
+ return PSA_ERROR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ /* Must fit on flash */
|
||||
+ if (start < primary_gpt.header.first_lba ||
|
||||
+ end < primary_gpt.header.first_lba ||
|
||||
+ start > primary_gpt.header.last_lba ||
|
||||
+ end > primary_gpt.header.last_lba)
|
||||
+ {
|
||||
+ ERROR("Requested move would not be on disk\n");
|
||||
+ return PSA_ERROR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ struct gpt_entry_t cached_entry;
|
||||
+ uint32_t cached_index;
|
||||
+ psa_status_t ret = find_gpt_entry(
|
||||
+ &primary_gpt,
|
||||
+ gpt_entry_cmp_guid,
|
||||
+ guid,
|
||||
+ 0,
|
||||
+ &cached_entry,
|
||||
+ &cached_index);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Prevent unecessary I/O */
|
||||
+ if (start == cached_entry.start && end == cached_entry.end) {
|
||||
+ return PSA_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ /* It is not possible to move a partition such that it overlaps with an
|
||||
+ * existing partition (other than itself). Check the currently cached LBA
|
||||
+ * first, then the others to avoid reading this LBA twice
|
||||
+ */
|
||||
+ struct gpt_entry_t entry;
|
||||
+ const uint64_t checked_lba = cached_lba;
|
||||
+ const uint64_t array_end_lba = partition_array_last_lba(&primary_gpt);
|
||||
+ uint32_t num_entries_in_cached_lba;
|
||||
+ if (cached_lba == array_end_lba) {
|
||||
+ /* If this is 0, then the last LBA is full */
|
||||
+ uint32_t num_entries_in_last_lba = primary_gpt.num_used_partitions % gpt_entry_per_lba_count();
|
||||
+ if (num_entries_in_last_lba == 0) {
|
||||
+ num_entries_in_cached_lba = gpt_entry_per_lba_count();
|
||||
+ } else {
|
||||
+ num_entries_in_cached_lba = num_entries_in_last_lba;
|
||||
+ }
|
||||
+ } else {
|
||||
+ num_entries_in_cached_lba = gpt_entry_per_lba_count();
|
||||
+ }
|
||||
+
|
||||
+ /* Cached LBA */
|
||||
+ for (uint32_t i = 0; i < num_entries_in_cached_lba; ++i) {
|
||||
+ memcpy(&entry, lba_buf + (i * primary_gpt.header.entry_size), GPT_ENTRY_SIZE);
|
||||
+
|
||||
+ const struct efi_guid_t ent_guid = entry.unique_guid;
|
||||
+ if (efi_guid_cmp(&ent_guid, guid) == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if ((start >= entry.start && start <= entry.end) ||
|
||||
+ (end >= entry.start && end <= entry.end) ||
|
||||
+ (start <= entry.start && end >= entry.end))
|
||||
+ {
|
||||
+ return PSA_ERROR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* All the rest */
|
||||
+ for (uint32_t i = 0; i < primary_gpt.num_used_partitions; ++i) {
|
||||
+ if (partition_entry_lba(&primary_gpt, i) == checked_lba) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ ret = read_entry_from_flash(&primary_gpt, i, &entry);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if ((start >= entry.start && start <= entry.end) ||
|
||||
+ (end >= entry.start && end <= entry.end) ||
|
||||
+ (start <= entry.start && end >= entry.end))
|
||||
+ {
|
||||
+ return PSA_ERROR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = move_partition(
|
||||
+ cached_entry.start,
|
||||
+ start,
|
||||
+ end - start + 1);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ cached_entry.start = start;
|
||||
+ cached_entry.end = end;
|
||||
+
|
||||
+ return write_entry(cached_index, &cached_entry, false);
|
||||
+}
|
||||
+
|
||||
/* Initialises GPT from first block. */
|
||||
psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, uint64_t max_partitions)
|
||||
{
|
||||
@@ -586,6 +695,49 @@ static psa_status_t find_gpt_entry(const struct gpt_t *table,
|
||||
return io_failure ? PSA_ERROR_STORAGE_FAILURE : PSA_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
+/* Move a single LBAs data to somewhere else */
|
||||
+static psa_status_t move_lba(const uint64_t old_lba, const uint64_t new_lba)
|
||||
+{
|
||||
+ const psa_status_t ret = read_from_flash(old_lba);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return write_to_flash(new_lba);
|
||||
+}
|
||||
+
|
||||
+/* Moves a partition's data to start from one logical block to another */
|
||||
+static psa_status_t move_partition(const uint64_t old_lba,
|
||||
+ const uint64_t new_lba,
|
||||
+ const uint64_t num_blocks)
|
||||
+{
|
||||
+ if (old_lba == new_lba) {
|
||||
+ return PSA_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ if (old_lba < new_lba) {
|
||||
+ /* Move block by block backwards */
|
||||
+ for (uint64_t block = num_blocks; block > 0; --block) {
|
||||
+ const psa_status_t ret = move_lba(old_lba + block - 1, new_lba + block - 1);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* Move block by block forwards */
|
||||
+ for (uint64_t block = 0; block < num_blocks; ++block) {
|
||||
+ const psa_status_t ret = move_lba(old_lba + block, new_lba + block);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ write_buffered = false;
|
||||
+
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
+
|
||||
/* Updates the header of the GPT based on new number of partitions */
|
||||
static psa_status_t update_header(uint32_t num_partitions)
|
||||
{
|
||||
@@ -794,8 +946,8 @@ static psa_status_t flush_lba_buf(void)
|
||||
/* Backup array entry. Write to backup and primary array */
|
||||
ret = write_entries_to_flash(cached_lba - backup_gpt_array_lba, false);
|
||||
} else {
|
||||
- /* Shouldn't be possible */
|
||||
- ERROR("Unknown data in LBA cache, discarding\n");
|
||||
+ /* Some other LBA is cached, possibly data. Write it anyway */
|
||||
+ ret = write_to_flash(cached_lba);
|
||||
}
|
||||
|
||||
in_flush = false;
|
||||
diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
index 1121f7c73..251b04ee9 100644
|
||||
--- a/lib/gpt/unittests/gpt/test_gpt.c
|
||||
+++ b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
@@ -368,6 +368,134 @@ void test_gpt_init_should_failWhenFlashDriverNotFullyDefined(void)
|
||||
mock_driver.erase = erase_fn;
|
||||
}
|
||||
|
||||
+void test_gpt_entry_move_should_moveEntry(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ setup_valid_gpt();
|
||||
+ struct gpt_entry_t *test_entry = &(test_partition_array[TEST_DEFAULT_NUM_PARTITIONS - 1]);
|
||||
+ struct efi_guid_t test_guid = test_entry->guid;
|
||||
+
|
||||
+ /* First all entries are read to determine for overlap */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ /* Move the partition. Read each block to then write. It doesn't matter what
|
||||
+ * the data is
|
||||
+ */
|
||||
+ char unused_read_data = 'X';
|
||||
+ register_mocked_read(&unused_read_data, sizeof(unused_read_data));
|
||||
+
|
||||
+ /* Header update - reads partition array to calculate crc32 and also then
|
||||
+ * reads the header to modify and write back
|
||||
+ */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+ register_mocked_read(&test_header, sizeof(test_header));
|
||||
+
|
||||
+ /* Do a valid move and resize in one */
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_entry_move(
|
||||
+ &test_guid,
|
||||
+ TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ TEST_GPT_THIRD_PARTITION_END + 1));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_move_should_failWhenEntryNotExisting(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Read every entry */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ struct efi_guid_t non_existing = NULL_GUID;
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_move(
|
||||
+ &non_existing,
|
||||
+ TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ TEST_GPT_THIRD_PARTITION_END + 1));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_move_should_failWhenEndLessThanStart(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ struct efi_guid_t test_guid = test_partition_array[0].guid;
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_move(
|
||||
+ &test_guid,
|
||||
+ TEST_GPT_THIRD_PARTITION_END + 2,
|
||||
+ TEST_GPT_THIRD_PARTITION_END + 1));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_move_should_failWhenLbaOverlapping(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Try to move an entry. Each entry is read to determine for overlap */
|
||||
+ size_t test_index = 1;
|
||||
+ struct gpt_entry_t *test_entry = &(test_partition_array[test_index]);
|
||||
+ struct efi_guid_t test_guid = test_entry->guid;
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ /* Try to move the test entry into the middle of the entry just read.
|
||||
+ * Starting at the same LBA
|
||||
+ */
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_move(
|
||||
+ &test_guid,
|
||||
+ TEST_GPT_FIRST_PARTITION_START,
|
||||
+ TEST_GPT_SECOND_PARTITION_END));
|
||||
+
|
||||
+ /* Try to move the test entry into the middle of the entry just read.
|
||||
+ * Starting in the middle
|
||||
+ */
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_move(
|
||||
+ &test_guid,
|
||||
+ TEST_GPT_FIRST_PARTITION_START + 1,
|
||||
+ TEST_GPT_SECOND_PARTITION_END));
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_move(
|
||||
+ &test_guid,
|
||||
+ TEST_GPT_SECOND_PARTITION_START,
|
||||
+ TEST_GPT_THIRD_PARTITION_START));
|
||||
+
|
||||
+ /* Try to move the test entry into the middle of the entry just read.
|
||||
+ * Starting and ending in the middle.
|
||||
+ */
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_move(
|
||||
+ &test_guid,
|
||||
+ TEST_GPT_FIRST_PARTITION_START + 1,
|
||||
+ TEST_GPT_FIRST_PARTITION_START + 1));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_move_should_failWhenLbaOffDisk(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Try to move an entry. */
|
||||
+ size_t test_index = 1;
|
||||
+ struct gpt_entry_t *test_entry = &(test_partition_array[test_index]);
|
||||
+ struct efi_guid_t test_guid = test_entry->guid;
|
||||
+
|
||||
+ /* First start on disk, then go off the disk */
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_move(
|
||||
+ &test_guid,
|
||||
+ TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ TEST_DISK_NUM_BLOCKS + 1));
|
||||
+
|
||||
+ /* Second, start off the disk entirely */
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_move(
|
||||
+ &test_guid,
|
||||
+ TEST_DISK_NUM_BLOCKS + 1,
|
||||
+ TEST_DISK_NUM_BLOCKS + 2));
|
||||
+
|
||||
+ /* Third, do the same but in the header area */
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_move(
|
||||
+ &test_guid,
|
||||
+ TEST_GPT_PRIMARY_LBA,
|
||||
+ TEST_GPT_THIRD_PARTITION_END + 2));
|
||||
+
|
||||
+ /* Fourth, start in the backup header area */
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_move(
|
||||
+ &test_guid,
|
||||
+ TEST_GPT_BACKUP_LBA,
|
||||
+ TEST_GPT_BACKUP_LBA + 1));
|
||||
+}
|
||||
+
|
||||
void test_gpt_attr_set_should_setAttributes(void)
|
||||
{
|
||||
/* Start with a populated GPT */
|
||||
-713
@@ -1,713 +0,0 @@
|
||||
From bec8f44a2732c20e8f69a06841637673af90c37e Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Tue, 30 Dec 2025 10:16:21 +0000
|
||||
Subject: [PATCH] lib: gpt: Added ability to create and remove partitions
|
||||
|
||||
With this change, new GPT partitions can be created and added to the
|
||||
table and old partitions can be removed. Both of these are metadata
|
||||
changes and only make changes to the partition entry array and header
|
||||
(primary and backup).
|
||||
|
||||
New partitions must be created in empty space only. The data that the
|
||||
partition points to is not cleared and if desired this should be done by
|
||||
the caller before or after creation.
|
||||
|
||||
When a partition is removed, the data it pointed to is not cleared so
|
||||
this should be done by the caller if desired. After removal, that data
|
||||
is considered empty space.
|
||||
|
||||
Change-Id: Iecccb814aaf8f48cbdd8e29b3d2b54fb5b58aae8
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [4d69babc99917e3cc2df284a311ec37004c3ee3f]
|
||||
---
|
||||
lib/gpt/CMakeLists.txt | 1 +
|
||||
lib/gpt/inc/gpt.h | 37 +++
|
||||
lib/gpt/src/gpt.c | 249 ++++++++++++++-
|
||||
lib/gpt/unittests/gpt/test_gpt.c | 284 ++++++++++++++++++
|
||||
lib/gpt/unittests/gpt/utcfg.cmake | 2 +
|
||||
.../include/mbedtls/mbedtls_config.h | 18 ++
|
||||
6 files changed, 590 insertions(+), 1 deletion(-)
|
||||
create mode 100644 lib/gpt/unittests/include/mbedtls/mbedtls_config.h
|
||||
|
||||
diff --git a/lib/gpt/CMakeLists.txt b/lib/gpt/CMakeLists.txt
|
||||
index 25d0de9cd..5befc346f 100644
|
||||
--- a/lib/gpt/CMakeLists.txt
|
||||
+++ b/lib/gpt/CMakeLists.txt
|
||||
@@ -23,6 +23,7 @@ target_sources(tfm_gpt
|
||||
target_include_directories(tfm_gpt
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
|
||||
+ $<INSTALL_INTERFACE:inc>
|
||||
)
|
||||
|
||||
target_compile_definitions(tfm_gpt
|
||||
diff --git a/lib/gpt/inc/gpt.h b/lib/gpt/inc/gpt.h
|
||||
index 85f9bed9c..f04643957 100644
|
||||
--- a/lib/gpt/inc/gpt.h
|
||||
+++ b/lib/gpt/inc/gpt.h
|
||||
@@ -170,6 +170,43 @@ psa_status_t gpt_entry_move(const struct efi_guid_t *guid,
|
||||
const uint64_t start,
|
||||
const uint64_t end);
|
||||
|
||||
+/**
|
||||
+ * \brief Creates a partition entry in the table.
|
||||
+ *
|
||||
+ * \param[in] type Partition type.
|
||||
+ * \param[in] start Starting LBA (0 uses the lowest free LBA possible).
|
||||
+ * \param[in] size Size of the partition in LBAs.
|
||||
+ * \param[in] attr Attributes for the partition.
|
||||
+ * \param[in] name Partition name in unicode.
|
||||
+ * \param[out] guid GUID populated on success for subsequent API calls.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS Success.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_INSUFFICIENT_STORAGE Maximum number of partitions reached.
|
||||
+ * \retval PSA_ERROR_INVALID_ARGUMENT Partition would extend beyond the flash.
|
||||
+ * \retval PSA_ERROR_INVALID_ARGUMENT New entry would overlap an existing partition, the name is empty,
|
||||
+ * or \p size is zero.
|
||||
+ */
|
||||
+__attribute__((nonnull(1,5,6)))
|
||||
+psa_status_t gpt_entry_create(const struct efi_guid_t *type,
|
||||
+ const uint64_t start,
|
||||
+ const uint64_t size,
|
||||
+ const uint64_t attr,
|
||||
+ const char name[GPT_ENTRY_NAME_LENGTH],
|
||||
+ struct efi_guid_t *guid);
|
||||
+
|
||||
+/**
|
||||
+ * \brief Removes a partition entry from the table.
|
||||
+ *
|
||||
+ * \param[in] guid Entry to remove.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS Success.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_DOES_NOT_EXIST No entry found with the provided GUID.
|
||||
+ */
|
||||
+__attribute__((nonnull(1)))
|
||||
+psa_status_t gpt_entry_remove(const struct efi_guid_t *guid);
|
||||
+
|
||||
/**
|
||||
* \brief Reads the GPT header from the second block (LBA 1).
|
||||
*
|
||||
diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c
|
||||
index 40b73f3e9..676f04fd6 100644
|
||||
--- a/lib/gpt/src/gpt.c
|
||||
+++ b/lib/gpt/src/gpt.c
|
||||
@@ -9,11 +9,12 @@
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
-#include "psa/error.h"
|
||||
+#include "psa/crypto.h"
|
||||
#include "gpt.h"
|
||||
#include "gpt_flash.h"
|
||||
#include "tfm_log.h"
|
||||
#include "efi_guid_structs.h"
|
||||
+#include "efi_guid.h"
|
||||
#include "efi_soft_crc.h"
|
||||
|
||||
/* This needs to be defined by the platform and is used by the GPT library as
|
||||
@@ -500,6 +501,252 @@ psa_status_t gpt_entry_move(const struct efi_guid_t *guid,
|
||||
return write_entry(cached_index, &cached_entry, false);
|
||||
}
|
||||
|
||||
+psa_status_t gpt_entry_create(const struct efi_guid_t *type,
|
||||
+ const uint64_t start,
|
||||
+ const uint64_t size,
|
||||
+ const uint64_t attr,
|
||||
+ const char name[GPT_ENTRY_NAME_LENGTH],
|
||||
+ struct efi_guid_t *guid)
|
||||
+{
|
||||
+ /* Using inequlity here handles when reading an initial GPT has more than
|
||||
+ * the maximum defined number of partitions.
|
||||
+ */
|
||||
+ if (primary_gpt.num_used_partitions >= plat_max_partitions) {
|
||||
+ ERROR("Maximum number of partitions reached\n");
|
||||
+ return PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
+ }
|
||||
+ if (size == 0) {
|
||||
+ ERROR("Cannot create entry of size 0\n");
|
||||
+ return PSA_ERROR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+ if (name[0] == '\0') {
|
||||
+ ERROR("Cannot create entry with no name\n");
|
||||
+ return PSA_ERROR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ uint64_t start_lba = start;
|
||||
+ psa_status_t ret = PSA_SUCCESS;
|
||||
+ if (start_lba == 0) {
|
||||
+ /* Use the lowest free LBA possible. Each partition uses contiguous space,
|
||||
+ * so if there is a gap between partitions, that will be shown by the end
|
||||
+ * and start not being contiguous.
|
||||
+ */
|
||||
+ uint64_t prev_end = primary_gpt.header.first_lba;
|
||||
+ for (uint32_t i = 0; i < primary_gpt.header.num_partitions; ++i) {
|
||||
+ struct gpt_entry_t entry = {0};
|
||||
+ ret = read_entry_from_flash(&primary_gpt, i, &entry);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (entry.start - 1 > prev_end) {
|
||||
+ start_lba = prev_end + 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ prev_end = entry.end;
|
||||
+ }
|
||||
+
|
||||
+ if (start_lba != prev_end + 1) {
|
||||
+ /* No free space */
|
||||
+ ERROR("No free space on device!\n");
|
||||
+ return PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Must fit on flash */
|
||||
+ const uint64_t end_lba = start_lba + size - 1;
|
||||
+ if (start_lba < primary_gpt.header.first_lba ||
|
||||
+ end_lba < primary_gpt.header.first_lba ||
|
||||
+ start_lba > primary_gpt.header.last_lba ||
|
||||
+ end_lba > primary_gpt.header.last_lba)
|
||||
+ {
|
||||
+ ERROR("Requested partition would not be on disk\n");
|
||||
+ return PSA_ERROR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ /* Do not allow overlapping partitions */
|
||||
+ struct gpt_entry_t entry;
|
||||
+ for (uint32_t i = 0; i < primary_gpt.num_used_partitions; ++i) {
|
||||
+ ret = read_entry_from_flash(&primary_gpt, i, &entry);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if ((start_lba >= entry.start && start_lba <= entry.end) ||
|
||||
+ (end_lba >= entry.start && end_lba <= entry.end) ||
|
||||
+ (start_lba <= entry.start && end_lba >= entry.end))
|
||||
+ {
|
||||
+ return PSA_ERROR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Generate the new random GUID */
|
||||
+ if (efi_guid_generate_random(guid) != PSA_SUCCESS) {
|
||||
+ ERROR("Unable to generate GUID\n");
|
||||
+ return PSA_ERROR_STORAGE_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ /* Set new entry's metadata */
|
||||
+ struct gpt_entry_t new_entry = {0};
|
||||
+ new_entry.start = start_lba;
|
||||
+ new_entry.end = end_lba;
|
||||
+ new_entry.attr = attr;
|
||||
+ memcpy(new_entry.name, name, GPT_ENTRY_NAME_LENGTH);
|
||||
+ new_entry.partition_type = *type;
|
||||
+ new_entry.unique_guid = *guid;
|
||||
+
|
||||
+ /* Write the new entry. Skip header update as it is explicitely called
|
||||
+ * below with new number of partitions
|
||||
+ */
|
||||
+ ret = write_entry(primary_gpt.num_used_partitions++, &new_entry, true);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ --primary_gpt.num_used_partitions;
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Flush the buffered LBA if not done so. This will cause the header to be
|
||||
+ * updated
|
||||
+ */
|
||||
+ if (write_buffered) {
|
||||
+ /* flush_lba_buf will update the header */
|
||||
+ ret = flush_lba_buf();
|
||||
+ } else {
|
||||
+ ret = update_header(primary_gpt.num_used_partitions);
|
||||
+ }
|
||||
+
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+psa_status_t gpt_entry_remove(const struct efi_guid_t *guid)
|
||||
+{
|
||||
+ struct gpt_entry_t cached_entry;
|
||||
+ uint32_t cached_index;
|
||||
+ psa_status_t ret = find_gpt_entry(
|
||||
+ &primary_gpt,
|
||||
+ gpt_entry_cmp_guid,
|
||||
+ guid,
|
||||
+ 0,
|
||||
+ &cached_entry,
|
||||
+ &cached_index);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Shuffle the remainder of the array up. This will overwrite the
|
||||
+ * most previous entry.
|
||||
+ *
|
||||
+ * The first LBA to potentially modify is in memory. It doesn't need
|
||||
+ * to be modified if the last entry in the array was moved or if it is
|
||||
+ * the only LBA used by the partition array
|
||||
+ */
|
||||
+ if (cached_index != primary_gpt.num_used_partitions - 1 ||
|
||||
+ cached_index < gpt_entry_per_lba_count())
|
||||
+ {
|
||||
+ /* Shuffle up the remainder of the LBA. If it was the last entry
|
||||
+ * in the LBA, there is nothing to do.
|
||||
+ */
|
||||
+ const uint32_t lba_index = cached_index % gpt_entry_per_lba_count();
|
||||
+ if (lba_index + 1 != gpt_entry_per_lba_count()) {
|
||||
+ memmove(
|
||||
+ lba_buf + lba_index * primary_gpt.header.entry_size,
|
||||
+ lba_buf + (lba_index + 1) * primary_gpt.header.entry_size,
|
||||
+ (gpt_entry_per_lba_count() - lba_index - 1) * primary_gpt.header.entry_size);
|
||||
+ }
|
||||
+
|
||||
+ /* If this is not the last LBA, then read the next LBA into memory and
|
||||
+ * place it's first element in the final slot of the currently modified
|
||||
+ * LBA. Repeat this for each LBA read.
|
||||
+ *
|
||||
+ * Use a second buffer to read each consecutive LBA and copy that to
|
||||
+ * the global LBA buffer to then write afterwards.
|
||||
+ */
|
||||
+ const uint64_t array_end_lba = partition_array_last_lba(&primary_gpt);
|
||||
+ for (uint64_t i = partition_entry_lba(&primary_gpt, cached_index) + 1;
|
||||
+ i <= array_end_lba;
|
||||
+ ++i)
|
||||
+ {
|
||||
+ uint8_t array_buf[TFM_GPT_BLOCK_SIZE] = {0};
|
||||
+ int read_ret = plat_flash_driver->read(i, array_buf);
|
||||
+ if (read_ret != TFM_GPT_BLOCK_SIZE) {
|
||||
+ ERROR("Unable to read LBA 0x%08x%08x\n",
|
||||
+ (uint32_t)(i >> 32), (uint32_t)i);
|
||||
+ return PSA_ERROR_STORAGE_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(
|
||||
+ lba_buf + primary_gpt.header.entry_size * (gpt_entry_per_lba_count() - 1),
|
||||
+ array_buf,
|
||||
+ GPT_ENTRY_SIZE);
|
||||
+
|
||||
+ /* Write to backup first, then primary partition array */
|
||||
+ if (backup_gpt_array_lba != 0) {
|
||||
+ ret = write_to_flash(backup_gpt_array_lba + i - 1 - PRIMARY_GPT_ARRAY_LBA);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ ret = write_to_flash(i - 1);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ memmove(
|
||||
+ array_buf,
|
||||
+ array_buf + primary_gpt.header.entry_size,
|
||||
+ sizeof(array_buf) - primary_gpt.header.entry_size);
|
||||
+ memcpy(lba_buf, array_buf, TFM_GPT_BLOCK_SIZE);
|
||||
+ }
|
||||
+
|
||||
+ /* What was the final LBA is now cached and may be empty or partially-filled */
|
||||
+ cached_lba = array_end_lba;
|
||||
+ write_buffered = false;
|
||||
+ uint32_t entries_in_last_lba = (--primary_gpt.num_used_partitions) % gpt_entry_per_lba_count();
|
||||
+ if (entries_in_last_lba == 0) {
|
||||
+ /* There's nothing left in this LBA, so zero it all and write it out.
|
||||
+ * There is also no need to do an erase just to zero afterwards.
|
||||
+ */
|
||||
+ memset(lba_buf, 0, TFM_GPT_BLOCK_SIZE);
|
||||
+ if (backup_gpt_array_lba != 0) {
|
||||
+ int write_ret = plat_flash_driver->write(
|
||||
+ backup_gpt_array_lba + array_end_lba - PRIMARY_GPT_ARRAY_LBA,
|
||||
+ lba_buf);
|
||||
+ if (write_ret != TFM_GPT_BLOCK_SIZE) {
|
||||
+ return PSA_ERROR_STORAGE_FAILURE;
|
||||
+ }
|
||||
+ }
|
||||
+ int write_ret = plat_flash_driver->write(array_end_lba, lba_buf);
|
||||
+ if (write_ret != TFM_GPT_BLOCK_SIZE) {
|
||||
+ return PSA_ERROR_STORAGE_FAILURE;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* Zero what is not needed anymore */
|
||||
+ memset(
|
||||
+ lba_buf + primary_gpt.header.entry_size * entries_in_last_lba,
|
||||
+ 0,
|
||||
+ (gpt_entry_per_lba_count() - entries_in_last_lba) * primary_gpt.header.entry_size);
|
||||
+ if (backup_gpt_array_lba != 0) {
|
||||
+ ret = write_to_flash(backup_gpt_array_lba + array_end_lba - PRIMARY_GPT_ARRAY_LBA);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ ret = write_to_flash(array_end_lba);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Update the header after flash changes */
|
||||
+ ret = update_header(primary_gpt.num_used_partitions);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/* Initialises GPT from first block. */
|
||||
psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, uint64_t max_partitions)
|
||||
{
|
||||
diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
index 251b04ee9..18cf2c8f3 100644
|
||||
--- a/lib/gpt/unittests/gpt/test_gpt.c
|
||||
+++ b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
+#include "mock_efi_guid.h"
|
||||
#include "mock_efi_soft_crc.h"
|
||||
#include "mock_tfm_log.h"
|
||||
#include "mock_tfm_vprintf.h"
|
||||
@@ -368,6 +369,260 @@ void test_gpt_init_should_failWhenFlashDriverNotFullyDefined(void)
|
||||
mock_driver.erase = erase_fn;
|
||||
}
|
||||
|
||||
+void test_gpt_entry_create_should_createNewEntry(void)
|
||||
+{
|
||||
+ /* Add an entry. It must not overlap with an existing entry and must also
|
||||
+ * fit on the storage device. The GUID should be populated with something.
|
||||
+ */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Each entry will be read in order to check that it doesn't overlap with
|
||||
+ * any of them
|
||||
+ */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ /* Update header. Read each entry for CRC calculation. */
|
||||
+ struct gpt_entry_t new_entry = {
|
||||
+ .type = NULL_GUID,
|
||||
+ .start = TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ .end = TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ .attr = 0,
|
||||
+ .name = "Fourth partition"
|
||||
+ };
|
||||
+
|
||||
+ /* Mock out the call to create a new GUID */
|
||||
+ struct efi_guid_t expected_guid = MAKE_EFI_GUID(5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11);
|
||||
+ efi_guid_generate_random_ExpectAnyArgsAndReturn(PSA_SUCCESS);
|
||||
+ efi_guid_generate_random_ReturnThruPtr_guid(&expected_guid);
|
||||
+
|
||||
+ /* Ensure also the that a new GUID is assigned */
|
||||
+ struct efi_guid_t new_guid = MAKE_EFI_GUID(4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11);
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_entry_create(
|
||||
+ &expected_guid,
|
||||
+ new_entry.start,
|
||||
+ new_entry.end - new_entry.start + 1,
|
||||
+ new_entry.attr,
|
||||
+ new_entry.name,
|
||||
+ &new_guid));
|
||||
+ TEST_ASSERT_EQUAL_MEMORY(&expected_guid, &new_guid, sizeof(new_guid));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_create_should_createNewEntryNextToLastEntry(void)
|
||||
+{
|
||||
+ /* Add an entry, allowing the library to choose the start LBA.
|
||||
+ * The GUID should be populated with something.
|
||||
+ */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Each entry will be read in order to check that it doesn't overlap with
|
||||
+ * any of them
|
||||
+ */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ /* Update header. Read each entry for CRC calculation. */
|
||||
+ struct gpt_entry_t new_entry = {
|
||||
+ .type = NULL_GUID,
|
||||
+ .start = TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ .end = TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ .attr = 0,
|
||||
+ .name = "Fourth partition"
|
||||
+ };
|
||||
+
|
||||
+ /* Mock out the call to create a new GUID */
|
||||
+ struct efi_guid_t expected_guid = MAKE_EFI_GUID(5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11);
|
||||
+ efi_guid_generate_random_ExpectAnyArgsAndReturn(PSA_SUCCESS);
|
||||
+ efi_guid_generate_random_ReturnThruPtr_guid(&expected_guid);
|
||||
+
|
||||
+ /* Ensure also the that a new GUID is assigned */
|
||||
+ struct efi_guid_t new_guid = MAKE_EFI_GUID(4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11);
|
||||
+ char name[GPT_ENTRY_NAME_LENGTH] = {'\0'};
|
||||
+ name[0] = 'a';
|
||||
+
|
||||
+ /* Ensure also the that a new GUID is assigned */
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_entry_create(
|
||||
+ &expected_guid,
|
||||
+ 0,
|
||||
+ 1,
|
||||
+ new_entry.attr,
|
||||
+ name,
|
||||
+ &new_guid));
|
||||
+ TEST_ASSERT_EQUAL_MEMORY(&expected_guid, &new_guid, sizeof(new_guid));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_create_should_failToCreateEntryWhenLowestFreeLbaDoesNotHaveSpace(void)
|
||||
+{
|
||||
+ /* Add an entry, allowing the library to choose the start LBA.
|
||||
+ * The GUID should be populated with something.
|
||||
+ */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Each entry will be read in order to check that it doesn't overlap with
|
||||
+ * any of them
|
||||
+ */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ /* Ensure also the that a new GUID is assigned */
|
||||
+ struct efi_guid_t existing_guid = MAKE_EFI_GUID(4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11);
|
||||
+ struct efi_guid_t new_guid;
|
||||
+ char name[GPT_ENTRY_NAME_LENGTH] = {'\0'};
|
||||
+ name[0] = 'a';
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_create(
|
||||
+ &(existing_guid),
|
||||
+ 0,
|
||||
+ TEST_DISK_NUM_BLOCKS,
|
||||
+ 0,
|
||||
+ name,
|
||||
+ &(new_guid)));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_create_should_failWhenTableFull(void)
|
||||
+{
|
||||
+ /* Start with a full array of entries */
|
||||
+ struct gpt_entry_t new_entry = {
|
||||
+ .type = MAKE_EFI_GUID(4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11),
|
||||
+ .start = TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ .end = TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ .attr = 0,
|
||||
+ .guid = MAKE_EFI_GUID(4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11),
|
||||
+ .name = "Fourth partition"
|
||||
+ };
|
||||
+ test_partition_array[TEST_MAX_PARTITIONS - 1] = new_entry;
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ struct efi_guid_t type = MAKE_EFI_GUID(5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11);
|
||||
+ struct efi_guid_t guid;
|
||||
+ char name[GPT_ENTRY_NAME_LENGTH] = {'\0'};
|
||||
+ name[0] = 'a';
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INSUFFICIENT_STORAGE, gpt_entry_create(
|
||||
+ &type,
|
||||
+ TEST_GPT_THIRD_PARTITION_END + 4,
|
||||
+ 1,
|
||||
+ 0,
|
||||
+ name,
|
||||
+ &guid));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_create_should_failWhenLbaOffDisk(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* First start on disk, then go off the disk */
|
||||
+ struct efi_guid_t type = NULL_GUID;
|
||||
+ struct efi_guid_t guid;
|
||||
+ char name[GPT_ENTRY_NAME_LENGTH] = {'\0'};
|
||||
+ name[0] = 'a';
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_create(
|
||||
+ &type,
|
||||
+ TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ 1000,
|
||||
+ 0,
|
||||
+ name,
|
||||
+ &guid));
|
||||
+
|
||||
+ /* Second, start off the disk entirely */
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_create(
|
||||
+ &type,
|
||||
+ TEST_DISK_NUM_BLOCKS + 100,
|
||||
+ 1,
|
||||
+ 0,
|
||||
+ name,
|
||||
+ &guid));
|
||||
+
|
||||
+ /* Third, do the same but in the header area */
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_create(
|
||||
+ &type,
|
||||
+ TEST_GPT_PRIMARY_LBA,
|
||||
+ 1,
|
||||
+ 0,
|
||||
+ name,
|
||||
+ &guid));
|
||||
+
|
||||
+ /* Fourth, start in the backup header area */
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_create(
|
||||
+ &type,
|
||||
+ TEST_GPT_BACKUP_LBA,
|
||||
+ 1,
|
||||
+ 0,
|
||||
+ name,
|
||||
+ &guid));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_create_should_failWhenOverlapping(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Since the disk is not fragmented by default, there are two test cases:
|
||||
+ * 1. start in the middle of a partition and end in the middle of a partition
|
||||
+ * 2. start in the middle of a partition and end in free space
|
||||
+ */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+ struct efi_guid_t type = NULL_GUID;
|
||||
+ struct efi_guid_t guid;
|
||||
+ char name[GPT_ENTRY_NAME_LENGTH] = {'\0'};
|
||||
+ name[0] = 'a';
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_create(
|
||||
+ &type,
|
||||
+ TEST_GPT_FIRST_PARTITION_START,
|
||||
+ TEST_GPT_FIRST_PARTITION_END - TEST_GPT_FIRST_PARTITION_START + 1,
|
||||
+ 0,
|
||||
+ name,
|
||||
+ &guid));
|
||||
+
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_create(
|
||||
+ &type,
|
||||
+ TEST_GPT_FIRST_PARTITION_START,
|
||||
+ TEST_GPT_LAST_USABLE_LBA - TEST_GPT_FIRST_PARTITION_START,
|
||||
+ 0,
|
||||
+ name,
|
||||
+ &guid));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_create_should_failWhenNameIsEmpty(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ struct efi_guid_t type = NULL_GUID;
|
||||
+ struct gpt_entry_t new_entry = {
|
||||
+ .type = type,
|
||||
+ .start = TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ .end = TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ .attr = 0,
|
||||
+ };
|
||||
+
|
||||
+ /* Make an entry with an empty name */
|
||||
+ char name[GPT_ENTRY_NAME_LENGTH] = {'\0'};
|
||||
+ struct efi_guid_t new_guid;
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_create(
|
||||
+ &type,
|
||||
+ new_entry.start,
|
||||
+ 1,
|
||||
+ 0,
|
||||
+ name,
|
||||
+ &new_guid));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_create_should_failWhenSizeIsZero(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ struct efi_guid_t type = NULL_GUID;
|
||||
+
|
||||
+ /* Make the size zero */
|
||||
+ struct efi_guid_t new_guid;
|
||||
+ char name[GPT_ENTRY_NAME_LENGTH] = {'\0'};
|
||||
+ name[0] = 'a';
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_entry_create(
|
||||
+ &type,
|
||||
+ TEST_GPT_THIRD_PARTITION_END + 1,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ name,
|
||||
+ &new_guid));
|
||||
+}
|
||||
+
|
||||
void test_gpt_entry_move_should_moveEntry(void)
|
||||
{
|
||||
/* Start with a populated GPT */
|
||||
@@ -654,6 +909,35 @@ void test_gpt_entry_rename_should_failWhenEntryNotExisting(void)
|
||||
TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_rename(&non_existing, new_name));
|
||||
}
|
||||
|
||||
+void test_gpt_entry_remove_should_removeEntry(void)
|
||||
+{
|
||||
+ /* Start with a populated GPT */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Each entry is read */
|
||||
+ struct gpt_entry_t *test_entry = &(default_partition_array[TEST_DEFAULT_NUM_PARTITIONS - 1]);
|
||||
+ struct efi_guid_t test_guid = test_entry->guid;
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_entry_remove(&test_guid));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_entry_remove_should_failWhenEntryNotExisting(void)
|
||||
+{
|
||||
+ /* Start by trying to remove from an empty table */
|
||||
+ setup_empty_gpt();
|
||||
+
|
||||
+ struct efi_guid_t non_existing = NULL_GUID;
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_remove(&non_existing));
|
||||
+
|
||||
+ /* Now, have a non-empty GPT but search for a non-existing GUID */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* Each entry should be read. */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_remove(&non_existing));
|
||||
+}
|
||||
+
|
||||
void test_gpt_entry_read_should_populateEntry(void)
|
||||
{
|
||||
/* Start with a populated GPT */
|
||||
diff --git a/lib/gpt/unittests/gpt/utcfg.cmake b/lib/gpt/unittests/gpt/utcfg.cmake
|
||||
index 620d15b4c..f3f4e7dcc 100644
|
||||
--- a/lib/gpt/unittests/gpt/utcfg.cmake
|
||||
+++ b/lib/gpt/unittests/gpt/utcfg.cmake
|
||||
@@ -15,11 +15,13 @@ set(UNIT_TEST_SUITE ${CMAKE_CURRENT_LIST_DIR}/test_gpt.c)
|
||||
list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/interface/include)
|
||||
list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/lib/efi_guid/inc)
|
||||
list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/lib/gpt/inc)
|
||||
+list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/lib/gpt/unittests/include)
|
||||
list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/lib/ext/efi_soft_crc/inc)
|
||||
list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/lib/tfm_log/inc)
|
||||
list(APPEND UNIT_TEST_INCLUDE_DIRS ${TFM_ROOT_DIR}/lib/tfm_vprintf/inc)
|
||||
|
||||
# Headers to be mocked
|
||||
+list(APPEND MOCK_HEADERS ${TFM_ROOT_DIR}/lib/efi_guid/inc/efi_guid.h)
|
||||
list(APPEND MOCK_HEADERS ${TFM_ROOT_DIR}/lib/tfm_log/inc/tfm_log.h)
|
||||
list(APPEND MOCK_HEADERS ${TFM_ROOT_DIR}/lib/tfm_vprintf/inc/tfm_vprintf.h)
|
||||
list(APPEND MOCK_HEADERS ${TFM_ROOT_DIR}/lib/ext/efi_soft_crc/inc/efi_soft_crc.h)
|
||||
diff --git a/lib/gpt/unittests/include/mbedtls/mbedtls_config.h b/lib/gpt/unittests/include/mbedtls/mbedtls_config.h
|
||||
new file mode 100644
|
||||
index 000000000..5144daae3
|
||||
--- /dev/null
|
||||
+++ b/lib/gpt/unittests/include/mbedtls/mbedtls_config.h
|
||||
@@ -0,0 +1,18 @@
|
||||
+/*
|
||||
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-3-Clause
|
||||
+ */
|
||||
+
|
||||
+#ifndef MBEDTLS_CONFIG_H
|
||||
+#define MBEDTLS_CONFIG_H
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
-412
@@ -1,412 +0,0 @@
|
||||
From c0037dc1779d181ce7d7dbd5871519c9d218440a Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Tue, 30 Dec 2025 10:29:47 +0000
|
||||
Subject: [PATCH] lib: gpt: Added table validation operations
|
||||
|
||||
Added validate and restore operations. Both of these operate on the
|
||||
entirety of the table and allow the caller to:
|
||||
|
||||
1. determine if the GPT is valid or not.
|
||||
2. restore a GPT from the alternative at the other end of the storage
|
||||
device.
|
||||
|
||||
Both of these operations can be performed on either the primary or
|
||||
backup table to allow full recovery.
|
||||
|
||||
Change-Id: Ie5ac2fdc42858cb439a2dcd08f4203eb181d4e88
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [62a038e80574e094e64617953748633737cd760d]
|
||||
---
|
||||
lib/gpt/inc/gpt.h | 22 ++++
|
||||
lib/gpt/src/gpt.c | 184 +++++++++++++++++++++++++++++++
|
||||
lib/gpt/unittests/gpt/test_gpt.c | 135 +++++++++++++++++++++++
|
||||
3 files changed, 341 insertions(+)
|
||||
|
||||
diff --git a/lib/gpt/inc/gpt.h b/lib/gpt/inc/gpt.h
|
||||
index f04643957..0ce4d04ab 100644
|
||||
--- a/lib/gpt/inc/gpt.h
|
||||
+++ b/lib/gpt/inc/gpt.h
|
||||
@@ -207,6 +207,28 @@ psa_status_t gpt_entry_create(const struct efi_guid_t *type,
|
||||
__attribute__((nonnull(1)))
|
||||
psa_status_t gpt_entry_remove(const struct efi_guid_t *guid);
|
||||
|
||||
+/**
|
||||
+ * \brief Validates the GPT.
|
||||
+ *
|
||||
+ * \param[in] is_primary True to validate the primary table, false to validate the backup.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS GPT is valid.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_INVALID_SIGNATURE GPT is invalid.
|
||||
+ */
|
||||
+psa_status_t gpt_validate(bool is_primary);
|
||||
+
|
||||
+/**
|
||||
+ * \brief Restores either the primary or backup GPT from the other copy.
|
||||
+ *
|
||||
+ * \param[in] is_primary True to restore the primary table, false to restore the backup.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS GPT restored.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error.
|
||||
+ * \retval PSA_ERROR_INVALID_SIGNATURE Restoring GPT invalid; cannot restore.
|
||||
+ */
|
||||
+psa_status_t gpt_restore(bool is_primary);
|
||||
+
|
||||
/**
|
||||
* \brief Reads the GPT header from the second block (LBA 1).
|
||||
*
|
||||
diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c
|
||||
index 676f04fd6..1bc592bb3 100644
|
||||
--- a/lib/gpt/src/gpt.c
|
||||
+++ b/lib/gpt/src/gpt.c
|
||||
@@ -223,6 +223,8 @@ static psa_status_t mbr_load(struct mbr_t *mbr);
|
||||
static bool gpt_entry_cmp_guid(const struct gpt_entry_t *entry, const void *guid);
|
||||
static bool gpt_entry_cmp_name(const struct gpt_entry_t *entry, const void *name);
|
||||
static bool gpt_entry_cmp_type(const struct gpt_entry_t *entry, const void *type);
|
||||
+static psa_status_t validate_table(struct gpt_t *table, bool is_primary);
|
||||
+static psa_status_t restore_table(struct gpt_t *restore_from, bool is_primary);
|
||||
|
||||
/* PUBLIC API FUNCTIONS */
|
||||
|
||||
@@ -747,6 +749,76 @@ psa_status_t gpt_entry_remove(const struct efi_guid_t *guid)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+psa_status_t gpt_validate(bool is_primary)
|
||||
+{
|
||||
+ if (!is_primary && (backup_gpt_lba == 0 || backup_gpt_array_lba == 0)) {
|
||||
+ ERROR("Backup GPT location unknown!\n");
|
||||
+ return PSA_ERROR_STORAGE_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ /* Flush and invalidate the in-memory buffer before attempting to validate
|
||||
+ * a table. The in-memory header needs to be updated if the flushed LBA was
|
||||
+ * part of the entry array
|
||||
+ */
|
||||
+ psa_status_t ret;
|
||||
+ if (write_buffered) {
|
||||
+ ret = flush_lba_buf();
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ write_buffered = false;
|
||||
+ }
|
||||
+ cached_lba = 0;
|
||||
+
|
||||
+ if (is_primary) {
|
||||
+ return validate_table(&primary_gpt, true);
|
||||
+ } else {
|
||||
+ struct gpt_t backup_gpt;
|
||||
+ ret = read_table_from_flash(&backup_gpt, false);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ return validate_table(&backup_gpt, false);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+psa_status_t gpt_restore(bool is_primary)
|
||||
+{
|
||||
+ if (!is_primary && (backup_gpt_lba == 0 || backup_gpt_array_lba == 0)) {
|
||||
+ ERROR("Backup GPT location unknown!\n");
|
||||
+ return PSA_ERROR_STORAGE_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ /* Flush and invalidate the in-memory buffer before attempting to restore a
|
||||
+ * table. The in-memory header needs to be updated if the flushed LBA was
|
||||
+ * part of the entry array
|
||||
+ */
|
||||
+ psa_status_t ret;
|
||||
+ if (write_buffered) {
|
||||
+ ret = flush_lba_buf();
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ write_buffered = false;
|
||||
+ }
|
||||
+ cached_lba = 0;
|
||||
+
|
||||
+ if (is_primary) {
|
||||
+ struct gpt_t backup_gpt;
|
||||
+ ret = read_table_from_flash(&backup_gpt, false);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = count_used_partitions(&backup_gpt, &backup_gpt.num_used_partitions);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ return restore_table(&backup_gpt, false);
|
||||
+ } else {
|
||||
+ return restore_table(&primary_gpt, true);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Initialises GPT from first block. */
|
||||
psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, uint64_t max_partitions)
|
||||
{
|
||||
@@ -1349,6 +1421,118 @@ static inline void swap_headers(const struct gpt_header_t *src, struct gpt_heade
|
||||
primary_gpt.header.array_lba);
|
||||
}
|
||||
|
||||
+/* Validates a specific GPT. */
|
||||
+static psa_status_t validate_table(struct gpt_t *table, bool is_primary)
|
||||
+{
|
||||
+ struct gpt_header_t *header = &(table->header);
|
||||
+
|
||||
+ /* Check signature */
|
||||
+ if (strncmp(header->signature, GPT_SIG, GPT_SIG_LEN) != 0) {
|
||||
+ ERROR("Invalid GPT signature\n");
|
||||
+ return PSA_ERROR_INVALID_SIGNATURE;
|
||||
+ }
|
||||
+
|
||||
+ /* Check header CRC */
|
||||
+ uint32_t calc_crc = 0;
|
||||
+ uint32_t old_crc = header->header_crc;
|
||||
+ header->header_crc = 0;
|
||||
+ calc_crc = efi_soft_crc32_update(calc_crc, (uint8_t *)header, GPT_HEADER_SIZE);
|
||||
+ header->header_crc = old_crc;
|
||||
+
|
||||
+ if (old_crc != calc_crc) {
|
||||
+ ERROR("CRC of header does not match, expected 0x%x got 0x%x\n",
|
||||
+ old_crc, calc_crc);
|
||||
+ return PSA_ERROR_INVALID_SIGNATURE;
|
||||
+ }
|
||||
+
|
||||
+ /* Check MyLBA field points to this table */
|
||||
+ const uint64_t table_lba = (is_primary ? PRIMARY_GPT_LBA : backup_gpt_lba);
|
||||
+ if (table_lba != header->current_lba) {
|
||||
+ ERROR("MyLBA not pointing to this GPT, expected 0x%08x%08x, got 0x%08x%08x\n",
|
||||
+ (uint32_t)(table_lba >> 32),
|
||||
+ (uint32_t)table_lba,
|
||||
+ (uint32_t)(header->current_lba >> 32),
|
||||
+ (uint32_t)(header->current_lba));
|
||||
+ return PSA_ERROR_INVALID_SIGNATURE;
|
||||
+ }
|
||||
+
|
||||
+ /* Check the CRC of the partition array */
|
||||
+ calc_crc = 0;
|
||||
+ for (uint32_t i = 0; i < header->num_partitions; ++i) {
|
||||
+ uint8_t entry_buf[header->entry_size];
|
||||
+ memset(entry_buf, 0, header->entry_size);
|
||||
+ struct gpt_entry_t *entry = (struct gpt_entry_t *)entry_buf;
|
||||
+
|
||||
+ psa_status_t ret = read_entry_from_flash(table, i, entry);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ calc_crc = efi_soft_crc32_update(calc_crc, (uint8_t *)entry, header->entry_size);
|
||||
+ }
|
||||
+
|
||||
+ if (calc_crc != header->array_crc) {
|
||||
+ ERROR("CRC of partition array does not match, expected 0x%x got 0x%x\n",
|
||||
+ calc_crc, header->array_crc);
|
||||
+ return PSA_ERROR_INVALID_SIGNATURE;
|
||||
+ }
|
||||
+
|
||||
+ if (is_primary) {
|
||||
+ /* Any time the primary table is considered valid, cache the backup
|
||||
+ * LBA field
|
||||
+ */
|
||||
+ backup_gpt_lba = header->backup_lba;
|
||||
+ } else {
|
||||
+ /* Any time backup table is considered valid, cache its array LBA
|
||||
+ * field and crc32
|
||||
+ */
|
||||
+ backup_gpt_array_lba = header->array_lba;
|
||||
+ backup_crc32 = header->header_crc;
|
||||
+ }
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+/* Restore a table from another. The second parameter indicates whether the
|
||||
+ * restoring table is the primary GPT or not
|
||||
+ */
|
||||
+static psa_status_t restore_table(struct gpt_t *restore_from, bool is_primary)
|
||||
+{
|
||||
+ /* Determine if the restoring GPT is valid */
|
||||
+ psa_status_t ret = validate_table(restore_from, is_primary);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ struct gpt_t restore_to;
|
||||
+ swap_headers(&(restore_from->header), &(restore_to.header));
|
||||
+
|
||||
+ /* Copy the partition array as well */
|
||||
+ ret = move_partition(
|
||||
+ restore_from->header.array_lba,
|
||||
+ restore_to.header.array_lba,
|
||||
+ (restore_from->header.num_partitions +
|
||||
+ gpt_entry_per_lba_count() - 1) / gpt_entry_per_lba_count());
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Write the header */
|
||||
+ ret = write_header_to_flash(&restore_to);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ ERROR("Unable to write %s GPT header\n", is_primary ? "backup" : "primary");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* The primary GPT is cached in memory */
|
||||
+ if (!is_primary) {
|
||||
+ memcpy(&(primary_gpt.header), &(restore_to.header), GPT_HEADER_SIZE);
|
||||
+ primary_gpt.num_used_partitions = restore_from->num_used_partitions;
|
||||
+ }
|
||||
+
|
||||
+ INFO("Successfully restored %s GPT table\n", is_primary ? "backup" : "primary");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Converts unicode string to valid ascii */
|
||||
static psa_status_t unicode_to_ascii(const char *unicode, char *ascii)
|
||||
{
|
||||
diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
index 18cf2c8f3..f15a0a737 100644
|
||||
--- a/lib/gpt/unittests/gpt/test_gpt.c
|
||||
+++ b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
@@ -369,6 +369,141 @@ void test_gpt_init_should_failWhenFlashDriverNotFullyDefined(void)
|
||||
mock_driver.erase = erase_fn;
|
||||
}
|
||||
|
||||
+void test_gpt_validate_should_validateWhenGptGood(void)
|
||||
+{
|
||||
+ setup_test_gpt();
|
||||
+
|
||||
+ /* Each entry will be read in order to check the partition array CRC */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_validate(true));
|
||||
+
|
||||
+ /* Now do the backup */
|
||||
+ setup_backup_gpt();
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_validate(false));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_validate_should_failWhenGptSigBad(void)
|
||||
+{
|
||||
+ test_header.signature[0] = '\0';
|
||||
+ setup_test_gpt();
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true));
|
||||
+
|
||||
+ /* Now do the backup */
|
||||
+ setup_backup_gpt();
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(false));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_validate_should_failWhenHeaderCrcBad(void)
|
||||
+{
|
||||
+ test_header.header_crc--;
|
||||
+ setup_test_gpt();
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true));
|
||||
+
|
||||
+ /* Now do the backup */
|
||||
+ struct gpt_header_t backup_header;
|
||||
+ MAKE_BACKUP_HEADER(backup_header, test_header);
|
||||
+ backup_header.header_crc--;
|
||||
+ register_mocked_read(&backup_header, sizeof(backup_header));
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(false));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_validate_should_failWhenLbaPointerBad(void)
|
||||
+{
|
||||
+ test_header.current_lba = 2;
|
||||
+ test_header.backup_lba = 3;
|
||||
+ setup_test_gpt();
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true));
|
||||
+
|
||||
+ /* Now set the backup LBA to be something different that what it should be
|
||||
+ * to force a mismatch
|
||||
+ */
|
||||
+ test_header.current_lba = default_header.current_lba;
|
||||
+ test_header.backup_lba = default_header.backup_lba - 1;
|
||||
+
|
||||
+ /* Now do the backup */
|
||||
+ struct gpt_header_t backup_header;
|
||||
+ MAKE_BACKUP_HEADER(backup_header, test_header);
|
||||
+ register_mocked_read(&backup_header, sizeof(backup_header));
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(false));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_validate_should_failWhenArrayCrcBad(void)
|
||||
+{
|
||||
+ test_header.array_crc--;
|
||||
+ setup_test_gpt();
|
||||
+
|
||||
+ /* Each entry will be read in order to check the partition array CRC */
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true));
|
||||
+
|
||||
+ /* Now do the backup */
|
||||
+ struct gpt_header_t backup_header;
|
||||
+ MAKE_BACKUP_HEADER(backup_header, test_header);
|
||||
+ backup_header.array_crc--;
|
||||
+ register_mocked_read(&backup_header, sizeof(test_partition_array));
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(false));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_restore_should_restorePrimaryFromBackup(void)
|
||||
+{
|
||||
+ /* Start with a valid GPT */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* The backup table is read and checked for validity, including taking
|
||||
+ * CRC32 of partition array
|
||||
+ */
|
||||
+ setup_backup_gpt();
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_restore(true));
|
||||
+}
|
||||
+
|
||||
+void test_gpt_restore_should_failToRestoreWhenBackupIsBad(void)
|
||||
+{
|
||||
+ /* Start with a valid GPT */
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ /* The backup table is read and checked for validity. Corrupt it in
|
||||
+ * various ways
|
||||
+ */
|
||||
+ struct gpt_header_t backup_header;
|
||||
+
|
||||
+ /* Bad signature */
|
||||
+ MAKE_BACKUP_HEADER(backup_header, test_header);
|
||||
+ backup_header.signature[0] = '\0';
|
||||
+ register_mocked_read(&backup_header, sizeof(backup_header));
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_restore(true));
|
||||
+
|
||||
+ /* Bad header CRC */
|
||||
+ MAKE_BACKUP_HEADER(backup_header, test_header);
|
||||
+ backup_header.header_crc = 0;
|
||||
+ register_mocked_read(&backup_header, sizeof(backup_header));
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_restore(true));
|
||||
+
|
||||
+ /* Bad LBA */
|
||||
+ test_header.backup_lba = 2;
|
||||
+ MAKE_BACKUP_HEADER(backup_header, test_header);
|
||||
+ register_mocked_read(&backup_header, sizeof(backup_header));
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_restore(true));
|
||||
+ test_header.backup_lba = default_header.backup_lba;
|
||||
+
|
||||
+ /* Bad array CRC. Will involve reading array entries */
|
||||
+ MAKE_BACKUP_HEADER(backup_header, test_header);
|
||||
+ backup_header.array_crc = 0;
|
||||
+ register_mocked_read(&backup_header, sizeof(backup_header));
|
||||
+ register_mocked_read(&test_partition_array, sizeof(test_partition_array));
|
||||
+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_restore(true));
|
||||
+}
|
||||
+
|
||||
void test_gpt_entry_create_should_createNewEntry(void)
|
||||
{
|
||||
/* Add an entry. It must not overlap with an existing entry and must also
|
||||
-280
@@ -1,280 +0,0 @@
|
||||
From ba38f0f304ad69047ce9830b81a4f9cfbccb8fcb Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Tue, 30 Dec 2025 10:51:57 +0000
|
||||
Subject: [PATCH] lib: gpt: Added defragmentation operation
|
||||
|
||||
Defragmentation moves all of used data of the device to the beginning
|
||||
such that all of the free space is afterwards towards the end. This is
|
||||
less meaningful on flash devices however is still provided as an
|
||||
operation for completeness. This is done by ordering the partition entry
|
||||
array first, so that it is safe to shuffle data in one direction without
|
||||
risk of data loss/overwriting.
|
||||
|
||||
Change-Id: Ic401c79ac8c1fba2489ab2680efc02139c759c66
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [21ff1f85c0b5463c1ea75fd61d872c0029eed902]
|
||||
---
|
||||
lib/gpt/inc/gpt.h | 8 ++
|
||||
lib/gpt/src/gpt.c | 190 +++++++++++++++++++++++++++++++
|
||||
lib/gpt/unittests/gpt/test_gpt.c | 7 ++
|
||||
3 files changed, 205 insertions(+)
|
||||
|
||||
diff --git a/lib/gpt/inc/gpt.h b/lib/gpt/inc/gpt.h
|
||||
index 0ce4d04ab..baf4767f9 100644
|
||||
--- a/lib/gpt/inc/gpt.h
|
||||
+++ b/lib/gpt/inc/gpt.h
|
||||
@@ -229,6 +229,14 @@ psa_status_t gpt_validate(bool is_primary);
|
||||
*/
|
||||
psa_status_t gpt_restore(bool is_primary);
|
||||
|
||||
+/**
|
||||
+ * \brief Defragments the GPT, ensuring free space becomes contiguous.
|
||||
+ *
|
||||
+ * \retval PSA_SUCCESS Success.
|
||||
+ * \retval PSA_ERROR_STORAGE_FAILURE I/O failure.
|
||||
+ */
|
||||
+psa_status_t gpt_defragment(void);
|
||||
+
|
||||
/**
|
||||
* \brief Reads the GPT header from the second block (LBA 1).
|
||||
*
|
||||
diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c
|
||||
index 1bc592bb3..b1d4597cd 100644
|
||||
--- a/lib/gpt/src/gpt.c
|
||||
+++ b/lib/gpt/src/gpt.c
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
+#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
@@ -225,6 +226,7 @@ static bool gpt_entry_cmp_name(const struct gpt_entry_t *entry, const void *name
|
||||
static bool gpt_entry_cmp_type(const struct gpt_entry_t *entry, const void *type);
|
||||
static psa_status_t validate_table(struct gpt_t *table, bool is_primary);
|
||||
static psa_status_t restore_table(struct gpt_t *restore_from, bool is_primary);
|
||||
+static psa_status_t sort_partition_array(struct gpt_t *table);
|
||||
|
||||
/* PUBLIC API FUNCTIONS */
|
||||
|
||||
@@ -819,6 +821,66 @@ psa_status_t gpt_restore(bool is_primary)
|
||||
}
|
||||
}
|
||||
|
||||
+psa_status_t gpt_defragment(void)
|
||||
+{
|
||||
+ /* First, sort the partition array according to start LBA. This means that
|
||||
+ * moving partitions towards the start of the flash sequentially is safe
|
||||
+ * and will not result in lost data.
|
||||
+ */
|
||||
+ psa_status_t ret = sort_partition_array(&primary_gpt);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ WARN("Unable to defragment flash!\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ uint64_t prev_end = primary_gpt.header.first_lba;
|
||||
+ struct gpt_entry_t entry;
|
||||
+
|
||||
+ for (uint32_t i = 0; i < primary_gpt.num_used_partitions; ++i) {
|
||||
+ ret = read_entry_from_flash(&primary_gpt, i, &entry);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Move to be next to previous entry. Continue if already where it
|
||||
+ * needs to be.
|
||||
+ */
|
||||
+ if (prev_end == entry.start) {
|
||||
+ prev_end = entry.end + 1;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ const uint64_t num_blocks = entry.end - entry.start + 1;
|
||||
+ ret = move_partition(entry.start, prev_end, num_blocks);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Update header information */
|
||||
+ entry.start = prev_end;
|
||||
+ entry.end = entry.start + num_blocks - 1;
|
||||
+ prev_end = entry.end + 1;
|
||||
+
|
||||
+ /* Write the entry change, skipping header update until every entry
|
||||
+ * written
|
||||
+ */
|
||||
+ ret = write_entry(i, &entry, true);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Write everything to flash after defragmentation if not done so already.
|
||||
+ * The previous loop will write the last entry to the LBA buffer, which may
|
||||
+ * or not may not be flushed
|
||||
+ */
|
||||
+ if (write_buffered) {
|
||||
+ return flush_lba_buf();
|
||||
+ }
|
||||
+
|
||||
+ return update_header(primary_gpt.num_used_partitions);
|
||||
+}
|
||||
+
|
||||
/* Initialises GPT from first block. */
|
||||
psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, uint64_t max_partitions)
|
||||
{
|
||||
@@ -1533,6 +1595,134 @@ static psa_status_t restore_table(struct gpt_t *restore_from, bool is_primary)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Comparison function to pass to qsort */
|
||||
+static int cmp_u64(const void *a, const void *b)
|
||||
+{
|
||||
+ const uint64_t *a_u64 = (const uint64_t *)a;
|
||||
+ const uint64_t *b_u64 = (const uint64_t *)b;
|
||||
+ return (*a_u64 > *b_u64) - (*a_u64 < *b_u64);
|
||||
+}
|
||||
+
|
||||
+/* bsearch but returns the index rather than the item */
|
||||
+static int64_t bsearch_index(uint64_t arr[], uint32_t len, uint64_t key)
|
||||
+{
|
||||
+ uint32_t l = 0;
|
||||
+ uint32_t r = len;
|
||||
+
|
||||
+ while (l < r) {
|
||||
+ uint32_t m = l + (r - l) / 2;
|
||||
+ uint64_t item = arr[m];
|
||||
+
|
||||
+ if (item < key) {
|
||||
+ l = m + 1;
|
||||
+ } else if (item > key) {
|
||||
+ r = m;
|
||||
+ } else {
|
||||
+ return (int64_t)m;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+/* Sorts the partition array for the given table by the start LBA for each
|
||||
+ * partition. This makes defragmentation easier.
|
||||
+ */
|
||||
+static psa_status_t sort_partition_array(struct gpt_t *table)
|
||||
+{
|
||||
+ /* To avoid as much I/O as possible, the LBA's for each entry are sorted in
|
||||
+ * memory and then the entries rearranged on flash after
|
||||
+ */
|
||||
+ uint64_t lba_arr[table->num_used_partitions];
|
||||
+ psa_status_t ret;
|
||||
+ for (uint32_t i = 0; i < table->num_used_partitions; ++i) {
|
||||
+ struct gpt_entry_t entry;
|
||||
+ ret = read_entry_from_flash(table, i, &entry);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ lba_arr[i] = entry.start;
|
||||
+ }
|
||||
+
|
||||
+ qsort(lba_arr, table->num_used_partitions, sizeof(uint64_t), cmp_u64);
|
||||
+
|
||||
+ /* Now read and place the entries in the correct spot, starting with the
|
||||
+ * first. Each entry is dealt with as it is encountered. When an entry is
|
||||
+ * found and already in the correct spot, the next smallest index not yet
|
||||
+ * handled becomes the next.
|
||||
+ */
|
||||
+ struct gpt_entry_t saved_entry = {0};
|
||||
+ struct gpt_entry_t curr_entry;
|
||||
+ uint8_t handled_indices[table->num_used_partitions];
|
||||
+ memset(handled_indices, 0, table->num_used_partitions);
|
||||
+
|
||||
+ ret = read_entry_from_flash(table, 0, &curr_entry);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ for (uint32_t i = 0; i < table->num_used_partitions; ++i) {
|
||||
+ const int64_t new_index = bsearch_index(
|
||||
+ lba_arr,
|
||||
+ table->num_used_partitions,
|
||||
+ curr_entry.start);
|
||||
+ if (new_index < 0) {
|
||||
+ ERROR("Encountered unknown partition entry!\n");
|
||||
+ return PSA_ERROR_STORAGE_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ /* For final entry, just write it out */
|
||||
+ if (i == table->num_used_partitions - 1) {
|
||||
+ ret = write_entry((uint32_t)new_index, &curr_entry, false);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Replace the entry in the new_index place with the current entry */
|
||||
+ ret = read_entry_from_flash(table, (uint32_t)new_index, &saved_entry);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ struct efi_guid_t saved_guid = saved_entry.unique_guid;
|
||||
+ struct efi_guid_t curr_guid = curr_entry.unique_guid;
|
||||
+ if (efi_guid_cmp(&saved_guid, &curr_guid) == 0) {
|
||||
+ /* This entry is already where it needs to be, so try the smallest
|
||||
+ * index not yet handled next
|
||||
+ */
|
||||
+ handled_indices[new_index] = 1;
|
||||
+ uint32_t next_entry = 0;
|
||||
+ while(next_entry < table->num_used_partitions && handled_indices[next_entry]) {
|
||||
+ ++next_entry;
|
||||
+ }
|
||||
+
|
||||
+ if (next_entry == table->num_used_partitions) {
|
||||
+ /* Done everything */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ ret = read_entry_from_flash(table, next_entry, &saved_entry);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* Write, skipping header update until very end */
|
||||
+ ret = write_entry((uint32_t)new_index, &curr_entry, true);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Ready up for the next loop */
|
||||
+ curr_entry = saved_entry;
|
||||
+ handled_indices[new_index] = 1;
|
||||
+ }
|
||||
+
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
+
|
||||
/* Converts unicode string to valid ascii */
|
||||
static psa_status_t unicode_to_ascii(const char *unicode, char *ascii)
|
||||
{
|
||||
diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
index f15a0a737..2f05a6b4a 100644
|
||||
--- a/lib/gpt/unittests/gpt/test_gpt.c
|
||||
+++ b/lib/gpt/unittests/gpt/test_gpt.c
|
||||
@@ -504,6 +504,13 @@ void test_gpt_restore_should_failToRestoreWhenBackupIsBad(void)
|
||||
TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_restore(true));
|
||||
}
|
||||
|
||||
+void test_gpt_defragment_should_succeedWhenNoIOFailure(void)
|
||||
+{
|
||||
+ setup_valid_gpt();
|
||||
+
|
||||
+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_defragment());
|
||||
+}
|
||||
+
|
||||
void test_gpt_entry_create_should_createNewEntry(void)
|
||||
{
|
||||
/* Add an entry. It must not overlap with an existing entry and must also
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
From f9e4d1f48a4553278dc4de82b0d2f4d82b1e5193 Mon Sep 17 00:00:00 2001
|
||||
From: Antonio de Angelis <antonio.deangelis@arm.com>
|
||||
Date: Wed, 4 Mar 2026 13:05:51 +0000
|
||||
Subject: [PATCH] lib: GPT: Fix cppcheck warnings
|
||||
|
||||
Change-Id: Ia9e99dc59cbf869b804a24ba029f19f7170860b4
|
||||
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
|
||||
Upstream-Status: Backport [92d5b6b7d296c174364e684508089c0a0678e3bb]
|
||||
---
|
||||
lib/gpt/src/gpt.c | 15 ++++++++++-----
|
||||
1 file changed, 10 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c
|
||||
index b1d4597cd..a9dbb918e 100644
|
||||
--- a/lib/gpt/src/gpt.c
|
||||
+++ b/lib/gpt/src/gpt.c
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
+#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@@ -194,7 +195,7 @@ static inline uint64_t gpt_entry_per_lba_count(void);
|
||||
static inline void swap_headers(const struct gpt_header_t *src, struct gpt_header_t *dst);
|
||||
static psa_status_t count_used_partitions(const struct gpt_t *table,
|
||||
uint32_t *num_used);
|
||||
-static inline void parse_entry(struct gpt_entry_t *entry,
|
||||
+static inline void parse_entry(const struct gpt_entry_t *entry,
|
||||
struct partition_entry_t *partition_entry);
|
||||
static psa_status_t read_from_flash(uint64_t required_lba);
|
||||
static psa_status_t read_entry_from_flash(const struct gpt_t *table,
|
||||
@@ -226,7 +227,7 @@ static bool gpt_entry_cmp_name(const struct gpt_entry_t *entry, const void *name
|
||||
static bool gpt_entry_cmp_type(const struct gpt_entry_t *entry, const void *type);
|
||||
static psa_status_t validate_table(struct gpt_t *table, bool is_primary);
|
||||
static psa_status_t restore_table(struct gpt_t *restore_from, bool is_primary);
|
||||
-static psa_status_t sort_partition_array(struct gpt_t *table);
|
||||
+static psa_status_t sort_partition_array(const struct gpt_t *table);
|
||||
|
||||
/* PUBLIC API FUNCTIONS */
|
||||
|
||||
@@ -1006,7 +1007,7 @@ static inline uint64_t gpt_entry_per_lba_count(void)
|
||||
}
|
||||
|
||||
/* Copies information from the entry to the user visible structure */
|
||||
-static inline void parse_entry(struct gpt_entry_t *entry,
|
||||
+static inline void parse_entry(const struct gpt_entry_t *entry,
|
||||
struct partition_entry_t *partition_entry)
|
||||
{
|
||||
partition_entry->start = entry->start;
|
||||
@@ -1604,7 +1605,7 @@ static int cmp_u64(const void *a, const void *b)
|
||||
}
|
||||
|
||||
/* bsearch but returns the index rather than the item */
|
||||
-static int64_t bsearch_index(uint64_t arr[], uint32_t len, uint64_t key)
|
||||
+static int64_t bsearch_index(const uint64_t arr[], uint32_t len, uint64_t key)
|
||||
{
|
||||
uint32_t l = 0;
|
||||
uint32_t r = len;
|
||||
@@ -1628,8 +1629,12 @@ static int64_t bsearch_index(uint64_t arr[], uint32_t len, uint64_t key)
|
||||
/* Sorts the partition array for the given table by the start LBA for each
|
||||
* partition. This makes defragmentation easier.
|
||||
*/
|
||||
-static psa_status_t sort_partition_array(struct gpt_t *table)
|
||||
+static psa_status_t sort_partition_array(const struct gpt_t *table)
|
||||
{
|
||||
+ if (table->num_used_partitions == 0) {
|
||||
+ assert(table->num_used_partitions > 0);
|
||||
+ return PSA_ERROR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
/* To avoid as much I/O as possible, the LBA's for each entry are sorted in
|
||||
* memory and then the entries rearranged on flash after
|
||||
*/
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
From 31cd6d9eb82792efd5af7d99802581eace13a083 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Fri, 13 Mar 2026 17:10:25 +0000
|
||||
Subject: [PATCH] lib: efi_guid: Remove unecessary include folder
|
||||
|
||||
There are no header files in the src folder, so there is nothing to
|
||||
include. This line was redundant.
|
||||
|
||||
Change-Id: I5289932119629fc1ef6a71f0a0ceb63e5a466c96
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [e74a1f467317c16487b9d41f43f147dd41985cb9]
|
||||
---
|
||||
lib/efi_guid/CMakeLists.txt | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/lib/efi_guid/CMakeLists.txt b/lib/efi_guid/CMakeLists.txt
|
||||
index 656eb72ea..9c4771cba 100644
|
||||
--- a/lib/efi_guid/CMakeLists.txt
|
||||
+++ b/lib/efi_guid/CMakeLists.txt
|
||||
@@ -15,8 +15,6 @@ target_sources(tfm_efi_guid
|
||||
target_include_directories(tfm_efi_guid
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
|
||||
- PRIVATE
|
||||
- ${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
target_link_libraries(tfm_efi_guid
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
From 0b6a2e681b0f76c425896990ebc4afcbc65419d3 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Fri, 13 Mar 2026 17:11:05 +0000
|
||||
Subject: [PATCH] lib: efi_guid: Correct included folder
|
||||
|
||||
The use of the variables is unecessary and has no real effect. This
|
||||
change is therefore simplified.
|
||||
|
||||
Change-Id: I0811b4768502d15b62f1af3ef90a56db3e9df525
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [7bb11e81cd69718df3b11a3f8b42a3b5edf4c42d]
|
||||
---
|
||||
lib/efi_guid/CMakeLists.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/efi_guid/CMakeLists.txt b/lib/efi_guid/CMakeLists.txt
|
||||
index 9c4771cba..95d7b8f1e 100644
|
||||
--- a/lib/efi_guid/CMakeLists.txt
|
||||
+++ b/lib/efi_guid/CMakeLists.txt
|
||||
@@ -14,7 +14,7 @@ target_sources(tfm_efi_guid
|
||||
|
||||
target_include_directories(tfm_efi_guid
|
||||
PUBLIC
|
||||
- $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
|
||||
+ inc
|
||||
)
|
||||
|
||||
target_link_libraries(tfm_efi_guid
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
From f1862245d39a726c8e37f58498dd433c6fd99d1b Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Fri, 13 Mar 2026 17:13:07 +0000
|
||||
Subject: [PATCH] lib: efi_soft_crc: Correct include directory
|
||||
|
||||
The variables had no real effect, so this is therefore simplified.
|
||||
|
||||
Change-Id: Ifa03bc23e0419f9d6d598e7753f23dfde57c7bf6
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [3856d55117b727c6c21bb821fa4236b113fb08ef]
|
||||
---
|
||||
lib/ext/efi_soft_crc/CMakeLists.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/ext/efi_soft_crc/CMakeLists.txt b/lib/ext/efi_soft_crc/CMakeLists.txt
|
||||
index 47fd2d507..d77310167 100644
|
||||
--- a/lib/ext/efi_soft_crc/CMakeLists.txt
|
||||
+++ b/lib/ext/efi_soft_crc/CMakeLists.txt
|
||||
@@ -14,5 +14,5 @@ target_sources(tfm_efi_soft_crc
|
||||
|
||||
target_include_directories(tfm_efi_soft_crc
|
||||
PUBLIC
|
||||
- $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
|
||||
+ inc
|
||||
)
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
From 343bba6c20802555dfb92c3e2b22a7e07c10a57a Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Fri, 13 Mar 2026 17:16:00 +0000
|
||||
Subject: [PATCH] lib: gpt: Add missing link library
|
||||
|
||||
tfm_log requires tfm_vprintf. When building for a platform with logging
|
||||
enabled, these headers are therefore required.
|
||||
|
||||
Change-Id: I63b35d5af818ea5ad7b1fe76200250ad98584a63
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [92a3738634fe121766705599d66e4a8b772ce06e]
|
||||
---
|
||||
lib/gpt/CMakeLists.txt | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/lib/gpt/CMakeLists.txt b/lib/gpt/CMakeLists.txt
|
||||
index 5befc346f..ed31adfbe 100644
|
||||
--- a/lib/gpt/CMakeLists.txt
|
||||
+++ b/lib/gpt/CMakeLists.txt
|
||||
@@ -36,6 +36,7 @@ target_compile_definitions(tfm_gpt
|
||||
target_link_libraries(tfm_gpt
|
||||
PUBLIC
|
||||
tfm_log_headers
|
||||
+ tfm_vprintf_headers
|
||||
PRIVATE
|
||||
tfm_efi_guid
|
||||
tfm_efi_soft_crc
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
From 1ae97df8db8babcaa999e47d9641c83c4ee8424a Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Fri, 13 Mar 2026 17:17:33 +0000
|
||||
Subject: [PATCH] lib: gpt: Correct variable name used
|
||||
|
||||
Change-Id: I86d616b3c86cf0a1fd053b732565477278030d89
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [bc9522f5c47c7e3f3a92189073166e73323010e9]
|
||||
---
|
||||
lib/gpt/unittests/gpt/utcfg.cmake | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/gpt/unittests/gpt/utcfg.cmake b/lib/gpt/unittests/gpt/utcfg.cmake
|
||||
index f3f4e7dcc..69a1d10bd 100644
|
||||
--- a/lib/gpt/unittests/gpt/utcfg.cmake
|
||||
+++ b/lib/gpt/unittests/gpt/utcfg.cmake
|
||||
@@ -27,6 +27,6 @@ list(APPEND MOCK_HEADERS ${TFM_ROOT_DIR}/lib/tfm_vprintf/inc/tfm_vprintf.h)
|
||||
list(APPEND MOCK_HEADERS ${TFM_ROOT_DIR}/lib/ext/efi_soft_crc/inc/efi_soft_crc.h)
|
||||
|
||||
# Compile-time definitions
|
||||
-list(APPEND UNIT_TEST_COMPILE_DEFS LOG_LEVEL=LOG_LEVEL_VERBOSE)
|
||||
+list(APPEND UNIT_TEST_COMPILE_DEFS GPT_LOG_LEVEL=LOG_LEVEL_VERBOSE)
|
||||
list(APPEND UNIT_TEST_COMPILE_DEFS TFM_GPT_BLOCK_SIZE=512)
|
||||
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
From eb934a532bbc8385cd9b062fc80cece61350f086 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Fri, 13 Mar 2026 17:19:50 +0000
|
||||
Subject: [PATCH] lib: gpt: Correct include directory
|
||||
|
||||
The variables have no real effect, so therefore this is simplified.
|
||||
|
||||
Change-Id: Ie912941f8eafd9cd5bf4dd88927640ad70d0676a
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [369c897be0b9102cec8141c53b3d3fe6abb56b6e]
|
||||
---
|
||||
lib/gpt/CMakeLists.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/gpt/CMakeLists.txt b/lib/gpt/CMakeLists.txt
|
||||
index ed31adfbe..19cfe5bc2 100644
|
||||
--- a/lib/gpt/CMakeLists.txt
|
||||
+++ b/lib/gpt/CMakeLists.txt
|
||||
@@ -22,7 +22,7 @@ target_sources(tfm_gpt
|
||||
|
||||
target_include_directories(tfm_gpt
|
||||
PUBLIC
|
||||
- $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
|
||||
+ inc
|
||||
$<INSTALL_INTERFACE:inc>
|
||||
)
|
||||
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
From ce3a4f3dd8900c068f2bfe951d55b895e3c10d43 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Fri, 13 Mar 2026 17:29:04 +0000
|
||||
Subject: [PATCH] lib: gpt: Move contents of CMake config file
|
||||
|
||||
A config.cmake used in a library can be a little confusing, especially
|
||||
considering that such files are used for platform configurations. The
|
||||
contents of the file are placed directly in the CMakeLists.txt that was
|
||||
including it.
|
||||
|
||||
Change-Id: I8a88971feebaf37498828af5854de94e74e16f2c
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Backport [4b569b02b98a577e45e833f4dd9886e54df71a7d]
|
||||
---
|
||||
lib/gpt/CMakeLists.txt | 6 +++---
|
||||
lib/gpt/config.cmake | 8 --------
|
||||
2 files changed, 3 insertions(+), 11 deletions(-)
|
||||
delete mode 100644 lib/gpt/config.cmake
|
||||
|
||||
diff --git a/lib/gpt/CMakeLists.txt b/lib/gpt/CMakeLists.txt
|
||||
index 19cfe5bc2..4a15173fd 100644
|
||||
--- a/lib/gpt/CMakeLists.txt
|
||||
+++ b/lib/gpt/CMakeLists.txt
|
||||
@@ -9,10 +9,10 @@ cmake_minimum_required(VERSION 3.21)
|
||||
|
||||
add_library(tfm_gpt STATIC)
|
||||
|
||||
-include(./config.cmake)
|
||||
+set(GPT_LOG_LEVEL LOG_LEVEL_INFO CACHE STRING "Set default log level for the GPT library")
|
||||
|
||||
-if(NOT DEFINED TFM_GPT_BLOCK_SIZE OR NOT DEFINED GPT_LOG_LEVEL)
|
||||
- message(FATAL_ERROR "TFM_GPT_BLOCK_SIZE and GPT_LOG_LEVEL must be defined to use GPT library")
|
||||
+if(NOT DEFINED TFM_GPT_BLOCK_SIZE)
|
||||
+ message(FATAL_ERROR "TFM_GPT_BLOCK_SIZE must be defined to use GPT library")
|
||||
endif()
|
||||
|
||||
target_sources(tfm_gpt
|
||||
diff --git a/lib/gpt/config.cmake b/lib/gpt/config.cmake
|
||||
deleted file mode 100644
|
||||
index 9575aa8a8..000000000
|
||||
--- a/lib/gpt/config.cmake
|
||||
+++ /dev/null
|
||||
@@ -1,8 +0,0 @@
|
||||
-#-------------------------------------------------------------------------------
|
||||
-# SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
|
||||
-#
|
||||
-# SPDX-License-Identifier: BSD-3-Clause
|
||||
-#
|
||||
-#-------------------------------------------------------------------------------
|
||||
-
|
||||
-set(GPT_LOG_LEVEL LOG_LEVEL_INFO CACHE STRING "Set default log level for the GPT library")
|
||||
-261
@@ -1,261 +0,0 @@
|
||||
From 9402dd67413e74284bc598225b4c5399fbd1a099 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Wed, 19 Nov 2025 17:12:13 +0000
|
||||
Subject: [PATCH] plat: cs1k: Fixed formatting errors
|
||||
|
||||
Many of these were tab characters, however the style guide for this repo
|
||||
is clear that spaces shall be used.
|
||||
|
||||
Sometimes the wrong number of spaces was used and that is fixed here as
|
||||
well.
|
||||
|
||||
Change-Id: I4c797d1de9723961eac707476e249062653aece0
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/49423]
|
||||
---
|
||||
.../target/arm/corstone1000/CMakeLists.txt | 6 +-
|
||||
.../bootloader/mcuboot/tfm_mcuboot_fwu.c | 60 +++++++++----------
|
||||
2 files changed, 33 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/CMakeLists.txt b/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
index 993c51591..58edae74e 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
+++ b/platform/ext/target/arm/corstone1000/CMakeLists.txt
|
||||
@@ -242,7 +242,7 @@ target_include_directories(platform_bl1_1_interface
|
||||
${PLATFORM_DIR}/ext/target/arm/drivers/usart/pl011
|
||||
$<$<BOOL:${CRYPTO_HW_ACCELERATOR}>:${CMAKE_SOURCE_DIR}/platform/ext/accelerator/interface>
|
||||
${PLATFORM_DIR}/ext/accelerator/cc312/
|
||||
- ${CMAKE_SOURCE_DIR}/lib/fih/inc/
|
||||
+ ${CMAKE_SOURCE_DIR}/lib/fih/inc/
|
||||
)
|
||||
|
||||
target_link_libraries(platform_bl1_1
|
||||
@@ -289,7 +289,7 @@ target_include_directories(platform_bl1_2
|
||||
${PLATFORM_DIR}/ext/target/arm/drivers/flash/n25q256a/
|
||||
${PLATFORM_DIR}/ext/target/arm/drivers/flash/sst26vf064b/
|
||||
${PLATFORM_DIR}/ext/accelerator/cc312/
|
||||
- ${CMAKE_SOURCE_DIR}/interface/include # for psa/error.h
|
||||
+ ${CMAKE_SOURCE_DIR}/interface/include # for psa/error.h
|
||||
)
|
||||
|
||||
#========================= Platform BL2 =======================================#
|
||||
@@ -397,7 +397,7 @@ target_include_directories(platform_bl2
|
||||
${MCUBOOT_PATH}/boot/bootutil/include # for fault_injection_hardening.h only
|
||||
${CMAKE_BINARY_DIR}/bl2/ext/mcuboot # for mcuboot_config.h only
|
||||
$<BUILD_INTERFACE:${BL2_SOURCE}/ext/mcuboot/include>
|
||||
- ${CMAKE_SOURCE_DIR}/interface/include # for psa/error.h
|
||||
+ ${CMAKE_SOURCE_DIR}/interface/include # for psa/error.h
|
||||
)
|
||||
|
||||
#========================= ns_agent_mailbox ===================================#
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
index a458b5478..cff80b755 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
@@ -995,7 +995,7 @@ psa_status_t fwu_metadata_provision(void)
|
||||
static uint8_t get_fwu_image_state(
|
||||
struct fwu_metadata *metadata,
|
||||
struct fwu_private_metadata *priv_metadata,
|
||||
- uint32_t fwu_image_index)
|
||||
+ uint32_t fwu_image_index)
|
||||
{
|
||||
FWU_LOG_MSG("%s: enter\n\r", __func__);
|
||||
|
||||
@@ -1305,12 +1305,12 @@ psa_status_t corstone1000_fwu_host_ack(void)
|
||||
|
||||
ret = PSA_SUCCESS; /* nothing to be done */
|
||||
|
||||
- for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
|
||||
- fmp_set_image_info(&fwu_image[i].image_guid,
|
||||
- priv_metadata.fmp_version[i],
|
||||
- priv_metadata.fmp_last_attempt_version[i],
|
||||
- priv_metadata.fmp_last_attempt_status[i]);
|
||||
- }
|
||||
+ for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
|
||||
+ fmp_set_image_info(&fwu_image[i].image_guid,
|
||||
+ priv_metadata.fmp_version[i],
|
||||
+ priv_metadata.fmp_last_attempt_version[i],
|
||||
+ priv_metadata.fmp_last_attempt_status[i]);
|
||||
+ }
|
||||
|
||||
goto out;
|
||||
|
||||
@@ -1322,13 +1322,13 @@ psa_status_t corstone1000_fwu_host_ack(void)
|
||||
|
||||
/* firmware update failed, revert back to previous bank */
|
||||
|
||||
- for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
|
||||
+ for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
|
||||
if(get_fwu_image_state(&_metadata, &priv_metadata, i) == PSA_FWU_TRIAL) {
|
||||
priv_metadata.fmp_last_attempt_version[i] =
|
||||
_metadata.fw_desc.img_entry[i].img_props[_metadata.active_index].version;
|
||||
|
||||
priv_metadata.fmp_last_attempt_status[i] = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
|
||||
- }
|
||||
+ }
|
||||
}
|
||||
ret = fwu_select_previous(&_metadata, &priv_metadata);
|
||||
|
||||
@@ -1455,14 +1455,14 @@ psa_status_t fwu_stage_nv_counter(enum fwu_nv_counter_index_t index,
|
||||
|
||||
psa_status_t corstone1000_fwu_flash_image(void)
|
||||
{
|
||||
- return PSA_SUCCESS;
|
||||
+ return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/* Verify if image index is valid or not */
|
||||
bool is_image_index_valid(uint8_t fwu_image_index) {
|
||||
return (fwu_image_index != FWU_FAKE_IMAGE_INDEX &&
|
||||
fwu_image_index != FWU_IMAGE_INDEX_ESRT &&
|
||||
- fwu_image_index < FWU_COMPONENT_NUMBER);
|
||||
+ fwu_image_index < FWU_COMPONENT_NUMBER);
|
||||
}
|
||||
|
||||
static psa_status_t get_esrt_data(struct fwu_esrt_data_wrapper *esrt)
|
||||
@@ -1585,8 +1585,8 @@ static void fmp_header_image_info_init()
|
||||
for (int i=0; i<FWU_COMPONENT_NUMBER; i++)
|
||||
{
|
||||
fmp_header_image_info[i].fmp_hdr_size_recvd = 0;
|
||||
- fmp_header_image_info[i].image_size_recvd = 0;
|
||||
- memset(&fmp_header_image_info[i].fmp_hdr, 0, sizeof(fmp_header_image_info[i].fmp_hdr));
|
||||
+ fmp_header_image_info[i].image_size_recvd = 0;
|
||||
+ memset(&fmp_header_image_info[i].fmp_hdr, 0, sizeof(fmp_header_image_info[i].fmp_hdr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1598,7 +1598,7 @@ static psa_status_t erase_staging_area(struct fwu_metadata* metadata, psa_fwu_co
|
||||
|
||||
if (!is_image_index_valid(component)) {
|
||||
FWU_LOG_MSG("%s: Invalid Component received \n\r", __func__);
|
||||
- return PSA_ERROR_GENERIC_ERROR;
|
||||
+ return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
uint32_t active_index = metadata->active_index;
|
||||
@@ -1691,7 +1691,7 @@ psa_status_t parse_fmp_header(psa_fwu_component_t component, const void *block,
|
||||
(sizeof(fmp_header_image_info[component].fmp_hdr) - fmp_header_image_info[component].fmp_hdr_size_recvd));
|
||||
|
||||
fmp_header_image_info[component].fmp_hdr_size_recvd = sizeof(fmp_header_image_info[component].fmp_hdr);
|
||||
- return PSA_SUCCESS;
|
||||
+ return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1738,7 +1738,7 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component,
|
||||
}
|
||||
if (ret == PSA_SUCCESS) {
|
||||
block_size -= fmp_header_image_info[fwu_image_index].fmp_hdr_size_recvd;
|
||||
- block += fmp_header_image_info[fwu_image_index].fmp_hdr_size_recvd;
|
||||
+ block += fmp_header_image_info[fwu_image_index].fmp_hdr_size_recvd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1774,7 +1774,7 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component,
|
||||
if (fw_version <=
|
||||
_metadata.fw_desc.img_entry[fwu_image_index].img_props[active_index].version)
|
||||
{
|
||||
- /* Version is extracted from the fmp_payload_header */
|
||||
+ /* Version is extracted from the fmp_payload_header */
|
||||
priv_metadata.fmp_last_attempt_version[fwu_image_index] = fmp_header_image_info[fwu_image_index].fmp_hdr.fw_version;
|
||||
priv_metadata.fmp_last_attempt_status[fwu_image_index] = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
|
||||
private_metadata_write(&priv_metadata);
|
||||
@@ -1785,8 +1785,8 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component,
|
||||
priv_metadata.fmp_last_attempt_status[fwu_image_index]);
|
||||
|
||||
FWU_LOG_MSG("ERROR: %s: version error\n\r",__func__);
|
||||
- ret = PSA_OPERATION_INCOMPLETE;
|
||||
- goto out;
|
||||
+ ret = PSA_OPERATION_INCOMPLETE;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if (active_index == BANK_0) {
|
||||
@@ -1828,7 +1828,7 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component,
|
||||
priv_metadata.fmp_last_attempt_version[fwu_image_index],
|
||||
priv_metadata.fmp_last_attempt_status[fwu_image_index]);
|
||||
ret = PSA_OPERATION_INCOMPLETE;
|
||||
- goto out;
|
||||
+ goto out;
|
||||
}
|
||||
else {
|
||||
ret = PSA_SUCCESS;
|
||||
@@ -1871,7 +1871,7 @@ static psa_status_t fwu_update_metadata(const psa_fwu_component_t *candidates, u
|
||||
} else {
|
||||
FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index);
|
||||
ret = PSA_ERROR_DATA_INVALID;
|
||||
- goto out;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
_metadata.active_index = previous_active_index;
|
||||
@@ -1881,7 +1881,7 @@ static psa_status_t fwu_update_metadata(const psa_fwu_component_t *candidates, u
|
||||
/* Change system state to trial bank state */
|
||||
for (int i = 0; i < number; i++) {
|
||||
/* Skip image with index 0 and ESRT image */
|
||||
- if(!is_image_index_valid(candidates[i])) {
|
||||
+ if(!is_image_index_valid(candidates[i])) {
|
||||
FWU_LOG_MSG("%s: Invalid image index received \n\r", __func__);
|
||||
continue;
|
||||
}
|
||||
@@ -1946,7 +1946,7 @@ static psa_status_t copy_image_from_other_bank(int image_index,
|
||||
}
|
||||
|
||||
offset_read += data_size;
|
||||
-
|
||||
+
|
||||
/* write image data to flash */
|
||||
data_transferred_count = FWU_METADATA_FLASH_DEV.ProgramData(offset_write, data, data_size);
|
||||
if (data_transferred_count < 0) {
|
||||
@@ -1961,7 +1961,7 @@ static psa_status_t copy_image_from_other_bank(int image_index,
|
||||
}
|
||||
|
||||
offset_write += data_size;
|
||||
- remaining_size -= data_size;
|
||||
+ remaining_size -= data_size;
|
||||
}
|
||||
|
||||
FWU_LOG_MSG("%s: exit \n\r", __func__);
|
||||
@@ -2004,8 +2004,8 @@ static psa_status_t maintain_bank_consistency(void)
|
||||
ret = copy_image_from_other_bank(i, active_index, previous_active_index);
|
||||
if(ret) {
|
||||
FWU_LOG_MSG("ERROR: %s: copy_image_from_other_bank failed for Image : %d\n\r",__func__, i);
|
||||
- return ret;
|
||||
- }
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
_metadata.fw_desc.img_entry[i].img_props[previous_active_index].version =
|
||||
_metadata.fw_desc.img_entry[i].img_props[active_index].version;
|
||||
@@ -2110,7 +2110,7 @@ psa_status_t fwu_bootloader_mark_image_accepted(const psa_fwu_component_t *trial
|
||||
|
||||
/* firmware update successful */
|
||||
for (int i = 0; i < number; i++) {
|
||||
- if(!is_image_index_valid(trials[i])) {
|
||||
+ if(!is_image_index_valid(trials[i])) {
|
||||
FWU_LOG_MSG("%s: Invalid image index received \n\r", __func__);
|
||||
continue;
|
||||
}
|
||||
@@ -2201,7 +2201,7 @@ psa_status_t fwu_bootloader_reject_staged_image(psa_fwu_component_t component)
|
||||
} else {
|
||||
FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index);
|
||||
ret = PSA_ERROR_GENERIC_ERROR;
|
||||
- goto out;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
image_offset = bank_offset + fwu_image[image_index].image_offset;
|
||||
@@ -2308,11 +2308,11 @@ psa_status_t fwu_bootloader_get_image_info(psa_fwu_component_t component,
|
||||
ret = get_esrt_data(&esrt);
|
||||
if (ret) {
|
||||
FWU_LOG_MSG("%s: ERROR : Unable to populate ESRT \n\r", __func__);
|
||||
- goto out;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
memcpy(&info->impl.candidate_digest, &esrt, esrt_size);
|
||||
- if (query_state) {
|
||||
+ if (query_state) {
|
||||
info->state = PSA_FWU_READY;
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
From 50db5724ef37d5c7cec019254d135b3dcfd0d340 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Mon, 29 Dec 2025 11:30:32 +0000
|
||||
Subject: [PATCH] plat: cs1k: Fixed bad function returns
|
||||
|
||||
The rest of the functions would go to a label to perform some cleanup
|
||||
before exiting the function, however these particular errors did not. The
|
||||
cleanup would reset the write mode on flash, which is required since the
|
||||
errors occur after it being changed.
|
||||
|
||||
Change-Id: Ic8277a3295398922b2f05fcaddfb5a188b14e537
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/49425]
|
||||
---
|
||||
.../arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
index 52db60bbc..2c17d4b79 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
@@ -1798,7 +1798,8 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component,
|
||||
bank_offset = BANK_0_PARTITION_OFFSET;
|
||||
} else {
|
||||
FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index);
|
||||
- return PSA_ERROR_DATA_INVALID;
|
||||
+ ret = PSA_ERROR_DATA_INVALID;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
image_offset = bank_offset + fwu_image[fwu_image_index].image_offset;
|
||||
@@ -2002,7 +2003,7 @@ static psa_status_t maintain_bank_consistency(void)
|
||||
ret = copy_image_from_other_bank(i, active_index, previous_active_index);
|
||||
if(ret) {
|
||||
FWU_LOG_MSG("ERROR: %s: copy_image_from_other_bank failed for Image : %d\n\r",__func__, i);
|
||||
- return ret;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
_metadata.fw_desc.img_entry[i].img_props[previous_active_index].version =
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
From f48a0a6b60309433269c7927dac992eff06f3745 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Mon, 29 Dec 2025 11:29:33 +0000
|
||||
Subject: [PATCH] plat: cs1k: Improved logging in function
|
||||
|
||||
The enter log statement claims to log when the function is entered,
|
||||
however it was possible for the function to return before reaching it.
|
||||
The error cases have now been given log statements too in order to make
|
||||
it easier to track when and why the function exited.
|
||||
|
||||
Change-Id: I7fe610ca6a596b6af1e48720a503b76064eed3ff
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/49424]
|
||||
---
|
||||
.../arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
index 83b0bd27d..52db60bbc 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c
|
||||
@@ -1700,11 +1700,16 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component,
|
||||
size_t block_size)
|
||||
{
|
||||
|
||||
+ FWU_LOG_MSG("%s: enter: block_offset = %u, block = 0x%p, block_size = %u\n\r"
|
||||
+ , __func__, block_offset, block, block_size);
|
||||
+
|
||||
if (block == NULL) {
|
||||
+ FWU_LOG_MSG("%s: exit: block is NULL\n\r", __func__);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!is_initialized) {
|
||||
+ FWU_LOG_MSG("%s: exit: not initialised\n\r", __func__);
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
@@ -1726,9 +1731,6 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component,
|
||||
uint8_t fwu_image_index = component - FWU_FAKE_IMAGES_INDEX_COUNT;
|
||||
struct fwu_private_metadata priv_metadata;
|
||||
|
||||
- FWU_LOG_MSG("%s: enter: block_offset = %u, block = 0x%p, block_size = %u\n\r"
|
||||
- , __func__, block_offset, block, block_size);
|
||||
-
|
||||
/* Parse the incoming block to make sure complete FMP header is received */
|
||||
if (fmp_header_image_info[fwu_image_index].fmp_hdr_size_recvd != sizeof(fmp_header_image_info[fwu_image_index].fmp_hdr)) {
|
||||
ret = parse_fmp_header(fwu_image_index, block, block_size);
|
||||
Loaded 100 of 271 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user