From 130e764b78b3607c4ceb0e9f375ecd53e118d4df Mon Sep 17 00:00:00 2001 From: Ahmed Gomaa Date: Thu, 20 Aug 2026 15:20:38 +0100 Subject: [PATCH] arm-bsp/trusted-firmware-m: corstone1000: bump to 2.3.0 Select TF-M and its native scripts at version 2.3 for both Corstone-1000 and Corstone-1000-A320. Remove 45 obsolete TF-M patches and two obsolete PSA-ADAC patches, 47 in total. Refresh three retained TF-M patches and renumber the remaining series: 15 TF-M patches and two PSA-ADAC patches. Drop the Corstone-specific PSA-ADAC revision override to use the revision pinned by the generic TF-M 2.3 recipe, which includes the required Corstone-1000 Secure Debug fixes. Configure Corstone-1000 image signing with the TF-M default non-secure PSA key ID required by TF-M 2.3 image verification. Without this metadata, BL2 cannot select the expected built-in verification key. Update the user guide recipe references to TF-M 2.3.0. Signed-off-by: Ahmed Gomaa --- .../conf/machine/include/corstone1000.inc | 4 +- .../corstone1000-a320/topics/user-guide.md | 2 +- .../documentation/corstone1000/user-guide.rst | 2 +- .../corstone1000-flash-firmware-image.bb | 1 + ...f-cc312-differences-between-fvp-and.patch} | 0 ...ware-m-disable-address-warnings-into.patch | 25 - ...nable-different-DRBG-configurations.patch} | 0 ...tform-CS1000-Remove-unused-BL1-files.patch | 449 -- ...e1000-Fix-BL1-compiler-switch-and-re.patch | 43 - ...-1000-secure-debug-waiting-in-CM-LCS.patch | 90 + ...004-Workaround-compile-errors-in-AES.patch | 30 + ...rm-Corstone1000-Enable-FWU-partition.patch | 33 - ...-plat-cs1k-Removed-unused-variables.patch} | 13 +- ...e1000-Implement-Bootloader-Abstracti.patch | 5067 ----------------- ...nt-of-GUIDs-in-unittests-more-clear.patch} | 0 ...m-Corstone1000-Increase-buffer-sizes.patch | 46 - ...rovide-macro-identifying-free-space.patch} | 0 ...e1000-Remove-duplicate-configuration.patch | 31 - ...-Add-operation-to-duplicate-entries.patch} | 0 ...vely-erase-blocks-when-moving-parti.patch} | 0 ...0-Add-support-for-Cortex-A320-varian.patch | 487 -- ... 0010-lib-gpt-Clarify-API-operation.patch} | 0 ...0-Remove-psa_adac_to_tfm_apply_permi.patch | 48 - ...pt-Add-metadata-only-API-operations.patch} | 0 ...-1000-secure-debug-waiting-in-CM-LCS.patch | 53 - ...lat-cs1k-Add-flash-erase-protection.patch} | 0 ...adjust-CS1000-platform-for-GCC-v14.2.patch | 147 - ...unused-FWU-partitions-upon-version-.patch} | 0 ...014-Workaround-compile-errors-in-AES.patch | 48 - ...at-cs1k-Duplicate-old-images-in-FWU.patch} | 0 ...d-barrier-before-first-AO-lock-write.patch | 41 - ...one1000-Increase-FIP-partition-size.patch} | 0 ...ke-mutlicore-support-platform-generi.patch | 90 - ...-lib-efi_guid-Added-EFI-GUID-library.patch | 217 - ...b-efi_soft_crc-Added-EFI-CRC-library.patch | 136 - ...emented-generic-GPT-parser-for-flash.patch | 1495 ----- ...-how-GPT-partition-can-be-identified.patch | 308 - ...dded-operations-to-modify-partitions.patch | 961 ---- ...ib-gpt-Added-operation-to-move-entry.patch | 374 -- ...ility-to-create-and-remove-partition.patch | 713 --- ...pt-Added-table-validation-operations.patch | 412 -- ...-gpt-Added-defragmentation-operation.patch | 280 - .../0026-lib-GPT-Fix-cppcheck-warnings.patch | 74 - ...uid-Remove-unecessary-include-folder.patch | 28 - ...lib-efi_guid-Correct-included-folder.patch | 28 - ...i_soft_crc-Correct-include-directory.patch | 25 - ...030-lib-gpt-Add-missing-link-library.patch | 27 - ...1-lib-gpt-Correct-variable-name-used.patch | 24 - ...32-lib-gpt-Correct-include-directory.patch | 27 - ...t-Move-contents-of-CMake-config-file.patch | 51 - ...34-plat-cs1k-Fixed-formatting-errors.patch | 261 - ...plat-cs1k-Fixed-bad-function-returns.patch | 40 - ...at-cs1k-Improved-logging-in-function.patch | 48 - ...038-plat-cs1k-Remove-unused-function.patch | 93 - ...039-plat-cs1k-Reduce-BL1-binary-size.patch | 464 -- ...-plat-cs1k-Update-license-identifier.patch | 35 - ...-cs1k-Changed-to-use-new-GPT-library.patch | 4536 --------------- ...s1k-Move-variable-from-stack-to-data.patch | 55 - ...eate-and-remove-FWU-image-partitions.patch | 521 -- ...ive-host-base-addresses-from-offsets.patch | 111 - ...NPU-via-external-system-reset-contro.patch | 75 - ...pt-Fix-final-entry-not-being-removed.patch | 114 - ...lib-gpt-Replace-warnings-with-errors.patch | 37 - ...-gpt-Enforce-entry-size-of-128-bytes.patch | 268 - ...Ensure-block-size-complies-with-spec.patch | 38 - ...0050-lib-gpt-Expand-table-validation.patch | 352 -- .../0001-Build-Fix-compiler-warnings.patch | 151 - ...-Fix-psa_key_handle_t-initialization.patch | 32 - ...te-psa_adac_psa_crypto-dependencies.patch} | 0 .../trusted-firmware-m-corstone1000.inc | 80 +- 70 files changed, 148 insertions(+), 19093 deletions(-) rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0004-CC312-alignment-of-cc312-differences-between-fvp-and.patch => 0001-CC312-alignment-of-cc312-differences-between-fvp-and.patch} (100%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-arm-trusted-firmware-m-disable-address-warnings-into.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0010-Corstone-1000-Enable-different-DRBG-configurations.patch => 0002-Corstone-1000-Enable-different-DRBG-configurations.patch} (100%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Platform-CS1000-Remove-unused-BL1-files.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0003-Platform-Corstone1000-Fix-BL1-compiler-switch-and-re.patch create mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0003-bl2-corstone-1000-secure-debug-waiting-in-CM-LCS.patch create mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0004-Workaround-compile-errors-in-AES.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0005-Platform-Corstone1000-Enable-FWU-partition.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0035-plat-cs1k-Removed-unused-variables.patch => 0005-plat-cs1k-Removed-unused-variables.patch} (80%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0006-Platform-Corstone1000-Implement-Bootloader-Abstracti.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0051-lib-gpt-Show-intent-of-GUIDs-in-unittests-more-clear.patch => 0006-lib-gpt-Show-intent-of-GUIDs-in-unittests-more-clear.patch} (100%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0007-Platform-Corstone1000-Increase-buffer-sizes.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0052-lib-gpt-Provide-macro-identifying-free-space.patch => 0007-lib-gpt-Provide-macro-identifying-free-space.patch} (100%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0008-Platform-Corstone1000-Remove-duplicate-configuration.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0053-lib-gpt-Add-operation-to-duplicate-entries.patch => 0008-lib-gpt-Add-operation-to-duplicate-entries.patch} (100%) rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0054-lib-gpt-Consecutively-erase-blocks-when-moving-parti.patch => 0009-lib-gpt-Consecutively-erase-blocks-when-moving-parti.patch} (100%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0009-plat-corstone1000-Add-support-for-Cortex-A320-varian.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0055-lib-gpt-Clarify-API-operation.patch => 0010-lib-gpt-Clarify-API-operation.patch} (100%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0011-bl2-corstone-1000-Remove-psa_adac_to_tfm_apply_permi.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0056-lib-gpt-Add-metadata-only-API-operations.patch => 0011-lib-gpt-Add-metadata-only-API-operations.patch} (100%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0012-bl2-corstone-1000-secure-debug-waiting-in-CM-LCS.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0057-plat-cs1k-Add-flash-erase-protection.patch => 0012-plat-cs1k-Add-flash-erase-protection.patch} (100%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0013-Build-adjust-CS1000-platform-for-GCC-v14.2.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0058-plat-cs1k-Remove-unused-FWU-partitions-upon-version-.patch => 0013-plat-cs1k-Remove-unused-FWU-partitions-upon-version-.patch} (100%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0014-Workaround-compile-errors-in-AES.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0059-plat-cs1k-Duplicate-old-images-in-FWU.patch => 0014-plat-cs1k-Duplicate-old-images-in-FWU.patch} (100%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0015-CC312-Add-barrier-before-first-AO-lock-write.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/{0060-platform-corstone1000-Increase-FIP-partition-size.patch => 0015-platform-corstone1000-Increase-FIP-partition-size.patch} (100%) delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0016-Platform-CS1K-make-mutlicore-support-platform-generi.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0017-lib-efi_guid-Added-EFI-GUID-library.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0018-lib-efi_soft_crc-Added-EFI-CRC-library.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0019-lib-gpt-Implemented-generic-GPT-parser-for-flash.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0020-lib-gpt-Expanded-how-GPT-partition-can-be-identified.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0021-lib-gpt-Added-operations-to-modify-partitions.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0022-lib-gpt-Added-operation-to-move-entry.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0023-lib-gpt-Added-ability-to-create-and-remove-partition.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0024-lib-gpt-Added-table-validation-operations.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0025-lib-gpt-Added-defragmentation-operation.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0026-lib-GPT-Fix-cppcheck-warnings.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0027-lib-efi_guid-Remove-unecessary-include-folder.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0028-lib-efi_guid-Correct-included-folder.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0029-lib-efi_soft_crc-Correct-include-directory.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0030-lib-gpt-Add-missing-link-library.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0031-lib-gpt-Correct-variable-name-used.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0032-lib-gpt-Correct-include-directory.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0033-lib-gpt-Move-contents-of-CMake-config-file.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0034-plat-cs1k-Fixed-formatting-errors.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0036-plat-cs1k-Fixed-bad-function-returns.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0037-plat-cs1k-Improved-logging-in-function.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0038-plat-cs1k-Remove-unused-function.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0039-plat-cs1k-Reduce-BL1-binary-size.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0040-plat-cs1k-Update-license-identifier.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0041-plat-cs1k-Changed-to-use-new-GPT-library.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0042-plat-cs1k-Move-variable-from-stack-to-data.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0043-plat-cs1k-Create-and-remove-FWU-image-partitions.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0044-plat-cs1k-Derive-host-base-addresses-from-offsets.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0045-plat-cs1k-Drive-NPU-via-external-system-reset-contro.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0046-lib-gpt-Fix-final-entry-not-being-removed.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0047-lib-gpt-Replace-warnings-with-errors.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0048-lib-gpt-Enforce-entry-size-of-128-bytes.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0049-lib-gpt-Ensure-block-size-complies-with-spec.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0050-lib-gpt-Expand-table-validation.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0001-Build-Fix-compiler-warnings.patch delete mode 100644 meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0002-Fix-psa_key_handle_t-initialization.patch rename meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/{0003-cmake-Update-psa_adac_psa_crypto-dependencies.patch => 0002-cmake-Update-psa_adac_psa_crypto-dependencies.patch} (100%) diff --git a/meta-arm-bsp/conf/machine/include/corstone1000.inc b/meta-arm-bsp/conf/machine/include/corstone1000.inc index 754e9798..26ab5c04 100644 --- a/meta-arm-bsp/conf/machine/include/corstone1000.inc +++ b/meta-arm-bsp/conf/machine/include/corstone1000.inc @@ -5,8 +5,8 @@ require ${TUNE_FILE} MACHINEOVERRIDES =. "corstone1000:" # TF-M -PREFERRED_VERSION_trusted-firmware-m ?= "2.2.%" -PREFERRED_VERSION_trusted-firmware-m-scripts-native ?= "2.2.%" +PREFERRED_VERSION_trusted-firmware-m ?= "2.3.%" +PREFERRED_VERSION_trusted-firmware-m-scripts-native ?= "2.3.%" # TF-A TFA_PLATFORM = "corstone1000" diff --git a/meta-arm-bsp/documentation/corstone1000-a320/topics/user-guide.md b/meta-arm-bsp/documentation/corstone1000-a320/topics/user-guide.md index e32ac9ff..fca22013 100644 --- a/meta-arm-bsp/documentation/corstone1000-a320/topics/user-guide.md +++ b/meta-arm-bsp/documentation/corstone1000-a320/topics/user-guide.md @@ -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} diff --git a/meta-arm-bsp/documentation/corstone1000/user-guide.rst b/meta-arm-bsp/documentation/corstone1000/user-guide.rst index 4fc547b2..31f8c2f1 100644 --- a/meta-arm-bsp/documentation/corstone1000/user-guide.rst +++ b/meta-arm-bsp/documentation/corstone1000/user-guide.rst @@ -173,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`` | +----------+-------------------------------------------------------------------------------------------------------+ ************************************ diff --git a/meta-arm-bsp/recipes-bsp/images/corstone1000-flash-firmware-image.bb b/meta-arm-bsp/recipes-bsp/images/corstone1000-flash-firmware-image.bb index 5ce621bb..9e4c1468 100644 --- a/meta-arm-bsp/recipes-bsp/images/corstone1000-flash-firmware-image.bb +++ b/meta-arm-bsp/recipes-bsp/images/corstone1000-flash-firmware-image.bb @@ -163,6 +163,7 @@ TFA_FIP_RE_IMAGE_LOAD_ADDRESS = "0x68130000" 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() { diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0004-CC312-alignment-of-cc312-differences-between-fvp-and.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-CC312-alignment-of-cc312-differences-between-fvp-and.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0004-CC312-alignment-of-cc312-differences-between-fvp-and.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-CC312-alignment-of-cc312-differences-between-fvp-and.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-arm-trusted-firmware-m-disable-address-warnings-into.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-arm-trusted-firmware-m-disable-address-warnings-into.patch deleted file mode 100644 index 73fbd0a6..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0001-arm-trusted-firmware-m-disable-address-warnings-into.patch +++ /dev/null @@ -1,25 +0,0 @@ -From f3400c6527e6d0c073215694e19734a6268a6bc9 Mon Sep 17 00:00:00 2001 -From: Ali Can Ozaslan -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 -Signed-off-by: Ali Can Ozaslan -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 diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0010-Corstone-1000-Enable-different-DRBG-configurations.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Corstone-1000-Enable-different-DRBG-configurations.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0010-Corstone-1000-Enable-different-DRBG-configurations.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Corstone-1000-Enable-different-DRBG-configurations.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Platform-CS1000-Remove-unused-BL1-files.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Platform-CS1000-Remove-unused-BL1-files.patch deleted file mode 100644 index b68c5f4f..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0002-Platform-CS1000-Remove-unused-BL1-files.patch +++ /dev/null @@ -1,449 +0,0 @@ -From 9ed08f26cafc2c6e5bf1d5cc04f91ca17d94a1bd Mon Sep 17 00:00:00 2001 -From: Harsimran Singh Tungal -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 -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 -- $<$:-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 -- $<$:${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 $ --) -- --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 -- $<$: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 -- $ --) -- --# Include path needed for mbedcrypto headers --target_include_directories(bl1_main -- PRIVATE -- $ --) -- --# 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 -- $ --) -- --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 -- $ -- $ -- $ --) -- --# Configurations based on platform/CMakeLists.txt --target_include_directories(bl1_main -- PRIVATE -- $ -- $ -- $ -- $ -- $<$:${CMAKE_SOURCE_DIR}/platform/ext/accelerator/interface> --) -- --target_sources(bl1_main -- PRIVATE -- $<$:${CMAKE_SOURCE_DIR}/platform/ext/common/uart_stdout.c> -- $<$:${CMAKE_SOURCE_DIR}/platform/ext/common/template/nv_counters.c> -- $<$,$>:${CMAKE_SOURCE_DIR}/platform/ext/common/template/flash_otp_nv_counters_backend.c> -- $<$:${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} -- $<$:SYMMETRIC_INITIAL_ATTESTATION> -- $<$:PLATFORM_DEFAULT_NV_COUNTERS> -- $<$:MCUBOOT_HW_KEY> -- MCUBOOT_FIH_PROFILE_${MCUBOOT_FIH_PROFILE} -- $<$:PLATFORM_DEFAULT_NV_COUNTERS> -- $<$:PLATFORM_DEFAULT_OTP> -- $<$:OTP_NV_COUNTERS_RAM_EMULATION=1> -- $<$:TFM_DUMMY_PROVISIONING> -- $<$:OTP_WRITEABLE> --) -- --# Configurations based on cc312 cmake files --target_compile_definitions(bl1_main -- PRIVATE -- $<$:CRYPTO_HW_ACCELERATOR_OTP_${CRYPTO_HW_ACCELERATOR_OTP_STATE}> -- $<$:CRYPTO_HW_ACCELERATOR> -- $<$:ENABLE_FWU_AGENT_DEBUG_LOGS> --) -- --target_include_directories(bl1_main -- PRIVATE -- $<$:${CMAKE_SOURCE_DIR}/platform/ext/accelerator/cc312> -- $<$:${CMAKE_SOURCE_DIR}/lib/ext/cryptocell-312-runtime/shared/include/mbedtls> -- $<$:${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 -- $<$:-E\;-xc> -- $<$:-E\;-xc> -- $<$:--preprocess=ns\;$> --) --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 $/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 $ -- -k ${MCUBOOT_KEY_S} -- --public-key-format $,full,hash> -- --align 1 -- --pad -- --pad-header -- -H 0x400 -- -s ${MCUBOOT_SECURITY_COUNTER_S} -- -d \"\(0,${MCUBOOT_S_IMAGE_MIN_VER}\)\" -- $<$:--overwrite-only> -- $<$:-E${MCUBOOT_KEY_ENC}> -- $<$:--measured-boot-record> -- $/bl2.bin -- ${CMAKE_CURRENT_BINARY_DIR}/bl2_signed.bin -- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/bl2_signed.bin $ --) -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 --#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; --} diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0003-Platform-Corstone1000-Fix-BL1-compiler-switch-and-re.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0003-Platform-Corstone1000-Fix-BL1-compiler-switch-and-re.patch deleted file mode 100644 index ef73c572..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0003-Platform-Corstone1000-Fix-BL1-compiler-switch-and-re.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 1d7ab426f171516c15ce8e5223541c62c91ec596 Mon Sep 17 00:00:00 2001 -From: Harsimran Singh Tungal -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 -Signed-off-by: Bence Balogh -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 - $<$: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 diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0003-bl2-corstone-1000-secure-debug-waiting-in-CM-LCS.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0003-bl2-corstone-1000-secure-debug-waiting-in-CM-LCS.patch new file mode 100644 index 00000000..d458a435 --- /dev/null +++ b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0003-bl2-corstone-1000-secure-debug-waiting-in-CM-LCS.patch @@ -0,0 +1,90 @@ +From f0567aa80b2cc88d278c3adb0a5366ae9ff8cf58 Mon Sep 17 00:00:00 2001 +From: Devaraj Ranganna +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 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 +Signed-off-by: Ahmed Gomaa +--- + .../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 9bc0f20e10..d034efe59f 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; diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0004-Workaround-compile-errors-in-AES.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0004-Workaround-compile-errors-in-AES.patch new file mode 100644 index 00000000..453c8685 --- /dev/null +++ b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0004-Workaround-compile-errors-in-AES.patch @@ -0,0 +1,30 @@ +From cc48c5782b6968a34fa69047c04f3caf99a3bf18 Mon Sep 17 00:00:00 2001 +From: Jon Mason +Date: Mon, 23 Feb 2026 11:53:38 -0500 +Subject: [PATCH] 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 +Signed-off-by: Ahmed Gomaa +--- + 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 6bc89fe115..2008e9641b 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; + } diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0005-Platform-Corstone1000-Enable-FWU-partition.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0005-Platform-Corstone1000-Enable-FWU-partition.patch deleted file mode 100644 index 4e890975..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0005-Platform-Corstone1000-Enable-FWU-partition.patch +++ /dev/null @@ -1,33 +0,0 @@ -From fdfbb3b82f62a2d4575a983ebaee14a67130d316 Mon Sep 17 00:00:00 2001 -From: Ali Can Ozaslan -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 -Signed-off-by: Harsimran Singh Tungal ---- - 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.") diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0035-plat-cs1k-Removed-unused-variables.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0005-plat-cs1k-Removed-unused-variables.patch similarity index 80% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0035-plat-cs1k-Removed-unused-variables.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0005-plat-cs1k-Removed-unused-variables.patch index 5c8464b0..f10a6557 100644 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0035-plat-cs1k-Removed-unused-variables.patch +++ b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0005-plat-cs1k-Removed-unused-variables.patch @@ -1,4 +1,4 @@ -From c579565c25937ae9455efe9cc3fbcace84c3e580 Mon Sep 17 00:00:00 2001 +From 3dcaa54afe671534b11a0586a49a9036b2bb2011 Mon Sep 17 00:00:00 2001 From: Frazer Carsley Date: Mon, 29 Dec 2025 11:28:47 +0000 Subject: [PATCH] plat: cs1k: Removed unused variables @@ -6,15 +6,16 @@ Subject: [PATCH] plat: cs1k: Removed unused variables Change-Id: I0dd3ff834c47c58dc833586c74791deca679a3ab Signed-off-by: Frazer Carsley Upstream-Status: Backport +Signed-off-by: Ahmed Gomaa --- .../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 9fe9df0..89c2696 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, +@@ -1594,7 +1594,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 +@@ -2070,7 +2069,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 - +@@ -2085,10 +2083,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; diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0006-Platform-Corstone1000-Implement-Bootloader-Abstracti.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0006-Platform-Corstone1000-Implement-Bootloader-Abstracti.patch deleted file mode 100644 index 28c5e67d..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0006-Platform-Corstone1000-Implement-Bootloader-Abstracti.patch +++ /dev/null @@ -1,5067 +0,0 @@ -From ab77323c82d4d1983e81fe20b7b3c8eda743d808 Mon Sep 17 00:00:00 2001 -From: Ali Can Ozaslan -Date: Tue, 15 Oct 2024 12:50:16 +0000 -Subject: [PATCH] Platform: Corstone1000: Implement Bootloader Abstraction - Layer - -This commit introduces the Bootloader Abstraction Layer (BAL) for -Corstone-1000. The following changes are made: - -1. Move the previous Capsule Update implementation for Corstone-1000 -from "fwu_update_agent/" to "bootloader/mcuboot/". This serves as -the placeholder for the Bootloader Abstraction Layer (BAL). - -2. Move content of "fwu_agent.c" to "tfm_mcuboot_fwu.c". This source -file is the actual implementation of bootloader abstraction layer. -Adapt the previous Capsule Update implementation in -"tfm_mcuboot_fwu.c "to align with the PSA Firmware Update (FWU) -state machine. - -3. Remove "uefi_capsule_parser.c" and "uefi_capsule_parser.h". -The UEFI capsule header parsing is now done in U-Boot. - -4. Modify "uefi_fmp.c" to support modification of FMP information -for multiple images. In the previous capsule update implementation, -this file only supports updates FMP information for single -Corstone-1000 image. - -5. New functions for capsule update implementation in bootloader -abstraction layer supports different return values. Update checks of -return values in "provisioning.c" and "security_cnt_bl2.c", as these -files use functions defined in bootloader abstraction layer. - -6. Update "config.cmake" and "CMakeLists.txt" to support compilation -and configuration of bootloader abstraction layer for Corstone-1000. - -7. Create FWU configuration file "fwu_config.h.in" for Corstone-1000 -with default configuration values. - -8. FWU implementation in U-Boot expects to have metadata size field -updated in metadata. Store the metadata size in metadata, so U-Boot -can use it. - -9. Update metadata for FWU accept. Store image GUIDs and bank state -in metadata. This is used by the U-Boot to decide the trial state -and accept the images based on GUIDs. - -10. Add rollback version check. Bootloader abstraction layer refuses -to update the lower version firmware than the current version. - -11. Add support for FVP and MPS3 image GUID's. - -12. Add support for EFI ESRT v1 and code refactoring - -Add support to configure the ESRT entries during -tfm_fwu_query() function call. The ESRT image component -is defined to represent the ESRT image. The tfm_fwu_query() -function returns the ESRT data requested by FWU client in -the psa_fwu_impl_info_t structure object. -The psa_fwu_impl_info_t structure object is used to store -the ESRT entries for all the images. This structure object -is declared in psa_fwu_component_info_t structure which -stores all the data requested by update client via -tfm_fwu_query(). - -For Corstone-1000, the TFM_FWU_MAX_DIGEST_SIZE represents -the maximum size needed to store the ESRT entries for all -the images in a bank. -ESRT details can be found here: -https://uefi.org/specs/UEFI/2.9_A/23_Firmware_Update_and_Reporting.html#efi-system-resource-table - -13. Define max payload size and enable trial state - -14. Implement Partial Capsule Update Support -Introduces support for partial capsule updates -with the following changes: --> Copy unchanged images from the other bank to the updated - bank to ensure consistency across banks. --> Add image offsets and sizes for each payload to facilitate - accurate image management during updates. - -Upstream-Status: Backport [fb790fc19904a0ca9bacba7e58cf4dff5576b1d0] -Signed-off-by: Harsimran Singh Tungal -Signed-off-by: Ali Can Ozaslan ---- - .../target/arm/corstone1000/CMakeLists.txt | 34 +- - .../arm/corstone1000/bl1/provisioning.c | 2 +- - .../arm/corstone1000/bl2/security_cnt_bl2.c | 5 +- - .../arm/corstone1000/bootloader/fwu_agent.h | 123 + - .../corstone1000/bootloader/fwu_config.h.in | 58 + - .../bootloader/mcuboot/CMakeLists.txt | 52 + - .../bootloader/mcuboot/tfm_mcuboot_fwu.c | 2345 +++++++++++++++++ - .../mcuboot}/uefi_fmp.c | 111 +- - .../tfm_bootloader_fwu_abstraction.h | 189 ++ - .../uefi_fmp.h | 7 +- - .../ext/target/arm/corstone1000/config.cmake | 11 +- - .../corstone1000/fw_update_agent/fwu_agent.c | 1405 ---------- - .../corstone1000/fw_update_agent/fwu_agent.h | 73 - - .../fw_update_agent/uefi_capsule_parser.c | 176 -- - .../fw_update_agent/uefi_capsule_parser.h | 33 - - .../arm/corstone1000/partition/flash_layout.h | 14 +- - 16 files changed, 2883 insertions(+), 1755 deletions(-) - create mode 100644 platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h - create mode 100644 platform/ext/target/arm/corstone1000/bootloader/fwu_config.h.in - create mode 100644 platform/ext/target/arm/corstone1000/bootloader/mcuboot/CMakeLists.txt - create mode 100644 platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c - rename platform/ext/target/arm/corstone1000/{fw_update_agent => bootloader/mcuboot}/uefi_fmp.c (66%) - create mode 100644 platform/ext/target/arm/corstone1000/bootloader/tfm_bootloader_fwu_abstraction.h - rename platform/ext/target/arm/corstone1000/{fw_update_agent => bootloader}/uefi_fmp.h (89%) - delete mode 100644 platform/ext/target/arm/corstone1000/fw_update_agent/fwu_agent.c - delete mode 100644 platform/ext/target/arm/corstone1000/fw_update_agent/fwu_agent.h - delete mode 100644 platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.c - delete mode 100644 platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.h - -diff --git a/platform/ext/target/arm/corstone1000/CMakeLists.txt b/platform/ext/target/arm/corstone1000/CMakeLists.txt -index 66dfb2399503..91bf197d86b7 100644 ---- a/platform/ext/target/arm/corstone1000/CMakeLists.txt -+++ b/platform/ext/target/arm/corstone1000/CMakeLists.txt -@@ -115,7 +115,7 @@ target_include_directories(platform_s - ${PLATFORM_DIR}/ext/target/arm/drivers/usart/pl011 - INTERFACE - cc312 -- fw_update_agent -+ bootloader - soft_crc - io - partition -@@ -133,9 +133,8 @@ target_sources(platform_s - Native_Driver/watchdog.c - Native_Driver/arm_watchdog_drv.c - $<$:${CMAKE_CURRENT_SOURCE_DIR}/services/src/tfm_platform_system.c> -- fw_update_agent/uefi_capsule_parser.c -- fw_update_agent/fwu_agent.c -- fw_update_agent/uefi_fmp.c -+ bootloader/mcuboot/tfm_mcuboot_fwu.c -+ bootloader/mcuboot/uefi_fmp.c - soft_crc/soft_crc.c - io/io_block.c - io/io_flash.c -@@ -199,9 +198,8 @@ target_sources(platform_bl1_1 - ./Native_Driver/watchdog.c - ./bl1/boot_hal_bl1_1.c - ./bl1/provisioning.c -- ./fw_update_agent/fwu_agent.c -- ./fw_update_agent/uefi_capsule_parser.c -- ./fw_update_agent/uefi_fmp.c -+ ./bootloader/mcuboot/tfm_mcuboot_fwu.c -+ ./bootloader/mcuboot/uefi_fmp.c - ./soft_crc/soft_crc.c - $<$>:${PLATFORM_DIR}/ext/accelerator/cc312/otp_cc312.c> - $<$>:${CMAKE_CURRENT_SOURCE_DIR}/bl1/cc312_rom_crypto.c> -@@ -232,7 +230,7 @@ target_include_directories(platform_bl1_1_interface - ./Device/Config - ./Native_Driver - ./CMSIS_Driver/Config -- ./fw_update_agent -+ ./bootloader - ./soft_crc - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/cfi - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/common -@@ -244,6 +242,7 @@ target_include_directories(platform_bl1_1_interface - ${PLATFORM_DIR}/ext/target/arm/drivers/usart/pl011 - $<$:${CMAKE_SOURCE_DIR}/platform/ext/accelerator/interface> - ${PLATFORM_DIR}/ext/accelerator/cc312/ -+ ${CMAKE_SOURCE_DIR}/lib/fih/inc/ - ) - - target_link_libraries(platform_bl1_1 -@@ -251,6 +250,11 @@ target_link_libraries(platform_bl1_1 - $<$>:cc3xx> - ) - -+target_include_directories(platform_bl1_1 -+ PRIVATE -+ ${CMAKE_SOURCE_DIR}/interface/include # for psa/error.h -+) -+ - target_sources(platform_bl1_2 - PRIVATE - ./bl1/boot_hal_bl1_2.c -@@ -276,7 +280,7 @@ target_include_directories(platform_bl1_2 - ./Device/Config - ./Native_Driver - ./CMSIS_Driver/Config -- ./fw_update_agent -+ ./bootloader - ./soft_crc - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/common - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/cfi -@@ -285,6 +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 - ) - - #========================= Platform BL2 =======================================# -@@ -301,7 +306,7 @@ target_sources(platform_bl2 - Native_Driver/watchdog.c - Native_Driver/arm_watchdog_drv.c - fip_parser/fip_parser.c -- fw_update_agent/fwu_agent.c -+ bootloader/mcuboot/tfm_mcuboot_fwu.c - bl2/security_cnt_bl2.c - $<$>:${PLATFORM_DIR}/ext/accelerator/cc312/otp_cc312.c> - io/io_block.c -@@ -356,6 +361,12 @@ target_compile_definitions(bl2 - $<$:CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING> - $<$:PLATFORM_PSA_ADAC_SECURE_DEBUG> - ) -+ -+target_include_directories(bl2 -+ PRIVATE -+ ${CMAKE_SOURCE_DIR}/interface/include # for psa/error.h -+) -+ - target_compile_definitions(bootutil - PRIVATE - MULTIPLE_EXECUTABLE_RAM_REGIONS -@@ -367,7 +378,7 @@ target_include_directories(platform_bl2 - Device/Include - fip_parser - Native_Driver -- fw_update_agent -+ bootloader - soft_crc - io - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/common -@@ -386,6 +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 - $ -+ ${CMAKE_SOURCE_DIR}/interface/include # for psa/error.h - ) - - #========================= ns_agent_mailbox ===================================# -diff --git a/platform/ext/target/arm/corstone1000/bl1/provisioning.c b/platform/ext/target/arm/corstone1000/bl1/provisioning.c -index b8b03ad558b9..b28c840f8668 100644 ---- a/platform/ext/target/arm/corstone1000/bl1/provisioning.c -+++ b/platform/ext/target/arm/corstone1000/bl1/provisioning.c -@@ -92,7 +92,7 @@ enum tfm_plat_err_t provision_assembly_and_test(void) - } - - err = fwu_metadata_provision(); -- if (err != FWU_AGENT_SUCCESS) { -+ if (err != PSA_SUCCESS) { - return 1; - } - -diff --git a/platform/ext/target/arm/corstone1000/bl2/security_cnt_bl2.c b/platform/ext/target/arm/corstone1000/bl2/security_cnt_bl2.c -index da9f74e1c88c..850ed46ac2d8 100644 ---- a/platform/ext/target/arm/corstone1000/bl2/security_cnt_bl2.c -+++ b/platform/ext/target/arm/corstone1000/bl2/security_cnt_bl2.c -@@ -76,7 +76,8 @@ int32_t boot_nv_security_counter_update(uint32_t image_id, - { - enum tfm_nv_counter_t nv_counter; - enum tfm_plat_err_t err; -- enum fwu_agent_error_t fwu_err; -+ bool provisioning_required; -+ psa_status_t fwu_err; - - nv_counter = get_nv_counter_from_image_id(image_id); - if (nv_counter >= TFM_BOOT_NV_COUNTER_MAX) { -@@ -100,7 +101,7 @@ int32_t boot_nv_security_counter_update(uint32_t image_id, - return -1; - } - -- if (fwu_err != FWU_AGENT_SUCCESS) { -+ if (fwu_err != PSA_SUCCESS) { - return -1; - } - -diff --git a/platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h b/platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h -new file mode 100644 -index 000000000000..aa5af15b26ce ---- /dev/null -+++ b/platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h -@@ -0,0 +1,123 @@ -+/* -+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved. -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ */ -+ -+#ifndef FWU_AGENT_H -+#define FWU_AGENT_H -+ -+#include "psa/error.h" -+#include "../fip_parser/external/uuid.h" -+ -+#define ENABLE_FWU_AGENT_DEBUG_LOGS -+#ifdef ENABLE_FWU_AGENT_DEBUG_LOGS -+ #include -+ #define FWU_LOG_MSG(f_, ...) printf((f_), ##__VA_ARGS__) -+#else -+ #define FWU_LOG_MSG(f_, ...) -+#endif -+ -+#define FWU_ASSERT(_c_) \ -+ if (!(_c_)) { \ -+ FWU_LOG_MSG("%s:%d assert hit\n\r", __func__, __LINE__); \ -+ while(1) {}; \ -+ } \ -+ -+ -+/* Version used for the very first image of the device. */ -+#define FWU_IMAGE_INITIAL_VERSION 0 -+ -+#define EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION 1 -+typedef struct { -+ uint32_t signature; -+ uint32_t header_size; -+ uint32_t fw_version; -+ uint32_t lowest_supported_version; -+} __packed fmp_payload_header_t; -+ -+typedef struct { -+ fmp_payload_header_t fmp_hdr; -+ size_t fmp_hdr_size_recvd; -+ size_t image_size_recvd; -+} __packed fmp_header_image_info_t; -+ -+/* Store image information common for both the banks */ -+typedef struct { -+ /* Total size of the image */ -+ uint32_t image_size; -+ -+ /* Offset of image within a bank */ -+ uint32_t image_offset; -+ -+ /* Image GUID */ -+ struct efi_guid image_guid; -+} __packed fwu_bank_image_info_t; -+ -+/* ESRT v1 */ -+struct __attribute__((__packed__)) efi_system_resource_entry { -+ struct efi_guid fw_class; -+ uint32_t fw_type; -+ uint32_t fw_version; -+ uint32_t lowest_supported_fw_version; -+ uint32_t capsule_flags; -+ uint32_t last_attempt_version; -+ uint32_t last_attempt_status; -+}; -+ -+struct __attribute__((__packed__)) efi_system_resource_table { -+ uint32_t fw_resource_count; -+ uint32_t fw_resource_count_max; -+ uint64_t fw_resource_version; -+ struct efi_system_resource_entry entries[]; -+}; -+ -+psa_status_t fwu_metadata_provision(void); -+psa_status_t fwu_metadata_init(void); -+ -+/* host to secure enclave: -+ * firwmare update image is sent accross -+ */ -+psa_status_t corstone1000_fwu_flash_image(void); -+ -+/* host to secure enclave: -+ * host responds with this api to acknowledge its successful -+ * boot. -+ */ -+psa_status_t corstone1000_fwu_host_ack(void); -+ -+void bl1_get_active_bl2_image(uint32_t *bank_offset); -+uint8_t bl2_get_boot_bank(void); -+ -+/* When in trial state, start the timer for host to respond. -+ * Diable timer when host responds back either by calling -+ * corstone1000_fwu_accept_image or corstone1000_fwu_select_previous. -+ * Otherwise, resets the system. -+ */ -+void host_acknowledgement_timer_to_reset(void); -+ -+enum fwu_nv_counter_index_t { -+ FWU_BL2_NV_COUNTER = 0, -+ FWU_TFM_NV_COUNTER, -+ FWU_TFA_NV_COUNTER, -+ FWU_MAX_NV_COUNTER_INDEX = FWU_TFA_NV_COUNTER -+}; -+ -+/* stage nv counter into private metadata section of the flash. -+ * staged nv counters are written to the otp when firmware update -+ * is successful -+ * the function assumes that the api is called in the boot loading -+ * stage -+ */ -+psa_status_t fwu_stage_nv_counter(enum fwu_nv_counter_index_t index, -+ uint32_t img_security_cnt); -+ -+/* -+ * Check if both metadata replica is valid by calculating and comparing crc32. -+ * If one of the replica is corrupted then update it with the valid replica. -+ * If both of the replicas are corrupted then the correction is not possible. -+ */ -+psa_status_t fwu_metadata_check_and_correct_integrity(void); -+ -+#endif /* FWU_AGENT_H */ -diff --git a/platform/ext/target/arm/corstone1000/bootloader/fwu_config.h.in b/platform/ext/target/arm/corstone1000/bootloader/fwu_config.h.in -new file mode 100644 -index 000000000000..acb8de05e107 ---- /dev/null -+++ b/platform/ext/target/arm/corstone1000/bootloader/fwu_config.h.in -@@ -0,0 +1,58 @@ -+/* -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ */ -+ -+#ifndef __FWU_CONFIG_H__ -+#define __FWU_CONFIG_H__ -+ -+/* This file contains device specific configurations in FWU partition based -+ * on MCUboot. -+ */ -+ -+/* Components of the device. When porting a specific bootloader to FWU partition, -+ * the bootloader specific image types can be defined here. -+ */ -+#define FWU_COMPONENT_NUMBER 6 -+ -+/* Maximum number of FWU Images -+ * FWU_COMPONENT_NUMBER takes into account the fact our image index is starting from 1 and also we have an ESRT image -+ */ -+#define FWU_IMAGE_COUNT (FWU_COMPONENT_NUMBER - 2) -+ -+/* sizeof(struct efi_system_resource_entry) -+ * Size of one ESRT v1 Image entry structure object -+ */ -+#define ESRT_IMAGE_ENTRY_SIZE 40 -+ -+/* sizeof(struct efi_system_resource_table) - sizeof(struct efi_system_resource_entry) -+ * Size of remaining fields of ESRT v1 t -+ */ -+#define ESRT_REMAINING_FIELDS_SIZE 16 -+ -+#if FWU_COMPONENT_NUMBER > 1 -+#define FWU_COMPONENT_ID_SECURE 0x00U -+#define FWU_COMPONENT_ID_NONSECURE 0x01U -+#else -+#define FWU_COMPONENT_ID_FULL 0x00U -+#endif -+ -+/* The maximum size of an image digest in bytes. This is dependent -+ * on the hash algorithm used. -+ */ -+#define TFM_FWU_MAX_DIGEST_SIZE ((FWU_IMAGE_COUNT * ESRT_IMAGE_ENTRY_SIZE) + ESRT_REMAINING_FIELDS_SIZE) -+ -+/* The maximum permitted size for block in psa_fwu_write(), in bytes. */ -+#define TFM_CONFIG_FWU_MAX_WRITE_SIZE @TFM_CONFIG_FWU_MAX_WRITE_SIZE@ -+ -+/* The maximum permitted size for manifest in psa_fwu_start(), in bytes. */ -+#define TFM_CONFIG_FWU_MAX_MANIFEST_SIZE @TFM_CONFIG_FWU_MAX_MANIFEST_SIZE@ -+ -+/* Whether TRIAL component state is supported or not. This is device specific -+ * configuration. -+ */ -+#cmakedefine FWU_SUPPORT_TRIAL_STATE -+ -+#endif /* __FWU_CONFIG_H__ */ -diff --git a/platform/ext/target/arm/corstone1000/bootloader/mcuboot/CMakeLists.txt b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/CMakeLists.txt -new file mode 100644 -index 000000000000..13a3caf5431a ---- /dev/null -+++ b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/CMakeLists.txt -@@ -0,0 +1,52 @@ -+#------------------------------------------------------------------------------- -+# SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+#------------------------------------------------------------------------------- -+cmake_minimum_required(VERSION 3.21) -+ -+add_library(tfm_fwu_mcuboot_util INTERFACE) -+ -+target_sources(tfm_fwu_mcuboot_util -+ INTERFACE -+ ${MCUBOOT_PATH}/boot/bootutil/src/bootutil_public.c -+ ${MCUBOOT_PATH}/boot/bootutil/src/tlv.c -+ ${CMAKE_SOURCE_DIR}/bl2/src/flash_map.c -+ ${CMAKE_SOURCE_DIR}/bl2/ext/mcuboot/flash_map_extended.c -+ ./tfm_mcuboot_fwu.c -+ ./uefi_fmp.c -+ $<$:${CMAKE_SOURCE_DIR}/bl2/src/default_flash_map.c> -+) -+ -+target_include_directories(tfm_fwu_mcuboot_util -+ INTERFACE -+ ${CMAKE_BINARY_DIR}/bl2/ext/mcuboot -+ ${CMAKE_SOURCE_DIR}/bl2/ext/mcuboot/include -+ ${MCUBOOT_PATH}/boot/bootutil/include -+ ${MCUBOOT_PATH}/boot/bootutil/src -+ ${CMAKE_CURRENT_SOURCE_DIR}/../ -+ ${MBEDCRYPTO_PATH}/include -+) -+ -+target_link_libraries(tfm_fwu_mcuboot_util -+ INTERFACE -+ platform_region_defs -+) -+ -+target_link_libraries(tfm_psa_rot_partition_fwu -+ PRIVATE -+ tfm_fwu_mcuboot_util -+) -+ -+configure_file(${CMAKE_SOURCE_DIR}/platform/ext/target/arm/corstone1000/bootloader/fwu_config.h.in -+ ${CMAKE_BINARY_DIR}/platform/ext/target/arm/corstone1000/bootloader/fwu_config.h -+ @ONLY) -+set(FWU_DEVICE_CONFIG_FILE "${CMAKE_BINARY_DIR}/platform/ext/target/arm/corstone1000/bootloader/fwu_config.h") -+ -+target_compile_definitions(tfm_psa_rot_partition_fwu -+ PRIVATE -+ MCUBOOT_${MCUBOOT_UPGRADE_STRATEGY} -+ $<$:MCUBOOT_DIRECT_XIP_REVERT> -+ FWU_DEVICE_CONFIG_FILE="${FWU_DEVICE_CONFIG_FILE}" -+) -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 -new file mode 100644 -index 000000000000..a458b5478fe6 ---- /dev/null -+++ b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c -@@ -0,0 +1,2345 @@ -+/* -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ */ -+#include -+#include "psa/crypto.h" -+#include "psa/error.h" -+#include "tfm_bootloader_fwu_abstraction.h" -+ -+#include -+#include -+#include "fwu_agent.h" -+#include "Driver_Flash.h" -+#include "flash_layout.h" -+#include "fip_parser/external/uuid.h" -+#include "region_defs.h" -+#include "flash_common.h" -+#include "platform_base_address.h" -+#include "platform_description.h" -+#include "tfm_plat_nv_counters.h" -+#include "tfm_plat_defs.h" -+#include "uefi_fmp.h" -+#include "uart_stdout.h" -+#include "soft_crc.h" -+#ifndef BL1_BUILD -+#include "partition.h" -+#include "platform.h" -+#endif -+ -+#define FWU_METADATA_VERSION 2 -+#define FWU_FW_STORE_DESC_OFFSET 0x20 -+#define NR_OF_MAX_FW_BANKS 4 -+ -+/* Size of a chunk transferred at once from one bank to another -+ * This is used when bank consistency is maintained during partial capsule update -+ */ -+#define FLASH_CHUNK_SIZE 512 -+ -+/* Possible states of the bank. -+ * Naming convention here matches the implementation in U-Boot -+ */ -+#define FWU_BANK_INVALID (uint8_t)0xFF -+#define FWU_BANK_VALID (uint8_t)0xFE -+#define FWU_BANK_ACCEPTED (uint8_t)0xFC -+ -+/* The component number for the ESRT image. -+ * The ESRT image is used to read ESRT entries for all the images in a bank -+ */ -+#define FWU_IMAGE_INDEX_ESRT FWU_COMPONENT_NUMBER - 1 -+ -+/* Index count for fake images to be ignored -+ * The image index for firmware images in capsule starts from 1. -+ * So, the image at index 0 should be ignored */ -+#define FWU_FAKE_IMAGES_INDEX_COUNT 1 -+#define FWU_FAKE_IMAGE_INDEX 0 -+ -+/* -+ * Metadata version 2 data structures defined by PSA_FW update specification -+ * at https://developer.arm.com/documentation/den0118/latest/ -+ */ -+ -+/* Properties of image in a bank */ -+struct fwu_image_properties { -+ -+ /* The UUID of the image in this bank */ -+ uuid_t img_uuid; -+ -+ /* [0]: bit describing the image acceptance status – -+ * status - 1 means the image is accepted -+ * [31:1]: MBZ -+ */ -+ uint32_t accepted; -+ -+ /* NOTE: using the reserved field */ -+ /* image version */ -+ uint32_t version; -+ -+} __packed; -+ -+/* Image entry information */ -+struct fwu_image_entry { -+ -+ /* The UUID identifying the image type */ -+ uuid_t img_type_uuid; -+ -+ /* The UUID of the storage volume where the image is located */ -+ uuid_t location_uuid; -+ -+ /* The Properties of images with img_type_uuid in the different FW banks */ -+ struct fwu_image_properties img_props[NR_OF_FW_BANKS]; -+ -+} __packed; -+ -+struct fwu_fw_store_descriptor { -+ -+ /* The number of firmware banks in the Firmware Store */ -+ uint8_t num_banks; -+ -+ /* Reserved */ -+ uint8_t reserved; -+ -+ /* The number of images per bank. This should be the number of entries in the img_entry array */ -+ uint16_t num_images; -+ -+ /* The size of image_entry(all banks) in bytes */ -+ uint16_t img_entry_size; -+ -+ /* The size of image bank info structure in bytes */ -+ uint16_t bank_info_entry_size; -+ -+ /* Array of fwu_image_entry structs */ -+ struct fwu_image_entry img_entry[NR_OF_IMAGES_IN_FW_BANK]; -+ -+} __packed; -+ -+struct fwu_metadata { -+ -+ /* The metadata CRC value */ -+ uint32_t crc_32; -+ -+ /* The metadata version */ -+ uint32_t version; -+ -+ /* The bank index with which device boots */ -+ uint32_t active_index; -+ -+ /* The previous bank index with which device booted successfully */ -+ uint32_t previous_active_index; -+ -+ /* The size of the entire metadata in bytes */ -+ uint32_t metadata_size; -+ -+ /* The offset of the image descriptor structure */ -+ uint16_t desc_offset; -+ -+ /* Reserved */ -+ uint16_t reserved1; -+ -+ /* The state of each bank -+ * Each bank_state entry can take one of the following values: -+ * • 0xFF: invalid – One or more images in the bank are corrupted or were partially overwritten. -+ * • 0xFE: valid – The bank contains a valid set of images, but some images are in an unaccepted state. -+ * • 0xFC: accepted – all of the images in the bank are valid and have been accepted. -+ */ -+ uint8_t bank_state[NR_OF_MAX_FW_BANKS]; -+ -+ /* Reserved */ -+ uint32_t reserved2; -+ -+ struct fwu_fw_store_descriptor fw_desc; -+ -+} __packed; -+ -+/* This is Corstone1000 speific metadata for OTA. -+ * Private metadata is written at next sector following -+ * FWU METADATA location */ -+struct fwu_private_metadata { -+ -+ /* The bank from which system is booted from */ -+ uint32_t boot_index; -+ -+ /* The tracking number of boot attempted so far */ -+ uint32_t boot_attempted; -+ -+ /* The temprary location of staged nv_counter before written to the otp */ -+ uint32_t nv_counter[NR_OF_IMAGES_IN_FW_BANK]; -+ -+ /* The current FMP version of each image */ -+ uint32_t fmp_version[NR_OF_IMAGES_IN_FW_BANK]; -+ -+ /* The last attempted FMP version of each image */ -+ uint32_t fmp_last_attempt_version[NR_OF_IMAGES_IN_FW_BANK]; -+ -+ /* The last attempted FMP status of each image */ -+ uint32_t fmp_last_attempt_status[NR_OF_IMAGES_IN_FW_BANK]; -+ -+} __packed; -+ -+/* -+ * struct fwu_esrt_data_wrapper - Wrapper for the ESRT data -+ * @data: The ESRT data -+ * @entries: The ESRT image entries -+ */ -+struct __attribute__((__packed__)) fwu_esrt_data_wrapper { -+ /* The ESRT data */ -+ struct efi_system_resource_table data; -+ -+ /* The ESRT image entries */ -+ struct efi_system_resource_entry entries[NR_OF_IMAGES_IN_FW_BANK]; -+}; -+ -+#define MAX_BOOT_ATTEMPTS_PER_BANK 3 -+ -+/* -+ * GUIDs for capsule updatable firmware images -+ * -+ * The GUIDs are generating with the UUIDv5 format. -+ * Namespace used for FVP GUIDs: 989f3a4e-46e0-4cd0-9877-a25c70c01329 -+ * Namespace used for MPS3 GUIDs: df1865d1-90fb-4d59-9c38-c9f2c1bba8cc -+ * Names: the image names stated in the fw_name field -+ */ -+fwu_bank_image_info_t fwu_image[NR_OF_IMAGES_IN_FW_BANK] = { -+#if PLATFORM_IS_FVP -+ // FVP payloads GUIDs -+ // bl2_signed -+ { -+ .image_size = SE_BL2_PARTITION_SIZE, -+ .image_offset = SE_BL2_PARTITION_BANK_OFFSET, -+ .image_guid = { -+ .time_low = 0xf1d883f9, -+ .time_mid = 0xdfeb, -+ .time_hi_and_version = 0x5363, -+ .clock_seq_and_node = {0x98, 0xd8, 0x68, 0x6e, 0xe3, 0xb6, 0x9f, 0x4f} -+ }, -+ }, -+ // tfm_s_signed -+ { -+ .image_size = TFM_PARTITION_SIZE, -+ .image_offset = TFM_PARTITION_BANK_OFFSET, -+ .image_guid = { -+ .time_low = 0x7fad470e, -+ .time_mid = 0x5ec5, -+ .time_hi_and_version = 0x5c03, -+ .clock_seq_and_node = {0xa2, 0xc1, 0x47, 0x56, 0xb4, 0x95, 0xde, 0x61} -+ }, -+ }, -+ // signed_fip-corstone1000 -+ { -+ .image_size = FIP_PARTITION_SIZE, -+ .image_offset = FIP_PARTITION_BANK_OFFSET, -+ .image_guid = { -+ .time_low = 0xf1933675, -+ .time_mid = 0x5a8c, -+ .time_hi_and_version = 0x5b6d, -+ .clock_seq_and_node = {0x9e, 0xf4, 0x84, 0x67, 0x39, 0xe8, 0x9b, 0xc8} -+ }, -+ }, -+ // Image.gz-initramfs-corstone1000-fvp -+ { -+ .image_size = INITRAMFS_PARTITION_SIZE, -+ .image_offset = INITRAMFS_PARTITION_BANK_OFFSET, -+ .image_guid = { -+ .time_low = 0xf771aff9, -+ .time_mid = 0xc7e9, -+ .time_hi_and_version = 0x5f99, -+ .clock_seq_and_node = {0x9e, 0xda, 0x23, 0x69, 0xdd, 0x69, 0x4f, 0x61} -+ }, -+ }, -+#else -+ // MPS3 payloads GUIDs -+ // bl2_signed payload GUID -+ { -+ .image_size = SE_BL2_PARTITION_SIZE, -+ .image_offset = SE_BL2_PARTITION_BANK_OFFSET, -+ .image_guid = { -+ .time_low = 0xfbfbefaa, -+ .time_mid = 0x0a56, -+ .time_hi_and_version = 0x50d5, -+ .clock_seq_and_node = {0xb6, 0x51, 0x74, 0x09, 0x1d, 0x3d, 0x62, 0xcf} -+ }, -+ }, -+ // tfm_s_signed -+ { -+ .image_size = TFM_PARTITION_SIZE, -+ .image_offset = TFM_PARTITION_BANK_OFFSET, -+ .image_guid = { -+ .time_low = 0xaf4cc7ad, -+ .time_mid = 0xee2e, -+ .time_hi_and_version = 0x5a39, -+ .clock_seq_and_node = {0xaa, 0xd5, 0xfa, 0xc8, 0xa1, 0xe6, 0x17, 0x3c} -+ }, -+ }, -+ // signed_fip-corstone1000 -+ { -+ .image_size = FIP_PARTITION_SIZE, -+ .image_offset = FIP_PARTITION_BANK_OFFSET, -+ .image_guid = { -+ .time_low = 0x55302f96, -+ .time_mid = 0xc4f0, -+ .time_hi_and_version = 0x5cf9, -+ .clock_seq_and_node = {0x86, 0x24, 0xe7, 0xcc, 0x38, 0x8f, 0x2b, 0x68} -+ }, -+ }, -+ // Image.gz-initramfs-corstone1000-mps3 -+ { -+ .image_size = INITRAMFS_PARTITION_SIZE, -+ .image_offset = INITRAMFS_PARTITION_BANK_OFFSET, -+ .image_guid = { -+ .time_low = 0x3e8ac972, -+ .time_mid = 0xc33c, -+ .time_hi_and_version = 0x5cc9, -+ .clock_seq_and_node = {0x90, 0xa0, 0xcd, 0xd3, 0x15, 0x96, 0x83, 0xea} -+ }, -+ }, -+#endif -+}; -+ -+struct fwu_metadata _metadata; -+ -+bool is_initialized = false; -+bool is_installed = false; -+ -+fmp_header_image_info_t fmp_header_image_info[FWU_COMPONENT_NUMBER]; -+struct fwu_esrt_data_wrapper esrt; -+ -+#define IMAGE_ACCEPTED (1) -+#define IMAGE_NOT_ACCEPTED (0) -+#define BANK_0 (0) -+#define BANK_1 (1) -+#define INVALID_VERSION (0xffffffff) -+#define INVALID_IMAGE (0xf) -+ -+#ifndef FWU_METADATA_FLASH_DEV -+ #ifndef FLASH_DEV_NAME -+ #error "FWU_METADATA_FLASH_DEV or FLASH_DEV_NAME must be defined in flash_layout.h" -+ #else -+ #define FWU_METADATA_FLASH_DEV FLASH_DEV_NAME -+ #endif -+#endif -+ -+/* Import the CMSIS flash device driver */ -+extern ARM_DRIVER_FLASH FWU_METADATA_FLASH_DEV; -+ -+#define SYSTICK_PER_MINUTE 60 -+#define BOOT_TIME_IN_MINUTES 6 -+#define HOST_ACK_SYSTICK_TIMEOUT (BOOT_TIME_IN_MINUTES * SYSTICK_PER_MINUTE) /* Number of system ticks to be precise. -+ * This is the value decided after monitoring the total time -+ * taken by the host to boot both on FVP and FPGA. -+ */ -+ -+#ifdef BL1_BUILD -+static psa_status_t private_metadata_read( -+ struct fwu_private_metadata* priv_metadata) -+{ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if (!priv_metadata) { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ int ret = FWU_METADATA_FLASH_DEV.ReadData(FWU_PRIVATE_METADATA_REPLICA_1_OFFSET, priv_metadata, -+ sizeof(*priv_metadata)); -+ if (ret < 0) { -+ FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (ret != sizeof(*priv_metadata)) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata read (expected %zu, got %d)\n\r", -+ __func__, sizeof(*priv_metadata), ret); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ FWU_LOG_MSG("%s: success: boot_index = %u\n\r", __func__, -+ priv_metadata->boot_index); -+ -+ return PSA_SUCCESS; -+} -+#else -+static psa_status_t private_metadata_read( -+ struct fwu_private_metadata* priv_metadata) -+{ -+ partition_entry_t *part; -+ uuid_t private_uuid = PRIVATE_METADATA_TYPE_UUID; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if (!priv_metadata) { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ part = get_partition_entry_by_type(&private_uuid); -+ if (!part) { -+ FWU_LOG_MSG("Private metadata partition not found\n\r"); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ int ret = FWU_METADATA_FLASH_DEV.ReadData(part->start, priv_metadata, -+ sizeof(*priv_metadata)); -+ if (ret < 0) { -+ FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (ret != sizeof(*priv_metadata)) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata read (expected %zu, got %d)\n\r", -+ __func__, sizeof(*priv_metadata), ret); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ FWU_LOG_MSG("%s: success: boot_index = %u\n\r", __func__, -+ priv_metadata->boot_index); -+ -+ return PSA_SUCCESS; -+} -+#endif -+ -+#ifdef BL1_BUILD -+static psa_status_t private_metadata_write( -+ struct fwu_private_metadata* priv_metadata) -+{ -+ FWU_LOG_MSG("%s: enter: boot_index = %u\n\r", __func__, -+ priv_metadata->boot_index); -+ -+ if (!priv_metadata) { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ int ret = FWU_METADATA_FLASH_DEV.EraseSector(FWU_PRIVATE_METADATA_REPLICA_1_OFFSET); -+ if (ret != ARM_DRIVER_OK) { -+ FWU_LOG_MSG("%s: ERROR - Flash erase failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ ret = FWU_METADATA_FLASH_DEV.ProgramData(FWU_PRIVATE_METADATA_REPLICA_1_OFFSET, -+ priv_metadata, sizeof(*priv_metadata)); -+ if (ret < 0) { -+ FWU_LOG_MSG("%s: ERROR - Flash write failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (ret != sizeof(*priv_metadata)) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata write (expected %zu, written %d)\n\r", -+ __func__, sizeof(*priv_metadata), ret); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ FWU_LOG_MSG("%s: success\n\r", __func__); -+ return PSA_SUCCESS; -+} -+#else -+static psa_status_t private_metadata_write( -+ struct fwu_private_metadata* priv_metadata) -+{ -+ uuid_t private_uuid = PRIVATE_METADATA_TYPE_UUID; -+ partition_entry_t *part; -+ -+ FWU_LOG_MSG("%s: enter: boot_index = %u\n\r", __func__, -+ priv_metadata->boot_index); -+ -+ if (!priv_metadata) { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ part = get_partition_entry_by_type(&private_uuid); -+ if (!part) { -+ FWU_LOG_MSG("Private metadata partition not found\n\r"); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ int ret = FWU_METADATA_FLASH_DEV.EraseSector(part->start); -+ if (ret != ARM_DRIVER_OK) { -+ FWU_LOG_MSG("%s: ERROR - Flash erase failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ ret = FWU_METADATA_FLASH_DEV.ProgramData(part->start, -+ priv_metadata, sizeof(*priv_metadata)); -+ if (ret < 0) { -+ FWU_LOG_MSG("%s: ERROR - Flash write failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (ret != sizeof(*priv_metadata)) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata write (expected %zu, written %d)\n\r", -+ __func__, sizeof(*priv_metadata), ret); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ FWU_LOG_MSG("%s: success\n\r", __func__); -+ return PSA_SUCCESS; -+} -+#endif -+ -+static psa_status_t metadata_validate(struct fwu_metadata *metadata) -+{ -+ FWU_LOG_MSG("%s: enter:\n\r", __func__); -+ -+ if (!metadata) { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ uint32_t calculated_crc32 = crc32((uint8_t *)&(metadata->version), -+ sizeof(*metadata) - sizeof(uint32_t)); -+ -+ if (metadata->crc_32 != calculated_crc32) { -+ FWU_LOG_MSG("%s: failed: crc32 calculated: 0x%x, given: 0x%x\n\r", __func__, -+ calculated_crc32, metadata->crc_32); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ FWU_LOG_MSG("%s: success\n\r", __func__); -+ -+ return PSA_SUCCESS; -+} -+ -+#ifdef BL1_BUILD -+static psa_status_t metadata_read_without_validation(struct fwu_metadata *metadata) -+{ -+ FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -+ FWU_METADATA_REPLICA_1_OFFSET, sizeof(*metadata)); -+ -+ if (!metadata) { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ int ret = FWU_METADATA_FLASH_DEV.ReadData(FWU_METADATA_REPLICA_1_OFFSET, -+ metadata, sizeof(*metadata)); -+ if (ret < 0) { -+ FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (ret != sizeof(*metadata)) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata read (expected %zu, got %d)\n\r", -+ __func__, sizeof(*metadata), ret); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -+ metadata->active_index, metadata->previous_active_index); -+ -+ return PSA_SUCCESS; -+} -+#else -+static psa_status_t metadata_read_without_validation(struct fwu_metadata *metadata) -+{ -+ uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID; -+ partition_entry_t *part; -+ -+ if (!metadata) { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ part = get_partition_entry_by_type(&metadata_uuid); -+ if (!part) { -+ FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -+ part->start, sizeof(*metadata)); -+ -+ -+ int ret = FWU_METADATA_FLASH_DEV.ReadData(part->start, -+ metadata, sizeof(*metadata)); -+ if (ret < 0) { -+ FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (ret != sizeof(*metadata)) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata read (expected %zu, got %d)\n\r", -+ __func__, sizeof(*metadata), ret); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -+ metadata->active_index, metadata->previous_active_index); -+ -+ return PSA_SUCCESS; -+} -+#endif -+ -+#ifdef BL1_BUILD -+static psa_status_t metadata_read(struct fwu_metadata *metadata, uint8_t replica_num) -+{ -+ uint32_t replica_offset = 0; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if (!metadata) { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ if (replica_num == 1) { -+ replica_offset = FWU_METADATA_REPLICA_1_OFFSET; -+ } else if (replica_num == 2) { -+ replica_offset = FWU_METADATA_REPLICA_2_OFFSET; -+ } else { -+ FWU_LOG_MSG("%s: replica_num must be 1 or 2\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ FWU_LOG_MSG("%s: flash addr = %u, size = %d\n\r", __func__, -+ replica_offset, sizeof(*metadata)); -+ -+ -+ int ret = FWU_METADATA_FLASH_DEV.ReadData(replica_offset, -+ metadata, sizeof(*metadata)); -+ if (ret < 0) { -+ FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (ret != sizeof(*metadata)) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata read (expected %zu, got %d)\n\r", -+ __func__, sizeof(*metadata), ret); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ if (metadata_validate(metadata) != PSA_SUCCESS) { -+ FWU_LOG_MSG("%s: ERROR - Metadata validation failed\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -+ metadata->active_index, metadata->previous_active_index); -+ -+ return PSA_SUCCESS; -+} -+#else -+static psa_status_t metadata_read(struct fwu_metadata *metadata, uint8_t replica_num) -+{ -+ uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID; -+ partition_entry_t *part; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if (!metadata) { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ if (replica_num == 1) { -+ part = get_partition_entry_by_type(&metadata_uuid); -+ } else if (replica_num == 2) { -+ part = get_partition_replica_by_type(&metadata_uuid); -+ } else { -+ FWU_LOG_MSG("%s: replica_num must be 1 or 2\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ if (!part) { -+ FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -+ part->start, sizeof(*metadata)); -+ -+ int ret = FWU_METADATA_FLASH_DEV.ReadData(part->start, -+ metadata, sizeof(*metadata)); -+ if (ret < 0) { -+ FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (ret != sizeof(*metadata)) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata read (expected %zu, got %d)\n\r", -+ __func__, sizeof(*metadata), ret); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ if (metadata_validate(metadata) != PSA_SUCCESS) { -+ FWU_LOG_MSG("%s: ERROR - Metadata validation failed\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -+ metadata->active_index, metadata->previous_active_index); -+ -+ return PSA_SUCCESS; -+} -+#endif -+ -+ -+#ifdef BL1_BUILD -+static psa_status_t metadata_write( -+ struct fwu_metadata *metadata, uint8_t replica_num) -+{ -+ uint32_t replica_offset = 0; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if (!metadata) { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ if (replica_num == 1) { -+ replica_offset = FWU_METADATA_REPLICA_1_OFFSET; -+ } else if (replica_num == 2) { -+ replica_offset = FWU_METADATA_REPLICA_2_OFFSET; -+ } else { -+ FWU_LOG_MSG("%s: replica_num must be 1 or 2\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -+ replica_offset, sizeof(*metadata)); -+ -+ -+ int ret = FWU_METADATA_FLASH_DEV.EraseSector(replica_offset); -+ if (ret != ARM_DRIVER_OK) { -+ FWU_LOG_MSG("%s: ERROR - Flash erase failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ ret = FWU_METADATA_FLASH_DEV.ProgramData(replica_offset, -+ metadata, sizeof(*metadata)); -+ if (ret < 0) { -+ FWU_LOG_MSG("%s: ERROR - Flash write failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (ret != sizeof(*metadata)) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata write (expected %zu, written %d)\n\r", -+ __func__, sizeof(*metadata), ret); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -+ metadata->active_index, metadata->previous_active_index); -+ return PSA_SUCCESS; -+} -+#else -+static psa_status_t metadata_write( -+ struct fwu_metadata *metadata, uint8_t replica_num) -+{ -+ uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID; -+ partition_entry_t *part; -+ -+ if (!metadata) { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ if (replica_num == 1) { -+ part = get_partition_entry_by_type(&metadata_uuid); -+ } else if (replica_num == 2) { -+ part = get_partition_replica_by_type(&metadata_uuid); -+ } else { -+ FWU_LOG_MSG("%s: replica_num must be 1 or 2\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ if (!part) { -+ FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -+ part->start, sizeof(*metadata)); -+ -+ int ret = FWU_METADATA_FLASH_DEV.EraseSector(part->start); -+ if (ret != ARM_DRIVER_OK) { -+ FWU_LOG_MSG("%s: ERROR - Flash erase failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ ret = FWU_METADATA_FLASH_DEV.ProgramData(part->start, -+ metadata, sizeof(*metadata)); -+ if (ret < 0) { -+ FWU_LOG_MSG("%s: ERROR - Flash write failed (ret = %d)\n\r", __func__, ret); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (ret != sizeof(*metadata)) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata write (expected %zu, written %d)\n\r", -+ __func__, sizeof(*metadata), ret); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -+ metadata->active_index, metadata->previous_active_index); -+ return PSA_SUCCESS; -+} -+#endif -+ -+static psa_status_t metadata_write_both_replica( -+ struct fwu_metadata *metadata) -+{ -+ psa_status_t ret = PSA_ERROR_GENERIC_ERROR; -+ -+ ret = metadata_write(metadata, 1); -+ if (ret) { -+ return ret; -+ } -+ -+ ret = metadata_write(metadata, 2); -+ if (ret) { -+ return ret; -+ } -+ -+ return PSA_SUCCESS; -+} -+ -+psa_status_t fwu_metadata_check_and_correct_integrity(void) -+{ -+ psa_status_t ret_replica_1 = PSA_ERROR_GENERIC_ERROR; -+ psa_status_t ret_replica_2 = PSA_ERROR_GENERIC_ERROR; -+ -+ /* Check integrity of both metadata replica */ -+ ret_replica_1 = metadata_read(&_metadata, 1); -+ ret_replica_2 = metadata_read(&_metadata, 2); -+ -+ if (ret_replica_1 != PSA_SUCCESS && ret_replica_2 != PSA_SUCCESS) { -+ return PSA_ERROR_GENERIC_ERROR; -+ } else if (ret_replica_1 == PSA_SUCCESS && ret_replica_2 != PSA_SUCCESS) { -+ metadata_read(&_metadata, 1); -+ metadata_write(&_metadata, 2); -+ } else if (ret_replica_1 != PSA_SUCCESS && ret_replica_2 == PSA_SUCCESS) { -+ metadata_read(&_metadata, 2); -+ metadata_write(&_metadata, 1); -+ } -+ -+ return PSA_SUCCESS; -+} -+ -+psa_status_t fwu_metadata_init(void) -+{ -+ psa_status_t ret; -+ ARM_FLASH_INFO* flash_info; -+ -+#ifndef BL1_BUILD -+ plat_io_storage_init(); -+ partition_init(PLATFORM_GPT_IMAGE); -+#endif -+ -+ if (is_initialized) { -+ return PSA_SUCCESS; -+ } -+ -+ /* Code assumes everything fits into a sector */ -+ if (sizeof(struct fwu_metadata) > FWU_METADATA_FLASH_SECTOR_SIZE) { -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ if (sizeof(struct fwu_private_metadata) > FWU_METADATA_FLASH_SECTOR_SIZE) { -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ ret = FWU_METADATA_FLASH_DEV.Initialize(NULL); -+ if (ret != ARM_DRIVER_OK) { -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ flash_info = FWU_METADATA_FLASH_DEV.GetInfo(); -+ if (flash_info->program_unit != 1) { -+ FWU_METADATA_FLASH_DEV.Uninitialize(); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ is_initialized = true; -+ -+ return PSA_SUCCESS; -+} -+ -+static bool skip_metadata_provision(void) -+{ -+ metadata_read(&_metadata, 1); -+ return (((_metadata.active_index < 2) || (_metadata.previous_active_index < 2)) -+ && (_metadata.active_index ^ _metadata.previous_active_index) -+ ); -+} -+ -+static psa_status_t fwu_metadata_configure(void) -+{ -+ /* Provision FWU Agent Metadata */ -+ -+ psa_status_t ret; -+ uint32_t image_version = FWU_IMAGE_INITIAL_VERSION; -+ -+ memset(&_metadata, 0, sizeof(struct fwu_metadata)); -+ -+ _metadata.version = FWU_METADATA_VERSION; -+ _metadata.active_index = BANK_0; -+ _metadata.previous_active_index = BANK_1; -+ _metadata.desc_offset= FWU_FW_STORE_DESC_OFFSET; -+ _metadata.metadata_size = sizeof(struct fwu_metadata); -+ -+ _metadata.fw_desc.num_banks = NR_OF_FW_BANKS; -+ _metadata.fw_desc.num_images = NR_OF_IMAGES_IN_FW_BANK; -+ _metadata.fw_desc.img_entry_size = sizeof(struct fwu_image_entry) * NR_OF_IMAGES_IN_FW_BANK; -+ _metadata.fw_desc.bank_info_entry_size = sizeof(struct fwu_image_properties) * NR_OF_FW_BANKS; -+ _metadata.bank_state[BANK_0] = FWU_BANK_ACCEPTED; -+ _metadata.bank_state[BANK_1] = FWU_BANK_ACCEPTED; -+ /* bank 0 is the place where images are located at the -+ * start of device lifecycle */ -+ -+ for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) { -+ -+ _metadata.fw_desc.img_entry[i].img_props[BANK_0].accepted = IMAGE_ACCEPTED; -+ _metadata.fw_desc.img_entry[i].img_props[BANK_0].version = image_version; -+ memcpy(&(_metadata.fw_desc.img_entry[i].img_props[BANK_0].img_uuid), (const void *)&fwu_image[i].image_guid, sizeof(struct efi_guid)); -+ -+ _metadata.fw_desc.img_entry[i].img_props[BANK_1].accepted = INVALID_IMAGE; -+ _metadata.fw_desc.img_entry[i].img_props[BANK_1].version = INVALID_VERSION; -+ memcpy(&(_metadata.fw_desc.img_entry[i].img_props[BANK_1].img_uuid), (const void *)&fwu_image[i].image_guid, sizeof(struct efi_guid)); -+ } -+ -+ /* Calculate CRC32 for fwu metadata. The first filed in the _metadata has to be the crc_32. -+ * This should be omited from the calculation. */ -+ _metadata.crc_32 = crc32((uint8_t *)&_metadata.version, -+ sizeof(struct fwu_metadata) - sizeof(uint32_t)); -+ -+ ret = metadata_write_both_replica(&_metadata); -+ if (ret) { -+ return ret; -+ } -+ -+ memset(&_metadata, 0, sizeof(_metadata)); -+ ret = metadata_read(&_metadata, 1); -+ if (ret) { -+ return ret; -+ } -+ FWU_LOG_MSG("%s: provisioned values: active = %u, previous = %d\n\r", -+ __func__, _metadata.active_index, _metadata.previous_active_index); -+ return PSA_SUCCESS; -+ -+} -+ -+static psa_status_t fwu_private_metadata_configure(void) -+{ -+ /* Provision Private metadata for update agent which is shared -+ beween BL1 and tf-m of secure enclave */ -+ -+ psa_status_t ret; -+ struct fwu_private_metadata priv_metadata; -+ -+ memset(&priv_metadata, 0, sizeof(struct fwu_private_metadata)); -+ -+ priv_metadata.boot_index = BANK_0; -+ priv_metadata.boot_attempted = 0; -+ -+ for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) { -+ priv_metadata.fmp_version[i] = FWU_IMAGE_INITIAL_VERSION; -+ priv_metadata.fmp_last_attempt_version[i] = FWU_IMAGE_INITIAL_VERSION; -+ priv_metadata.fmp_last_attempt_status[i] = LAST_ATTEMPT_STATUS_SUCCESS; -+ } -+ ret = private_metadata_write(&priv_metadata); -+ if (ret) { -+ return ret; -+ } -+ -+ memset(&priv_metadata, 0, sizeof(struct fwu_private_metadata)); -+ ret = private_metadata_read(&priv_metadata); -+ if (ret) { -+ return ret; -+ } -+ FWU_LOG_MSG("%s: provisioned values: boot_index = %u\n\r", __func__, -+ priv_metadata.boot_index); -+ return PSA_SUCCESS; -+} -+ -+psa_status_t fwu_metadata_provision(void) -+{ -+ psa_status_t ret; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ ret = fwu_metadata_init(); -+ if (ret) { -+ FWU_LOG_MSG("%s: ERROR FWU Metadata init failed \n\r", __func__); -+ return ret; -+ } -+ -+ /* -+ * check by chance if the previous reboot -+ * had a firmware data?. If yes, then don't initialize -+ * metadata -+ */ -+ if(skip_metadata_provision()) { -+ FWU_LOG_MSG("%s: Skipping Metadata provisioning \n\r", __func__); -+ return PSA_SUCCESS; -+ } -+ -+ ret = fwu_metadata_configure(); -+ if(ret) { -+ FWU_LOG_MSG("%s: ERROR FWU Metadata configure failed \n\r", __func__); -+ return ret; -+ } -+ -+ ret = fwu_private_metadata_configure(); -+ if(ret) { -+ FWU_LOG_MSG("%s: ERROR FWU Private Metadata configure failed \n\r", __func__); -+ return ret; -+ } -+ -+ FWU_LOG_MSG("%s: FWU METADATA PROVISIONED.\n\r", __func__); -+ return PSA_SUCCESS; -+} -+ -+static uint8_t get_fwu_image_state( -+ struct fwu_metadata *metadata, -+ struct fwu_private_metadata *priv_metadata, -+ uint32_t fwu_image_index) -+{ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if ((metadata->fw_desc.img_entry[fwu_image_index].img_props[metadata->active_index].accepted) -+ == (IMAGE_NOT_ACCEPTED)) { -+ FWU_LOG_MSG("%s: exit: Image %d PSA_FWU_TRIAL\n\r", __func__, fwu_image_index); -+ return PSA_FWU_TRIAL; -+ } -+ -+ FWU_LOG_MSG("%s: exit: Image %d PSA_FWU_READY\n\r", __func__, fwu_image_index); -+ return PSA_FWU_READY; -+} -+ -+static uint8_t get_fwu_agent_state( -+ struct fwu_metadata *metadata, -+ struct fwu_private_metadata *priv_metadata) -+{ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if (priv_metadata->boot_index != metadata->active_index) { -+ FWU_LOG_MSG("%s: exit: FWU Agent PSA_FWU_TRIAL (index mismatch)\n\r", __func__); -+ return PSA_FWU_TRIAL; -+ } -+ -+ for (int i=0; i < NR_OF_IMAGES_IN_FW_BANK; i++) { -+ if(get_fwu_image_state(metadata, priv_metadata, i) == PSA_FWU_TRIAL) { -+ FWU_LOG_MSG("%s: exit: FWU Agent PSA_FWU_TRIAL (an image still is in trial state)\n\r", __func__); -+ return PSA_FWU_TRIAL; -+ } -+ } -+ -+ FWU_LOG_MSG("%s: exit: FWU Agent PSA_FWU_READY\n\r", __func__); -+ return PSA_FWU_READY; -+} -+ -+static psa_status_t erase_image(uint32_t image_offset, uint32_t image_size) -+{ -+ int ret; -+ uint32_t sectors; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if ((image_offset % FWU_METADATA_FLASH_SECTOR_SIZE) != 0) { -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ if ((image_size % FWU_METADATA_FLASH_SECTOR_SIZE) != 0) { -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ sectors = image_size / FWU_METADATA_FLASH_SECTOR_SIZE; -+ -+ FWU_LOG_MSG("%s: erasing sectors = %u, from offset = %u\n\r", __func__, -+ sectors, image_offset); -+ -+ for (int i = 0; i < sectors; i++) { -+ ret = FWU_METADATA_FLASH_DEV.EraseSector( -+ image_offset + (i * FWU_METADATA_FLASH_SECTOR_SIZE)); -+ if (ret != ARM_DRIVER_OK) { -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ } -+ -+ FWU_LOG_MSG("%s: exit\n\r", __func__); -+ return PSA_SUCCESS; -+} -+ -+static psa_status_t fwu_select_previous( -+ struct fwu_metadata *metadata, -+ struct fwu_private_metadata *priv_metadata) -+{ -+ psa_status_t ret; -+ uint8_t current_state; -+ uint32_t index; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ /* it is expected to receive this call only when -+ in trial state */ -+ current_state = get_fwu_agent_state(metadata, priv_metadata); -+ if (current_state != PSA_FWU_TRIAL) { -+ return PSA_ERROR_BAD_STATE; -+ } -+ -+ /* not expected to receive this call in this state, system -+ * did not boot from previous active index */ -+ if (metadata->previous_active_index != priv_metadata->boot_index) { -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ FWU_LOG_MSG("%s: trial state: active index = %u, previous active = %u\n\r", -+ __func__, metadata->active_index, metadata->previous_active_index); -+ -+ index = metadata->previous_active_index; -+ for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) { -+ if (metadata->fw_desc.img_entry[i].img_props[index].accepted != IMAGE_ACCEPTED) -+ { -+ FWU_ASSERT(0); -+ } -+ } -+ -+ index = metadata->active_index; -+ metadata->bank_state[index] = FWU_BANK_INVALID; -+ metadata->active_index = metadata->previous_active_index; -+ metadata->previous_active_index = index; -+ -+ priv_metadata->boot_attempted = 0; -+ -+ ret = private_metadata_write(priv_metadata); -+ if (ret) { -+ return ret; -+ } -+ metadata->crc_32 = crc32((uint8_t *)&metadata->version, -+ sizeof(struct fwu_metadata) - sizeof(uint32_t)); -+ -+ ret = metadata_write_both_replica(metadata); -+ if (ret) { -+ return ret; -+ } -+ -+ FWU_LOG_MSG("%s: in regular state by choosing previous active bank\n\r", -+ __func__); -+ -+ FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -+ return ret; -+ -+} -+ -+void bl1_get_active_bl2_image(uint32_t *offset) -+{ -+ struct fwu_private_metadata priv_metadata; -+ uint8_t current_state; -+ uint32_t boot_attempted; -+ uint32_t boot_index; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if (fwu_metadata_init()) { -+ FWU_ASSERT(0); -+ } -+ -+ if (private_metadata_read(&priv_metadata)) { -+ FWU_ASSERT(0); -+ } -+ -+ if (metadata_read(&_metadata, 1)) { -+ FWU_ASSERT(0); -+ } -+ -+ current_state = get_fwu_agent_state(&_metadata, &priv_metadata); -+ -+ if (current_state == PSA_FWU_READY) { -+ boot_index = _metadata.active_index; -+ FWU_ASSERT(boot_index == priv_metadata.boot_index); -+ boot_attempted = 0; -+ } else if (current_state == PSA_FWU_TRIAL) { -+ boot_attempted = (++priv_metadata.boot_attempted); -+ FWU_LOG_MSG("%s: attempting boot number = %u\n\r", -+ __func__, boot_attempted); -+ if (boot_attempted <= MAX_BOOT_ATTEMPTS_PER_BANK) { -+ boot_index = _metadata.active_index; -+ FWU_LOG_MSG("%s: booting from trial bank: %u\n\r", -+ __func__, boot_index); -+ } else if (boot_attempted <= (2 * MAX_BOOT_ATTEMPTS_PER_BANK)) { -+ boot_index = _metadata.previous_active_index; -+ FWU_LOG_MSG("%s: gave up booting from trial bank\n\r", __func__); -+ FWU_LOG_MSG("%s: booting from previous active bank: %u\n\r", -+ __func__, boot_index); -+ } else { -+ FWU_LOG_MSG("%s: cannot boot system from any bank, halting...\n\r", __func__); -+ FWU_ASSERT(0); -+ } -+ } else { -+ FWU_ASSERT(0); -+ } -+ -+ priv_metadata.boot_index = boot_index; -+ if (private_metadata_write(&priv_metadata) < 0) { -+ FWU_ASSERT(0); -+ } -+ -+ if (boot_index == BANK_0) { -+ *offset = SE_BL2_BANK_0_OFFSET; -+ } else if (boot_index == BANK_1) { -+ *offset = SE_BL2_BANK_1_OFFSET; -+ } else { -+ FWU_ASSERT(0); -+ } -+ -+ FWU_LOG_MSG("%s: exit: booting from bank = %u, offset = 0x%x\n\r", __func__, -+ boot_index, *offset); -+ -+ return; -+} -+ -+uint8_t bl2_get_boot_bank(void) -+{ -+ uint8_t boot_index; -+ struct fwu_private_metadata priv_metadata; -+ FWU_LOG_MSG("%s: enter", __func__); -+ if (fwu_metadata_init()) { -+ FWU_ASSERT(0); -+ } -+ if (private_metadata_read(&priv_metadata)) { -+ FWU_ASSERT(0); -+ } -+ boot_index = priv_metadata.boot_index; -+ FWU_LOG_MSG("%s: exit: booting from bank = %u", __func__, boot_index); -+ return boot_index; -+} -+ -+static void disable_host_ack_timer(void) -+{ -+ FWU_LOG_MSG("%s: timer to reset is disabled\n\r", __func__); -+ SysTick->CTRL &= (~SysTick_CTRL_ENABLE_Msk); -+} -+ -+static psa_status_t update_nv_counters( -+ struct fwu_private_metadata* priv_metadata) -+{ -+ enum tfm_plat_err_t err; -+ uint32_t security_cnt; -+ enum tfm_nv_counter_t tfm_nv_counter_i; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ /* The FWU_BL2_NV_COUNTER (0) is not mirrored in the private metadata. It is -+ * directly updated in the bl1_2_validate_image_at_addr() function, in -+ * tfm/bl1/bl1_2/main.c. -+ * Because of this, the index starts from FWU_TFM_NV_COUNTER (1). */ -+ for (int i = FWU_TFM_NV_COUNTER; i <= FWU_MAX_NV_COUNTER_INDEX; i++) { -+ -+ switch (i) { -+ case FWU_TFM_NV_COUNTER: -+ tfm_nv_counter_i = PLAT_NV_COUNTER_BL2_0; -+ break; -+ case FWU_TFA_NV_COUNTER: -+ tfm_nv_counter_i = PLAT_NV_COUNTER_BL2_1; -+ break; -+ default: -+ FWU_ASSERT(0); -+ break; -+ } -+ -+ err = tfm_plat_read_nv_counter(tfm_nv_counter_i, -+ sizeof(security_cnt), (uint8_t *)&security_cnt); -+ if (err != TFM_PLAT_ERR_SUCCESS) { -+ FWU_LOG_MSG("%s: couldn't read NV counter\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ if (priv_metadata->nv_counter[i] < security_cnt) { -+ FWU_LOG_MSG("%s: staged NV counter is smaller than current value\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } else if (priv_metadata->nv_counter[i] > security_cnt) { -+ FWU_LOG_MSG("%s: updating index = %u nv counter = %u->%u\n\r", -+ __func__, i, security_cnt, -+ priv_metadata->nv_counter[i]); -+ err = tfm_plat_set_nv_counter(tfm_nv_counter_i, -+ priv_metadata->nv_counter[i]); -+ if (err != TFM_PLAT_ERR_SUCCESS) { -+ FWU_LOG_MSG("%s: couldn't write NV counter\n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ } -+ -+ } -+ -+ FWU_LOG_MSG("%s: exit\n\r", __func__); -+ return PSA_SUCCESS; -+} -+ -+psa_status_t corstone1000_fwu_host_ack(void) -+{ -+ psa_status_t ret; -+ struct fwu_private_metadata priv_metadata; -+ uint8_t current_state; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if (!is_initialized) { -+ return PSA_ERROR_BAD_STATE; -+ } -+ -+ Select_Write_Mode_For_Shared_Flash(); -+ -+ /* This cannot be added to the fwu_metadata_init() because that function is -+ * called before the logging is enabled by TF-M. */ -+ ret = fwu_metadata_check_and_correct_integrity(); -+ if (ret != PSA_SUCCESS) { -+ FWU_LOG_MSG("fwu_metadata_check_and_correct_integrity failed\r\n"); -+ return ret; -+ } -+ -+ if (metadata_read(&_metadata, 1)) { -+ ret = PSA_ERROR_GENERIC_ERROR; -+ goto out; -+ } -+ -+ if (private_metadata_read(&priv_metadata)) { -+ ret = PSA_ERROR_GENERIC_ERROR; -+ goto out; -+ } -+ -+ current_state = get_fwu_agent_state(&_metadata, &priv_metadata); -+ if (current_state == PSA_FWU_READY) { -+ -+ 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]); -+ } -+ -+ goto out; -+ -+ } else if (current_state != PSA_FWU_TRIAL) { -+ FWU_ASSERT(0); -+ } -+ -+ if (_metadata.active_index != priv_metadata.boot_index) { -+ -+ /* firmware update failed, revert back to previous bank */ -+ -+ 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); -+ -+ } -+ -+ if (ret == PSA_SUCCESS) { -+ disable_host_ack_timer(); -+ 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]); -+ } -+ } -+ -+out: -+ Select_XIP_Mode_For_Shared_Flash(); -+ -+ FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -+ return ret; -+} -+ -+static int systic_counter = 0; -+ -+void SysTick_Handler(void) -+{ -+ systic_counter++; -+ if (systic_counter % 10 == 0) { -+ SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; -+ stdio_output_string("*", 1); -+ SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; -+ } -+ if (systic_counter == HOST_ACK_SYSTICK_TIMEOUT) { -+ SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; -+ stdio_output_string("timer expired!\n\r", -+ sizeof("timer expired!\n\r")); -+ NVIC_SystemReset(); -+ } -+} -+ -+/* When in trial state, start the timer for host to respond. -+ * Diable timer when host responds back either by calling -+ * corstone1000_fwu_accept_image or corstone1000_fwu_select_previous. -+ * Otherwise, resets the system. -+ */ -+void host_acknowledgement_timer_to_reset(void) -+{ -+ struct fwu_private_metadata priv_metadata; -+ uint8_t current_state; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ Select_Write_Mode_For_Shared_Flash(); -+ -+ if (!is_initialized) { -+ FWU_ASSERT(0); -+ } -+ -+ if (private_metadata_read(&priv_metadata)) { -+ FWU_ASSERT(0); -+ } -+ -+ if (metadata_read(&_metadata, 1)) { -+ FWU_ASSERT(0); -+ } -+ -+ Select_XIP_Mode_For_Shared_Flash(); -+ -+ current_state = get_fwu_agent_state(&_metadata, &priv_metadata); -+ -+ if (current_state == PSA_FWU_TRIAL) { -+ FWU_LOG_MSG("%s: in trial state, starting host ack timer\n\r", -+ __func__); -+ systic_counter = 0; -+ if (SysTick_Config(SysTick_LOAD_RELOAD_Msk)) { -+ FWU_LOG_MSG("%s: timer init failed\n\r", __func__); -+ FWU_ASSERT(0); -+ } else { -+ FWU_LOG_MSG("%s: timer started: seconds to expire : %u\n\r", -+ __func__, HOST_ACK_SYSTICK_TIMEOUT); -+ } -+ } -+ -+ FWU_LOG_MSG("%s: exit\n\r", __func__); -+ return; -+} -+ -+/* stage nv counter into private metadata section of the flash. -+ * staged nv counters are written to the otp when firmware update -+ * is successful -+ * the function assumes that the api is called in the boot loading -+ * stage -+ */ -+psa_status_t fwu_stage_nv_counter(enum fwu_nv_counter_index_t index, -+ uint32_t img_security_cnt) -+{ -+ struct fwu_private_metadata priv_metadata; -+ -+ FWU_LOG_MSG("%s: enter: index = %u, val = %u\n\r", __func__, -+ index, img_security_cnt); -+ -+ if (!is_initialized) { -+ FWU_ASSERT(0); -+ } -+ -+ if (index > FWU_MAX_NV_COUNTER_INDEX) { -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ if (private_metadata_read(&priv_metadata)) { -+ FWU_ASSERT(0); -+ } -+ -+ if (priv_metadata.nv_counter[index] != img_security_cnt) { -+ priv_metadata.nv_counter[index] = img_security_cnt; -+ if (private_metadata_write(&priv_metadata)) { -+ FWU_ASSERT(0); -+ } -+ } -+ -+ FWU_LOG_MSG("%s: exit\n\r", __func__); -+ return PSA_SUCCESS; -+} -+ -+psa_status_t corstone1000_fwu_flash_image(void) -+{ -+ 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); -+} -+ -+static psa_status_t get_esrt_data(struct fwu_esrt_data_wrapper *esrt) -+{ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if (!esrt) -+ { -+ FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ psa_status_t ret; -+ struct fwu_private_metadata priv_metadata; -+ -+ Select_Write_Mode_For_Shared_Flash(); -+ -+ if (private_metadata_read(&priv_metadata)) { -+ ret = PSA_ERROR_GENERIC_ERROR; -+ goto out; -+ } -+ -+ esrt->data.fw_resource_count = NR_OF_IMAGES_IN_FW_BANK; -+ esrt->data.fw_resource_count_max = NR_OF_IMAGES_IN_FW_BANK; -+ esrt->data.fw_resource_version = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION; -+ -+ for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) -+ { -+ memcpy(&esrt->entries[i].fw_class, &fwu_image[i].image_guid, sizeof(struct efi_guid)); -+ esrt->entries[i].fw_version = priv_metadata.fmp_version[i]; -+ esrt->entries[i].lowest_supported_fw_version = FWU_IMAGE_INITIAL_VERSION; -+ esrt->entries[i].last_attempt_version = priv_metadata.fmp_last_attempt_version[i]; -+ esrt->entries[i].last_attempt_status = priv_metadata.fmp_last_attempt_status[i]; -+ } -+ ret = PSA_SUCCESS; -+ -+out: -+ Select_XIP_Mode_For_Shared_Flash(); -+ FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -+ return ret; -+} -+ -+static psa_status_t fwu_accept_image(struct fwu_metadata *metadata, -+ struct fwu_private_metadata *priv_metadata, -+ const psa_fwu_component_t *trials, -+ uint8_t number) -+{ -+ uint8_t current_state; -+ uint32_t image_bank_offset; -+ uint32_t active_bank_index; -+ uint32_t fwu_image_index; -+ psa_status_t ret; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ -+ /* booted from previous_active_bank, not expected -+ * to receive this call in this state, rather host should -+ * call corstone1000_fwu_select_previous */ -+ if (metadata->active_index != priv_metadata->boot_index) { -+ return PSA_ERROR_BAD_STATE; -+ } -+ -+ active_bank_index = metadata->active_index; -+ metadata->bank_state[active_bank_index] = FWU_BANK_ACCEPTED; -+ -+ for (int i = 0; i < number; i++) { -+ -+ if (!is_image_index_valid(trials[i])) { -+ FWU_LOG_MSG("%s: Invalid image index received \n\r", __func__); -+ continue; -+ } -+ -+ /* it is expected to receive this call only when -+ in trial state */ -+ fwu_image_index = trials[i] - FWU_FAKE_IMAGES_INDEX_COUNT; -+ -+ current_state = get_fwu_image_state(metadata, priv_metadata, fwu_image_index); -+ if (current_state != PSA_FWU_TRIAL) { -+ return PSA_ERROR_BAD_STATE; -+ } -+ -+ metadata->fw_desc.img_entry[fwu_image_index].img_props[active_bank_index].accepted = -+ IMAGE_ACCEPTED; -+ } -+ -+ priv_metadata->boot_attempted = 0; -+ -+ ret = private_metadata_write(priv_metadata); -+ if (ret) { -+ return ret; -+ } -+ metadata->crc_32 = crc32((uint8_t *)&metadata->version, -+ sizeof(struct fwu_metadata) - sizeof(uint32_t)); -+ -+ ret = metadata_write_both_replica(metadata); -+ if (ret) { -+ return ret; -+ } -+ -+ FWU_LOG_MSG("%s: exit: fwu state is changed to regular, ret - %d\n\r", __func__, ret); -+ return ret; -+} -+ -+static psa_status_t uint_to_image_version(uint32_t ver_in, psa_fwu_image_version_t *ver_out) -+{ -+ if (!ver_out) { -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ ver_out->major = (uint8_t)((ver_in >> 24) & 0xF); -+ ver_out->minor = (uint8_t)((ver_in >> 16) & 0xF); -+ ver_out->patch = (uint16_t)(ver_in & 0xFF); -+ /* There's no room for the build number in the TS */ -+ return PSA_SUCCESS; -+} -+ -+static void fmp_header_image_info_init() -+{ -+ for (int i=0; iactive_index; -+ uint32_t bank_offset; -+ uint32_t image_offset; -+ uint8_t fwu_image_index = component - FWU_FAKE_IMAGES_INDEX_COUNT; /* Decrement to get the correct fwu image index */ -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ if (active_index == BANK_0) { -+ bank_offset = BANK_1_PARTITION_OFFSET; -+ } else if (active_index == BANK_1) { -+ bank_offset = BANK_0_PARTITION_OFFSET; -+ } else { -+ FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ image_offset = bank_offset + fwu_image[fwu_image_index].image_offset; -+ if (erase_image(image_offset, fwu_image[fwu_image_index].image_size)) { -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ FWU_LOG_MSG("%s: exit: Staging area erased succesfully \n\r", __func__); -+ return PSA_SUCCESS; -+} -+ -+psa_status_t fwu_bootloader_init(void) -+{ -+ psa_status_t ret; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ ret = fwu_metadata_init(); -+ if (ret) { -+ return ret; -+ } -+ -+ /* Initialize the fmp_header_image_info object */ -+ fmp_header_image_info_init(); -+ -+ FWU_LOG_MSG("%s: exit: Initialized\n\r", __func__); -+ -+ return PSA_SUCCESS; -+} -+ -+psa_status_t fwu_bootloader_staging_area_init(psa_fwu_component_t component, -+ const void *manifest, -+ size_t manifest_size) -+{ -+ if (component >= FWU_COMPONENT_NUMBER) { -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ if (!is_initialized) { -+ return PSA_ERROR_BAD_STATE; -+ } -+ -+ psa_status_t ret; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ Select_Write_Mode_For_Shared_Flash(); -+ -+ if (metadata_read(&_metadata, 1)) { -+ ret = PSA_ERROR_GENERIC_ERROR; -+ goto out; -+ } -+ -+ ret = erase_staging_area(&_metadata, component); -+ -+out: -+ Select_XIP_Mode_For_Shared_Flash(); -+ -+ FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -+ return ret; -+} -+ -+psa_status_t parse_fmp_header(psa_fwu_component_t component, const void *block, size_t size) -+{ -+ /* Parse the incoming block to make sure complete FMP header is received */ -+ if (sizeof(fmp_header_image_info[component].fmp_hdr) >= (fmp_header_image_info[component].fmp_hdr_size_recvd + size)) { -+ memcpy(&fmp_header_image_info[component].fmp_hdr, block, size); -+ fmp_header_image_info[component].fmp_hdr_size_recvd += size; -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ if (fmp_header_image_info[component].fmp_hdr_size_recvd != sizeof(fmp_header_image_info[component].fmp_hdr)) { -+ memcpy(&fmp_header_image_info[component].fmp_hdr, -+ 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; -+ } -+ -+} -+psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component, -+ size_t block_offset, -+ const void *block, -+ size_t block_size) -+{ -+ -+ if (block == NULL) { -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ if (!is_initialized) { -+ return PSA_ERROR_BAD_STATE; -+ } -+ -+ if (!is_image_index_valid(component)) { -+ FWU_LOG_MSG("%s: Invalid Component received \n\r", __func__); -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ psa_status_t ret; -+ int drv_ret; -+ int image_index; -+ uint32_t bank_offset; -+ uint32_t active_index; -+ uint32_t previous_active_index; -+ uint32_t nr_images; -+ uint32_t current_state; -+ uint32_t image_offset; -+ uint32_t fw_version; -+ 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); -+ if(ret == PSA_ERROR_INSUFFICIENT_DATA) { -+ return PSA_SUCCESS; -+ } -+ 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; -+ } -+ } -+ -+ /* Store the version of new firmare */ -+ fw_version = fmp_header_image_info[fwu_image_index].fmp_hdr.fw_version; -+ FWU_LOG_MSG("%s: Updated info after payload header parsing: block_offset = %u, block = 0x%p, block_size = %u\n\r" -+ , __func__, block_offset, block, block_size); -+ /* Check if it is the dummy FMP or not */ -+ if (!fmp_header_image_info[fwu_image_index].fmp_hdr.header_size) -+ { -+ FWU_LOG_MSG("%s: Dummy FMP received \n\r", __func__); -+ /* Do something for dummy FMP's */ -+ return PSA_ERROR_GENERIC_ERROR; -+ } -+ -+ /* Write the block containing actual image to flash */ -+ -+ Select_Write_Mode_For_Shared_Flash(); -+ -+ if (metadata_read(&_metadata, 1)) { -+ ret = PSA_ERROR_GENERIC_ERROR; -+ goto out; -+ } -+ -+ if (private_metadata_read(&priv_metadata)) { -+ ret = PSA_ERROR_GENERIC_ERROR; -+ goto out; -+ } -+ -+ active_index = _metadata.active_index; -+ FWU_LOG_MSG("FMP version: 0x%d, metadata version : 0x%d\n", fw_version, -+ _metadata.fw_desc.img_entry[fwu_image_index].img_props[active_index].version); -+ if (fw_version <= -+ _metadata.fw_desc.img_entry[fwu_image_index].img_props[active_index].version) -+ { -+ /* 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); -+ -+ fmp_set_image_info(&fwu_image[fwu_image_index].image_guid, -+ priv_metadata.fmp_version[fwu_image_index], -+ priv_metadata.fmp_last_attempt_version[fwu_image_index], -+ 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; -+ } -+ -+ if (active_index == BANK_0) { -+ previous_active_index = BANK_1; -+ bank_offset = BANK_1_PARTITION_OFFSET; -+ } else if (active_index == BANK_1) { -+ previous_active_index = BANK_0; -+ 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; -+ } -+ -+ image_offset = bank_offset + fwu_image[fwu_image_index].image_offset; -+ -+ /* Firmware update process can only start in regular state. */ -+ current_state = get_fwu_image_state(&_metadata, &priv_metadata, fwu_image_index); -+ if (current_state != PSA_FWU_READY) { -+ ret = PSA_ERROR_BAD_STATE; -+ goto out; -+ } -+ -+ FWU_LOG_MSG("%s: writing image to the flash at offset = %u...\n\r", -+ __func__, (image_offset + fmp_header_image_info[fwu_image_index].image_size_recvd)); -+ drv_ret = FWU_METADATA_FLASH_DEV.ProgramData(image_offset + fmp_header_image_info[fwu_image_index].image_size_recvd, block, block_size); -+ FWU_LOG_MSG("%s: images are written to bank offset = %u\n\r", __func__, -+ image_offset); -+ if (drv_ret < 0 || drv_ret != block_size) { -+ FWU_LOG_MSG("Flashing image %d is not successful\n\r", component); -+ -+ /* 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); -+ -+ fmp_set_image_info(&fwu_image[fwu_image_index].image_guid, -+ priv_metadata.fmp_version[fwu_image_index], -+ priv_metadata.fmp_last_attempt_version[fwu_image_index], -+ priv_metadata.fmp_last_attempt_status[fwu_image_index]); -+ ret = PSA_OPERATION_INCOMPLETE; -+ goto out; -+ } -+ else { -+ ret = PSA_SUCCESS; -+ } -+ FWU_LOG_MSG("%s: images are written to bank return status = %u\n\r", __func__, -+ ret); -+ fmp_header_image_info[fwu_image_index].image_size_recvd += block_size; -+ -+out: -+ Select_XIP_Mode_For_Shared_Flash(); -+ -+ FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -+ return ret; -+} -+ -+static psa_status_t fwu_update_metadata(const psa_fwu_component_t *candidates, uint8_t number) -+{ -+ int ret; -+ uint32_t active_index; -+ uint32_t bank_offset; -+ uint32_t previous_active_index; -+ uint8_t fwu_image_index; -+ -+ FWU_LOG_MSG("%s: enter function\n\r", __func__); -+ -+ Select_Write_Mode_For_Shared_Flash(); -+ -+ if (metadata_read(&_metadata, 1)) { -+ ret = PSA_ERROR_GENERIC_ERROR; -+ goto out; -+ } -+ active_index = _metadata.active_index; -+ -+ if (active_index == BANK_0) { -+ previous_active_index = BANK_1; -+ bank_offset = BANK_1_PARTITION_OFFSET; -+ } else if (active_index == BANK_1) { -+ previous_active_index = BANK_0; -+ bank_offset = BANK_0_PARTITION_OFFSET; -+ } else { -+ FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index); -+ ret = PSA_ERROR_DATA_INVALID; -+ goto out; -+ } -+ -+ _metadata.active_index = previous_active_index; -+ _metadata.previous_active_index = active_index; -+ _metadata.bank_state[previous_active_index] = FWU_BANK_VALID; -+ -+ /* 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])) { -+ FWU_LOG_MSG("%s: Invalid image index received \n\r", __func__); -+ continue; -+ } -+ -+ fwu_image_index = candidates[i] - FWU_FAKE_IMAGES_INDEX_COUNT; -+ _metadata.fw_desc.img_entry[fwu_image_index].img_props[previous_active_index].accepted = -+ IMAGE_NOT_ACCEPTED; -+ _metadata.fw_desc.img_entry[fwu_image_index].img_props[previous_active_index].version = fmp_header_image_info[fwu_image_index].fmp_hdr.fw_version; -+ } -+ -+ _metadata.crc_32 = crc32((uint8_t *)&_metadata.version, -+ sizeof(struct fwu_metadata) - sizeof(uint32_t)); -+ -+ ret = metadata_write_both_replica(&_metadata); -+ if (ret) { -+ goto out; -+ } -+ -+ ret = PSA_SUCCESS; -+ -+out: -+ Select_XIP_Mode_For_Shared_Flash(); -+ -+ FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -+ return ret; -+} -+ -+static psa_status_t copy_image_from_other_bank(int image_index, -+ uint32_t active_index, -+ uint32_t previous_active_index) -+{ -+ uint32_t bank_offset[NR_OF_FW_BANKS] = {BANK_0_PARTITION_OFFSET, BANK_1_PARTITION_OFFSET}; -+ uint8_t data[FLASH_CHUNK_SIZE]; -+ size_t remaining_size = fwu_image[image_index].image_size; -+ size_t data_size; -+ size_t offset_read = bank_offset[active_index] + fwu_image[image_index].image_offset; -+ size_t offset_write = bank_offset[previous_active_index] + fwu_image[image_index].image_offset; -+ int data_transferred_count; -+ -+ FWU_LOG_MSG("%s: Enter \n\r", __func__); -+ -+ psa_status_t ret = erase_image(offset_write, fwu_image[image_index].image_size); -+ if (ret != PSA_SUCCESS) { -+ FWU_LOG_MSG("%s: ERROR - Flash erase failed for Image: %d\n\r", __func__, image_index); -+ return ret; -+ } -+ -+ while(remaining_size > 0) { -+ data_size = (remaining_size > FLASH_CHUNK_SIZE) ? FLASH_CHUNK_SIZE : remaining_size; -+ -+ /* read image data from flash */ -+ data_transferred_count = FWU_METADATA_FLASH_DEV.ReadData(offset_read, data, data_size); -+ if (data_transferred_count < 0) { -+ FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, data_transferred_count); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (data_transferred_count != data_size) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata read (expected %zu, got %d)\n\r", -+ __func__, data_size, data_transferred_count); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ 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) { -+ FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, data_transferred_count); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ if (data_transferred_count != data_size) { -+ FWU_LOG_MSG("%s: ERROR - Incomplete metadata write (expected %zu, written %d)\n\r", -+ __func__, data_size, data_transferred_count); -+ return PSA_ERROR_INSUFFICIENT_DATA; -+ } -+ -+ offset_write += data_size; -+ remaining_size -= data_size; -+ } -+ -+ FWU_LOG_MSG("%s: exit \n\r", __func__); -+ return PSA_SUCCESS; -+} -+ -+static psa_status_t maintain_bank_consistency(void) -+{ -+ psa_status_t ret; -+ uint32_t active_index; -+ uint32_t previous_active_index; -+ struct fwu_private_metadata priv_metadata; -+ -+ FWU_LOG_MSG("%s: Enter \n\r", __func__); -+ Select_Write_Mode_For_Shared_Flash(); -+ -+ if (metadata_read(&_metadata, 1) || private_metadata_read(&priv_metadata)) { -+ ret = PSA_ERROR_GENERIC_ERROR; -+ goto out; -+ } -+ -+ active_index = _metadata.active_index; -+ if (active_index == BANK_0) { -+ previous_active_index = BANK_1; -+ } else if (active_index == BANK_1) { -+ previous_active_index = BANK_0; -+ } else { -+ FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index); -+ ret = PSA_ERROR_DATA_INVALID; -+ goto out; -+ } -+ -+ for (int i=0; i= FWU_COMPONENT_NUMBER) { -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ /* Skipping image at 0th index -+ * The image index in the capsule starts from 1 -+ */ -+ if (!component) { -+ if(query_state) -+ info->state = PSA_FWU_READY; -+ return PSA_SUCCESS; -+ } -+ -+ struct fwu_private_metadata priv_metadata; -+ uint32_t version; -+ uint8_t fwu_image_index = component - 1; -+ uint8_t current_state; -+ psa_status_t ret; -+ -+ FWU_LOG_MSG("%s: enter\n\r", __func__); -+ -+ -+ Select_Write_Mode_For_Shared_Flash(); -+ if (private_metadata_read(&priv_metadata)) { -+ ret = PSA_ERROR_GENERIC_ERROR; -+ goto out; -+ } -+ -+ if (metadata_read(&_metadata, 1)) { -+ ret = PSA_ERROR_GENERIC_ERROR; -+ goto out; -+ } -+ -+ if (component == FWU_IMAGE_INDEX_ESRT) { -+ -+ size_t esrt_size = TFM_FWU_MAX_DIGEST_SIZE; -+ if (TFM_FWU_MAX_DIGEST_SIZE > sizeof(struct fwu_esrt_data_wrapper)) -+ esrt_size = sizeof(struct fwu_esrt_data_wrapper); -+ -+ /* Populate the ESRT */ -+ ret = get_esrt_data(&esrt); -+ if (ret) { -+ FWU_LOG_MSG("%s: ERROR : Unable to populate ESRT \n\r", __func__); -+ goto out; -+ } -+ -+ memcpy(&info->impl.candidate_digest, &esrt, esrt_size); -+ if (query_state) { -+ info->state = PSA_FWU_READY; -+ } -+ } -+ else { -+ current_state = get_fwu_image_state(&_metadata, &priv_metadata, fwu_image_index); -+ if (query_state) { -+ info->state = current_state; -+ } -+ -+ /* Fill the other required fields for component */ -+ info->max_size = fwu_image[fwu_image_index].image_size; -+ -+ version = _metadata.fw_desc.img_entry[fwu_image_index].img_props[_metadata.active_index].version; -+ ret = uint_to_image_version(version, &info->version); -+ if (ret) { -+ FWU_LOG_MSG("%s: ERROR : Image version not found \n\r", __func__); -+ goto out; -+ } -+ } -+ -+out: -+ Select_XIP_Mode_For_Shared_Flash(); -+ FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -+ return ret; -+} -+ -+psa_status_t fwu_bootloader_clean_component(psa_fwu_component_t component) -+{ -+ return PSA_SUCCESS; -+} -diff --git a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_fmp.c b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/uefi_fmp.c -similarity index 66% -rename from platform/ext/target/arm/corstone1000/fw_update_agent/uefi_fmp.c -rename to platform/ext/target/arm/corstone1000/bootloader/mcuboot/uefi_fmp.c -index 896658995a55..3edd4ebd0ea9 100644 ---- a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_fmp.c -+++ b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/uefi_fmp.c -@@ -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 - * -@@ -9,11 +9,12 @@ - #include - #include "tfm_hal_device_header.h" - #include "uefi_fmp.h" -+#include "flash_layout.h" - - /* The count will increase when partial update is supported. - * At present, only full WIC is considered as updatable image. - */ --#define NUMBER_OF_FMP_IMAGES 1 -+#define NUMBER_OF_FMP_IMAGES NR_OF_IMAGES_IN_FW_BANK - #define NO_OF_FMP_VARIABLES_PER_IMAGE 6 - - #define UEFI_ARCHITECTURE_64 -@@ -74,18 +75,41 @@ typedef __PACKED_STRUCT { - uint32_t ImageVersionNameSize; - } EFI_FIRMWARE_MANAGEMENT_PROTOCOL_IMAGE_INFO; - -- --static uint16_t corstone_image_name0[] = { 'C', 'O', 'R', 'S', 'T', 'O', 'N', 'E', '1', '0', '0', '0', '_', 'W', 'I', 'C', '\0' }; --static uint16_t corstone_version_name0[] = { 'C', 'O', 'R', 'S', 'T', 'O', 'N', 'E', '1', '0', '0', '0', '_', 'B', 'E', 'S', 'T', '\0'}; -- -+struct corstone_image_info { -+ uint8_t corstone_image_name[50]; -+ uint8_t corstone_version_name[50]; -+} __packed; -+ -+/* Change image names and version name when partial update is implemented */ -+struct corstone_image_info image_info[NUMBER_OF_FMP_IMAGES] = { -+ { -+ { 'C', 'O', 'R', 'S', 'T', 'O', 'N', 'E', '1', '0', '0', '0', '_', 'W', 'I', 'C', '\0' }, -+ { 'C', 'O', 'R', 'S', 'T', 'O', 'N', 'E', '1', '0', '0', '0', '_', 'B', 'E', 'S', 'T', '\0'}, -+ }, -+ { -+ { 'C', 'O', 'R', 'S', 'T', 'O', 'N', 'E', '1', '0', '0', '0', '_', 'W', 'I', 'C', '\0' }, -+ { 'C', 'O', 'R', 'S', 'T', 'O', 'N', 'E', '1', '0', '0', '0', '_', 'B', 'E', 'S', 'T', '\0'}, -+ }, -+ { -+ { 'C', 'O', 'R', 'S', 'T', 'O', 'N', 'E', '1', '0', '0', '0', '_', 'W', 'I', 'C', '\0' }, -+ { 'C', 'O', 'R', 'S', 'T', 'O', 'N', 'E', '1', '0', '0', '0', '_', 'B', 'E', 'S', 'T', '\0'}, -+ }, -+ { -+ { 'C', 'O', 'R', 'S', 'T', 'O', 'N', 'E', '1', '0', '0', '0', '_', 'W', 'I', 'C', '\0' }, -+ { 'C', 'O', 'R', 'S', 'T', 'O', 'N', 'E', '1', '0', '0', '0', '_', 'B', 'E', 'S', 'T', '\0'}, -+ }, -+}; - static EFI_FIRMWARE_MANAGEMENT_PROTOCOL_IMAGE_INFO fmp_info[NUMBER_OF_FMP_IMAGES]; - --extern struct efi_guid full_capsule_image_guid; -+extern fwu_bank_image_info_t fwu_image[]; - - static bool is_fmp_info_initialized = false; - - static void init_fmp_info(void) - { -+ if(is_fmp_info_initialized) { -+ return; -+ } - memset(fmp_info, 0, - sizeof(EFI_FIRMWARE_MANAGEMENT_PROTOCOL_IMAGE_INFO) * NUMBER_OF_FMP_IMAGES); - -@@ -93,42 +117,44 @@ static void init_fmp_info(void) - * Add further details when partial image is supported. - */ - -- fmp_info[0].DescriptorVersion = 4; -- fmp_info[0].DescriptorCount = NUMBER_OF_FMP_IMAGES; -- fmp_info[0].DescriptorsSize = -- sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR) + -- sizeof(corstone_image_name0) + sizeof(corstone_version_name0); -- -- fmp_info[0].ImageDescriptor.ImageIndex = 1; -- -- memcpy(&fmp_info[0].ImageDescriptor.ImageTypeId, &full_capsule_image_guid, -- sizeof(struct efi_guid)); -- -- fmp_info[0].ImageDescriptor.ImageId = 1; -- fmp_info[0].ImageDescriptor.Version = FWU_IMAGE_INITIAL_VERSION; -- fmp_info[0].ImageDescriptor.AttributesSupported = 1; -- fmp_info[0].ImageDescriptor.AttributesSetting = ( -- IMAGE_ATTRIBUTE_IMAGE_UPDATABLE | IMAGE_ATTRIBUTE_RESET_REQUIRED); -- fmp_info[0].ImageDescriptor.LowestSupportedImageVersion = -- FWU_IMAGE_INITIAL_VERSION; -- fmp_info[0].ImageDescriptor.LastAttemptVersion = FWU_IMAGE_INITIAL_VERSION; -- fmp_info[0].ImageDescriptor.LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; -- -- fmp_info[0].ImageName = corstone_image_name0; -- fmp_info[0].ImageNameSize = sizeof(corstone_image_name0); -- fmp_info[0].ImageVersionName = corstone_version_name0; -- fmp_info[0].ImageVersionNameSize = sizeof(corstone_version_name0); -- -+ for (int i = 0; i < NUMBER_OF_FMP_IMAGES; i++) -+ { -+ fmp_info[i].DescriptorVersion = 4; -+ fmp_info[i].DescriptorCount = NUMBER_OF_FMP_IMAGES; -+ fmp_info[i].DescriptorsSize = -+ sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR) + -+ sizeof(image_info[i].corstone_image_name) + sizeof(image_info[i].corstone_version_name); -+ -+ fmp_info[i].ImageDescriptor.ImageIndex = i+1; -+ -+ memcpy(&fmp_info[i].ImageDescriptor.ImageTypeId, &fwu_image[i].image_guid, -+ sizeof(struct efi_guid)); -+ -+ fmp_info[i].ImageDescriptor.ImageId = i+1; -+ fmp_info[i].ImageDescriptor.Version = FWU_IMAGE_INITIAL_VERSION; -+ fmp_info[i].ImageDescriptor.AttributesSupported = 1; -+ fmp_info[i].ImageDescriptor.AttributesSetting = ( -+ IMAGE_ATTRIBUTE_IMAGE_UPDATABLE | IMAGE_ATTRIBUTE_RESET_REQUIRED); -+ fmp_info[i].ImageDescriptor.LowestSupportedImageVersion = -+ FWU_IMAGE_INITIAL_VERSION; -+ fmp_info[i].ImageDescriptor.LastAttemptVersion = FWU_IMAGE_INITIAL_VERSION; -+ fmp_info[i].ImageDescriptor.LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; -+ -+ fmp_info[i].ImageName = (uint16_t *)image_info[i].corstone_image_name; -+ fmp_info[i].ImageNameSize = sizeof(image_info[i].corstone_image_name); -+ fmp_info[i].ImageVersionName = (uint16_t *)image_info[i].corstone_version_name; -+ fmp_info[i].ImageVersionNameSize = sizeof(image_info[i].corstone_version_name); -+ } - is_fmp_info_initialized = true; - - return; - } - --enum fwu_agent_error_t fmp_set_image_info(struct efi_guid *guid, -+psa_status_t fmp_set_image_info(struct efi_guid *guid, - uint32_t current_version, uint32_t attempt_version, - uint32_t last_attempt_status) - { -- enum fwu_agent_error_t status = FWU_AGENT_ERROR; -+ psa_status_t status = PSA_ERROR_GENERIC_ERROR; - - FWU_LOG_MSG("%s:%d Enter\n\r", __func__, __LINE__); - -@@ -149,7 +175,7 @@ enum fwu_agent_error_t fmp_set_image_info(struct efi_guid *guid, - "version=%u last_attempt_version=%u.\n\r", - last_attempt_status, current_version, - attempt_version); -- status = FWU_AGENT_SUCCESS; -+ status = PSA_SUCCESS; - break; - } - } -@@ -161,7 +187,7 @@ enum fwu_agent_error_t fmp_set_image_info(struct efi_guid *guid, - - #define NO_OF_FMP_VARIABLES (NUMBER_OF_FMP_IMAGES * NO_OF_FMP_VARIABLES_PER_IMAGE) - --static enum fwu_agent_error_t pack_image_info(void *buffer, uint32_t size) -+static psa_status_t pack_image_info(void *buffer, uint32_t size) - { - typedef __PACKED_STRUCT { - uint32_t variable_count; -@@ -178,7 +204,7 @@ static enum fwu_agent_error_t pack_image_info(void *buffer, uint32_t size) - - if (size < current_size) { - FWU_LOG_MSG("%s:%d Buffer too small.\n\r", __func__, __LINE__); -- return FWU_AGENT_ERROR; -+ return PSA_ERROR_INVALID_ARGUMENT; - } - - packed_buffer->variable_count = NO_OF_FMP_VARIABLES; -@@ -201,7 +227,7 @@ static enum fwu_agent_error_t pack_image_info(void *buffer, uint32_t size) - - if (size < current_size) { - FWU_LOG_MSG("%s:%d Buffer too small.\n\r", __func__, __LINE__); -- return FWU_AGENT_ERROR; -+ return PSA_ERROR_BUFFER_TOO_SMALL; - } - - FWU_LOG_MSG("%s:%d ImageInfo size = %u, ImageName size = %u, " -@@ -222,12 +248,12 @@ static enum fwu_agent_error_t pack_image_info(void *buffer, uint32_t size) - - } - -- return FWU_AGENT_SUCCESS; -+ return PSA_SUCCESS; - } - --enum fwu_agent_error_t fmp_get_image_info(void *buffer, uint32_t size) -+psa_status_t fmp_get_image_info(void *buffer, uint32_t size) - { -- enum fwu_agent_error_t status; -+ psa_status_t status; - - FWU_LOG_MSG("%s:%d Enter\n\r", __func__, __LINE__); - -@@ -237,4 +263,3 @@ enum fwu_agent_error_t fmp_get_image_info(void *buffer, uint32_t size) - - return status; - } -- -diff --git a/platform/ext/target/arm/corstone1000/bootloader/tfm_bootloader_fwu_abstraction.h b/platform/ext/target/arm/corstone1000/bootloader/tfm_bootloader_fwu_abstraction.h -new file mode 100644 -index 000000000000..909b4857b8a9 ---- /dev/null -+++ b/platform/ext/target/arm/corstone1000/bootloader/tfm_bootloader_fwu_abstraction.h -@@ -0,0 +1,189 @@ -+/* -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ */ -+ -+#ifndef __TFM_BOOTLOADER_FWU_ABSTRACTION_H__ -+#define __TFM_BOOTLOADER_FWU_ABSTRACTION_H__ -+ -+#include "stdbool.h" -+#include "psa/update.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/** -+ * Bootloader related initialization for firmware update, such as reading -+ * some necessary shared data from the memory if needed. -+ * -+ * \return PSA_SUCCESS On success -+ * PSA_ERROR_GENERIC_ERROR On failure -+ */ -+psa_status_t fwu_bootloader_init(void); -+ -+/** -+ * \brief Initialize the staging area of the component. -+ * -+ * The component is in READY state. Prepare the staging area of the component -+ * for image download. -+ * For example, initialize the staging area, open the flash area, and so on. -+ * The image will be written into the staging area later. -+ * -+ * \param[in] component The identifier of the target component in bootloader. -+ * \param[in] manifest A pointer to a buffer containing a detached manifest for -+ * the update. If the manifest is bundled with the firmware -+ * image, manifest must be NULL. -+ * \param[in] manifest_size Size of the manifest buffer in bytes. -+ * -+ * \return PSA_SUCCESS On success -+ * PSA_ERROR_INVALID_SIGNATURE A signature or integrity check on the -+ * manifest has failed. -+ * PSA_ERROR_INVALID_ARGUMENT Invalid input parameter -+ * PSA_ERROR_INSUFFICIENT_MEMORY -+ * PSA_ERROR_INSUFFICIENT_STORAGE -+ * PSA_ERROR_COMMUNICATION_FAILURE -+ * PSA_ERROR_STORAGE_FAILURE -+ * -+ */ -+psa_status_t fwu_bootloader_staging_area_init(psa_fwu_component_t component, -+ const void *manifest, -+ size_t manifest_size); -+ -+/** -+ * \brief Load the image into the target component. -+ * -+ * The component is in WRITING state. Write the image data into the target -+ * component. -+ * -+ * \param[in] component The identifier of the target component in bootloader. -+ * \param[in] image_offset The offset of the image being passed into block, in -+ * bytes -+ * \param[in] block A buffer containing a block of image data. This -+ * might be a complete image or a subset. -+ * \param[in] block_size Size of block. -+ * -+ * \return PSA_SUCCESS On success -+ * PSA_ERROR_INVALID_ARGUMENT Invalid input parameter -+ * PSA_ERROR_INSUFFICIENT_MEMORY There is no enough memory to -+ * process the update -+ * PSA_ERROR_INSUFFICIENT_STORAGE There is no enough storage to -+ * process the update -+ * PSA_ERROR_GENERIC_ERROR A fatal error occurred -+ * -+ */ -+psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component, -+ size_t image_offset, -+ const void *block, -+ size_t block_size); -+ -+/** -+ * \brief Starts the installation of an image. -+ * -+ * The components are in CANDIDATE state. Check the authenticity and integrity of -+ * the staged image in the components. If a reboot is required to complete the -+ * check, then mark this image as a candidate so that the next time bootloader -+ * runs it will take this image as a candidate one to bootup. Return the error -+ * code PSA_SUCCESS_REBOOT. -+ * -+ * \param[in] candidates A list of components in CANDIDATE state. -+ * \param[in] number Number of components in CANDIDATE state. -+ * -+ * \return PSA_SUCCESS On success -+ * PSA_SUCCESS_REBOOT A system reboot is needed to finish installation -+ * TFM_SUCCESS_RESTART A restart of the updated component is required -+ * to complete the update -+ * PSA_ERROR_DEPENDENCY_NEEDED Another image needs to be installed to -+ * finish installation -+ * PSA_ERROR_INVALID_ARGUMENT Invalid input parameter -+ * PSA_ERROR_INVALID_SIGNATURE The signature is incorrect -+ * PSA_ERROR_GENERIC_ERROR A fatal error occurred -+ * TFM_ERROR_ROLLBACK_DETECTED The image is too old to be installed. -+ * If the image metadata contains a -+ * timestamp and it has expired, then -+ * this error is also returned. -+ */ -+psa_status_t fwu_bootloader_install_image(const psa_fwu_component_t *candidates, -+ uint8_t number); -+ -+/** -+ * \brief Mark the TRIAL(running) image in component as confirmed. -+ * -+ * Call this API to mark the running images as permanent/accepted to avoid -+ * revert when next time bootup. Usually, this API is called after the running -+ * images have been verified as valid. -+ * -+ * \param[in] candidates A list of components in TRIAL state. -+ * \param[in] number Number of components in TRIAL state. -+ * -+ * \return PSA_SUCCESS On success -+ * PSA_ERROR_INSUFFICIENT_MEMORY -+ * PSA_ERROR_INSUFFICIENT_STORAGE -+ * PSA_ERROR_COMMUNICATION_FAILURE -+ * PSA_ERROR_STORAGE_FAILURE -+ */ -+psa_status_t fwu_bootloader_mark_image_accepted(const psa_fwu_component_t *trials, -+ uint8_t number); -+ -+/** -+ * \brief Uninstall the staged image in the component. -+ * -+ * The component is in STAGED state. Uninstall the staged image in the component -+ * so that this image will not be treated as a candidate next time bootup. -+ * -+ * \return PSA_SUCCESS On success -+ * PSA_ERROR_INSUFFICIENT_MEMORY -+ * PSA_ERROR_INSUFFICIENT_STORAGE -+ * PSA_ERROR_COMMUNICATION_FAILURE -+ * PSA_ERROR_STORAGE_FAILURE -+ */ -+psa_status_t fwu_bootloader_reject_staged_image(psa_fwu_component_t component); -+ -+/** -+ * \brief Reject the trial image in the component. -+ * -+ * The component is in TRIAL state. Mark the running image in the component as -+ * rejected. -+ * -+ * \return PSA_SUCCESS On success -+ * PSA_ERROR_INSUFFICIENT_MEMORY -+ * PSA_ERROR_INSUFFICIENT_STORAGE -+ * PSA_ERROR_COMMUNICATION_FAILURE -+ * PSA_ERROR_STORAGE_FAILURE -+ */ -+psa_status_t fwu_bootloader_reject_trial_image(psa_fwu_component_t component); -+ -+/** -+ * \brief The component is in FAILED or UPDATED state. Clean the staging area of the component. -+ * -+ * \return PSA_SUCCESS On success -+ * PSA_ERROR_INVALID_ARGUMENT Invalid input parameter -+ * PSA_ERROR_STORAGE_FAILURE -+ */ -+psa_status_t fwu_bootloader_clean_component(psa_fwu_component_t component); -+ -+/** -+ * \brief Get the image information. -+ * -+ * Get the image information of the given component in staging area -+ * or the running area. -+ * -+ * \param[in] component The identifier of the target component in bootloader. -+ * \param[in] query_state Query 'state' field. -+ * \param[in] query_impl_info Query 'impl' field. -+ * \param[out] info Buffer containing return the component information. -+ -+ * \return PSA_SUCCESS On success -+ * PSA_ERROR_INVALID_ARGUMENT Invalid input parameter -+ * PSA_ERROR_GENERIC_ERROR A fatal error occurred -+ */ -+psa_status_t fwu_bootloader_get_image_info(psa_fwu_component_t component, -+ bool query_state, -+ bool query_impl_info, -+ psa_fwu_component_info_t *info); -+#ifdef __cplusplus -+} -+#endif -+#endif /* __TFM_BOOTLOADER_FWU_ABSTRACTION_H__ */ -diff --git a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_fmp.h b/platform/ext/target/arm/corstone1000/bootloader/uefi_fmp.h -similarity index 89% -rename from platform/ext/target/arm/corstone1000/fw_update_agent/uefi_fmp.h -rename to platform/ext/target/arm/corstone1000/bootloader/uefi_fmp.h -index d876bd7cff05..36c604714900 100644 ---- a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_fmp.h -+++ b/platform/ext/target/arm/corstone1000/bootloader/uefi_fmp.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2022, Arm Limited. All rights reserved. -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors - * - * SPDX-License-Identifier: BSD-3-Clause - * -@@ -40,7 +40,7 @@ - * attempt_version: attempted versions for the image - * - */ --enum fwu_agent_error_t fmp_set_image_info(struct efi_guid *guid, -+psa_status_t fmp_set_image_info(struct efi_guid *guid, - uint32_t current_version, uint32_t attempt_version, - uint32_t last_attempt_status); - -@@ -51,6 +51,5 @@ enum fwu_agent_error_t fmp_set_image_info(struct efi_guid *guid, - * size : size of the buffer - * - */ --enum fwu_agent_error_t fmp_get_image_info(void *buffer, uint32_t size); -- -+psa_status_t fmp_get_image_info(void *buffer, uint32_t size); - #endif /* UEFI_FMP_H */ -diff --git a/platform/ext/target/arm/corstone1000/config.cmake b/platform/ext/target/arm/corstone1000/config.cmake -index 6d9cb1fea750..a923f63ca697 100644 ---- a/platform/ext/target/arm/corstone1000/config.cmake -+++ b/platform/ext/target/arm/corstone1000/config.cmake -@@ -55,10 +55,13 @@ 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") -+set(TFM_PARTITION_FIRMWARE_UPDATE ON CACHE BOOL "Enable firmware update partition") -+set(PLATFORM_HAS_FIRMWARE_UPDATE_SUPPORT ON CACHE BOOL "Whether 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 configuration file for Firmware Update partition") -+set(TFM_CONFIG_FWU_MAX_MANIFEST_SIZE 0 CACHE STRING "The maximum permitted size for manifest in psa_fwu_start(), in bytes.") -+set(TFM_CONFIG_FWU_MAX_WRITE_SIZE 4096 CACHE STRING "The maximum permitted size for block in psa_fwu_write, in bytes.") -+set(FWU_SUPPORT_TRIAL_STATE ON CACHE BOOL "Device support TRIAL component state.") - - 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.") -diff --git a/platform/ext/target/arm/corstone1000/fw_update_agent/fwu_agent.c b/platform/ext/target/arm/corstone1000/fw_update_agent/fwu_agent.c -deleted file mode 100644 -index 29c7be9a3bb3..000000000000 ---- a/platform/ext/target/arm/corstone1000/fw_update_agent/fwu_agent.c -+++ /dev/null -@@ -1,1405 +0,0 @@ --/* -- * Copyright (c) 2021-2024, Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- * -- */ -- --#include --#include --#include "fwu_agent.h" --#include "Driver_Flash.h" --#include "flash_layout.h" --#include "fip_parser/external/uuid.h" --#include "region_defs.h" --#include "uefi_capsule_parser.h" --#include "flash_common.h" --#include "platform_base_address.h" --#include "platform_description.h" --#include "tfm_plat_nv_counters.h" --#include "tfm_plat_defs.h" --#include "uefi_fmp.h" --#include "uart_stdout.h" --#include "soft_crc.h" --#if !BL1 --#include "partition.h" --#include "platform.h" --#endif -- --#define FWU_METADATA_VERSION 2 --#define FWU_FW_STORE_DESC_OFFSET 0x20 --#define NR_OF_MAX_FW_BANKS 4 -- --/* -- * Metadata version 2 data structures defined by PSA_FW update specification -- * at https://developer.arm.com/documentation/den0118/latest/ -- */ -- --/* Properties of image in a bank */ --struct fwu_image_properties { -- -- /* UUID of the image in this bank */ -- uuid_t img_uuid; -- -- /* [0]: bit describing the image acceptance status – -- * 1 means the image is accepted -- * [31:1]: MBZ -- */ -- uint32_t accepted; -- -- /* NOTE: using the reserved field */ -- /* image version */ -- uint32_t version; -- --} __packed; -- --/* Image entry information */ --struct fwu_image_entry { -- -- /* UUID identifying the image type */ -- uuid_t img_type_uuid; -- -- /* UUID of the storage volume where the image is located */ -- uuid_t location_uuid; -- -- /* Properties of images with img_type_uuid in the different FW banks */ -- struct fwu_image_properties img_props[NR_OF_FW_BANKS]; -- --} __packed; -- --struct fwu_fw_store_descriptor { -- -- /* Number of Banks */ -- uint8_t num_banks; -- -- /* Reserved */ -- uint8_t reserved; -- -- /* Number of images per bank */ -- uint16_t num_images; -- -- /* Size of image_entry(all banks) in bytes */ -- uint16_t img_entry_size; -- -- /* Size of image bank info structure in bytes */ -- uint16_t bank_info_entry_size; -- -- /* Array of fwu_image_entry structs */ -- struct fwu_image_entry img_entry[NR_OF_IMAGES_IN_FW_BANK]; -- --} __packed; -- --struct fwu_metadata { -- -- /* Metadata CRC value */ -- uint32_t crc_32; -- -- /* Metadata version */ -- uint32_t version; -- -- /* Bank index with which device boots */ -- uint32_t active_index; -- -- /* Previous bank index with which device booted successfully */ -- uint32_t previous_active_index; -- -- /* Size of the entire metadata in bytes */ -- uint32_t metadata_size; -- -- /* Offset of the image descriptor structure */ -- uint16_t desc_offset; -- -- /* Reserved */ -- uint16_t reserved1; -- -- /* Bank state: It's not used in corstone1000 at the moment.Currently -- * not used by any sw componenets such as u-boot and TF-A */ -- uint8_t bank_state[NR_OF_MAX_FW_BANKS]; -- -- /* Reserved */ -- uint32_t reserved2; -- -- struct fwu_fw_store_descriptor fw_desc; -- --} __packed; -- --/* This is Corstone1000 speific metadata for OTA. -- * Private metadata is written at next sector following -- * FWU METADATA location */ --struct fwu_private_metadata { -- -- /* boot_index: the bank from which system is booted from */ -- uint32_t boot_index; -- -- /* counter: tracking number of boot attempted so far */ -- uint32_t boot_attempted; -- -- /* staged nv_counter: temprary location before written to the otp */ -- uint32_t nv_counter[NR_OF_IMAGES_IN_FW_BANK]; -- -- /* FMP information */ -- uint32_t fmp_version; -- uint32_t fmp_last_attempt_version; -- uint32_t fmp_last_attempt_status; -- --} __packed; -- --#define MAX_BOOT_ATTEMPTS_PER_BANK 3 -- --struct fwu_metadata _metadata; -- --int is_initialized = 0; -- --capsule_image_info_t capsule_info; -- --enum fwu_agent_state_t { -- FWU_AGENT_STATE_UNKNOWN = -1, -- FWU_AGENT_STATE_REGULAR = 0, -- FWU_AGENT_STATE_TRIAL, --}; -- --struct efi_guid full_capsule_image_guid = { -- .time_low = 0x989f3a4e, -- .time_mid = 0x46e0, -- .time_hi_and_version = 0x4cd0, -- .clock_seq_and_node = {0x98, 0x77, 0xa2, 0x5c, 0x70, 0xc0, 0x13, 0x29} --}; -- -- --#define IMAGE_ACCEPTED (1) --#define IMAGE_NOT_ACCEPTED (0) --#define BANK_0 (0) --#define BANK_1 (1) --#define IMAGE_0 (0) --#define IMAGE_1 (1) --#define IMAGE_2 (2) --#define IMAGE_3 (3) --#define IMAGE_END (IMAGE_3) --#define IMAGE_ALL (IMAGE_END + 1) --#define IMAGE_NOT_RECOGNIZED (-1) --#define INVALID_VERSION (0xffffffff) -- -- --#ifndef FWU_METADATA_FLASH_DEV -- #ifndef FLASH_DEV_NAME -- #error "FWU_METADATA_FLASH_DEV or FLASH_DEV_NAME must be defined in flash_layout.h" -- #else -- #define FWU_METADATA_FLASH_DEV FLASH_DEV_NAME -- #endif --#endif -- --/* Import the CMSIS flash device driver */ --extern ARM_DRIVER_FLASH FWU_METADATA_FLASH_DEV; -- --#define HOST_ACK_TIMEOUT_SEC (6 * 60) /* ~seconds, not exact */ -- --#if BL1 --static enum fwu_agent_error_t private_metadata_read( -- struct fwu_private_metadata* p_metadata) --{ -- int ret; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- if (!p_metadata) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ReadData(FWU_PRIVATE_METADATA_REPLICA_1_OFFSET, p_metadata, -- sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: success: boot_index = %u\n\r", __func__, -- p_metadata->boot_index); -- -- return FWU_AGENT_SUCCESS; --} --#elif --static enum fwu_agent_error_t private_metadata_read( -- struct fwu_private_metadata* p_metadata) --{ -- partition_entry_t *part; -- uuid_t private_uuid = PRIVATE_METADATA_TYPE_UUID; -- int ret; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- if (!p_metadata) { -- return FWU_AGENT_ERROR; -- } -- -- part = get_partition_entry_by_type(&private_uuid); -- if (!part) { -- FWU_LOG_MSG("Private metadata partition not found\n\r"); -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ReadData(part->start, p_metadata, -- sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: success: boot_index = %u\n\r", __func__, -- p_metadata->boot_index); -- -- return FWU_AGENT_SUCCESS; --} --#endif -- --#if BL1 --static enum fwu_agent_error_t private_metadata_write( -- struct fwu_private_metadata* p_metadata) --{ -- int ret; -- -- FWU_LOG_MSG("%s: enter: boot_index = %u\n\r", __func__, -- p_metadata->boot_index); -- -- if (!p_metadata) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.EraseSector(FWU_PRIVATE_METADATA_REPLICA_1_OFFSET); -- if (ret != ARM_DRIVER_OK) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ProgramData(FWU_PRIVATE_METADATA_REPLICA_1_OFFSET, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: success\n\r", __func__); -- return FWU_AGENT_SUCCESS; --} --#elif --static enum fwu_agent_error_t private_metadata_write( -- struct fwu_private_metadata* p_metadata) --{ -- uuid_t private_uuid = PRIVATE_METADATA_TYPE_UUID; -- partition_entry_t *part; -- int ret; -- -- FWU_LOG_MSG("%s: enter: boot_index = %u\n\r", __func__, -- p_metadata->boot_index); -- -- if (!p_metadata) { -- return FWU_AGENT_ERROR; -- } -- -- part = get_partition_entry_by_type(&private_uuid); -- if (!part) { -- FWU_LOG_MSG("Private metadata partition not found\n\r"); -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.EraseSector(part->start); -- if (ret != ARM_DRIVER_OK) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ProgramData(part->start, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: success\n\r", __func__); -- return FWU_AGENT_SUCCESS; --} --#endif -- --static enum fwu_agent_error_t metadata_validate(struct fwu_metadata *p_metadata) --{ -- FWU_LOG_MSG("%s: enter:\n\r", __func__); -- -- if (!p_metadata) { -- return FWU_AGENT_ERROR; -- } -- -- uint32_t calculated_crc32 = crc32((uint8_t *)&(p_metadata->version), -- sizeof(*p_metadata) - sizeof(p_metadata->crc_32)); -- -- if (p_metadata->crc_32 != calculated_crc32) { -- FWU_LOG_MSG("%s: failed: crc32 calculated: 0x%x, given: 0x%x\n\r", __func__, -- calculated_crc32, p_metadata->crc_32); -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: success\n\r", __func__); -- -- return FWU_AGENT_SUCCESS; --} -- --#if BL1 --static enum fwu_agent_error_t metadata_read_without_validation(struct fwu_metadata *p_metadata) --{ -- int ret; -- -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- FWU_METADATA_REPLICA_1_OFFSET, sizeof(*p_metadata)); -- -- if (!p_metadata) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ReadData(FWU_METADATA_REPLICA_1_OFFSET, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -- p_metadata->active_index, p_metadata->previous_active_index); -- -- return FWU_AGENT_SUCCESS; --} --#elif --static enum fwu_agent_error_t metadata_read_without_validation(struct fwu_metadata *p_metadata) --{ -- uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID; -- partition_entry_t *part; -- int ret; -- -- if (!p_metadata) { -- return FWU_AGENT_ERROR; -- } -- -- part = get_partition_entry_by_type(&metadata_uuid); -- if (!part) { -- FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__); -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- part->start, sizeof(*p_metadata)); -- -- -- ret = FWU_METADATA_FLASH_DEV.ReadData(part->start, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -- p_metadata->active_index, p_metadata->previous_active_index); -- -- return FWU_AGENT_SUCCESS; --} --#endif -- --#if BL1 --static enum fwu_agent_error_t metadata_read(struct fwu_metadata *p_metadata) --{ -- int ret; -- -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- FWU_METADATA_REPLICA_1_OFFSET, sizeof(*p_metadata)); -- -- if (!p_metadata) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ReadData(FWU_METADATA_REPLICA_1_OFFSET, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- if (metadata_validate(p_metadata) != FWU_AGENT_SUCCESS) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -- p_metadata->active_index, p_metadata->previous_active_index); -- -- return FWU_AGENT_SUCCESS; --} --#elif --static enum fwu_agent_error_t metadata_read(struct fwu_metadata *p_metadata) --{ -- uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID; -- partition_entry_t *part; -- int ret; -- -- if (!p_metadata) { -- return FWU_AGENT_ERROR; -- } -- -- part = get_partition_entry_by_type(&metadata_uuid); -- if (!part) { -- FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__); -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- part->start, sizeof(*p_metadata)); -- -- ret = FWU_METADATA_FLASH_DEV.ReadData(part->start, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- if (metadata_validate(p_metadata) != FWU_AGENT_SUCCESS) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -- p_metadata->active_index, p_metadata->previous_active_index); -- -- return FWU_AGENT_SUCCESS; --} --#endif -- -- --#if BL1 --static enum fwu_agent_error_t metadata_write( -- struct fwu_metadata *p_metadata) --{ -- int ret; -- -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- FWU_METADATA_REPLICA_1_OFFSET, sizeof(*p_metadata)); -- -- if (!p_metadata) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.EraseSector(FWU_METADATA_REPLICA_1_OFFSET); -- if (ret != ARM_DRIVER_OK) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ProgramData(FWU_METADATA_REPLICA_1_OFFSET, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- FWU_METADATA_REPLICA_2_OFFSET, sizeof(*p_metadata)); -- -- ret = FWU_METADATA_FLASH_DEV.EraseSector(FWU_METADATA_REPLICA_2_OFFSET); -- if (ret != ARM_DRIVER_OK) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ProgramData(FWU_METADATA_REPLICA_2_OFFSET, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- FWU_METADATA_REPLICA_2_OFFSET, sizeof(*p_metadata)); -- -- ret = FWU_METADATA_FLASH_DEV.EraseSector(FWU_METADATA_REPLICA_2_OFFSET); -- if (ret != ARM_DRIVER_OK) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ProgramData(FWU_METADATA_REPLICA_2_OFFSET, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -- p_metadata->active_index, p_metadata->previous_active_index); -- return FWU_AGENT_SUCCESS; --} --#elif --static enum fwu_agent_error_t metadata_write( -- struct fwu_metadata *p_metadata) --{ -- uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID; -- partition_entry_t *part; -- int ret; -- -- if (!p_metadata) { -- return FWU_AGENT_ERROR; -- } -- -- part = get_partition_entry_by_type(&metadata_uuid); -- if (!part) { -- FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__); -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- part->start, sizeof(*p_metadata)); -- -- ret = FWU_METADATA_FLASH_DEV.EraseSector(part->start); -- if (ret != ARM_DRIVER_OK) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ProgramData(part->start, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- part = get_partition_replica_by_type(&metadata_uuid); -- if (!part) { -- FWU_LOG_MSG("%s: FWU metadata replica partition not found\n\r", __func__); -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- part->start, sizeof(*p_metadata)); -- -- ret = FWU_METADATA_FLASH_DEV.EraseSector(part->start); -- if (ret != ARM_DRIVER_OK) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ProgramData(part->start, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- FWU_METADATA_REPLICA_2_OFFSET, sizeof(*p_metadata)); -- -- ret = FWU_METADATA_FLASH_DEV.EraseSector(FWU_METADATA_REPLICA_2_OFFSET); -- if (ret != ARM_DRIVER_OK) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.ProgramData(FWU_METADATA_REPLICA_2_OFFSET, -- p_metadata, sizeof(*p_metadata)); -- if (ret < 0 || ret != sizeof(*p_metadata)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -- p_metadata->active_index, p_metadata->previous_active_index); -- return FWU_AGENT_SUCCESS; --} --#endif -- -- --enum fwu_agent_error_t fwu_metadata_init(void) --{ -- enum fwu_agent_error_t ret; -- ARM_FLASH_INFO* flash_info; -- -- -- if (is_initialized) { -- return FWU_AGENT_SUCCESS; -- } -- -- /* Code assumes everything fits into a sector */ -- if (sizeof(_metadata) > FWU_METADATA_FLASH_SECTOR_SIZE) { -- return FWU_AGENT_ERROR; -- } -- -- if (sizeof(struct fwu_private_metadata) > FWU_METADATA_FLASH_SECTOR_SIZE) { -- return FWU_AGENT_ERROR; -- } -- -- ret = FWU_METADATA_FLASH_DEV.Initialize(NULL); -- if (ret != ARM_DRIVER_OK) { -- return FWU_AGENT_ERROR; -- } -- -- flash_info = FWU_METADATA_FLASH_DEV.GetInfo(); -- if (flash_info->program_unit != 1) { -- FWU_METADATA_FLASH_DEV.Uninitialize(); -- return FWU_AGENT_ERROR; -- } -- -- is_initialized = 1; -- -- return FWU_AGENT_SUCCESS; --} -- --enum fwu_agent_error_t fwu_metadata_provision(void) --{ -- enum fwu_agent_error_t ret; -- struct fwu_private_metadata priv_metadata; -- uint32_t image_version = FWU_IMAGE_INITIAL_VERSION; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- --#if !BL1 -- plat_io_storage_init(); -- partition_init(PLATFORM_GPT_IMAGE); --#endif -- -- ret = fwu_metadata_init(); -- if (ret) { -- return ret; -- } -- -- /* -- * check by chance if the previous reboot -- * had a firmware data?. If yes, then don't initialize -- * metadata -- */ -- metadata_read(&_metadata); -- if(_metadata.active_index < 2 || _metadata.previous_active_index <2){ -- if(_metadata.active_index ^ _metadata.previous_active_index) -- return FWU_AGENT_SUCCESS; -- } -- /* Provision FWU Agent Metadata */ -- -- memset(&_metadata, 0, sizeof(_metadata)); -- -- _metadata.version = FWU_METADATA_VERSION; -- _metadata.active_index = BANK_0; -- _metadata.previous_active_index = BANK_1; -- _metadata.desc_offset= FWU_FW_STORE_DESC_OFFSET; -- -- _metadata.fw_desc.num_banks = NR_OF_FW_BANKS; -- _metadata.fw_desc.num_images = NR_OF_IMAGES_IN_FW_BANK; -- _metadata.fw_desc.img_entry_size = sizeof(struct fwu_image_entry) * NR_OF_IMAGES_IN_FW_BANK; -- _metadata.fw_desc.bank_info_entry_size = sizeof(struct fwu_image_properties) * NR_OF_FW_BANKS; -- /* bank 0 is the place where images are located at the -- * start of device lifecycle */ -- -- for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) { -- -- _metadata.fw_desc.img_entry[i].img_props[BANK_0].accepted = IMAGE_ACCEPTED; -- _metadata.fw_desc.img_entry[i].img_props[BANK_0].version = image_version; -- -- _metadata.fw_desc.img_entry[i].img_props[BANK_1].accepted = IMAGE_NOT_ACCEPTED; -- _metadata.fw_desc.img_entry[i].img_props[BANK_1].version = INVALID_VERSION; -- } -- -- /* Calculate CRC32 for fwu metadata. The first filed in the _metadata has to be the crc_32. -- * This should be omited from the calculation. */ -- _metadata.crc_32 = crc32((uint8_t *)&_metadata.version, -- sizeof(_metadata) - sizeof(_metadata.crc_32)); -- -- ret = metadata_write(&_metadata); -- if (ret) { -- return ret; -- } -- -- memset(&_metadata, 0, sizeof(_metadata)); -- ret = metadata_read(&_metadata); -- if (ret) { -- return ret; -- } -- FWU_LOG_MSG("%s: provisioned values: active = %u, previous = %d\n\r", -- __func__, _metadata.active_index, _metadata.previous_active_index); -- -- -- /* Provision Private metadata for update agent which is shared -- beween BL1 and tf-m of secure enclave */ -- -- memset(&priv_metadata, 0, sizeof(priv_metadata)); -- -- priv_metadata.boot_index = BANK_0; -- priv_metadata.boot_attempted = 0; -- -- priv_metadata.fmp_version = FWU_IMAGE_INITIAL_VERSION; -- priv_metadata.fmp_last_attempt_version = FWU_IMAGE_INITIAL_VERSION; -- priv_metadata.fmp_last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS; -- -- ret = private_metadata_write(&priv_metadata); -- if (ret) { -- return ret; -- } -- -- memset(&priv_metadata, 0, sizeof(priv_metadata)); -- ret = private_metadata_read(&priv_metadata); -- if (ret) { -- return ret; -- } -- FWU_LOG_MSG("%s: provisioned values: boot_index = %u\n\r", __func__, -- priv_metadata.boot_index); -- -- FWU_LOG_MSG("%s: FWU METADATA PROVISIONED.\n\r", __func__); -- return FWU_AGENT_SUCCESS; --} -- --static enum fwu_agent_state_t get_fwu_agent_state( -- struct fwu_metadata *metadata_ptr, -- struct fwu_private_metadata *priv_metadata_ptr) --{ -- uint32_t boot_index; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- boot_index = priv_metadata_ptr->boot_index; -- -- if (boot_index != metadata_ptr->active_index) { -- return FWU_AGENT_STATE_TRIAL; -- } -- -- for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) { -- if ((metadata_ptr->fw_desc.img_entry[i].img_props[boot_index].accepted) -- == (IMAGE_NOT_ACCEPTED)) { -- return FWU_AGENT_STATE_TRIAL; -- } -- } -- -- FWU_LOG_MSG("%s: exit: FWU_AGENT_STATE_REGULAR\n\r", __func__); -- return FWU_AGENT_STATE_REGULAR; --} -- --static int get_image_info_in_bank(struct efi_guid* guid, uint32_t* image_bank_offset) --{ -- if ((memcmp(guid, &full_capsule_image_guid, sizeof(*guid))) == 0) { -- *image_bank_offset = 0; -- return IMAGE_ALL; -- } -- -- return IMAGE_NOT_RECOGNIZED; --} -- --static enum fwu_agent_error_t erase_bank(uint32_t bank_offset) --{ -- int ret; -- uint32_t sectors; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- if ((bank_offset % FWU_METADATA_FLASH_SECTOR_SIZE) != 0) { -- return FWU_AGENT_ERROR; -- } -- -- if ((BANK_PARTITION_SIZE % FWU_METADATA_FLASH_SECTOR_SIZE) != 0) { -- return FWU_AGENT_ERROR; -- } -- -- sectors = BANK_PARTITION_SIZE / FWU_METADATA_FLASH_SECTOR_SIZE; -- -- FWU_LOG_MSG("%s: erasing sectors = %u, from offset = %u\n\r", __func__, -- sectors, bank_offset); -- -- for (int i = 0; i < sectors; i++) { -- ret = FWU_METADATA_FLASH_DEV.EraseSector( -- bank_offset + (i * FWU_METADATA_FLASH_SECTOR_SIZE)); -- if (ret != ARM_DRIVER_OK) { -- return FWU_AGENT_ERROR; -- } -- } -- -- FWU_LOG_MSG("%s: exit\n\r", __func__); -- return FWU_AGENT_SUCCESS; --} -- -- --static enum fwu_agent_error_t flash_full_capsule( -- struct fwu_metadata* metadata, void* images, uint32_t size, -- uint32_t version) --{ -- int ret; -- uint32_t active_index = metadata->active_index; -- uint32_t bank_offset; -- uint32_t previous_active_index; -- -- FWU_LOG_MSG("%s: enter: image = 0x%p, size = %u, version = %u\n\r" -- , __func__, images, size, version); -- -- if (!metadata || !images) { -- return FWU_AGENT_ERROR; -- } -- -- if (size > BANK_PARTITION_SIZE) { -- FWU_LOG_MSG("ERROR: %s: size error\n\r",__func__); -- return FWU_AGENT_ERROR; -- } -- -- if (version <= -- (metadata->fw_desc.img_entry[IMAGE_0].img_props[active_index].version)) { -- FWU_LOG_MSG("ERROR: %s: version error\n\r",__func__); -- return FWU_AGENT_ERROR; -- } -- -- if (active_index == BANK_0) { -- previous_active_index = BANK_1; -- bank_offset = BANK_1_PARTITION_OFFSET; -- } else if (active_index == BANK_1) { -- previous_active_index = BANK_0; -- bank_offset = BANK_0_PARTITION_OFFSET; -- } else { -- FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index); -- return FWU_AGENT_ERROR; -- } -- -- if (erase_bank(bank_offset)) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: writing capsule to the flash at offset = %u...\n\r", -- __func__, bank_offset); -- ret = FWU_METADATA_FLASH_DEV.ProgramData(bank_offset, images, size); -- if (ret < 0 || ret != size) { -- return FWU_AGENT_ERROR; -- } -- FWU_LOG_MSG("%s: images are written to bank offset = %u\n\r", __func__, -- bank_offset); -- -- /* Change system state to trial bank state */ -- for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) { -- metadata->fw_desc.img_entry[i].img_props[previous_active_index].accepted = -- IMAGE_NOT_ACCEPTED; -- metadata->fw_desc.img_entry[i].img_props[previous_active_index].version = version; -- } -- metadata->active_index = previous_active_index; -- metadata->previous_active_index = active_index; -- metadata->crc_32 = crc32((uint8_t *)&metadata->version, -- sizeof(*metadata) - sizeof(metadata->crc_32)); -- -- ret = metadata_write(metadata); -- if (ret) { -- return ret; -- } -- -- FWU_LOG_MSG("%s: exit\n\r", __func__); -- return FWU_AGENT_SUCCESS; --} -- --enum fwu_agent_error_t corstone1000_fwu_flash_image(void) --{ -- enum fwu_agent_error_t ret; -- struct fwu_private_metadata priv_metadata; -- enum fwu_agent_state_t current_state; -- void *capsule_ptr = (char*)CORSTONE1000_HOST_DRAM_UEFI_CAPSULE; -- int image_index; -- uint32_t image_bank_offset; -- uint32_t nr_images; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- if (!is_initialized) { -- return FWU_AGENT_ERROR; -- } -- -- Select_Write_Mode_For_Shared_Flash(); -- -- if (metadata_read(&_metadata)) { -- ret = FWU_AGENT_ERROR; -- goto out; -- } -- -- if (private_metadata_read(&priv_metadata)) { -- ret = FWU_AGENT_ERROR; -- goto out; -- } -- -- /* Firmware update process can only start in regular state. */ -- current_state = get_fwu_agent_state(&_metadata, &priv_metadata); -- if (current_state != FWU_AGENT_STATE_REGULAR) { -- ret = FWU_AGENT_ERROR; -- goto out; -- } -- -- memset(&capsule_info, 0, sizeof(capsule_info)); -- if (uefi_capsule_retrieve_images(capsule_ptr, &capsule_info)) { -- ret = FWU_AGENT_ERROR; -- goto out; -- } -- nr_images = capsule_info.nr_image; -- -- for (int i = 0; i < nr_images; i++) { -- image_index = get_image_info_in_bank(&capsule_info.guid[i], -- &image_bank_offset); -- switch(image_index) { -- case IMAGE_ALL: -- -- ret = flash_full_capsule(&_metadata, capsule_info.image[i], -- capsule_info.size[i], -- capsule_info.version[i]); -- -- if (ret != FWU_AGENT_SUCCESS) { -- -- priv_metadata.fmp_last_attempt_version = capsule_info.version[i]; -- priv_metadata.fmp_last_attempt_status = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; -- -- private_metadata_write(&priv_metadata); -- -- fmp_set_image_info(&full_capsule_image_guid, -- priv_metadata.fmp_version, -- priv_metadata.fmp_last_attempt_version, -- priv_metadata.fmp_last_attempt_status); -- } -- -- -- break; -- default: -- FWU_LOG_MSG("%s: sent image not recognized\n\r", __func__); -- ret = FWU_AGENT_ERROR; -- break; -- } -- } -- --out: -- Select_XIP_Mode_For_Shared_Flash(); -- -- FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -- return ret; --} -- --static enum fwu_agent_error_t accept_full_capsule( -- struct fwu_metadata* metadata, -- struct fwu_private_metadata* priv_metadata) --{ -- uint32_t active_index = metadata->active_index; -- enum fwu_agent_error_t ret; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) { -- metadata->fw_desc.img_entry[i].img_props[active_index].accepted = -- IMAGE_ACCEPTED; -- } -- -- priv_metadata->boot_attempted = 0; -- -- ret = private_metadata_write(priv_metadata); -- if (ret) { -- return ret; -- } -- metadata->crc_32 = crc32((uint8_t *)&metadata->version, -- sizeof(*metadata) - sizeof(metadata->crc_32)); -- -- ret = metadata_write(metadata); -- if (ret) { -- return ret; -- } -- -- FWU_LOG_MSG("%s: exit: fwu state is changed to regular\n\r", __func__); -- return FWU_AGENT_SUCCESS; --} -- --static enum fwu_agent_error_t fwu_accept_image(struct efi_guid* guid, -- struct fwu_metadata *metadata, -- struct fwu_private_metadata *priv_metadata) --{ -- enum fwu_agent_state_t current_state; -- int image_index; -- uint32_t image_bank_offset; -- enum fwu_agent_error_t ret; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- /* it is expected to receive this call only when -- in trial state */ -- current_state = get_fwu_agent_state(metadata, priv_metadata); -- if (current_state != FWU_AGENT_STATE_TRIAL) { -- return FWU_AGENT_ERROR; -- } -- -- /* booted from previous_active_bank, not expected -- * to receive this call in this state, rather host should -- * call corstone1000_fwu_select_previous */ -- if (metadata->active_index != priv_metadata->boot_index) { -- return FWU_AGENT_ERROR; -- } -- -- image_index = get_image_info_in_bank(guid, &image_bank_offset); -- switch(image_index) { -- case IMAGE_ALL: -- ret = accept_full_capsule(metadata, priv_metadata); -- break; -- default: -- FWU_LOG_MSG("%s: sent image not recognized\n\r", __func__); -- ret = FWU_AGENT_ERROR; -- break; -- } -- -- FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -- return ret; --} -- --static enum fwu_agent_error_t fwu_select_previous( -- struct fwu_metadata *metadata, -- struct fwu_private_metadata *priv_metadata) --{ -- enum fwu_agent_error_t ret; -- enum fwu_agent_state_t current_state; -- uint32_t index; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- /* it is expected to receive this call only when -- in trial state */ -- current_state = get_fwu_agent_state(metadata, priv_metadata); -- if (current_state != FWU_AGENT_STATE_TRIAL) { -- return FWU_AGENT_ERROR; -- } -- -- /* not expected to receive this call in this state, system -- * did not boot from previous active index */ -- if (metadata->previous_active_index != priv_metadata->boot_index) { -- return FWU_AGENT_ERROR; -- } -- -- FWU_LOG_MSG("%s: trial state: active index = %u, previous active = %u\n\r", -- __func__, metadata->active_index, metadata->previous_active_index); -- -- index = metadata->previous_active_index; -- for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) { -- if (metadata->fw_desc.img_entry[i].img_props[index].accepted != IMAGE_ACCEPTED) -- { -- FWU_ASSERT(0); -- } -- } -- -- index = metadata->active_index; -- metadata->active_index = metadata->previous_active_index; -- metadata->previous_active_index = index; -- -- priv_metadata->boot_attempted = 0; -- -- ret = private_metadata_write(priv_metadata); -- if (ret) { -- return ret; -- } -- metadata->crc_32 = crc32((uint8_t *)&metadata->version, -- sizeof(*metadata) - sizeof(metadata->crc_32)); -- -- ret = metadata_write(metadata); -- if (ret) { -- return ret; -- } -- -- FWU_LOG_MSG("%s: in regular state by choosing previous active bank\n\r", -- __func__); -- -- FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -- return ret; -- --} -- --void bl1_get_active_bl2_image(uint32_t *offset) --{ -- struct fwu_private_metadata priv_metadata; -- enum fwu_agent_state_t current_state; -- uint32_t boot_attempted; -- uint32_t boot_index; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- if (fwu_metadata_init()) { -- FWU_ASSERT(0); -- } -- -- if (private_metadata_read(&priv_metadata)) { -- FWU_ASSERT(0); -- } -- -- if (metadata_read(&_metadata)) { -- FWU_ASSERT(0); -- } -- -- current_state = get_fwu_agent_state(&_metadata, &priv_metadata); -- -- if (current_state == FWU_AGENT_STATE_REGULAR) { -- boot_index = _metadata.active_index; -- FWU_ASSERT(boot_index == priv_metadata.boot_index); -- boot_attempted = 0; -- } else if (current_state == FWU_AGENT_STATE_TRIAL) { -- boot_attempted = (++priv_metadata.boot_attempted); -- FWU_LOG_MSG("%s: attempting boot number = %u\n\r", -- __func__, boot_attempted); -- if (boot_attempted <= MAX_BOOT_ATTEMPTS_PER_BANK) { -- boot_index = _metadata.active_index; -- FWU_LOG_MSG("%s: booting from trial bank: %u\n\r", -- __func__, boot_index); -- } else if (boot_attempted <= (2 * MAX_BOOT_ATTEMPTS_PER_BANK)) { -- boot_index = _metadata.previous_active_index; -- FWU_LOG_MSG("%s: gave up booting from trial bank\n\r", __func__); -- FWU_LOG_MSG("%s: booting from previous active bank: %u\n\r", -- __func__, boot_index); -- } else { -- FWU_LOG_MSG("%s: cannot boot system from any bank, halting...\n\r", __func__); -- FWU_ASSERT(0); -- } -- } else { -- FWU_ASSERT(0); -- } -- -- priv_metadata.boot_index = boot_index; -- if (private_metadata_write(&priv_metadata) < 0) { -- FWU_ASSERT(0); -- } -- -- if (boot_index == BANK_0) { -- *offset = SE_BL2_BANK_0_OFFSET; -- } else if (boot_index == BANK_1) { -- *offset = SE_BL2_BANK_1_OFFSET; -- } else { -- FWU_ASSERT(0); -- } -- -- FWU_LOG_MSG("%s: exit: booting from bank = %u, offset = 0x%x\n\r", __func__, -- boot_index, *offset); -- -- return; --} -- --uint8_t bl2_get_boot_bank(void) --{ -- uint8_t boot_index; -- struct fwu_private_metadata priv_metadata; -- FWU_LOG_MSG("%s: enter", __func__); -- if (fwu_metadata_init()) { -- FWU_ASSERT(0); -- } -- if (private_metadata_read(&priv_metadata)) { -- FWU_ASSERT(0); -- } -- boot_index = priv_metadata.boot_index; -- FWU_LOG_MSG("%s: exit: booting from bank = %u", __func__, boot_index); -- return boot_index; --} -- --static void disable_host_ack_timer(void) --{ -- FWU_LOG_MSG("%s: timer to reset is disabled\n\r", __func__); -- SysTick->CTRL &= (~SysTick_CTRL_ENABLE_Msk); --} -- --static enum fwu_agent_error_t update_nv_counters( -- struct fwu_private_metadata* priv_metadata) --{ -- enum tfm_plat_err_t err; -- uint32_t security_cnt; -- enum tfm_nv_counter_t tfm_nv_counter_i; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- /* The FWU_BL2_NV_COUNTER (0) is not mirrored in the private metadata. It is -- * directly updated in the bl1_2_validate_image_at_addr() function, in -- * tfm/bl1/bl1_2/main.c. -- * Because of this, the index starts from FWU_TFM_NV_COUNTER (1). */ -- for (int i = FWU_TFM_NV_COUNTER; i <= FWU_MAX_NV_COUNTER_INDEX; i++) { -- -- switch (i) { -- case FWU_TFM_NV_COUNTER: -- tfm_nv_counter_i = PLAT_NV_COUNTER_BL2_0; -- break; -- case FWU_TFA_NV_COUNTER: -- tfm_nv_counter_i = PLAT_NV_COUNTER_BL2_1; -- break; -- default: -- FWU_ASSERT(0); -- break; -- } -- -- err = tfm_plat_read_nv_counter(tfm_nv_counter_i, -- sizeof(security_cnt), (uint8_t *)&security_cnt); -- if (err != TFM_PLAT_ERR_SUCCESS) { -- FWU_LOG_MSG("%s: couldn't read NV counter\n\r", __func__); -- return FWU_AGENT_ERROR; -- } -- -- if (priv_metadata->nv_counter[i] < security_cnt) { -- FWU_LOG_MSG("%s: staged NV counter is smaller than current value\n\r", __func__); -- return FWU_AGENT_ERROR; -- } else if (priv_metadata->nv_counter[i] > security_cnt) { -- FWU_LOG_MSG("%s: updating index = %u nv counter = %u->%u\n\r", -- __func__, i, security_cnt, -- priv_metadata->nv_counter[i]); -- err = tfm_plat_set_nv_counter(tfm_nv_counter_i, -- priv_metadata->nv_counter[i]); -- if (err != TFM_PLAT_ERR_SUCCESS) { -- FWU_LOG_MSG("%s: couldn't write NV counter\n\r", __func__); -- return FWU_AGENT_ERROR; -- } -- } -- -- } -- -- FWU_LOG_MSG("%s: exit\n\r", __func__); -- return FWU_AGENT_SUCCESS; --} -- --enum fwu_agent_error_t corstone1000_fwu_host_ack(void) --{ -- enum fwu_agent_error_t ret; -- struct fwu_private_metadata priv_metadata; -- enum fwu_agent_state_t current_state; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- if (!is_initialized) { -- return FWU_AGENT_ERROR; -- } -- -- Select_Write_Mode_For_Shared_Flash(); -- -- if (metadata_read(&_metadata)) { -- ret = FWU_AGENT_ERROR; -- goto out; -- } -- -- if (private_metadata_read(&priv_metadata)) { -- ret = FWU_AGENT_ERROR; -- goto out; -- } -- -- current_state = get_fwu_agent_state(&_metadata, &priv_metadata); -- if (current_state == FWU_AGENT_STATE_REGULAR) { -- -- ret = FWU_AGENT_SUCCESS; /* nothing to be done */ -- -- fmp_set_image_info(&full_capsule_image_guid, -- priv_metadata.fmp_version, -- priv_metadata.fmp_last_attempt_version, -- priv_metadata.fmp_last_attempt_status); -- -- goto out; -- -- } else if (current_state != FWU_AGENT_STATE_TRIAL) { -- FWU_ASSERT(0); -- } -- -- if (_metadata.active_index != priv_metadata.boot_index) { -- -- /* firmware update failed, revert back to previous bank */ -- -- priv_metadata.fmp_last_attempt_version = -- _metadata.fw_desc.img_entry[IMAGE_0].img_props[_metadata.active_index].version; -- -- priv_metadata.fmp_last_attempt_status = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; -- -- ret = fwu_select_previous(&_metadata, &priv_metadata); -- -- } else { -- -- /* firmware update successful */ -- -- priv_metadata.fmp_version = -- _metadata.fw_desc.img_entry[IMAGE_0].img_props[_metadata.active_index].version; -- priv_metadata.fmp_last_attempt_version = -- _metadata.fw_desc.img_entry[IMAGE_0].img_props[_metadata.active_index].version; -- -- priv_metadata.fmp_last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS; -- -- ret = fwu_accept_image(&full_capsule_image_guid, &_metadata, -- &priv_metadata); -- if (!ret) { -- ret = update_nv_counters(&priv_metadata); -- } -- } -- -- if (ret == FWU_AGENT_SUCCESS) { -- disable_host_ack_timer(); -- fmp_set_image_info(&full_capsule_image_guid, -- priv_metadata.fmp_version, -- priv_metadata.fmp_last_attempt_version, -- priv_metadata.fmp_last_attempt_status); -- } -- --out: -- Select_XIP_Mode_For_Shared_Flash(); -- -- FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -- return ret; --} -- --static int systic_counter = 0; -- --void SysTick_Handler(void) --{ -- systic_counter++; -- if (systic_counter % 10 == 0) { -- SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; -- stdio_output_string("*", 1); -- SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; -- } -- if (systic_counter == HOST_ACK_TIMEOUT_SEC) { -- SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; -- stdio_output_string("timer expired!\n\r", -- sizeof("timer expired!\n\r")); -- NVIC_SystemReset(); -- } --} -- --/* When in trial state, start the timer for host to respond. -- * Diable timer when host responds back either by calling -- * corstone1000_fwu_accept_image or corstone1000_fwu_select_previous. -- * Otherwise, resets the system. -- */ --void host_acknowledgement_timer_to_reset(void) --{ -- struct fwu_private_metadata priv_metadata; -- enum fwu_agent_state_t current_state; -- -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- -- Select_Write_Mode_For_Shared_Flash(); -- -- if (!is_initialized) { -- FWU_ASSERT(0); -- } -- -- if (private_metadata_read(&priv_metadata)) { -- FWU_ASSERT(0); -- } -- -- if (metadata_read(&_metadata)) { -- FWU_ASSERT(0); -- } -- -- Select_XIP_Mode_For_Shared_Flash(); -- -- current_state = get_fwu_agent_state(&_metadata, &priv_metadata); -- -- if (current_state == FWU_AGENT_STATE_TRIAL) { -- FWU_LOG_MSG("%s: in trial state, starting host ack timer\n\r", -- __func__); -- systic_counter = 0; -- if (SysTick_Config(SysTick_LOAD_RELOAD_Msk)) { -- FWU_LOG_MSG("%s: timer init failed\n\r", __func__); -- FWU_ASSERT(0); -- } else { -- FWU_LOG_MSG("%s: timer started: seconds to expire : %u\n\r", -- __func__, HOST_ACK_TIMEOUT_SEC); -- } -- } -- -- FWU_LOG_MSG("%s: exit\n\r", __func__); -- return; --} -- --/* stage nv counter into private metadata section of the flash. -- * staged nv counters are written to the otp when firmware update -- * is successful -- * the function assumes that the api is called in the boot loading -- * stage -- */ --enum fwu_agent_error_t fwu_stage_nv_counter(enum fwu_nv_counter_index_t index, -- uint32_t img_security_cnt) --{ -- struct fwu_private_metadata priv_metadata; -- -- FWU_LOG_MSG("%s: enter: index = %u, val = %u\n\r", __func__, -- index, img_security_cnt); -- -- if (!is_initialized) { -- FWU_ASSERT(0); -- } -- -- if (index > FWU_MAX_NV_COUNTER_INDEX) { -- return FWU_AGENT_ERROR; -- } -- -- if (private_metadata_read(&priv_metadata)) { -- FWU_ASSERT(0); -- } -- -- if (priv_metadata.nv_counter[index] != img_security_cnt) { -- priv_metadata.nv_counter[index] = img_security_cnt; -- if (private_metadata_write(&priv_metadata)) { -- FWU_ASSERT(0); -- } -- } -- -- FWU_LOG_MSG("%s: exit\n\r", __func__); -- return FWU_AGENT_SUCCESS; --} -diff --git a/platform/ext/target/arm/corstone1000/fw_update_agent/fwu_agent.h b/platform/ext/target/arm/corstone1000/fw_update_agent/fwu_agent.h -deleted file mode 100644 -index 701f20558370..000000000000 ---- a/platform/ext/target/arm/corstone1000/fw_update_agent/fwu_agent.h -+++ /dev/null -@@ -1,73 +0,0 @@ --/* -- * Copyright (c) 2021-2023, Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- * -- */ -- --#ifndef FWU_AGENT_H --#define FWU_AGENT_H -- --#ifdef ENABLE_FWU_AGENT_DEBUG_LOGS -- #include -- #define FWU_LOG_MSG(f_, ...) printf((f_), ##__VA_ARGS__) --#else -- #define FWU_LOG_MSG(f_, ...) --#endif -- --enum fwu_agent_error_t { -- FWU_AGENT_SUCCESS = 0, -- FWU_AGENT_ERROR = (-1) --}; -- --#define FWU_ASSERT(_c_) \ -- if (!(_c_)) { \ -- FWU_LOG_MSG("%s:%d assert hit\n\r", __func__, __LINE__); \ -- while(1) {}; \ -- } \ -- -- --/* Version used for the very first image of the device. */ --#define FWU_IMAGE_INITIAL_VERSION 0 -- --enum fwu_agent_error_t fwu_metadata_provision(void); --enum fwu_agent_error_t fwu_metadata_init(void); -- --/* host to secure enclave: -- * firwmare update image is sent accross -- */ --enum fwu_agent_error_t corstone1000_fwu_flash_image(void); -- --/* host to secure enclave: -- * host responds with this api to acknowledge its successful -- * boot. -- */ --enum fwu_agent_error_t corstone1000_fwu_host_ack(void); -- --void bl1_get_active_bl2_image(uint32_t *bank_offset); --uint8_t bl2_get_boot_bank(void); -- --/* When in trial state, start the timer for host to respond. -- * Diable timer when host responds back either by calling -- * corstone1000_fwu_accept_image or corstone1000_fwu_select_previous. -- * Otherwise, resets the system. -- */ --void host_acknowledgement_timer_to_reset(void); -- --enum fwu_nv_counter_index_t { -- FWU_BL2_NV_COUNTER = 0, -- FWU_TFM_NV_COUNTER, -- FWU_TFA_NV_COUNTER, -- FWU_MAX_NV_COUNTER_INDEX = FWU_TFA_NV_COUNTER --}; -- --/* stage nv counter into private metadata section of the flash. -- * staged nv counters are written to the otp when firmware update -- * is successful -- * the function assumes that the api is called in the boot loading -- * stage -- */ --enum fwu_agent_error_t fwu_stage_nv_counter(enum fwu_nv_counter_index_t index, -- uint32_t img_security_cnt); -- --#endif /* FWU_AGENT_H */ -diff --git a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.c b/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.c -deleted file mode 100644 -index 44566e08de36..000000000000 ---- a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.c -+++ /dev/null -@@ -1,176 +0,0 @@ --/* -- * Copyright (c) 2021-2024, Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- * -- */ -- --#include "cmsis_compiler.h" --#include "uefi_capsule_parser.h" --#include "fwu_agent.h" --#include -- --/* --Update Capsule Structure (UEFI spec 2.9 1004) -- EFI_CAPSULE_HEADER -- ... -- ... -- ... -- CAPSULE_BODY -- efi_firmware_management_capsule_header -- Optional Driver 1 (item_offset[0]) -- Optional Driver 2 (item_offset[1]) -- Payload 1 (item_offset[2]) -- efi_firmware_management_capsule_iamge_header -- Binary Update image (Image_length == update_image_size) -- Vendor Code bytes (Data lenght == update_vendorcode_size) -- Payload 2 (item_offset[3]) -- ... -- ... -- Payload n (item_offset[embedded_driver_count + payload_item_count -1]) --*/ -- --typedef __PACKED_STRUCT { -- struct efi_guid capsule_guid; -- uint32_t header_size; -- uint32_t flags; -- uint32_t capsule_image_size; --} efi_capsule_header_t; -- --typedef __PACKED_STRUCT { -- uint32_t version; -- uint16_t embedded_driver_count; -- uint16_t payload_item_count; -- uint64_t item_offset_list[]; --} efi_firmware_management_capsule_header_t; -- --typedef __PACKED_STRUCT { -- uint32_t version; -- struct efi_guid update_image_type_id; -- uint8_t update_image_index; -- uint8_t reserved_bytes[3]; -- uint32_t update_image_size; -- uint32_t update_vendorcode_size; -- uint64_t update_hardware_instance; //introduced in v2 -- uint64_t image_capsule_support; //introduced in v3 --} efi_firmware_management_capsule_image_header_t; -- --typedef __PACKED_STRUCT { -- uint32_t signature; -- uint32_t header_size; -- uint32_t fw_version; -- uint32_t lowest_supported_version; --} fmp_payload_header_t; -- --#define ANYSIZE_ARRAY 0 -- --typedef __PACKED_STRUCT { -- uint32_t dwLength; -- uint16_t wRevision; -- uint16_t wCertificateType; -- uint8_t bCertificate[ANYSIZE_ARRAY]; --} WIN_CERTIFICATE; -- --typedef __PACKED_STRUCT { -- WIN_CERTIFICATE hdr; -- struct efi_guid cert_type; -- uint8_t cert_data[ANYSIZE_ARRAY]; --} win_certificate_uefi_guid_t; -- --typedef __PACKED_STRUCT { -- uint64_t monotonic_count; -- win_certificate_uefi_guid_t auth_info; --} efi_firmware_image_authentication_t; -- -- --enum uefi_capsule_error_t uefi_capsule_retrieve_images(void* capsule_ptr, -- capsule_image_info_t* images_info) --{ -- char *ptr = (char*)capsule_ptr; -- efi_capsule_header_t* capsule_header; -- efi_firmware_management_capsule_header_t* fmp_capsule_header; -- efi_firmware_management_capsule_image_header_t* image_header; -- efi_firmware_image_authentication_t* image_auth; -- fmp_payload_header_t *fmp_payload_header; -- uint32_t total_size; -- uint32_t image_count; -- uint32_t auth_size; -- -- FWU_LOG_MSG("%s: enter, capsule ptr = 0x%p\n\r", __func__, capsule_ptr); -- -- if (!capsule_ptr) { -- return UEFI_CAPSULE_PARSER_ERROR; -- } -- -- capsule_header = (efi_capsule_header_t*)ptr; -- ptr += sizeof(efi_capsule_header_t); -- fmp_capsule_header = (efi_firmware_management_capsule_header_t*)ptr; -- -- total_size = capsule_header->capsule_image_size; -- image_count = fmp_capsule_header->payload_item_count; -- images_info->nr_image = image_count; -- -- FWU_LOG_MSG("%s: capsule size = %u, image count = %u\n\r", __func__, -- total_size, image_count); -- -- if ((image_count == 0) || (image_count > NR_OF_IMAGES_IN_FW_BANK)) { -- return UEFI_CAPSULE_PARSER_ERROR; -- } -- -- for (int i = 0; i < image_count; i++) { -- image_header = (efi_firmware_management_capsule_image_header_t*)(ptr + -- fmp_capsule_header->item_offset_list[i]); -- -- images_info->size[i] = image_header->update_image_size; -- --#ifdef AUTHENTICATED_CAPSULE -- image_auth = (efi_firmware_image_authentication_t*)( -- (char*)image_header + -- sizeof (efi_firmware_management_capsule_image_header_t) -- ); -- auth_size = sizeof(uint64_t) /* monotonic_count */ + -- image_auth->auth_info.hdr.dwLength/* WIN_CERTIFICATE + cert_data + cert_type */; -- -- fmp_payload_header = (fmp_payload_header_t*)((char*)image_auth + auth_size); -- -- FWU_LOG_MSG("%s: auth size = %u\n\r", __func__, auth_size); -- -- images_info->size[i] -= auth_size; -- -- images_info->image[i] = ( -- (char*)image_header + -- sizeof(efi_firmware_management_capsule_image_header_t) + -- auth_size + -- sizeof(*fmp_payload_header)); --#else -- images_info->image[i] = ( -- (char*)image_header + -- sizeof(efi_firmware_management_capsule_image_header_t) + -- sizeof(*fmp_payload_header)); -- -- fmp_payload_header = (fmp_payload_header_t*)((char*)image_header + -- sizeof(efi_firmware_management_capsule_image_header_t)); -- --#endif -- memcpy(&images_info->guid[i], &(image_header->update_image_type_id), -- sizeof(struct efi_guid)); -- -- images_info->version[i] = fmp_payload_header->fw_version; -- FWU_LOG_MSG("%s: image %i version = %d\n\r", __func__, i, -- images_info->version[i]); -- -- FWU_LOG_MSG("%s: image %d at %p, size=%u\n\r", __func__, i, -- images_info->image[i], images_info->size[i]); -- -- if ((fmp_capsule_header->item_offset_list[i] + -- sizeof(efi_firmware_management_capsule_image_header_t) + -- image_header->update_image_size) > total_size) -- { -- return UEFI_CAPSULE_PARSER_ERROR; -- } -- -- } -- -- FWU_LOG_MSG("%s: exit\n\r", __func__); -- return UEFI_CAPSULE_PARSER_SUCCESS; --} -diff --git a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.h b/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.h -deleted file mode 100644 -index a31cd8a3a0b7..000000000000 ---- a/platform/ext/target/arm/corstone1000/fw_update_agent/uefi_capsule_parser.h -+++ /dev/null -@@ -1,33 +0,0 @@ --/* -- * Copyright (c) 2021, Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- * -- */ -- --#ifndef UEFI_CAPSULE_PARSER_H --#define UEFI_CAPSULE_PARSER_H -- --#include --#include "fip_parser/external/uuid.h" --#include "flash_layout.h" -- --#define AUTHENTICATED_CAPSULE 1 -- --enum uefi_capsule_error_t { -- UEFI_CAPSULE_PARSER_SUCCESS = 0, -- UEFI_CAPSULE_PARSER_ERROR = (-1) --}; -- --typedef struct capsule_image_info { -- uint32_t nr_image; -- void *image[NR_OF_IMAGES_IN_FW_BANK]; -- struct efi_guid guid[NR_OF_IMAGES_IN_FW_BANK]; -- uint32_t size[NR_OF_IMAGES_IN_FW_BANK]; -- uint32_t version[NR_OF_IMAGES_IN_FW_BANK]; --} capsule_image_info_t; -- --enum uefi_capsule_error_t uefi_capsule_retrieve_images(void* capsule_ptr, -- capsule_image_info_t* images_info); -- --#endif /* UEFI_CAPSULE_PARSER_H */ -diff --git a/platform/ext/target/arm/corstone1000/partition/flash_layout.h b/platform/ext/target/arm/corstone1000/partition/flash_layout.h -index f42dda809658..e2219d80a75c 100644 ---- a/platform/ext/target/arm/corstone1000/partition/flash_layout.h -+++ b/platform/ext/target/arm/corstone1000/partition/flash_layout.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2024 Arm Limited. All rights reserved. -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. -@@ -134,8 +134,16 @@ - */ - - /* Bank configurations */ --#define BANK_PARTITION_SIZE (0xFE0000) /* 15.875 MB */ --#define TFM_PARTITION_SIZE (0x50000) /* 320 KiB */ -+#define BANK_PARTITION_SIZE (0xFE0000) /* 15.875 MB */ -+#define SE_BL2_PARTITION_BANK_OFFSET (0) -+#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_BANK_OFFSET (TFM_PARTITION_BANK_OFFSET + TFM_PARTITION_SIZE) -+ -+#define INITRAMFS_PARTITION_SIZE (0xC00000) /* 12 MB */ -+#define INITRAMFS_PARTITION_BANK_OFFSET (FIP_PARTITION_BANK_OFFSET + FIP_PARTITION_SIZE) - - /************************************************************/ - /* Bank : Images flash offsets are with respect to the bank */ diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0051-lib-gpt-Show-intent-of-GUIDs-in-unittests-more-clear.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0006-lib-gpt-Show-intent-of-GUIDs-in-unittests-more-clear.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0051-lib-gpt-Show-intent-of-GUIDs-in-unittests-more-clear.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0006-lib-gpt-Show-intent-of-GUIDs-in-unittests-more-clear.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0007-Platform-Corstone1000-Increase-buffer-sizes.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0007-Platform-Corstone1000-Increase-buffer-sizes.patch deleted file mode 100644 index 2980937d..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0007-Platform-Corstone1000-Increase-buffer-sizes.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 78231f27db0bbc747902b603bf279dce1707a3cc Mon Sep 17 00:00:00 2001 -From: Harsimran Singh Tungal -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 ---- - 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 diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0052-lib-gpt-Provide-macro-identifying-free-space.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0007-lib-gpt-Provide-macro-identifying-free-space.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0052-lib-gpt-Provide-macro-identifying-free-space.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0007-lib-gpt-Provide-macro-identifying-free-space.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0008-Platform-Corstone1000-Remove-duplicate-configuration.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0008-Platform-Corstone1000-Remove-duplicate-configuration.patch deleted file mode 100644 index 3728bf8d..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0008-Platform-Corstone1000-Remove-duplicate-configuration.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 291b717c9ff6124dd132602e84f75f320adbfda1 Mon Sep 17 00:00:00 2001 -From: Yogesh Wani -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 ---- - 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]") diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0053-lib-gpt-Add-operation-to-duplicate-entries.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0008-lib-gpt-Add-operation-to-duplicate-entries.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0053-lib-gpt-Add-operation-to-duplicate-entries.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0008-lib-gpt-Add-operation-to-duplicate-entries.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0054-lib-gpt-Consecutively-erase-blocks-when-moving-parti.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0009-lib-gpt-Consecutively-erase-blocks-when-moving-parti.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0054-lib-gpt-Consecutively-erase-blocks-when-moving-parti.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0009-lib-gpt-Consecutively-erase-blocks-when-moving-parti.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0009-plat-corstone1000-Add-support-for-Cortex-A320-varian.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0009-plat-corstone1000-Add-support-for-Cortex-A320-varian.patch deleted file mode 100644 index b46d4d68..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0009-plat-corstone1000-Add-support-for-Cortex-A320-varian.patch +++ /dev/null @@ -1,487 +0,0 @@ -From c5bcb737352ad2e1c24cc14a0b8ddf91ad7197b4 Mon Sep 17 00:00:00 2001 -From: Harsimran Singh Tungal -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 ---- - .../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 - $<$:${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 -+#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 -+#include -+#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(); diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0055-lib-gpt-Clarify-API-operation.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0010-lib-gpt-Clarify-API-operation.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0055-lib-gpt-Clarify-API-operation.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0010-lib-gpt-Clarify-API-operation.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0011-bl2-corstone-1000-Remove-psa_adac_to_tfm_apply_permi.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0011-bl2-corstone-1000-Remove-psa_adac_to_tfm_apply_permi.patch deleted file mode 100644 index 2621667d..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0011-bl2-corstone-1000-Remove-psa_adac_to_tfm_apply_permi.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 3a9e209596ca0ae5850ae382c624adf9932b16b4 Mon Sep 17 00:00:00 2001 -From: Devaraj Ranganna -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 ---- - .../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 */ - diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0056-lib-gpt-Add-metadata-only-API-operations.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0011-lib-gpt-Add-metadata-only-API-operations.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0056-lib-gpt-Add-metadata-only-API-operations.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0011-lib-gpt-Add-metadata-only-API-operations.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0012-bl2-corstone-1000-secure-debug-waiting-in-CM-LCS.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0012-bl2-corstone-1000-secure-debug-waiting-in-CM-LCS.patch deleted file mode 100644 index d0a9e9a6..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0012-bl2-corstone-1000-secure-debug-waiting-in-CM-LCS.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 901a63f09369cfbed8eff8c450b8615bd4c361af Mon Sep 17 00:00:00 2001 -From: Devaraj Ranganna -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 ---- - .../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; diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0057-plat-cs1k-Add-flash-erase-protection.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0012-plat-cs1k-Add-flash-erase-protection.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0057-plat-cs1k-Add-flash-erase-protection.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0012-plat-cs1k-Add-flash-erase-protection.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0013-Build-adjust-CS1000-platform-for-GCC-v14.2.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0013-Build-adjust-CS1000-platform-for-GCC-v14.2.patch deleted file mode 100644 index 90c1a2e1..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0013-Build-adjust-CS1000-platform-for-GCC-v14.2.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 14fff6df016dad1d76f1eda6f77dde1890836c3c Mon Sep 17 00:00:00 2001 -From: Anton Komlev -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 -Change-Id: Ia803ebd5ceeab03ab7c7afc7c79c4e5836e03b26 - -Upstream-Status: Backport [05c174df157eac428a3e87a1c40170ed7a74af57] -Signed-off-by: Jon Mason ---- - .../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 - #include -+#include - - #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 diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0058-plat-cs1k-Remove-unused-FWU-partitions-upon-version-.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0013-plat-cs1k-Remove-unused-FWU-partitions-upon-version-.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0058-plat-cs1k-Remove-unused-FWU-partitions-upon-version-.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0013-plat-cs1k-Remove-unused-FWU-partitions-upon-version-.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0014-Workaround-compile-errors-in-AES.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0014-Workaround-compile-errors-in-AES.patch deleted file mode 100644 index d4ffb9e6..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0014-Workaround-compile-errors-in-AES.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 949ecbcd29660225f42bdfc37bdff4b79917620a Mon Sep 17 00:00:00 2001 -From: Jon Mason -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 ---- - 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; - } diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0059-plat-cs1k-Duplicate-old-images-in-FWU.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0014-plat-cs1k-Duplicate-old-images-in-FWU.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0059-plat-cs1k-Duplicate-old-images-in-FWU.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0014-plat-cs1k-Duplicate-old-images-in-FWU.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0015-CC312-Add-barrier-before-first-AO-lock-write.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0015-CC312-Add-barrier-before-first-AO-lock-write.patch deleted file mode 100644 index c893d209..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0015-CC312-Add-barrier-before-first-AO-lock-write.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 3d2bdf81fee8832101fe47b633af5bdee251531a Mon Sep 17 00:00:00 2001 -From: Michael Safwat -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 -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 - diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0060-platform-corstone1000-Increase-FIP-partition-size.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0015-platform-corstone1000-Increase-FIP-partition-size.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0060-platform-corstone1000-Increase-FIP-partition-size.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0015-platform-corstone1000-Increase-FIP-partition-size.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0016-Platform-CS1K-make-mutlicore-support-platform-generi.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0016-Platform-CS1K-make-mutlicore-support-platform-generi.patch deleted file mode 100644 index 36a919e1..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0016-Platform-CS1K-make-mutlicore-support-platform-generi.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 9f86d644aa23589e5187f0a22394438cd525d574 Mon Sep 17 00:00:00 2001 -From: Alex Chapman -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 ---- - 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 -- $<$:CORSTONE1000_FVP_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 diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0017-lib-efi_guid-Added-EFI-GUID-library.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0017-lib-efi_guid-Added-EFI-GUID-library.patch deleted file mode 100644 index 244bc20a..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0017-lib-efi_guid-Added-EFI-GUID-library.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 5fc4f3857739a9fe93819cedc4a8108d33bf8241 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 -+ $ -+ 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 -+#include -+ -+#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 -+ -+#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; -+} diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0018-lib-efi_soft_crc-Added-EFI-CRC-library.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0018-lib-efi_soft_crc-Added-EFI-CRC-library.patch deleted file mode 100644 index b8715e3b..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0018-lib-efi_soft_crc-Added-EFI-CRC-library.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 4a47d926420bfec4a0e687b6ecc4cf52419e4f58 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 -+ $ -+) -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 -+#include -+ -+#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; -+} diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0019-lib-gpt-Implemented-generic-GPT-parser-for-flash.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0019-lib-gpt-Implemented-generic-GPT-parser-for-flash.patch deleted file mode 100644 index c75f1568..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0019-lib-gpt-Implemented-generic-GPT-parser-for-flash.patch +++ /dev/null @@ -1,1495 +0,0 @@ -From ea6748c8778d21e331b22ddea808f9343a654b4d Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Mon, 29 Dec 2025 17:36:22 +0000 -Subject: [PATCH] lib: gpt: Implemented generic GPT parser for flash - -The library can be used to parse GPT partitions on a flash device by -giving the library endpoint the GUID that identifies the partition. A -platform must register with the library a pseudo-device driver that -defines a read operation, allowing the library to perform I/O. - -Change-Id: Id504ceb93856561063751570a773c4aae592b535 -Signed-off-by: Frazer Carsley -Upstream-Status: Backport [2b155c6163f866757971ddf438014b518c4edd05] ---- - CMakeLists.txt | 5 + - config/config_base.cmake | 2 + - lib/gpt/CMakeLists.txt | 40 ++ - lib/gpt/config.cmake | 8 + - lib/gpt/inc/gpt.h | 80 ++++ - lib/gpt/inc/gpt_flash.h | 73 ++++ - lib/gpt/src/gpt.c | 592 ++++++++++++++++++++++++++++++ - lib/gpt/unittests/CMakeLists.txt | 179 +++++++++ - lib/gpt/unittests/gpt/test_gpt.c | 383 +++++++++++++++++++ - lib/gpt/unittests/gpt/utcfg.cmake | 28 ++ - 10 files changed, 1390 insertions(+) - create mode 100644 lib/gpt/CMakeLists.txt - create mode 100644 lib/gpt/config.cmake - create mode 100644 lib/gpt/inc/gpt.h - create mode 100644 lib/gpt/inc/gpt_flash.h - create mode 100644 lib/gpt/src/gpt.c - create mode 100644 lib/gpt/unittests/CMakeLists.txt - create mode 100644 lib/gpt/unittests/gpt/test_gpt.c - create mode 100644 lib/gpt/unittests/gpt/utcfg.cmake - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index b120de697..9e6e2ceda 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -42,6 +42,11 @@ set(CMAKE_CXX_COMPILER_FORCED true) - - project("Trusted Firmware M" VERSION ${TFM_VERSION} LANGUAGES C CXX ASM) - -+ -+if(PLATFORM_GPT_LIBRARY) -+ add_subdirectory(lib/gpt) -+endif() -+ - add_subdirectory(lib/backtrace) - add_subdirectory(lib/ext) - add_subdirectory(lib/efi_guid) -diff --git a/config/config_base.cmake b/config/config_base.cmake -index f4b2f3cd9..4cd14ab2b 100644 ---- a/config/config_base.cmake -+++ b/config/config_base.cmake -@@ -129,6 +129,8 @@ set(PLATFORM_DEFAULT_SYSTEM_RESET_HALT ON CACHE BOOL "Use default - set(PLATFORM_DEFAULT_IMAGE_SIGNING ON CACHE BOOL "Use default image signing implementation") - set(PLATFORM_DEFAULT_PROV_LINKER_SCRIPT ON CACHE BOOL "Use default provisioning linker script") - -+set(PLATFORM_GPT_LIBRARY OFF CACHE BOOL "Whether to build the GPT library or not") -+ - set(TFM_DUMMY_PROVISIONING ON CACHE BOOL "Provision with dummy values. NOT to be used in production") - - set(BL2_HEADER_SIZE 0x000 CACHE STRING "BL2 Header size") -diff --git a/lib/gpt/CMakeLists.txt b/lib/gpt/CMakeLists.txt -new file mode 100644 -index 000000000..2b5d6af8f ---- /dev/null -+++ b/lib/gpt/CMakeLists.txt -@@ -0,0 +1,40 @@ -+#------------------------------------------------------------------------------- -+# SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+#------------------------------------------------------------------------------- -+ -+cmake_minimum_required(VERSION 3.21) -+ -+add_library(tfm_gpt STATIC) -+ -+include(./config.cmake) -+ -+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") -+endif() -+ -+target_sources(tfm_gpt -+ PRIVATE -+ src/gpt.c -+) -+ -+target_include_directories(tfm_gpt -+ PUBLIC -+ $ -+) -+ -+target_compile_definitions(tfm_gpt -+ PUBLIC -+ TFM_GPT_BLOCK_SIZE=${TFM_GPT_BLOCK_SIZE} -+ PRIVATE -+ LOG_LEVEL=${GPT_LOG_LEVEL} -+) -+ -+target_link_libraries(tfm_gpt -+ PUBLIC -+ tfm_log_headers -+ PRIVATE -+ tfm_efi_guid -+) -diff --git a/lib/gpt/config.cmake b/lib/gpt/config.cmake -new file mode 100644 -index 000000000..9575aa8a8 ---- /dev/null -+++ b/lib/gpt/config.cmake -@@ -0,0 +1,8 @@ -+#------------------------------------------------------------------------------- -+# 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") -diff --git a/lib/gpt/inc/gpt.h b/lib/gpt/inc/gpt.h -new file mode 100644 -index 000000000..d98abe980 ---- /dev/null -+++ b/lib/gpt/inc/gpt.h -@@ -0,0 +1,80 @@ -+/* -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ */ -+ -+#ifndef __TFM_GPT_H__ -+#define __TFM_GPT_H__ -+ -+#include -+#include -+ -+#include "psa/error.h" -+#include "gpt_flash.h" -+#include "efi_guid_structs.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/** \brief Name length of a GPT partition entry. */ -+#define GPT_ENTRY_NAME_LENGTH 72 -+ -+/** -+ * \brief Information about a GPT partition presented to callers. -+ */ -+struct partition_entry_t { -+ uint64_t start; /**< Start Logical Block Address (LBA) of the partition. */ -+ uint64_t size; /**< Size of the partition in number of LBAs. */ -+ char name[GPT_ENTRY_NAME_LENGTH]; /**< Human readable name for the partition in unicode. */ -+ uint64_t attr; /**< Attributes associated with the partition. */ -+ struct efi_guid_t partition_guid; /**< Unique partition GUID. */ -+ struct efi_guid_t type_guid; /**< Partition type GUID. */ -+}; -+ -+/** -+ * \brief Reads the contents of a partition entry identified by a GUID. -+ * -+ * \param[in] guid GUID of the partition entry to read. -+ * \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 GUID. -+ */ -+__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 GPT header from the second block (LBA 1). -+ * -+ * \param[in] flash_driver Driver used to perform I/O. -+ * \param[in] max_partitions Maximum number of allowable partitions. -+ * -+ * \retval PSA_SUCCESS Success. -+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error. -+ * \retval PSA_ERROR_INVALID_ARGUMENT \p max_partitions is less than four, or one of the I/O -+ * functions defined by \p flash_driver is NULL. The init -+ * and uninit functions may be NULL if not required. -+ * \retval PSA_ERROR_NOT_SUPPORTED Legacy MBR is used and not GPT. -+ */ -+__attribute__((nonnull(1))) -+psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, -+ uint64_t max_partitions); -+ -+/** -+ * \brief Uninitialises the library. -+ * -+ * \retval PSA_SUCCESS Success. -+ * \retval PSA_ERROR_STORAGE_FAILURE I/O error. -+ */ -+psa_status_t gpt_uninit(void); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* __TFM_GPT_H__ */ -diff --git a/lib/gpt/inc/gpt_flash.h b/lib/gpt/inc/gpt_flash.h -new file mode 100644 -index 000000000..2b43390c1 ---- /dev/null -+++ b/lib/gpt/inc/gpt_flash.h -@@ -0,0 +1,73 @@ -+/* -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ */ -+ -+#ifndef __TFM_GPT_FLASH_H__ -+#define __TFM_GPT_FLASH_H__ -+ -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/** -+ * \brief Error codes returned by GPT flash driver operations. -+ */ -+typedef enum { -+ GPT_FLASH_SUCCESS = 0, /**< Operation completed successfully. */ -+ GPT_FLASH_GENERIC_ERROR = -1, /**< Unspecified error. */ -+ GPT_FLASH_NOT_INIT = -2, /**< Flash driver has not been initialised. */ -+ GPT_FLASH_UNAVAILABLE = -3, /**< Flash driver is unavailable. */ -+ GPT_FLASH_BAD_PARAM = -4, /**< Parameter supplied to the driver is invalid. */ -+} gpt_flash_err_t; -+ -+/** -+ * \brief Function used to initialise the driver. -+ * -+ * \retval GPT_FLASH_SUCCESS Success. -+ * \retval GPT_FLASH_GENERIC_ERROR Driver-specific failure. -+ */ -+typedef gpt_flash_err_t (*gpt_flash_init_t)(void); -+ -+/** -+ * \brief Function used to uninitialise the driver. -+ * -+ * \retval GPT_FLASH_SUCCESS Success. -+ * \retval GPT_FLASH_GENERIC_ERROR Driver-specific failure. -+ */ -+typedef gpt_flash_err_t (*gpt_flash_uninit_t)(void); -+ -+/** -+ * \brief Function that reads a logical block address. -+ * -+ * \param[in] lba Logical block address to read. -+ * \param[out] buf Buffer to populate. Must be at least the size of an LBA. -+ * -+ * \return Number of bytes read 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_read_t)(uint64_t lba, -+ void *buf); -+ -+/** -+ * \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. */ -+}; -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* __TFM_GPT_FLASH_H__ */ -diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c -new file mode 100644 -index 000000000..99d735797 ---- /dev/null -+++ b/lib/gpt/src/gpt.c -@@ -0,0 +1,592 @@ -+/* -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "psa/error.h" -+#include "gpt.h" -+#include "gpt_flash.h" -+#include "tfm_log.h" -+#include "efi_guid_structs.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) -+ */ -+#ifndef TFM_GPT_BLOCK_SIZE -+#error "TFM_GPT_BLOCK_SIZE must be defined if using GPT library!" -+#endif -+ -+/* Where Master Boot Record (MBR) is on flash */ -+#define MBR_LBA 0ULL -+ -+/* Number of unused bytes at the start of the MBR */ -+#define MBR_UNUSED_BYTES 446 -+ -+/* Cylinder Head Sector (CHS) length for MBR entry */ -+#define MBR_CHS_ADDRESS_LEN 3 -+ -+/* Number of entries in an MBR */ -+#define MBR_NUM_ENTRIES 4 -+ -+/* MBR signature as defined by UEFI spec */ -+#define MBR_SIG 0xAA55 -+ -+/* Type of MBR partition that indicates GPT in use */ -+#define MBR_TYPE_GPT 0xEE -+ -+/* Default GUID Partition Table (GPT) header size */ -+#define GPT_HEADER_SIZE 92 -+ -+/* "EFI PART" (without null byte) */ -+#define GPT_SIG "EFI PART" -+#define GPT_SIG_LEN 8 -+ -+/* Default partition entry size */ -+#define GPT_ENTRY_SIZE 128 -+ -+/* Minimum number of partition entries according to spec */ -+#define GPT_MIN_PARTITIONS 4 -+ -+/* Logical Block Address (LBA) for primary GPT */ -+#define PRIMARY_GPT_LBA 1 -+ -+/* LBA for primary GPT partition array */ -+#define PRIMARY_GPT_ARRAY_LBA 2 -+ -+/* MBR partition entry - both for protective MBR entry and -+ * legacy MBR entry -+ */ -+struct mbr_entry_t { -+ /* Indicates if bootable */ -+ uint8_t status; -+ /* For legacy MBR, not used by UEFI firmware. For protective MBR, set to -+ * 0x000200 -+ */ -+ uint8_t first_sector[MBR_CHS_ADDRESS_LEN]; -+ /* Type of partition */ -+ uint8_t os_type; -+ /* For legacy MBR, not used by UEFI firmware. For protective MBR, last -+ * block on flash. -+ */ -+ uint8_t last_sector[MBR_CHS_ADDRESS_LEN]; -+ /* For legacy MBR, starting LBA of partition. For protective MBR, set to -+ * 0x00000001 -+ */ -+ uint32_t first_lba; -+ /* For legacy MBR, size of partition. For protective MBR, size of flash -+ * minus one -+ */ -+ uint32_t size; -+} __attribute__((packed)); -+ -+/* MBR. This structure is used both for protective MBR and legacy MBR. The boot -+ * code, flash signature and unknown sections are not read because they are -+ * unused and do not change. -+ */ -+struct mbr_t { -+ /* Boot code at offset 0 is unused in EFI */ -+ /* Unique MBR Disk signature at offset 440 is unused */ -+ /* The next 2 bytes are also unused */ -+ /* Array of four MBR partition records. For protective MBR, only the first -+ * is valid -+ */ -+ struct mbr_entry_t partitions[MBR_NUM_ENTRIES]; -+ /* 0xAA55 */ -+ uint16_t sig; -+} __attribute__((packed)); -+ -+/* A GPT partition entry. */ -+ struct gpt_entry_t { -+ struct efi_guid_t partition_type; /* Partition type, defining purpose */ -+ struct efi_guid_t unique_guid; /* Unique GUID that defines each partition */ -+ uint64_t start; /* Starting LBA for partition */ -+ uint64_t end; /* Ending LBA for partition */ -+ uint64_t attr; /* Attribute bits */ -+ char name[GPT_ENTRY_NAME_LENGTH]; /* Human readable name for partition */ -+} __attribute__((packed)); -+ -+/* The GPT header. */ -+struct gpt_header_t { -+ char signature[GPT_SIG_LEN]; /* "EFI PART" */ -+ uint32_t revision; /* Revision number */ -+ uint32_t size; /* Size of this header */ -+ uint32_t header_crc; /* CRC of this header */ -+ uint32_t reserved; /* Reserved */ -+ uint64_t current_lba; /* LBA of this header */ -+ uint64_t backup_lba; /* LBA of backup GPT header */ -+ uint64_t first_lba; /* First usable LBA */ -+ uint64_t last_lba; /* Last usable LBA */ -+ struct efi_guid_t flash_guid; /* Disk GUID */ -+ uint64_t array_lba; /* First LBA of array of partition entries */ -+ uint32_t num_partitions; /* Number of partition entries in array */ -+ uint32_t entry_size; /* Size of a single partition entry */ -+ uint32_t array_crc; /* CRC of partitions array */ -+} __attribute__((packed)); -+ -+/* A GUID partition table in memory. The array is not stored in memory -+ * due to its size -+ */ -+struct gpt_t { -+ struct gpt_header_t header; /* GPT header */ -+ uint32_t num_used_partitions; /* Number of in-use partitions */ -+}; -+ -+/* A function for comparing some gpt entry's attribute with something known. -+ * Used to find entries of a certain kind, such as with a particular GUID, -+ * name or type. -+ */ -+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 flash driver, used to perform I/O */ -+static struct gpt_flash_driver_t *plat_flash_driver = NULL; -+ -+/* Maximum partitions on platform */ -+static uint32_t plat_max_partitions = 0; -+ -+/* The primary GPT (also used if legacy MBR, but GPT header and partition -+ * entries are zero'd) -+ */ -+static struct gpt_t primary_gpt = {0}; -+ -+/* Buffer to use for LBA I/O */ -+static uint8_t lba_buf[TFM_GPT_BLOCK_SIZE] = {0}; -+ -+/* LBA that is cached in the buffer. Zero is valid only for protective MBR, all -+ * other GPT operations must have LBA of one or greater -+ */ -+static uint64_t cached_lba = 0; -+ -+/* Helper function prototypes */ -+__attribute__((unused)) -+static void print_guid(struct efi_guid_t guid); -+__attribute__((unused)) -+static void dump_table(const struct gpt_t *table, bool header_only); -+__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 gpt_entry_per_lba_count(void); -+static psa_status_t count_used_partitions(const struct gpt_t *table, -+ uint32_t *num_used); -+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, -+ struct gpt_entry_t *entry); -+static psa_status_t read_table_from_flash(struct gpt_t *table, bool is_primary); -+static psa_status_t find_gpt_entry(const struct gpt_t *table, -+ gpt_entry_cmp_t compare, -+ const void *attr, -+ const uint32_t repeat_index, -+ struct gpt_entry_t *entry, -+ 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); -+ -+/* PUBLIC API FUNCTIONS */ -+ -+psa_status_t gpt_entry_read(const struct efi_guid_t *guid, -+ 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_guid, guid, 0, &cached_entry, NULL); -+ if (ret != PSA_SUCCESS) { -+ 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; -+ -+ return PSA_SUCCESS; -+} -+ -+/* Initialises GPT from first block. */ -+psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, uint64_t max_partitions) -+{ -+ cached_lba = 0; -+ 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) { -+ ERROR("I/O functions must be defined\n"); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ /* Retain information needed to perform I/O. */ -+ if (plat_flash_driver == NULL) { -+ plat_flash_driver = flash_driver; -+ } -+ if (plat_max_partitions == 0) { -+ plat_max_partitions = max_partitions; -+ } -+ if (plat_flash_driver->init != NULL) { -+ if (plat_flash_driver->init() != 0) { -+ ERROR("Unable to initialise flash driver\n"); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ } -+ -+ struct mbr_t mbr; -+ psa_status_t ret = mbr_load(&mbr); -+ if (ret != PSA_SUCCESS) { -+ goto fail_load; -+ } -+ -+ /* If the first record has type 0xEE (GPT protective), then the flash uses -+ * GPT. Else, treat it as legacy MBR -+ */ -+ if (mbr.partitions[0].os_type == MBR_TYPE_GPT) { -+ ret = read_table_from_flash(&primary_gpt, true); -+ } else { -+ WARN("Unsupported legacy MBR in use\n"); -+ ret = PSA_ERROR_NOT_SUPPORTED; -+ } -+ -+ if (ret != PSA_SUCCESS) { -+ goto fail_load; -+ } -+ -+ /* Count the number of used entries, assuming the array is not sparese */ -+ ret = count_used_partitions(&primary_gpt, &primary_gpt.num_used_partitions); -+ if (ret != PSA_SUCCESS) { -+ goto fail_load; -+ } -+ -+ /* Read the backup GPT and cache necessary values */ -+ backup_gpt_lba = primary_gpt.header.backup_lba; -+ if (backup_gpt_lba != 0) { -+ struct gpt_t backup_gpt; -+ ret = read_table_from_flash(&backup_gpt, false); -+ if (ret != PSA_SUCCESS) { -+ goto fail_load; -+ } -+ } else { -+ WARN("Backup GPT location is unknown!\n"); -+ } -+ -+ return PSA_SUCCESS; -+ -+fail_load: -+ /* Reset so that the user can try with something else if desired */ -+ plat_flash_driver = NULL; -+ plat_max_partitions = 0; -+ backup_gpt_lba = 0; -+ cached_lba = 0; -+ -+ return ret; -+} -+ -+psa_status_t gpt_uninit(void) -+{ -+ psa_status_t ret = PSA_SUCCESS; -+ -+ if (plat_flash_driver) { -+ /* Uninitialise driver if function provided */ -+ if (plat_flash_driver->uninit != NULL) { -+ if (plat_flash_driver->uninit() != 0) { -+ ERROR("Unable to uninitialise flash driver\n"); -+ ret = PSA_ERROR_STORAGE_FAILURE; -+ } -+ } -+ } -+ -+ plat_flash_driver = NULL; -+ plat_max_partitions = 0; -+ backup_gpt_lba = 0; -+ cached_lba = 0; -+ -+ return ret; -+} -+ -+/* Returns the number of partition entries in each LBA */ -+static inline uint64_t gpt_entry_per_lba_count(void) -+{ -+ static uint64_t num_entries = 0; -+ if (num_entries == 0) { -+ num_entries = TFM_GPT_BLOCK_SIZE / primary_gpt.header.entry_size; -+ } -+ return num_entries; -+} -+ -+/* Compare the entry with the given guid */ -+static bool gpt_entry_cmp_guid(const struct gpt_entry_t *entry, const void *guid) -+{ -+ const struct efi_guid_t *cmp_guid = (const struct efi_guid_t *)guid; -+ const struct efi_guid_t entry_guid = entry->unique_guid; -+ -+ return efi_guid_cmp(&entry_guid, cmp_guid) == 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, -+ const void *cmp_attr, -+ const uint32_t repeat_index, -+ struct gpt_entry_t *entry, -+ uint32_t *array_index) -+{ -+ if (table->num_used_partitions == 0) { -+ return PSA_ERROR_DOES_NOT_EXIST; -+ } -+ -+ uint32_t num_found = 0; -+ bool io_failure = false; -+ for (uint32_t i = 0; i < table->num_used_partitions; ++i) { -+ const psa_status_t ret = read_entry_from_flash(table, i, entry); -+ if (ret != PSA_SUCCESS) { -+ /* This might not have been the partition being sought after anyway, -+ * so may as well try the rest -+ */ -+ io_failure = true; -+ continue; -+ } -+ -+ if (compare(entry, cmp_attr) && num_found++ == repeat_index) { -+ if (array_index != NULL) { -+ *array_index = i; -+ } -+ return PSA_SUCCESS; -+ } -+ } -+ -+ return io_failure ? PSA_ERROR_STORAGE_FAILURE : PSA_ERROR_DOES_NOT_EXIST; -+} -+ -+/* Load MBR from flash */ -+static psa_status_t mbr_load(struct mbr_t *mbr) -+{ -+ /* Read the beginning of the first block of flash, which will contain either -+ * a legacy MBR or a protective MBR (in the case of GPT). The first -+ * MBR_UNUSED_BYTES are unused and so do not need to be considered. -+ */ -+ ssize_t ret = plat_flash_driver->read(MBR_LBA, lba_buf); -+ if (ret != TFM_GPT_BLOCK_SIZE) { -+ ERROR("Unable to read from flash at block 0x%08x%08x\n", -+ (uint32_t)(MBR_LBA >> 32), -+ (uint32_t)MBR_LBA); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ memcpy(mbr, lba_buf + MBR_UNUSED_BYTES, sizeof(*mbr)); -+ -+ /* Check MBR boot signature */ -+ if (mbr->sig != MBR_SIG) { -+ ERROR("MBR signature incorrect\n"); -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ -+ return PSA_SUCCESS; -+} -+ -+/* Reads an LBA from the flash device and caches it. If the requested LBA is -+ * already cached, this is a no-op -+ */ -+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 (ret != TFM_GPT_BLOCK_SIZE) { -+ ERROR("Unable to read from flash at block 0x%08x%08x\n", -+ (uint32_t)(required_lba >> 32), -+ (uint32_t)required_lba); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ cached_lba = required_lba; -+ } -+ -+ return PSA_SUCCESS; -+} -+ -+/* Returns the LBA that a particular partition entry is in based on its position -+ * in the array -+ */ -+static uint64_t inline partition_entry_lba(const struct gpt_t *table, -+ uint32_t array_index) -+{ -+ return table->header.array_lba + (array_index / gpt_entry_per_lba_count()); -+} -+ -+/* Returns the number of partition entries used in the array, assuming the -+ * array is not sparse -+ */ -+static psa_status_t count_used_partitions(const struct gpt_t *table, -+ uint32_t *num_used) -+{ -+ for (uint32_t i = 0; i < table->header.num_partitions; ++i) { -+ struct gpt_entry_t entry = {0}; -+ const psa_status_t ret = read_entry_from_flash(table, i, &entry); -+ if (ret != PSA_SUCCESS) { -+ return ret; -+ } -+ -+ const struct efi_guid_t null_guid = NULL_GUID; -+ const struct efi_guid_t entry_guid = entry.partition_type; -+ if (efi_guid_cmp(&null_guid, &entry_guid) == 0) { -+ *num_used = i; -+ return PSA_SUCCESS; -+ } -+ } -+ -+ *num_used = table->header.num_partitions; -+ return PSA_SUCCESS; -+} -+ -+/* Reads a GPT entry from the given table on flash */ -+static psa_status_t read_entry_from_flash(const struct gpt_t *table, -+ uint32_t array_index, -+ struct gpt_entry_t *entry) -+{ -+ uint64_t required_lba = partition_entry_lba(table, array_index); -+ const psa_status_t ret = read_from_flash(required_lba); -+ if (ret != PSA_SUCCESS) { -+ return ret; -+ } -+ -+ memcpy( -+ entry, -+ lba_buf + ((array_index % gpt_entry_per_lba_count()) * table->header.entry_size), -+ GPT_ENTRY_SIZE); -+ -+ return PSA_SUCCESS; -+} -+ -+/* Reads a GPT table from flash */ -+static psa_status_t read_table_from_flash(struct gpt_t *table, bool is_primary) -+{ -+ if (!is_primary && backup_gpt_lba == 0) { -+ ERROR("Backup GPT location unknown!\n"); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } -+ -+ const psa_status_t ret = read_from_flash(is_primary ? PRIMARY_GPT_LBA : backup_gpt_lba); -+ if (ret != PSA_SUCCESS) { -+ return ret; -+ } -+ -+ memcpy(&(table->header), lba_buf, GPT_HEADER_SIZE); -+ -+ return PSA_SUCCESS; -+} -+ -+/* Converts unicode string to valid ascii */ -+static psa_status_t unicode_to_ascii(const char *unicode, char *ascii) -+{ -+ /* Check whether the unicode string is valid */ -+ if (unicode[0] == '\0') { -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ for (int i = 1; i < GPT_ENTRY_NAME_LENGTH; i += 2) { -+ if (unicode[i] != '\0') { -+ return PSA_ERROR_INVALID_ARGUMENT; -+ } -+ } -+ -+ /* Convert the unicode string to ascii string */ -+ for (int i = 0; i < GPT_ENTRY_NAME_LENGTH; i += 2) { -+ ascii[i >> 1] = unicode[i]; -+ if (unicode[i] == '\0') { -+ break; -+ } -+ } -+ -+ return PSA_SUCCESS; -+} -+ -+/* Prints guid in human readable format. Useful for debugging but should never -+ * be used in production, hence marked as unused -+ */ -+static void print_guid(struct efi_guid_t guid) -+{ -+ INFO("%04x%04x-%04x-%04x-%04x-%04x%04x%04x\n", -+ ((uint16_t *)&guid)[0], -+ ((uint16_t *)&guid)[1], -+ ((uint16_t *)&guid)[2], -+ ((uint16_t *)&guid)[3], -+ ((uint16_t *)&guid)[4], -+ ((uint16_t *)&guid)[5], -+ ((uint16_t *)&guid)[6], -+ ((uint16_t *)&guid)[7]); -+} -+ -+/* Dumps header and optionally meta-data about array. Useful for debugging, -+ * but should never be used in production, hence marked as unused. -+ */ -+static void dump_table(const struct gpt_t *table, bool header_only) -+{ -+ /* Print the header first */ -+ const struct gpt_header_t *header = &(table->header); -+ INFO("----------\n"); -+ INFO("Signature: %8s\n", header->signature); -+ INFO("Revision: 0x%08x\n", header->revision); -+ INFO("HeaderSize: 0x%08x\n", header->size); -+ INFO("HeaderCRC32: 0x%08x\n", header->header_crc); -+ INFO("Reserved: 0x%08x\n", header->reserved); -+ INFO("MyLBA: 0x%08x%08x\n", -+ (uint32_t)(header->current_lba >> 32), -+ (uint32_t)(header->current_lba)); -+ INFO("AlternateLBA: 0x%08x%08x\n", -+ (uint32_t)(header->backup_lba >> 32), -+ (uint32_t)(header->backup_lba)); -+ INFO("FirstUsableLBA: 0x%08x%08x\n", -+ (uint32_t)(header->first_lba >> 32), -+ (uint32_t)(header->first_lba)); -+ INFO("LastUsableLBA: 0x%08x%08x\n", -+ (uint32_t)(header->last_lba >> 32), -+ (uint32_t)(header->last_lba)); -+ INFO("DiskGUID: "); -+ print_guid(header->flash_guid); -+ INFO("ParitionEntryLBA: 0x%08x%08x\n", -+ (uint32_t)(header->array_lba >> 32), -+ (uint32_t)(header->array_lba)); -+ INFO("NumberOfPartitionEntries: 0x%08x\n", header->num_partitions); -+ INFO("SizeOfPartitionEntry: 0x%08x\n", header->entry_size); -+ INFO("PartitionEntryArrayCRC32: 0x%08x\n", header->array_crc); -+ INFO("----------\n"); -+ -+ if (!header_only) { -+ /* Now print meta-data for each entry, including those not in use */ -+ for (uint32_t i = 0; i < table->num_used_partitions; ++i) { -+ struct gpt_entry_t entry; -+ psa_status_t ret = read_entry_from_flash(&primary_gpt, i, &entry); -+ if (ret != PSA_SUCCESS) { -+ continue; -+ } -+ -+ INFO("Entry number: %u\n", i); -+ INFO("\tPartitionTypeGUID: "); -+ print_guid(entry.partition_type); -+ INFO("\tUniquePartitionGUID: "); -+ print_guid(entry.unique_guid); -+ INFO("\tStartingLBA: 0x%08x%08x\n", -+ (uint32_t)(entry.start >> 32), -+ (uint32_t)(entry.start)); -+ INFO("\tEndingLBA: 0x%08x%08x\n", -+ (uint32_t)(entry.end >> 32), -+ (uint32_t)(entry.end)); -+ INFO("\tAttributes: 0x%08x%08x\n", -+ (uint32_t)(entry.attr >> 32), -+ (uint32_t)(entry.attr)); -+ char name[GPT_ENTRY_NAME_LENGTH >> 1]; -+ if (unicode_to_ascii(entry.name, name) != PSA_SUCCESS) { -+ INFO("\tPartitionName: [Not valid ascii]\n"); -+ } else { -+ INFO("\tPartitionName: %s\n", name); -+ } -+ } -+ } -+} -diff --git a/lib/gpt/unittests/CMakeLists.txt b/lib/gpt/unittests/CMakeLists.txt -new file mode 100644 -index 000000000..61c7078e5 ---- /dev/null -+++ b/lib/gpt/unittests/CMakeLists.txt -@@ -0,0 +1,179 @@ -+#------------------------------------------------------------------------------- -+# SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+#------------------------------------------------------------------------------- -+cmake_minimum_required(VERSION 3.21) -+ -+if (NOT DEFINED TFM_UNITTESTS_PATHS) -+ message(FATAL_ERROR "Please provide absolute paths to the unittests using -DTFM_UNITTESTS_PATHS=") -+endif() -+ -+if (NOT DEFINED TFM_ROOT_DIR) -+ message(FATAL_ERROR "Please provide absolute paths to the TF-M root directory using -DTFM_ROOT_DIR=") -+endif() -+ -+list(APPEND CMAKE_MODULE_PATH ${TFM_ROOT_DIR}/cmake) -+ -+project( -+ "tfm_gpt_unit_tests" -+ VERSION 1.0.0 -+ LANGUAGES C -+) -+ -+enable_testing() -+include(CTest) -+ -+find_package(Ruby) -+find_program(LCOV lcov REQUIRED) -+find_program(GENHTML genhtml REQUIRED) -+ -+set(UNITY_SRC_DIR ${TFM_ROOT_DIR}/platform/ext/target/arm/rse/common/unittests/framework/unity) -+set(CMOCK_SRC_DIR ${TFM_ROOT_DIR}/platform/ext/target/arm/rse/common/unittests/framework/cmock) -+ -+add_subdirectory(${UNITY_SRC_DIR} ${UNITY_SRC_DIR}) -+add_subdirectory(${CMOCK_SRC_DIR} ${CMOCK_SRC_DIR}) -+ -+function(generate_test UNIT_NAME UNIT_PATH) -+ include(${UNIT_PATH}/utcfg.cmake) -+ -+ # Generate runner for the test -+ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/unittests/${UNIT_NAME}) -+ add_custom_command( -+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/unittests/${UNIT_NAME}/test_runner.c -+ COMMAND ${Ruby_EXECUTABLE} -+ ${UNITY_PATH}/auto/generate_test_runner.rb -+ ${UNITY_SRC_DIR}/cfg.yml -+ ${UNIT_TEST_SUITE} -+ ${CMAKE_CURRENT_BINARY_DIR}/unittests/${UNIT_NAME}/test_runner.c -+ COMMENT "Generating test runner for ${UNIT_NAME}" -+ ) -+ -+ # test_ is the runner for -+ add_executable(test_${UNIT_NAME} ${UNIT_UNDER_TEST} -+ ${UNIT_TEST_SUITE} -+ ${CMAKE_CURRENT_BINARY_DIR}/unittests/${UNIT_NAME}/test_runner.c -+ ${UNIT_TEST_DEPS} -+ ) -+ -+ # Enable debug syms & coverage support while compiling -+ target_compile_options(test_${UNIT_NAME} -+ PUBLIC -+ -g3 -+ -fprofile-arcs -+ -ftest-coverage -+ ) -+ -+ target_link_libraries(test_${UNIT_NAME} -+ PRIVATE cmock -+ PRIVATE unity -+ PRIVATE gcov -+ ${UNIT_TEST_LINK_LIBS} -+ ) -+ -+ target_include_directories(test_${UNIT_NAME} -+ PUBLIC -+ ${UNIT_TEST_INCLUDE_DIRS} -+ ) -+ -+ # UNIT_TEST must always be defined, each unit test may define more -+ target_compile_definitions(test_${UNIT_NAME} -+ PUBLIC -+ UNIT_TEST -+ ${UNIT_TEST_COMPILE_DEFS} -+ ) -+ -+ # For every in, we build test_ -+ add_test( -+ NAME ${UNIT_NAME} -+ COMMAND test_${UNIT_NAME} -+ ) -+ -+ # Generate mocks -+ foreach(FILEPATH_TO_MOCK ${MOCK_HEADERS}) -+ get_filename_component(FILENAME_TO_MOCK ${FILEPATH_TO_MOCK} NAME_WE) -+ set(MOCK_TARGET ${UNIT_NAME}_mock_${FILENAME_TO_MOCK}) -+ -+ # Invoke CMock to generate mock_ -+ add_custom_command( -+ OUTPUT -+ ${CMAKE_BINARY_DIR}/unittests/${UNIT_NAME}/mock_${FILENAME_TO_MOCK}.c -+ COMMAND ${CMAKE_COMMAND} -E env -+ UNITY_DIR=${UNITY_PATH} -+ ${Ruby_EXECUTABLE} -+ ${CMOCK_PATH}/lib/cmock.rb -+ -o${CMOCK_SRC_DIR}/cfg.yml -+ ${FILEPATH_TO_MOCK} -+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/unittests/${UNIT_NAME} -+ DEPENDS ${FILEPATH_TO_MOCK} -+ COMMENT "Mocking ${FILEPATH_TO_MOCK} for ${UNIT_NAME}" -+ ) -+ -+ target_sources( -+ test_${UNIT_NAME} PRIVATE -+ ${CMAKE_BINARY_DIR}/unittests/${UNIT_NAME}/mock_${FILENAME_TO_MOCK}.c -+ ) -+ -+ target_include_directories( -+ test_${UNIT_NAME} PRIVATE -+ ${CMAKE_BINARY_DIR}/unittests/${UNIT_NAME} -+ ) -+ endforeach() -+endfunction() -+ -+# unittests target -+# Depends on -+# - All tests detected -+# Performs -+# - Execute all tests -+# - Generate and filter coverage info -+# - Convert report into browsable html -+add_custom_target(unittests) -+ -+add_custom_command( -+ TARGET unittests -+ POST_BUILD -+ COMMAND ${CMAKE_CTEST_COMMAND} -+ ARGS -+ --output-on-failure -+ COMMAND ${LCOV} -+ ARGS -+ --capture -+ --directory ${CMAKE_CURRENT_BINARY_DIR} -+ --output-file raw_test_coverage.info -+ > lcov.log 2>&1 -+ COMMAND ${LCOV} -+ ARGS -+ --remove raw_test_coverage.info -+ -o test_coverage.info -+ '/usr/*' -+ '${CMAKE_BINARY_DIR}/*' -+ '*tests*' -+ >> lcov.log 2>&1 -+ COMMAND ${GENHTML} -+ ARGS -+ test_coverage.info -+ --output-directory ${CMAKE_BINARY_DIR}/coverage_report -+ >> lcov.log 2>&1 -+ COMMAND ${CMAKE_COMMAND} -+ ARGS -+ -E echo "Coverage Report: file://${CMAKE_BINARY_DIR}/coverage_report/index.html" -+) -+ -+foreach(TFM_UNITTESTS_PATH ${TFM_UNITTESTS_PATHS}) -+ if (NOT EXISTS ${TFM_UNITTESTS_PATH}) -+ message(FATAL_ERROR "Path ${TFM_UNITTESTS_PATH} does not exist.") -+ endif() -+ -+ file(GLOB_RECURSE UNIT_PATHS LIST_DIRECTORIES TRUE "${TFM_UNITTESTS_PATH}/*") -+ foreach(UNIT_PATH ${UNIT_PATHS}) -+ # Only for directories that contain a utcfg.cmake -+ if(IS_DIRECTORY ${UNIT_PATH} AND EXISTS ${UNIT_PATH}/utcfg.cmake) -+ get_filename_component(UNIT_NAME ${UNIT_PATH} NAME) -+ message(STATUS "Found ${UNIT_NAME}") -+ generate_test(${UNIT_NAME} ${UNIT_PATH}) -+ add_dependencies(unittests test_${UNIT_NAME}) -+ endif() -+ endforeach() -+endforeach() -\ No newline at end of file -diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c -new file mode 100644 -index 000000000..325887fae ---- /dev/null -+++ b/lib/gpt/unittests/gpt/test_gpt.c -@@ -0,0 +1,383 @@ -+/* -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ */ -+ -+#include -+#include -+ -+#include "unity.h" -+ -+#include "mock_tfm_log.h" -+#include "mock_tfm_vprintf.h" -+ -+#include "efi_guid_structs.h" -+#include "gpt_flash.h" -+#include "gpt.h" -+#include "psa/error.h" -+ -+/* Basic mocked disk layout and number of partitions */ -+#define TEST_BLOCK_SIZE 512 -+#define TEST_DISK_NUM_BLOCKS 128 -+#define TEST_MAX_PARTITIONS 4 -+#define TEST_DEFAULT_NUM_PARTITIONS TEST_MAX_PARTITIONS - 1 -+ -+/* Maximum number of mocked reads per test */ -+#define TEST_MOCK_BUFFER_SIZE 512 -+ -+/* Master Boot Record (MBR) definitions for test */ -+#define TEST_MBR_SIG 0xAA55 -+#define TEST_MBR_TYPE_GPT 0xEE -+#define TEST_MBR_CHS_ADDRESS_LEN 3 -+#define TEST_MBR_NUM_PARTITIONS 4 -+#define TEST_MBR_UNUSED_BYTES 446 -+ -+/* GUID Partition Table (GPT) header values */ -+#define TEST_GPT_SIG_LEN 8 -+#define TEST_GPT_SIG_INITIALISER {'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T'} -+#define TEST_GPT_REVISION 0x00010000 -+#define TEST_GPT_HEADER_SIZE 92 -+#define TEST_GPT_CRC32 42 -+#define TEST_GPT_PRIMARY_LBA 1 -+#define TEST_GPT_BACKUP_LBA (TEST_DISK_NUM_BLOCKS - 1) -+#define TEST_GPT_ARRAY_LBA (TEST_GPT_PRIMARY_LBA + 1) -+#define TEST_GPT_BACKUP_ARRAY_LBA (TEST_GPT_BACKUP_LBA - 1) -+#define TEST_GPT_FIRST_USABLE_LBA (TEST_GPT_ARRAY_LBA + 2) -+#define TEST_GPT_LAST_USABLE_LBA (TEST_GPT_BACKUP_LBA - 2) -+#define TEST_GPT_DISK_GUID MAKE_EFI_GUID(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) -+#define TEST_GPT_ENTRY_SIZE 128 -+ -+/* Test data. These are defined to be not fragmented */ -+#define TEST_GPT_FIRST_PARTITION_START TEST_GPT_FIRST_USABLE_LBA -+#define TEST_GPT_FIRST_PARTITION_END (TEST_GPT_FIRST_PARTITION_START + 3) -+#define TEST_GPT_SECOND_PARTITION_START (TEST_GPT_FIRST_PARTITION_END + 1) -+#define TEST_GPT_SECOND_PARTITION_END (TEST_GPT_SECOND_PARTITION_START + 50) -+#define TEST_GPT_THIRD_PARTITION_START (TEST_GPT_SECOND_PARTITION_END + 1) -+#define TEST_GPT_THIRD_PARTITION_END (TEST_GPT_THIRD_PARTITION_START + 1) -+ -+/* Populates a backup header from a primary header and calculates the new CRC32 */ -+#define MAKE_BACKUP_HEADER(backup, primary) \ -+ do { \ -+ memcpy(&backup, &primary, TEST_GPT_HEADER_SIZE); \ -+ backup.header_crc = TEST_GPT_CRC32; \ -+ backup.current_lba = primary.backup_lba; \ -+ backup.backup_lba = primary.current_lba; \ -+ backup.array_lba = TEST_GPT_BACKUP_ARRAY_LBA; \ -+ } while (0) -+ -+/* MBR partition entry */ -+struct mbr_entry_t { -+ /* Indicates if bootable */ -+ uint8_t status; -+ /* For legacy MBR, not used by UEFI firmware. For protective MBR, set to -+ * 0x000200 -+ */ -+ uint8_t first_sector[TEST_MBR_CHS_ADDRESS_LEN]; -+ /* Type of partition */ -+ uint8_t os_type; -+ /* For legacy MBR, not used by UEFI firmware. For protective MBR, last -+ * block on disk. -+ */ -+ uint8_t last_sector[TEST_MBR_CHS_ADDRESS_LEN]; -+ /* For legacy MBR, starting LBA of partition. For protective MBR, set to -+ * 0x00000001 -+ */ -+ uint32_t first_lba; -+ /* For legacy MBR, size of partition. For protective MBR, size of disk -+ * minus one -+ */ -+ uint32_t size; -+} __attribute__((packed)); -+ -+/* Master Boot Record. */ -+struct mbr_t { -+ /* Unused bytes */ -+ uint8_t unused[TEST_MBR_UNUSED_BYTES]; -+ /* Array of four MBR partition records. For protective MBR, only the first -+ * is valid -+ */ -+ struct mbr_entry_t partitions[TEST_MBR_NUM_PARTITIONS]; -+ /* 0xAA55 */ -+ uint16_t sig; -+} __attribute__((packed)); -+ -+/* A gpt partition entry */ -+struct gpt_entry_t { -+ struct efi_guid_t type; /* Partition type */ -+ struct efi_guid_t guid; /* Unique GUID */ -+ uint64_t start; /* Starting LBA for partition */ -+ uint64_t end; /* Ending LBA for partition */ -+ uint64_t attr; /* Attribute bits */ -+ char name[GPT_ENTRY_NAME_LENGTH]; /* Human readable name for partition */ -+} __attribute__((packed)); -+ -+/* The gpt header */ -+struct gpt_header_t { -+ char signature[TEST_GPT_SIG_LEN]; /* "EFI PART" */ -+ uint32_t revision; /* Revision number. */ -+ uint32_t size; /* Size of this header */ -+ uint32_t header_crc; /* CRC of this header */ -+ uint32_t reserved; /* Reserved */ -+ uint64_t current_lba; /* LBA of this header */ -+ uint64_t backup_lba; /* LBA of backup GPT header */ -+ uint64_t first_lba; /* First usable LBA */ -+ uint64_t last_lba; /* Last usable LBA */ -+ struct efi_guid_t disk_guid; /* Disk GUID */ -+ uint64_t array_lba; /* First LBA of array of partition entries */ -+ uint32_t num_partitions; /* Number of partition entries in array */ -+ uint32_t entry_size; /* Size of a single partition entry */ -+ uint32_t array_crc; /* CRC of partition entry array */ -+} __attribute__((packed)); -+ -+static void register_mocked_read(void *buf, size_t num_bytes); -+static ssize_t test_driver_read(uint64_t lba, void *buf); -+ -+/* LBA driver used in test module */ -+static struct gpt_flash_driver_t mock_driver = { -+ .init = NULL, -+ .uninit = NULL, -+ .read = test_driver_read, -+}; -+ -+/* Valid MBR. Only signature is required to be valid */ -+static struct mbr_t default_mbr = { -+ .unused = {0}, -+ .sig = TEST_MBR_SIG, -+}; -+static struct mbr_t test_mbr; -+ -+/* Default GPT header. CRC values need to be populated to be valid. */ -+static struct gpt_header_t default_header = { -+ .signature = TEST_GPT_SIG_INITIALISER, -+ .revision = TEST_GPT_REVISION, -+ .size = TEST_GPT_HEADER_SIZE, -+ .header_crc = TEST_GPT_CRC32, -+ .reserved = 0, -+ .current_lba = TEST_GPT_PRIMARY_LBA, -+ .backup_lba = TEST_GPT_BACKUP_LBA, -+ .first_lba = TEST_GPT_FIRST_USABLE_LBA, -+ .last_lba = TEST_GPT_LAST_USABLE_LBA, -+ .disk_guid = TEST_GPT_DISK_GUID, -+ .array_lba = TEST_GPT_ARRAY_LBA, -+ .num_partitions = TEST_MAX_PARTITIONS, -+ .entry_size = TEST_GPT_ENTRY_SIZE, -+ .array_crc = TEST_GPT_CRC32 -+}; -+static struct gpt_header_t test_header; -+ -+/* Default entry array. This is valid, though fragmented. */ -+static struct gpt_entry_t default_partition_array[TEST_DEFAULT_NUM_PARTITIONS] = { -+ { -+ .type = MAKE_EFI_GUID(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), -+ .guid = MAKE_EFI_GUID(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), -+ .start = TEST_GPT_FIRST_PARTITION_START, -+ .end = TEST_GPT_FIRST_PARTITION_END, -+ .attr = 0, -+ .name = "First partition" -+ }, -+ { -+ .type = MAKE_EFI_GUID(2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), -+ .guid = MAKE_EFI_GUID(2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), -+ .start = TEST_GPT_SECOND_PARTITION_START, -+ .end = TEST_GPT_SECOND_PARTITION_END, -+ .attr = 0, -+ .name = "Second partition" -+ }, -+ { -+ .type = MAKE_EFI_GUID(3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11), -+ .guid = MAKE_EFI_GUID(3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11), -+ .start = TEST_GPT_THIRD_PARTITION_START, -+ .end = TEST_GPT_THIRD_PARTITION_END, -+ .attr = 0, -+ .name = "Third partition" -+ } -+}; -+static struct gpt_entry_t test_partition_array[TEST_MAX_PARTITIONS]; -+ -+/* Set to determine what is "read" by the flash driver. Allows for the mocking -+ * of multiple read calls -+ */ -+static unsigned int num_mocked_reads = 0; -+static unsigned int registered_mocked_reads = 0; -+static uint8_t mock_read_buffer[TEST_MOCK_BUFFER_SIZE][TEST_BLOCK_SIZE] = {0}; -+ -+/* Turn ascii string to unicode */ -+static void ascii_to_unicode(const char *ascii, char *unicode) -+{ -+ for (int i = 0; i < strlen(ascii) + 1; ++i) { -+ unicode[i << 1] = ascii[i]; -+ unicode[(i << 1) + 1] = '\0'; -+ } -+} -+ -+/* Tell the test what to return from the next read call. This is very much -+ * whitebox testing -+ */ -+static void register_mocked_read(void *data, size_t num_bytes) -+{ -+ memcpy(mock_read_buffer[registered_mocked_reads++], data, num_bytes); -+} -+ -+/* Driver function that always succeeds in reading the data it has been given */ -+static ssize_t test_driver_read(uint64_t lba, void *buf) -+{ -+ memcpy(buf, mock_read_buffer[num_mocked_reads++], TEST_BLOCK_SIZE); -+ return TEST_BLOCK_SIZE; -+} -+ -+/* Creates backup table from test table and registers a read for it */ -+static void setup_backup_gpt(void) -+{ -+ struct gpt_header_t backup_header; -+ MAKE_BACKUP_HEADER(backup_header, test_header); -+ -+ register_mocked_read(&backup_header, sizeof(backup_header)); -+} -+ -+/* Uses the test MBR and GPT header to initialise for tests */ -+static psa_status_t setup_test_gpt(void) -+{ -+ /* Expect first a valid MBR read */ -+ register_mocked_read(&test_mbr, sizeof(test_mbr)); -+ -+ /* Expect a GPT header read second */ -+ register_mocked_read(&test_header, sizeof(test_header)); -+ -+ /* Expect third each partition is read to find the number in use (if the -+ * number in the header is non-zero) -+ */ -+ if (test_header.num_partitions != 0) { -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ } -+ -+ /* Expect fourth the backup to be read */ -+ setup_backup_gpt(); -+ -+ return gpt_init(&mock_driver, TEST_MAX_PARTITIONS); -+} -+ -+/* Ensures a valid GPT populated with the default entries is initialised */ -+static void setup_valid_gpt(void) -+{ -+ TEST_ASSERT_EQUAL(PSA_SUCCESS, setup_test_gpt()); -+} -+ -+/* Ensures a valid but empty GPT is initialised */ -+static void setup_empty_gpt(void) -+{ -+ test_header.num_partitions = 0; -+ TEST_ASSERT_EQUAL(PSA_SUCCESS, setup_test_gpt()); -+} -+ -+void setUp(void) -+{ -+ /* Default starting points */ -+ test_mbr = default_mbr; -+ test_header = default_header; -+ memcpy(&test_partition_array, &default_partition_array, sizeof(default_partition_array)); -+ for (size_t i = 0; i < TEST_DEFAULT_NUM_PARTITIONS; ++i) { -+ char unicode_name[GPT_ENTRY_NAME_LENGTH] = {'\0'}; -+ ascii_to_unicode(test_partition_array[i].name, unicode_name); -+ memcpy(test_partition_array[i].name, unicode_name, GPT_ENTRY_NAME_LENGTH); -+ } -+ -+ test_mbr.partitions[0].os_type = TEST_MBR_TYPE_GPT; -+ -+ /* Ignore all logging calls */ -+ tfm_log_Ignore(); -+ -+ num_mocked_reads = 0; -+ registered_mocked_reads = 0; -+ memset(mock_read_buffer, 0, sizeof(mock_read_buffer)); -+} -+ -+void tearDown(void) -+{ -+ num_mocked_reads = 0; -+ registered_mocked_reads = 0; -+ memset(mock_read_buffer, 0, sizeof(mock_read_buffer)); -+ memset(&test_partition_array, 0, sizeof(test_partition_array)); -+ gpt_uninit(); -+} -+ -+void test_gpt_init_should_loadWhenGptGood(void) -+{ -+ setup_valid_gpt(); -+} -+ -+void test_gpt_init_should_overwriteOldGpt(void) -+{ -+ setup_valid_gpt(); -+ gpt_uninit(); -+ -+ /* Use a different disk GUID */ -+ const struct efi_guid_t new_guid = MAKE_EFI_GUID(1, 1, 3, 4, 5, 6 ,7 ,8, 9, 10, 11); -+ test_header.disk_guid = new_guid; -+ -+ setup_valid_gpt(); -+} -+ -+void test_gpt_init_should_failWhenMbrSigBad(void) -+{ -+ test_mbr.sig--; -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, setup_test_gpt()); -+} -+ -+void test_gpt_init_should_failWhenMbrTypeInvalid(void) -+{ -+ test_mbr.partitions[0].os_type--; -+ TEST_ASSERT_EQUAL(PSA_ERROR_NOT_SUPPORTED, setup_test_gpt()); -+} -+ -+void test_gpt_init_should_failWhenFlashDriverNotFullyDefined(void) -+{ -+ gpt_flash_read_t read_fn = mock_driver.read; -+ mock_driver.read = NULL; -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_ARGUMENT, gpt_init(&mock_driver, TEST_MAX_PARTITIONS)); -+ mock_driver.read = read_fn; -+} -+ -+void test_gpt_entry_read_should_populateEntry(void) -+{ -+ /* Start with a populated GPT */ -+ setup_valid_gpt(); -+ -+ /* Ensure an entry is found */ -+ struct partition_entry_t entry; -+ struct gpt_entry_t *desired = &(test_partition_array[TEST_DEFAULT_NUM_PARTITIONS - 1]); -+ struct efi_guid_t test_guid = desired->guid; -+ struct efi_guid_t test_type = desired->type; -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_entry_read(&test_guid, &entry)); -+ -+ /* Ensure this is the correct entry */ -+ TEST_ASSERT_EQUAL(0, efi_guid_cmp(&test_guid, &(entry.partition_guid))); -+ TEST_ASSERT_EQUAL(0, efi_guid_cmp(&test_type, &(entry.type_guid))); -+ TEST_ASSERT_EQUAL(desired->start, entry.start); -+ -+ /* Size is number of blocks, so subtract one */ -+ TEST_ASSERT_EQUAL(desired->end, entry.start + entry.size - 1); -+ -+ /* Name is unicode */ -+ TEST_ASSERT_EQUAL_MEMORY(desired->name, entry.name, GPT_ENTRY_NAME_LENGTH); -+} -+ -+void test_gpt_entry_read_should_failWhenEntryNotExisting(void) -+{ -+ /* Start with an empty GPT */ -+ setup_empty_gpt(); -+ -+ /* Try to read something */ -+ struct partition_entry_t entry; -+ struct efi_guid_t non_existing = NULL_GUID; -+ TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, gpt_entry_read(&non_existing, &entry)); -+ -+ /* 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_read(&non_existing, &entry)); -+} -diff --git a/lib/gpt/unittests/gpt/utcfg.cmake b/lib/gpt/unittests/gpt/utcfg.cmake -new file mode 100644 -index 000000000..37d72d138 ---- /dev/null -+++ b/lib/gpt/unittests/gpt/utcfg.cmake -@@ -0,0 +1,28 @@ -+#------------------------------------------------------------------------------- -+# SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+# -+# SPDX-License-Identifier: BSD-3-Clause -+# -+#------------------------------------------------------------------------------- -+ -+# Define what is being unit tested and by what -+set(UNIT_UNDER_TEST ${TFM_ROOT_DIR}/lib/gpt/src/gpt.c) -+set(UNIT_TEST_SUITE ${CMAKE_CURRENT_LIST_DIR}/test_gpt.c) -+ -+# Dependencies for the UUT, that get linked into the executable -+ -+# Include directories for compilation -+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/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) -+ -+# Compile-time definitions -+list(APPEND UNIT_TEST_COMPILE_DEFS LOG_LEVEL=LOG_LEVEL_VERBOSE) -+list(APPEND UNIT_TEST_COMPILE_DEFS TFM_GPT_BLOCK_SIZE=512) -+ diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0020-lib-gpt-Expanded-how-GPT-partition-can-be-identified.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0020-lib-gpt-Expanded-how-GPT-partition-can-be-identified.patch deleted file mode 100644 index dca104f3..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0020-lib-gpt-Expanded-how-GPT-partition-can-be-identified.patch +++ /dev/null @@ -1,308 +0,0 @@ -From b3775fd8aa2078e5e86d5cdb4164e6fc31fabbfc Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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)); -+} diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0021-lib-gpt-Added-operations-to-modify-partitions.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0021-lib-gpt-Added-operations-to-modify-partitions.patch deleted file mode 100644 index 04348b58..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0021-lib-gpt-Added-operations-to-modify-partitions.patch +++ /dev/null @@ -1,961 +0,0 @@ -From 02ec696240d0225ed6473ea5b01ec6617d897a41 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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) diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0022-lib-gpt-Added-operation-to-move-entry.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0022-lib-gpt-Added-operation-to-move-entry.patch deleted file mode 100644 index f6341e2d..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0022-lib-gpt-Added-operation-to-move-entry.patch +++ /dev/null @@ -1,374 +0,0 @@ -From 7a453edd736c919eccc40eec567e8e97c0597bba Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 */ diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0023-lib-gpt-Added-ability-to-create-and-remove-partition.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0023-lib-gpt-Added-ability-to-create-and-remove-partition.patch deleted file mode 100644 index bb8d0a3c..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0023-lib-gpt-Added-ability-to-create-and-remove-partition.patch +++ /dev/null @@ -1,713 +0,0 @@ -From bec8f44a2732c20e8f69a06841637673af90c37e Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 - $ -+ $ - ) - - 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 - #include - --#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 diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0024-lib-gpt-Added-table-validation-operations.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0024-lib-gpt-Added-table-validation-operations.patch deleted file mode 100644 index 95335926..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0024-lib-gpt-Added-table-validation-operations.patch +++ /dev/null @@ -1,412 +0,0 @@ -From c0037dc1779d181ce7d7dbd5871519c9d218440a Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0025-lib-gpt-Added-defragmentation-operation.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0025-lib-gpt-Added-defragmentation-operation.patch deleted file mode 100644 index 58da3276..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0025-lib-gpt-Added-defragmentation-operation.patch +++ /dev/null @@ -1,280 +0,0 @@ -From ba38f0f304ad69047ce9830b81a4f9cfbccb8fcb Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 - #include -+#include - #include - #include - -@@ -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 diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0026-lib-GPT-Fix-cppcheck-warnings.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0026-lib-GPT-Fix-cppcheck-warnings.patch deleted file mode 100644 index 58175cd1..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0026-lib-GPT-Fix-cppcheck-warnings.patch +++ /dev/null @@ -1,74 +0,0 @@ -From f9e4d1f48a4553278dc4de82b0d2f4d82b1e5193 Mon Sep 17 00:00:00 2001 -From: Antonio de Angelis -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 -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 - #include - #include - #include -@@ -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 - */ diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0027-lib-efi_guid-Remove-unecessary-include-folder.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0027-lib-efi_guid-Remove-unecessary-include-folder.patch deleted file mode 100644 index f713ad2a..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0027-lib-efi_guid-Remove-unecessary-include-folder.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 31cd6d9eb82792efd5af7d99802581eace13a083 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 - $ -- PRIVATE -- ${CMAKE_CURRENT_SOURCE_DIR}/src - ) - - target_link_libraries(tfm_efi_guid diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0028-lib-efi_guid-Correct-included-folder.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0028-lib-efi_guid-Correct-included-folder.patch deleted file mode 100644 index 56d3a6e6..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0028-lib-efi_guid-Correct-included-folder.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0b6a2e681b0f76c425896990ebc4afcbc65419d3 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 -- $ -+ inc - ) - - target_link_libraries(tfm_efi_guid diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0029-lib-efi_soft_crc-Correct-include-directory.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0029-lib-efi_soft_crc-Correct-include-directory.patch deleted file mode 100644 index c3340774..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0029-lib-efi_soft_crc-Correct-include-directory.patch +++ /dev/null @@ -1,25 +0,0 @@ -From f1862245d39a726c8e37f58498dd433c6fd99d1b Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 -- $ -+ inc - ) diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0030-lib-gpt-Add-missing-link-library.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0030-lib-gpt-Add-missing-link-library.patch deleted file mode 100644 index 64bdc489..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0030-lib-gpt-Add-missing-link-library.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 343bba6c20802555dfb92c3e2b22a7e07c10a57a Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0031-lib-gpt-Correct-variable-name-used.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0031-lib-gpt-Correct-variable-name-used.patch deleted file mode 100644 index 280b9774..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0031-lib-gpt-Correct-variable-name-used.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 1ae97df8db8babcaa999e47d9641c83c4ee8424a Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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) - diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0032-lib-gpt-Correct-include-directory.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0032-lib-gpt-Correct-include-directory.patch deleted file mode 100644 index 6121d293..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0032-lib-gpt-Correct-include-directory.patch +++ /dev/null @@ -1,27 +0,0 @@ -From eb934a532bbc8385cd9b062fc80cece61350f086 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 -- $ -+ inc - $ - ) - diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0033-lib-gpt-Move-contents-of-CMake-config-file.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0033-lib-gpt-Move-contents-of-CMake-config-file.patch deleted file mode 100644 index b3a9ee74..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0033-lib-gpt-Move-contents-of-CMake-config-file.patch +++ /dev/null @@ -1,51 +0,0 @@ -From ce3a4f3dd8900c068f2bfe951d55b895e3c10d43 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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") diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0034-plat-cs1k-Fixed-formatting-errors.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0034-plat-cs1k-Fixed-formatting-errors.patch deleted file mode 100644 index 28429f70..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0034-plat-cs1k-Fixed-formatting-errors.patch +++ /dev/null @@ -1,261 +0,0 @@ -From 9402dd67413e74284bc598225b4c5399fbd1a099 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 - $<$:${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 - $ -- ${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; iactive_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; - } - } diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0036-plat-cs1k-Fixed-bad-function-returns.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0036-plat-cs1k-Fixed-bad-function-returns.patch deleted file mode 100644 index 35643451..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0036-plat-cs1k-Fixed-bad-function-returns.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 50db5724ef37d5c7cec019254d135b3dcfd0d340 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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 = diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0037-plat-cs1k-Improved-logging-in-function.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0037-plat-cs1k-Improved-logging-in-function.patch deleted file mode 100644 index 3f302770..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0037-plat-cs1k-Improved-logging-in-function.patch +++ /dev/null @@ -1,48 +0,0 @@ -From f48a0a6b60309433269c7927dac992eff06f3745 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -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 -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); diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0038-plat-cs1k-Remove-unused-function.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0038-plat-cs1k-Remove-unused-function.patch deleted file mode 100644 index aae01d8d..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0038-plat-cs1k-Remove-unused-function.patch +++ /dev/null @@ -1,93 +0,0 @@ -From bd6d7dc80556e8c4261343141d675e865d4e960b Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Fri, 2 Jan 2026 13:33:25 +0000 -Subject: [PATCH] plat: cs1k: Remove unused function - -Change-Id: I6e054213dc1ec94a6dc8304705d4cb6e6da701cc -Signed-off-by: Frazer Carsley -Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/49426] ---- - .../bootloader/mcuboot/tfm_mcuboot_fwu.c | 70 ------------------- - 1 file changed, 70 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 2c17d4b79..76ee8a3dc 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 -@@ -501,76 +501,6 @@ static psa_status_t metadata_validate(struct fwu_metadata *metadata) - return PSA_SUCCESS; - } - --#ifdef BL1_BUILD --static psa_status_t metadata_read_without_validation(struct fwu_metadata *metadata) --{ -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- FWU_METADATA_REPLICA_1_OFFSET, sizeof(*metadata)); -- -- if (!metadata) { -- FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -- return PSA_ERROR_INVALID_ARGUMENT; -- } -- -- int ret = FWU_METADATA_FLASH_DEV.ReadData(FWU_METADATA_REPLICA_1_OFFSET, -- metadata, sizeof(*metadata)); -- if (ret < 0) { -- FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, ret); -- return PSA_ERROR_STORAGE_FAILURE; -- } -- -- if (ret != sizeof(*metadata)) { -- FWU_LOG_MSG("%s: ERROR - Incomplete metadata read (expected %zu, got %d)\n\r", -- __func__, sizeof(*metadata), ret); -- return PSA_ERROR_INSUFFICIENT_DATA; -- } -- -- FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -- metadata->active_index, metadata->previous_active_index); -- -- return PSA_SUCCESS; --} --#else --static psa_status_t metadata_read_without_validation(struct fwu_metadata *metadata) --{ -- uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID; -- partition_entry_t *part; -- -- if (!metadata) { -- FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -- return PSA_ERROR_INVALID_ARGUMENT; -- } -- -- part = get_partition_entry_by_type(&metadata_uuid); -- if (!part) { -- FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__); -- return PSA_ERROR_GENERIC_ERROR; -- } -- -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- part->start, sizeof(*metadata)); -- -- -- int ret = FWU_METADATA_FLASH_DEV.ReadData(part->start, -- metadata, sizeof(*metadata)); -- if (ret < 0) { -- FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, ret); -- return PSA_ERROR_STORAGE_FAILURE; -- } -- -- if (ret != sizeof(*metadata)) { -- FWU_LOG_MSG("%s: ERROR - Incomplete metadata read (expected %zu, got %d)\n\r", -- __func__, sizeof(*metadata), ret); -- return PSA_ERROR_INSUFFICIENT_DATA; -- } -- -- FWU_LOG_MSG("%s: success: active = %u, previous = %d\n\r", __func__, -- metadata->active_index, metadata->previous_active_index); -- -- return PSA_SUCCESS; --} --#endif -- - #ifdef BL1_BUILD - static psa_status_t metadata_read(struct fwu_metadata *metadata, uint8_t replica_num) - { diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0039-plat-cs1k-Reduce-BL1-binary-size.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0039-plat-cs1k-Reduce-BL1-binary-size.patch deleted file mode 100644 index 9190c04f..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0039-plat-cs1k-Reduce-BL1-binary-size.patch +++ /dev/null @@ -1,464 +0,0 @@ -From 939d18a0d8dcedd2b5c4b6220e1a0f6c6855fcf6 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Fri, 2 Jan 2026 14:21:57 +0000 -Subject: [PATCH] plat: cs1k: Reduce BL1 binary size - -The size of the BL1 binary is nearly at its maximum allowable size of -64KiB. By making logging a bit more consistent, string literals can be -re-used and reduce the size of the binary. This allows more space for -BL1_2. - -Some functions also had two or more "entry" logging statements, and so -the redundant statements were removed. - -The size of BL1_1 has been updated to reflect these changes. - -Change-Id: Id52dd0d319fb252d7d05e40b6f8f640d27d45ddb -Signed-off-by: Frazer Carsley -Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/49427] ---- - .../bootloader/mcuboot/tfm_mcuboot_fwu.c | 101 ++++++++++-------- - .../arm/corstone1000/partition/region_defs.h | 2 +- - 2 files changed, 56 insertions(+), 47 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 76ee8a3dc..dc7503d41 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 -@@ -56,6 +56,13 @@ - #define FWU_FAKE_IMAGES_INDEX_COUNT 1 - #define FWU_FAKE_IMAGE_INDEX 0 - -+/* These macros provide consistent logging for simple function enter and -+ * successful exit. This helps reduce the number of string literals in the -+ * final binary, thus reducing its size -+ */ -+#define FWU_LOG_FUNC_ENTER FWU_LOG_MSG("%s: enter\n\r", __func__) -+#define FWU_LOG_FUNC_EXIT_SUCCESS FWU_LOG_MSG("%s: success\n\r", __func__) -+ - /* - * Metadata version 2 data structures defined by PSA_FW update specification - * at https://developer.arm.com/documentation/den0118/latest/ -@@ -334,7 +341,7 @@ extern ARM_DRIVER_FLASH FWU_METADATA_FLASH_DEV; - static psa_status_t private_metadata_read( - struct fwu_private_metadata* priv_metadata) - { -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if (!priv_metadata) { - FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -@@ -366,7 +373,7 @@ static psa_status_t private_metadata_read( - partition_entry_t *part; - uuid_t private_uuid = PRIVATE_METADATA_TYPE_UUID; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if (!priv_metadata) { - FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -@@ -430,7 +437,7 @@ static psa_status_t private_metadata_write( - return PSA_ERROR_INSUFFICIENT_DATA; - } - -- FWU_LOG_MSG("%s: success\n\r", __func__); -+ FWU_LOG_FUNC_EXIT_SUCCESS; - return PSA_SUCCESS; - } - #else -@@ -473,14 +480,14 @@ static psa_status_t private_metadata_write( - return PSA_ERROR_INSUFFICIENT_DATA; - } - -- FWU_LOG_MSG("%s: success\n\r", __func__); -+ FWU_LOG_FUNC_EXIT_SUCCESS; - return PSA_SUCCESS; - } - #endif - - static psa_status_t metadata_validate(struct fwu_metadata *metadata) - { -- FWU_LOG_MSG("%s: enter:\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if (!metadata) { - FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -@@ -496,7 +503,7 @@ static psa_status_t metadata_validate(struct fwu_metadata *metadata) - return PSA_ERROR_GENERIC_ERROR; - } - -- FWU_LOG_MSG("%s: success\n\r", __func__); -+ FWU_LOG_FUNC_EXIT_SUCCESS; - - return PSA_SUCCESS; - } -@@ -506,7 +513,7 @@ static psa_status_t metadata_read(struct fwu_metadata *metadata, uint8_t replica - { - uint32_t replica_offset = 0; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if (!metadata) { - FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -@@ -525,7 +532,6 @@ static psa_status_t metadata_read(struct fwu_metadata *metadata, uint8_t replica - FWU_LOG_MSG("%s: flash addr = %u, size = %d\n\r", __func__, - replica_offset, sizeof(*metadata)); - -- - int ret = FWU_METADATA_FLASH_DEV.ReadData(replica_offset, - metadata, sizeof(*metadata)); - if (ret < 0) { -@@ -555,7 +561,7 @@ static psa_status_t metadata_read(struct fwu_metadata *metadata, uint8_t replica - uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID; - partition_entry_t *part; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if (!metadata) { - FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -@@ -611,7 +617,7 @@ static psa_status_t metadata_write( - { - uint32_t replica_offset = 0; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if (!metadata) { - FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); -@@ -627,10 +633,9 @@ static psa_status_t metadata_write( - return PSA_ERROR_GENERIC_ERROR; - } - -- FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -+ FWU_LOG_MSG("%s: flash addr = %u, size = %d\n\r", __func__, - replica_offset, sizeof(*metadata)); - -- - int ret = FWU_METADATA_FLASH_DEV.EraseSector(replica_offset); - if (ret != ARM_DRIVER_OK) { - FWU_LOG_MSG("%s: ERROR - Flash erase failed (ret = %d)\n\r", __func__, ret); -@@ -661,6 +666,8 @@ static psa_status_t metadata_write( - uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID; - partition_entry_t *part; - -+ FWU_LOG_FUNC_ENTER; -+ - if (!metadata) { - FWU_LOG_MSG("%s: ERROR - Null pointer received\n\r", __func__); - return PSA_ERROR_INVALID_ARGUMENT; -@@ -888,7 +895,7 @@ psa_status_t fwu_metadata_provision(void) - { - psa_status_t ret; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - ret = fwu_metadata_init(); - if (ret) { -@@ -918,7 +925,7 @@ psa_status_t fwu_metadata_provision(void) - return ret; - } - -- FWU_LOG_MSG("%s: FWU METADATA PROVISIONED.\n\r", __func__); -+ FWU_LOG_FUNC_EXIT_SUCCESS; - return PSA_SUCCESS; - } - -@@ -927,7 +934,7 @@ static uint8_t get_fwu_image_state( - struct fwu_private_metadata *priv_metadata, - uint32_t fwu_image_index) - { -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if ((metadata->fw_desc.img_entry[fwu_image_index].img_props[metadata->active_index].accepted) - == (IMAGE_NOT_ACCEPTED)) { -@@ -943,7 +950,7 @@ static uint8_t get_fwu_agent_state( - struct fwu_metadata *metadata, - struct fwu_private_metadata *priv_metadata) - { -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if (priv_metadata->boot_index != metadata->active_index) { - FWU_LOG_MSG("%s: exit: FWU Agent PSA_FWU_TRIAL (index mismatch)\n\r", __func__); -@@ -966,7 +973,7 @@ static psa_status_t erase_image(uint32_t image_offset, uint32_t image_size) - int ret; - uint32_t sectors; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if ((image_offset % FWU_METADATA_FLASH_SECTOR_SIZE) != 0) { - return PSA_ERROR_INVALID_ARGUMENT; -@@ -989,7 +996,7 @@ static psa_status_t erase_image(uint32_t image_offset, uint32_t image_size) - } - } - -- FWU_LOG_MSG("%s: exit\n\r", __func__); -+ FWU_LOG_FUNC_EXIT_SUCCESS; - return PSA_SUCCESS; - } - -@@ -1001,7 +1008,7 @@ static psa_status_t fwu_select_previous( - uint8_t current_state; - uint32_t index; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - /* it is expected to receive this call only when - in trial state */ -@@ -1049,8 +1056,8 @@ static psa_status_t fwu_select_previous( - FWU_LOG_MSG("%s: in regular state by choosing previous active bank\n\r", - __func__); - -- FWU_LOG_MSG("%s: exit: ret = %d\n\r", __func__, ret); -- return ret; -+ FWU_LOG_FUNC_EXIT_SUCCESS; -+ return PSA_SUCCESS; - - } - -@@ -1061,7 +1068,7 @@ void bl1_get_active_bl2_image(uint32_t *offset) - uint32_t boot_attempted; - uint32_t boot_index; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if (fwu_metadata_init()) { - FWU_ASSERT(0); -@@ -1125,7 +1132,7 @@ uint8_t bl2_get_boot_bank(void) - { - uint8_t boot_index; - struct fwu_private_metadata priv_metadata; -- FWU_LOG_MSG("%s: enter", __func__); -+ FWU_LOG_FUNC_ENTER; - if (fwu_metadata_init()) { - FWU_ASSERT(0); - } -@@ -1150,7 +1157,7 @@ static psa_status_t update_nv_counters( - uint32_t security_cnt; - enum tfm_nv_counter_t tfm_nv_counter_i; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - /* The FWU_BL2_NV_COUNTER (0) is not mirrored in the private metadata. It is - * directly updated in the bl1_2_validate_image_at_addr() function, in -@@ -1194,7 +1201,7 @@ static psa_status_t update_nv_counters( - - } - -- FWU_LOG_MSG("%s: exit\n\r", __func__); -+ FWU_LOG_FUNC_EXIT_SUCCESS; - return PSA_SUCCESS; - } - -@@ -1204,7 +1211,7 @@ psa_status_t corstone1000_fwu_host_ack(void) - struct fwu_private_metadata priv_metadata; - uint8_t current_state; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if (!is_initialized) { - return PSA_ERROR_BAD_STATE; -@@ -1309,7 +1316,7 @@ void host_acknowledgement_timer_to_reset(void) - struct fwu_private_metadata priv_metadata; - uint8_t current_state; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - Select_Write_Mode_For_Shared_Flash(); - -@@ -1342,7 +1349,7 @@ void host_acknowledgement_timer_to_reset(void) - } - } - -- FWU_LOG_MSG("%s: exit\n\r", __func__); -+ FWU_LOG_FUNC_EXIT_SUCCESS; - return; - } - -@@ -1379,7 +1386,7 @@ psa_status_t fwu_stage_nv_counter(enum fwu_nv_counter_index_t index, - } - } - -- FWU_LOG_MSG("%s: exit\n\r", __func__); -+ FWU_LOG_FUNC_EXIT_SUCCESS; - return PSA_SUCCESS; - } - -@@ -1397,7 +1404,7 @@ bool is_image_index_valid(uint8_t fwu_image_index) { - - static psa_status_t get_esrt_data(struct fwu_esrt_data_wrapper *esrt) - { -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - if (!esrt) - { -@@ -1445,7 +1452,7 @@ static psa_status_t fwu_accept_image(struct fwu_metadata *metadata, - uint32_t fwu_image_index; - psa_status_t ret; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - - /* booted from previous_active_bank, not expected -@@ -1492,8 +1499,8 @@ static psa_status_t fwu_accept_image(struct fwu_metadata *metadata, - return ret; - } - -- FWU_LOG_MSG("%s: exit: fwu state is changed to regular, ret - %d\n\r", __func__, ret); -- return ret; -+ FWU_LOG_MSG("%s: success: fwu state is changed to regular\n\r", __func__); -+ return PSA_SUCCESS; - } - - static psa_status_t uint_to_image_version(uint32_t ver_in, psa_fwu_image_version_t *ver_out) -@@ -1525,6 +1532,8 @@ static psa_status_t erase_staging_area(struct fwu_metadata* metadata, psa_fwu_co - return PSA_ERROR_INVALID_ARGUMENT; - } - -+ FWU_LOG_FUNC_ENTER; -+ - if (!is_image_index_valid(component)) { - FWU_LOG_MSG("%s: Invalid Component received \n\r", __func__); - return PSA_ERROR_GENERIC_ERROR; -@@ -1535,8 +1544,6 @@ static psa_status_t erase_staging_area(struct fwu_metadata* metadata, psa_fwu_co - uint32_t image_offset; - uint8_t fwu_image_index = component - FWU_FAKE_IMAGES_INDEX_COUNT; /* Decrement to get the correct fwu image index */ - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -- - if (active_index == BANK_0) { - bank_offset = BANK_1_PARTITION_OFFSET; - } else if (active_index == BANK_1) { -@@ -1551,7 +1558,7 @@ static psa_status_t erase_staging_area(struct fwu_metadata* metadata, psa_fwu_co - return PSA_ERROR_GENERIC_ERROR; - } - -- FWU_LOG_MSG("%s: exit: Staging area erased succesfully \n\r", __func__); -+ FWU_LOG_FUNC_EXIT_SUCCESS; - return PSA_SUCCESS; - } - -@@ -1559,7 +1566,7 @@ psa_status_t fwu_bootloader_init(void) - { - psa_status_t ret; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - ret = fwu_metadata_init(); - if (ret) { -@@ -1569,7 +1576,7 @@ psa_status_t fwu_bootloader_init(void) - /* Initialize the fmp_header_image_info object */ - fmp_header_image_info_init(); - -- FWU_LOG_MSG("%s: exit: Initialized\n\r", __func__); -+ FWU_LOG_FUNC_EXIT_SUCCESS; - - return PSA_SUCCESS; - } -@@ -1588,7 +1595,7 @@ psa_status_t fwu_bootloader_staging_area_init(psa_fwu_component_t component, - - psa_status_t ret; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - Select_Write_Mode_For_Shared_Flash(); - -@@ -1783,7 +1790,7 @@ static psa_status_t fwu_update_metadata(const psa_fwu_component_t *candidates, u - uint32_t previous_active_index; - uint8_t fwu_image_index; - -- FWU_LOG_MSG("%s: enter function\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - Select_Write_Mode_For_Shared_Flash(); - -@@ -1842,6 +1849,8 @@ static psa_status_t copy_image_from_other_bank(int image_index, - uint32_t active_index, - uint32_t previous_active_index) - { -+ FWU_LOG_FUNC_ENTER; -+ - uint32_t bank_offset[NR_OF_FW_BANKS] = {BANK_0_PARTITION_OFFSET, BANK_1_PARTITION_OFFSET}; - uint8_t data[FLASH_CHUNK_SIZE]; - size_t remaining_size = fwu_image[image_index].image_size; -@@ -1904,7 +1913,7 @@ static psa_status_t maintain_bank_consistency(void) - uint32_t previous_active_index; - struct fwu_private_metadata priv_metadata; - -- FWU_LOG_MSG("%s: Enter \n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - Select_Write_Mode_For_Shared_Flash(); - - if (metadata_read(&_metadata, 1) || private_metadata_read(&priv_metadata)) { -@@ -1979,7 +1988,7 @@ psa_status_t fwu_bootloader_install_image(const psa_fwu_component_t *candidates, - } - - psa_status_t ret; -- FWU_LOG_MSG("%s: enter function\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - /* Copy images from other bank which are not received by FWU client */ - ret = maintain_bank_consistency(); -@@ -2015,7 +2024,7 @@ psa_status_t fwu_bootloader_mark_image_accepted(const psa_fwu_component_t *trial - uint8_t current_state; - uint8_t fwu_image_index; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - Select_Write_Mode_For_Shared_Flash(); - -@@ -2114,7 +2123,7 @@ psa_status_t fwu_bootloader_reject_staged_image(psa_fwu_component_t component) - uint32_t image_offset; - uint8_t image_index = component - FWU_FAKE_IMAGES_INDEX_COUNT; /* Decrement to get the correct fwu image index */ - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - Select_Write_Mode_For_Shared_Flash(); - - if (metadata_read(&_metadata, 1)) { -@@ -2158,7 +2167,7 @@ psa_status_t fwu_bootloader_reject_trial_image(psa_fwu_component_t component) - int ret; - uint8_t fwu_image_index = component - FWU_FAKE_IMAGES_INDEX_COUNT; /* Decrement to get the correct fwu image index */ - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - /* Disable host ackowledgement timer */ - disable_host_ack_timer(); -@@ -2213,7 +2222,7 @@ psa_status_t fwu_bootloader_get_image_info(psa_fwu_component_t component, - uint8_t current_state; - psa_status_t ret; - -- FWU_LOG_MSG("%s: enter\n\r", __func__); -+ FWU_LOG_FUNC_ENTER; - - - Select_Write_Mode_For_Shared_Flash(); -diff --git a/platform/ext/target/arm/corstone1000/partition/region_defs.h b/platform/ext/target/arm/corstone1000/partition/region_defs.h -index 92e01c0e3..1feee7841 100644 ---- a/platform/ext/target/arm/corstone1000/partition/region_defs.h -+++ b/platform/ext/target/arm/corstone1000/partition/region_defs.h -@@ -94,7 +94,7 @@ - - /* SE BL1 regions */ - #define BL1_1_CODE_START (0) --#define BL1_1_CODE_SIZE (0x0000E800) /* 58 KiB */ -+#define BL1_1_CODE_SIZE (0x0000E748) /* 58 KiB */ - #define BL1_1_CODE_LIMIT (BL1_1_CODE_START + BL1_1_CODE_SIZE - 1) - - #define PROVISIONING_DATA_START (BL1_1_CODE_START + BL1_1_CODE_SIZE) diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0040-plat-cs1k-Update-license-identifier.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0040-plat-cs1k-Update-license-identifier.patch deleted file mode 100644 index 0859734f..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0040-plat-cs1k-Update-license-identifier.patch +++ /dev/null @@ -1,35 +0,0 @@ -From b4fd75b96b49756c4815685fc19089793fcc9356 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Wed, 14 Jan 2026 14:00:12 +0000 -Subject: [PATCH] plat: cs1k: Update license identifier - -Change-Id: I26af0dbf66359e76b7164b3abdbbf3ace3f358c6 -Signed-off-by: Frazer Carsley -Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/49428] ---- - platform/ext/target/arm/corstone1000/platform.c | 2 +- - platform/ext/target/arm/corstone1000/platform.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/platform/ext/target/arm/corstone1000/platform.c b/platform/ext/target/arm/corstone1000/platform.c -index d0f30b72a..32fdc55aa 100644 ---- a/platform/ext/target/arm/corstone1000/platform.c -+++ b/platform/ext/target/arm/corstone1000/platform.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2023, Arm Limited. All rights reserved. -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors - * - * SPDX-License-Identifier: BSD-3-Clause - * -diff --git a/platform/ext/target/arm/corstone1000/platform.h b/platform/ext/target/arm/corstone1000/platform.h -index a88093ed4..906a8f9ae 100644 ---- a/platform/ext/target/arm/corstone1000/platform.h -+++ b/platform/ext/target/arm/corstone1000/platform.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2023, Arm Limited. All rights reserved. -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors - * - * SPDX-License-Identifier: BSD-3-Clause - * diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0041-plat-cs1k-Changed-to-use-new-GPT-library.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0041-plat-cs1k-Changed-to-use-new-GPT-library.patch deleted file mode 100644 index a508252b..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0041-plat-cs1k-Changed-to-use-new-GPT-library.patch +++ /dev/null @@ -1,4536 +0,0 @@ -From 1b058b6ccc4318f6805d96da5073debf99c764a5 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Mon, 2 Mar 2026 14:37:12 +0000 -Subject: [PATCH] plat: cs1k: Changed to use new GPT library - -Corstone1000 already had a basic GPT parser implementation however -lacked full GPT support. Since the addition of the new GPT library, this -commit removes Corstone1000's parser and uses the library instead for -parsing/read operations. Because Corstone1000's firmware update -mechanism uses two banks with fixed offsets in each for the different -images/partitions, the GPT library is not used to modify any partitions. - -The GPT library requires callers to register a pseudo-device driver and -this is implemented by the io_gpt module. As such, there is no need -anymore for the abstraction provided by the previous io_* modules, as -this new module handles the translation between LBAs and -sectors/addresses of flash. - -Change-Id: I1bde0e482a4c5286997ae383f90648e9f8043083 -Signed-off-by: Frazer Carsley -Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/49429] ---- - .../target/arm/corstone1000/CMakeLists.txt | 68 ++- - .../arm/corstone1000/bl2/boot_hal_bl2.c | 67 ++- - .../arm/corstone1000/bootloader/fwu_agent.h | 21 +- - .../bootloader/mcuboot/tfm_mcuboot_fwu.c | 328 +++++++---- - .../bootloader/mcuboot/uefi_fmp.c | 13 +- - .../arm/corstone1000/bootloader/uefi_fmp.h | 3 +- - .../ci_regression_tests/CMakeLists.txt | 12 - - .../Driver_Flash_SRAM_Emu.c | 327 ----------- - .../ci_regression_tests/s_io_storage_test.c | 147 ----- - .../ci_regression_tests/s_io_storage_test.h | 15 - - .../corstone1000/ci_regression_tests/s_test.c | 3 +- - .../ci_regression_tests/s_test_config.cmake | 13 - - .../ci_regression_tests/test_flash.h | 25 - - .../ext/target/arm/corstone1000/config.cmake | 4 + - .../corstone1000/fip_parser/external/uuid.h | 74 --- - .../arm/corstone1000/fip_parser/fip_parser.c | 12 +- - .../arm/corstone1000/fip_parser/fip_parser.h | 26 +- - .../ext/target/arm/corstone1000/io/io_block.c | 528 ------------------ - .../ext/target/arm/corstone1000/io/io_block.h | 40 -- - .../ext/target/arm/corstone1000/io/io_defs.h | 27 - - .../target/arm/corstone1000/io/io_driver.h | 54 -- - .../ext/target/arm/corstone1000/io/io_flash.c | 183 ------ - .../ext/target/arm/corstone1000/io/io_flash.h | 37 -- - .../ext/target/arm/corstone1000/io/io_gpt.c | 179 ++++++ - .../ext/target/arm/corstone1000/io/io_gpt.h | 25 + - .../target/arm/corstone1000/io/io_storage.c | 289 ---------- - .../target/arm/corstone1000/io/io_storage.h | 92 --- - .../target/arm/corstone1000/partition/efi.h | 37 -- - .../target/arm/corstone1000/partition/gpt.c | 58 -- - .../target/arm/corstone1000/partition/gpt.h | 51 -- - .../target/arm/corstone1000/partition/mbr.h | 29 - - .../arm/corstone1000/partition/partition.c | 324 ----------- - .../arm/corstone1000/partition/partition.h | 48 -- - .../target/arm/corstone1000/partition/uuid.h | 76 --- - .../ext/target/arm/corstone1000/platform.c | 71 +-- - .../ext/target/arm/corstone1000/platform.h | 32 +- - .../arm/corstone1000/soft_crc/soft_crc.c | 121 ---- - .../arm/corstone1000/soft_crc/soft_crc.h | 18 - - 38 files changed, 606 insertions(+), 2871 deletions(-) - delete mode 100644 platform/ext/target/arm/corstone1000/ci_regression_tests/Driver_Flash_SRAM_Emu.c - delete mode 100644 platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.c - delete mode 100644 platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.h - delete mode 100644 platform/ext/target/arm/corstone1000/ci_regression_tests/s_test_config.cmake - delete mode 100644 platform/ext/target/arm/corstone1000/ci_regression_tests/test_flash.h - delete mode 100644 platform/ext/target/arm/corstone1000/fip_parser/external/uuid.h - delete mode 100644 platform/ext/target/arm/corstone1000/io/io_block.c - delete mode 100644 platform/ext/target/arm/corstone1000/io/io_block.h - delete mode 100644 platform/ext/target/arm/corstone1000/io/io_defs.h - delete mode 100644 platform/ext/target/arm/corstone1000/io/io_driver.h - delete mode 100644 platform/ext/target/arm/corstone1000/io/io_flash.c - delete mode 100644 platform/ext/target/arm/corstone1000/io/io_flash.h - create mode 100644 platform/ext/target/arm/corstone1000/io/io_gpt.c - create mode 100644 platform/ext/target/arm/corstone1000/io/io_gpt.h - delete mode 100644 platform/ext/target/arm/corstone1000/io/io_storage.c - delete mode 100644 platform/ext/target/arm/corstone1000/io/io_storage.h - delete mode 100644 platform/ext/target/arm/corstone1000/partition/efi.h - delete mode 100644 platform/ext/target/arm/corstone1000/partition/gpt.c - delete mode 100644 platform/ext/target/arm/corstone1000/partition/gpt.h - delete mode 100644 platform/ext/target/arm/corstone1000/partition/mbr.h - delete mode 100644 platform/ext/target/arm/corstone1000/partition/partition.c - delete mode 100644 platform/ext/target/arm/corstone1000/partition/partition.h - delete mode 100644 platform/ext/target/arm/corstone1000/partition/uuid.h - delete mode 100644 platform/ext/target/arm/corstone1000/soft_crc/soft_crc.c - delete mode 100644 platform/ext/target/arm/corstone1000/soft_crc/soft_crc.h - -diff --git a/platform/ext/target/arm/corstone1000/CMakeLists.txt b/platform/ext/target/arm/corstone1000/CMakeLists.txt -index 58edae74e..7168c1ca9 100644 ---- a/platform/ext/target/arm/corstone1000/CMakeLists.txt -+++ b/platform/ext/target/arm/corstone1000/CMakeLists.txt -@@ -116,9 +116,11 @@ target_include_directories(platform_s - INTERFACE - cc312 - bootloader -- soft_crc - io - partition -+ ${CMAKE_SOURCE_DIR}/lib/ext/efi_soft_crc/inc -+ ${CMAKE_SOURCE_DIR}/lib/efi_guid/inc -+ ${CMAKE_SOURCE_DIR}/lib/gpt/inc - ) - - target_sources(platform_s -@@ -135,19 +137,23 @@ target_sources(platform_s - $<$:${CMAKE_CURRENT_SOURCE_DIR}/services/src/tfm_platform_system.c> - bootloader/mcuboot/tfm_mcuboot_fwu.c - bootloader/mcuboot/uefi_fmp.c -- soft_crc/soft_crc.c -- io/io_block.c -- io/io_flash.c -- io/io_storage.c -- partition/partition.c -- partition/gpt.c - $<$>:${PLATFORM_DIR}/ext/accelerator/cc312/otp_cc312.c> - rse_comms_permissions_hal.c - mem_check_v6m_v7m_hal.c - ${PLATFORM_DIR}/ext/common/mem_check_v6m_v7m.c -+ io/io_gpt.c - platform.c - ) - -+target_link_libraries(platform_s -+ PUBLIC -+ tfm_log -+ PRIVATE -+ tfm_efi_soft_crc -+ tfm_efi_guid -+ tfm_gpt -+) -+ - if (PLATFORM_IS_FVP) - target_sources(platform_s - PRIVATE -@@ -167,6 +173,9 @@ target_compile_definitions(platform_s - PUBLIC - $<$:EXTERNAL_SYSTEM_SUPPORT> - $<$:PLATFORM_IS_FVP> -+ TFM_GPT_BLOCK_SIZE=${TFM_GPT_BLOCK_SIZE} -+ PLAT_MAX_PARTITION_ENTRIES=${PLAT_MAX_PARTITION_ENTRIES} -+ LOG_LEVEL=${GPT_LOG_LEVEL} - PRIVATE - $<$:TFM_S_REG_TEST> - $<$:ENABLE_FWU_AGENT_DEBUG_LOGS> -@@ -200,7 +209,6 @@ target_sources(platform_bl1_1 - ./bl1/provisioning.c - ./bootloader/mcuboot/tfm_mcuboot_fwu.c - ./bootloader/mcuboot/uefi_fmp.c -- ./soft_crc/soft_crc.c - $<$>:${PLATFORM_DIR}/ext/accelerator/cc312/otp_cc312.c> - $<$>:${CMAKE_CURRENT_SOURCE_DIR}/bl1/cc312_rom_crypto.c> - $<$>:${CMAKE_CURRENT_SOURCE_DIR}/bl1/cc312_rom_trng.c> -@@ -231,7 +239,6 @@ target_include_directories(platform_bl1_1_interface - ./Native_Driver - ./CMSIS_Driver/Config - ./bootloader -- ./soft_crc - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/cfi - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/common - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/strata -@@ -243,16 +250,22 @@ target_include_directories(platform_bl1_1_interface - $<$:${CMAKE_SOURCE_DIR}/platform/ext/accelerator/interface> - ${PLATFORM_DIR}/ext/accelerator/cc312/ - ${CMAKE_SOURCE_DIR}/lib/fih/inc/ -+ ${CMAKE_SOURCE_DIR}/lib/gpt/inc # for GPT_ENTRY_NAME_LENGTH - ) - - target_link_libraries(platform_bl1_1 - PRIVATE - $<$>:cc3xx> -+ tfm_efi_soft_crc -+ tfm_efi_guid - ) - - target_include_directories(platform_bl1_1 - PRIVATE - ${CMAKE_SOURCE_DIR}/interface/include # for psa/error.h -+ ${CMAKE_SOURCE_DIR}/lib/ext/efi_soft_crc/inc -+ ${CMAKE_SOURCE_DIR}/lib/efi_guid/inc -+ ${CMAKE_SOURCE_DIR}/lib/gpt/inc - ) - - target_sources(platform_bl1_2 -@@ -281,7 +294,6 @@ target_include_directories(platform_bl1_2 - ./Native_Driver - ./CMSIS_Driver/Config - ./bootloader -- ./soft_crc - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/common - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/cfi - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/strata -@@ -290,6 +302,15 @@ target_include_directories(platform_bl1_2 - ${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}/lib/ext/efi_soft_crc/inc -+ ${CMAKE_SOURCE_DIR}/lib/efi_guid/inc -+ ${CMAKE_SOURCE_DIR}/lib/gpt/inc # for GPT_ENTRY_NAME_LENGTH -+) -+ -+target_link_libraries(platform_bl1_2 -+ PRIVATE -+ tfm_efi_soft_crc -+ tfm_efi_guid - ) - - #========================= Platform BL2 =======================================# -@@ -309,12 +330,7 @@ target_sources(platform_bl2 - bootloader/mcuboot/tfm_mcuboot_fwu.c - bl2/security_cnt_bl2.c - $<$>:${PLATFORM_DIR}/ext/accelerator/cc312/otp_cc312.c> -- io/io_block.c -- io/io_flash.c -- io/io_storage.c -- soft_crc/soft_crc.c -- partition/partition.c -- partition/gpt.c -+ io/io_gpt.c - platform.c - ) - -@@ -334,6 +350,10 @@ target_sources(platform_bl2 - endif() - - target_compile_definitions(platform_bl2 -+ PUBLIC -+ TFM_GPT_BLOCK_SIZE=${TFM_GPT_BLOCK_SIZE} -+ PLAT_MAX_PARTITION_ENTRIES=${PLAT_MAX_PARTITION_ENTRIES} -+ LOG_LEVEL=${GPT_LOG_LEVEL} - PRIVATE - $<$:PLATFORM_IS_FVP> - $<$:TFM_S_REG_TEST> -@@ -353,6 +373,14 @@ target_sources(bl2 - target_link_libraries(bl2 - PRIVATE - $<$:trusted-firmware-m-psa-adac> -+ tfm_log -+) -+ -+target_link_libraries(platform_bl2 -+ PRIVATE -+ tfm_gpt -+ tfm_efi_soft_crc -+ tfm_efi_guid - ) - - target_compile_definitions(bl2 -@@ -365,6 +393,10 @@ target_compile_definitions(bl2 - target_include_directories(bl2 - PRIVATE - ${CMAKE_SOURCE_DIR}/interface/include # for psa/error.h -+ ${CMAKE_SOURCE_DIR}/lib/efi_guid/inc # for efi_guid_structs.h -+ ${CMAKE_SOURCE_DIR}/lib/gpt/inc -+ ${CMAKE_SOURCE_DIR}/lib/tfm_log/inc -+ ${CMAKE_SOURCE_DIR}/lib/tfm_vprintf/inc - ) - - target_compile_definitions(bootutil -@@ -379,7 +411,6 @@ target_include_directories(platform_bl2 - fip_parser - Native_Driver - bootloader -- soft_crc - io - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/common - ${PLATFORM_DIR}/ext/target/arm/drivers/flash/cfi -@@ -398,6 +429,9 @@ target_include_directories(platform_bl2 - ${CMAKE_BINARY_DIR}/bl2/ext/mcuboot # for mcuboot_config.h only - $ - ${CMAKE_SOURCE_DIR}/interface/include # for psa/error.h -+ ${CMAKE_SOURCE_DIR}/lib/ext/efi_soft_crc/inc -+ ${CMAKE_SOURCE_DIR}/lib/efi_guid/inc -+ ${CMAKE_SOURCE_DIR}/lib/gpt/inc - ) - - #========================= ns_agent_mailbox ===================================# -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 bf7b62881..1ed111af6 100644 ---- a/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c -+++ b/platform/ext/target/arm/corstone1000/bl2/boot_hal_bl2.c -@@ -5,6 +5,7 @@ - * - */ - -+#include - #include - #include - #include "tfm_hal_device_header.h" -@@ -31,8 +32,8 @@ - #include "crypto_hw.h" - #endif - --#include "efi.h" --#include "partition.h" -+#include "gpt.h" -+#include "io_gpt.h" - #include "platform.h" - - static const char* const tfm_part_names[] = {"tfm_primary", "tfm_secondary"}; -@@ -49,6 +50,14 @@ REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[]; - #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0])) - extern struct flash_area flash_map[]; - -+static void ascii_to_unicode(const char *ascii, char *unicode) -+{ -+ for (int i = 0; i < strlen(ascii) + 1; ++i) { -+ unicode[i << 1] = ascii[i]; -+ unicode[(i << 1) + 1] = '\0'; -+ } -+} -+ - static bool fill_flash_map_with_tfm_data(uint8_t boot_index) { - - if (boot_index >= ARRAY_SIZE(tfm_part_names)) { -@@ -56,14 +65,28 @@ static bool fill_flash_map_with_tfm_data(uint8_t boot_index) { - boot_index, ARRAY_SIZE(tfm_part_names)); - return false; - } -- const partition_entry_t *tfm_entry = -- get_partition_entry(tfm_part_names[boot_index]); -- if (tfm_entry == NULL) { -+ -+ /* Convert ascii to unicode so GPT library understands */ -+ char unicode_name[GPT_ENTRY_NAME_LENGTH] = {'\0'}; -+ ascii_to_unicode(tfm_part_names[boot_index], unicode_name); -+ struct partition_entry_t tfm_entry; -+ psa_status_t ret = gpt_entry_read_by_name( -+ unicode_name, -+ 0, -+ &tfm_entry); -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { -+ BOOT_LOG_ERR("Could not find partition %s", tfm_part_names[boot_index]); -+ return false; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ BOOT_LOG_ERR("%s: I/O error occurred with flash device", __func__); -+ return false; -+ } else if (ret < 0) { - BOOT_LOG_ERR("Could not find partition %s", tfm_part_names[boot_index]); - return false; - } -- flash_map[0].fa_off = tfm_entry->start; -- flash_map[0].fa_size = tfm_entry->length; -+ -+ flash_map[0].fa_off = tfm_entry.start * TFM_GPT_BLOCK_SIZE; -+ flash_map[0].fa_size = tfm_entry.size * TFM_GPT_BLOCK_SIZE; - return true; - } - -@@ -80,15 +103,27 @@ static bool fill_flash_map_with_fip_data(uint8_t boot_index) { - boot_index, ARRAY_SIZE(fip_part_names)); - return false; - } -- const partition_entry_t *fip_entry = -- get_partition_entry(fip_part_names[boot_index]); -- if (fip_entry == NULL) { -+ -+ struct partition_entry_t fip_entry; -+ char unicode_name[GPT_ENTRY_NAME_LENGTH] = {'\0'}; -+ ascii_to_unicode(fip_part_names[boot_index], unicode_name); -+ psa_status_t ret = gpt_entry_read_by_name( -+ unicode_name, -+ 0, -+ &fip_entry); -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { -+ BOOT_LOG_ERR("Could not find partition %s", fip_part_names[boot_index]); -+ return false; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ BOOT_LOG_ERR("%s: I/O error occurred with flash device", __func__); -+ return false; -+ } else if (ret < 0) { - BOOT_LOG_ERR("Could not find partition %s", fip_part_names[boot_index]); - return false; - } - -- fip_offset = fip_entry->start; -- fip_size = fip_entry->length; -+ fip_offset = fip_entry.start * TFM_GPT_BLOCK_SIZE; -+ fip_size = fip_entry.size * TFM_GPT_BLOCK_SIZE; - - /* parse directly from flash using XIP mode */ - /* FIP is large so its not a good idea to load it in memory */ -@@ -130,20 +165,21 @@ int32_t boot_platform_init(void) - } - - plat_io_storage_init(); -- partition_init(PLATFORM_GPT_IMAGE); -+ gpt_init(&io_gpt_flash_driver, PLAT_GPT_MAX_PARTITIONS); - - boot_index = bl2_get_boot_bank(); - -+ result = 0; - if (!fill_flash_map_with_tfm_data(boot_index) - #ifndef TFM_S_REG_TEST - || !fill_flash_map_with_fip_data(boot_index) - #endif - ) { - BOOT_LOG_ERR("Filling flash map has failed!"); -- return 1; -+ result = 1; - } - -- return 0; -+ return result; - } - - int32_t boot_platform_post_init(void) -@@ -223,5 +259,6 @@ void boot_platform_start_next_image(struct boot_arm_vector_table *vt) - __DSB(); - __ISB(); - -+ gpt_uninit(); - boot_jump_to_next_image(vt_cpy->reset); - } -diff --git a/platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h b/platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h -index aa5af15b2..4393f5f7b 100644 ---- a/platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h -+++ b/platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h -@@ -9,7 +9,8 @@ - #define FWU_AGENT_H - - #include "psa/error.h" --#include "../fip_parser/external/uuid.h" -+#include "efi_guid_structs.h" -+#include "gpt.h" - - #define ENABLE_FWU_AGENT_DEBUG_LOGS - #ifdef ENABLE_FWU_AGENT_DEBUG_LOGS -@@ -29,6 +30,9 @@ - /* Version used for the very first image of the device. */ - #define FWU_IMAGE_INITIAL_VERSION 0 - -+/* Maximum ascii name length of image */ -+#define FWU_IMAGE_NAME_LENGTH (GPT_ENTRY_NAME_LENGTH >> 1) -+ - #define EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION 1 - typedef struct { - uint32_t signature; -@@ -43,21 +47,24 @@ typedef struct { - size_t image_size_recvd; - } __packed fmp_header_image_info_t; - --/* Store image information common for both the banks */ -+/* Image information common for both the banks */ - typedef struct { - /* Total size of the image */ - uint32_t image_size; - -- /* Offset of image within a bank */ -+ /* Offset of image within a bank. */ - uint32_t image_offset; - -- /* Image GUID */ -- struct efi_guid image_guid; --} __packed fwu_bank_image_info_t; -+ /* Name of the image in ascii */ -+ char image_name[FWU_IMAGE_NAME_LENGTH]; -+ -+ /* Image-type GUID */ -+ struct efi_guid_t image_type; -+} fwu_image_info_t; - - /* ESRT v1 */ - struct __attribute__((__packed__)) efi_system_resource_entry { -- struct efi_guid fw_class; -+ struct efi_guid_t fw_class; - uint32_t fw_type; - uint32_t fw_version; - uint32_t lowest_supported_fw_version; -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 dc7503d41..5e1c4ecc5 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 -@@ -4,17 +4,19 @@ - * SPDX-License-Identifier: BSD-3-Clause - * - */ -+#include - #include - #include "psa/crypto.h" - #include "psa/error.h" - #include "tfm_bootloader_fwu_abstraction.h" -+#include "efi_soft_crc.h" - - #include - #include - #include "fwu_agent.h" - #include "Driver_Flash.h" -+#include "efi_guid_structs.h" - #include "flash_layout.h" --#include "fip_parser/external/uuid.h" - #include "region_defs.h" - #include "flash_common.h" - #include "platform_base_address.h" -@@ -23,10 +25,10 @@ - #include "tfm_plat_defs.h" - #include "uefi_fmp.h" - #include "uart_stdout.h" --#include "soft_crc.h" - #ifndef BL1_BUILD --#include "partition.h" -+#include "gpt.h" - #include "platform.h" -+#include "io_gpt.h" - #endif - - #define FWU_METADATA_VERSION 2 -@@ -72,7 +74,7 @@ - struct fwu_image_properties { - - /* The UUID of the image in this bank */ -- uuid_t img_uuid; -+ struct efi_guid_t img_uuid; - - /* [0]: bit describing the image acceptance status – - * status - 1 means the image is accepted -@@ -90,10 +92,10 @@ struct fwu_image_properties { - struct fwu_image_entry { - - /* The UUID identifying the image type */ -- uuid_t img_type_uuid; -+ struct efi_guid_t img_type_uuid; - - /* The UUID of the storage volume where the image is located */ -- uuid_t location_uuid; -+ struct efi_guid_t location_uuid; - - /* The Properties of images with img_type_uuid in the different FW banks */ - struct fwu_image_properties img_props[NR_OF_FW_BANKS]; -@@ -206,99 +208,114 @@ struct __attribute__((__packed__)) fwu_esrt_data_wrapper { - * The GUIDs are generating with the UUIDv5 format. - * Namespace used for FVP GUIDs: 989f3a4e-46e0-4cd0-9877-a25c70c01329 - * Namespace used for MPS3 GUIDs: df1865d1-90fb-4d59-9c38-c9f2c1bba8cc -- * Names: the image names stated in the fw_name field - */ --fwu_bank_image_info_t fwu_image[NR_OF_IMAGES_IN_FW_BANK] = { -+const fwu_image_info_t fwu_image[NR_OF_IMAGES_IN_FW_BANK] = { - #if PLATFORM_IS_FVP - // FVP payloads GUIDs -- // bl2_signed - { -+ .image_name = "bl2_secondary", - .image_size = SE_BL2_PARTITION_SIZE, - .image_offset = SE_BL2_PARTITION_BANK_OFFSET, -- .image_guid = { -+ .image_type = { - .time_low = 0xf1d883f9, - .time_mid = 0xdfeb, - .time_hi_and_version = 0x5363, -- .clock_seq_and_node = {0x98, 0xd8, 0x68, 0x6e, 0xe3, 0xb6, 0x9f, 0x4f} -+ .clock_seq_hi_and_reserved = 0x98, -+ .clock_seq_low = 0xd8, -+ .node = {0x68, 0x6e, 0xe3, 0xb6, 0x9f, 0x4f} - }, - }, -- // tfm_s_signed - { -+ .image_name = "tfm_secondary", - .image_size = TFM_PARTITION_SIZE, - .image_offset = TFM_PARTITION_BANK_OFFSET, -- .image_guid = { -+ .image_type = { - .time_low = 0x7fad470e, - .time_mid = 0x5ec5, - .time_hi_and_version = 0x5c03, -- .clock_seq_and_node = {0xa2, 0xc1, 0x47, 0x56, 0xb4, 0x95, 0xde, 0x61} -+ .clock_seq_hi_and_reserved = 0xa2, -+ .clock_seq_low = 0xc1, -+ .node = {0x47, 0x56, 0xb4, 0x95, 0xde, 0x61} - }, - }, -- // signed_fip-corstone1000 - { -+ .image_name = "FIP_B", - .image_size = FIP_PARTITION_SIZE, - .image_offset = FIP_PARTITION_BANK_OFFSET, -- .image_guid = { -+ .image_type = { - .time_low = 0xf1933675, - .time_mid = 0x5a8c, - .time_hi_and_version = 0x5b6d, -- .clock_seq_and_node = {0x9e, 0xf4, 0x84, 0x67, 0x39, 0xe8, 0x9b, 0xc8} -+ .clock_seq_hi_and_reserved = 0x9e, -+ .clock_seq_low = 0xf4, -+ .node = {0x84, 0x67, 0x39, 0xe8, 0x9b, 0xc8} - }, - }, -- // Image.gz-initramfs-corstone1000-fvp - { -+ .image_name = "kernel_secondary", - .image_size = INITRAMFS_PARTITION_SIZE, - .image_offset = INITRAMFS_PARTITION_BANK_OFFSET, -- .image_guid = { -+ .image_type = { - .time_low = 0xf771aff9, - .time_mid = 0xc7e9, - .time_hi_and_version = 0x5f99, -- .clock_seq_and_node = {0x9e, 0xda, 0x23, 0x69, 0xdd, 0x69, 0x4f, 0x61} -+ .clock_seq_hi_and_reserved = 0x9e, -+ .clock_seq_low = 0xda, -+ .node = {0x23, 0x69, 0xdd, 0x69, 0x4f, 0x61} - }, - }, - #else - // MPS3 payloads GUIDs -- // bl2_signed payload GUID - { -+ .image_name = "bl2_secondary", - .image_size = SE_BL2_PARTITION_SIZE, - .image_offset = SE_BL2_PARTITION_BANK_OFFSET, -- .image_guid = { -+ .image_type = { - .time_low = 0xfbfbefaa, - .time_mid = 0x0a56, - .time_hi_and_version = 0x50d5, -- .clock_seq_and_node = {0xb6, 0x51, 0x74, 0x09, 0x1d, 0x3d, 0x62, 0xcf} -+ .clock_seq_hi_and_reserved = 0xb6, -+ .clock_seq_low = 0x51, -+ .node = {0x74, 0x09, 0x1d, 0x3d, 0x62, 0xcf} - }, - }, -- // tfm_s_signed - { -+ .image_name = "tfm_secondary", - .image_size = TFM_PARTITION_SIZE, - .image_offset = TFM_PARTITION_BANK_OFFSET, -- .image_guid = { -+ .image_type = { - .time_low = 0xaf4cc7ad, - .time_mid = 0xee2e, - .time_hi_and_version = 0x5a39, -- .clock_seq_and_node = {0xaa, 0xd5, 0xfa, 0xc8, 0xa1, 0xe6, 0x17, 0x3c} -- }, -+ .clock_seq_hi_and_reserved = 0xaa, -+ .clock_seq_low = 0xd5, -+ .node = {0xfa, 0xc8, 0xa1, 0xe6, 0x17, 0x3c} -+ } - }, -- // signed_fip-corstone1000 - { -+ .image_name = "FIP_B", - .image_size = FIP_PARTITION_SIZE, - .image_offset = FIP_PARTITION_BANK_OFFSET, -- .image_guid = { -+ .image_type = { - .time_low = 0x55302f96, - .time_mid = 0xc4f0, - .time_hi_and_version = 0x5cf9, -- .clock_seq_and_node = {0x86, 0x24, 0xe7, 0xcc, 0x38, 0x8f, 0x2b, 0x68} -- }, -+ .clock_seq_hi_and_reserved = 0x86, -+ .clock_seq_low = 0x24, -+ .node = {0xe7, 0xcc, 0x38, 0x8f, 0x2b, 0x68} -+ } - }, -- // Image.gz-initramfs-corstone1000-mps3 - { -+ .image_name = "kernel_secondary", - .image_size = INITRAMFS_PARTITION_SIZE, - .image_offset = INITRAMFS_PARTITION_BANK_OFFSET, -- .image_guid = { -+ .image_type = { - .time_low = 0x3e8ac972, - .time_mid = 0xc33c, - .time_hi_and_version = 0x5cc9, -- .clock_seq_and_node = {0x90, 0xa0, 0xcd, 0xd3, 0x15, 0x96, 0x83, 0xea} -+ .clock_seq_hi_and_reserved = 0x90, -+ .clock_seq_low = 0xa0, -+ .node = {0xcd, 0xd3, 0x15, 0x96, 0x83, 0xea} - }, - }, - #endif -@@ -370,8 +387,8 @@ static psa_status_t private_metadata_read( - static psa_status_t private_metadata_read( - struct fwu_private_metadata* priv_metadata) - { -- partition_entry_t *part; -- uuid_t private_uuid = PRIVATE_METADATA_TYPE_UUID; -+ struct partition_entry_t part; -+ struct efi_guid_t private_uuid = PRIVATE_METADATA_TYPE_UUID; - - FWU_LOG_FUNC_ENTER; - -@@ -380,13 +397,19 @@ static psa_status_t private_metadata_read( - return PSA_ERROR_INVALID_ARGUMENT; - } - -- part = get_partition_entry_by_type(&private_uuid); -- if (!part) { -+ psa_status_t ret = gpt_entry_read_by_type(&private_uuid, 0, &part); -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { - FWU_LOG_MSG("Private metadata partition not found\n\r"); -- return PSA_ERROR_GENERIC_ERROR; -+ return ret; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s : ERROR - flash failure reading private metadata\n\r", __func__); -+ return ret; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("Unable to find private metadata partition, ret: %d\n\r", ret); -+ return ret; - } - -- int ret = FWU_METADATA_FLASH_DEV.ReadData(part->start, priv_metadata, -+ ret = FWU_METADATA_FLASH_DEV.ReadData(part.start * TFM_GPT_BLOCK_SIZE, priv_metadata, - sizeof(*priv_metadata)); - if (ret < 0) { - FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, ret); -@@ -444,8 +467,8 @@ static psa_status_t private_metadata_write( - static psa_status_t private_metadata_write( - struct fwu_private_metadata* priv_metadata) - { -- uuid_t private_uuid = PRIVATE_METADATA_TYPE_UUID; -- partition_entry_t *part; -+ struct efi_guid_t private_uuid = PRIVATE_METADATA_TYPE_UUID; -+ struct partition_entry_t part; - - FWU_LOG_MSG("%s: enter: boot_index = %u\n\r", __func__, - priv_metadata->boot_index); -@@ -455,19 +478,25 @@ static psa_status_t private_metadata_write( - return PSA_ERROR_INVALID_ARGUMENT; - } - -- part = get_partition_entry_by_type(&private_uuid); -- if (!part) { -+ psa_status_t ret = gpt_entry_read_by_type(&private_uuid, 0, &part); -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { - FWU_LOG_MSG("Private metadata partition not found\n\r"); -- return PSA_ERROR_GENERIC_ERROR; -+ return ret; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: ERROR - flash failure reading private metadata\n\r", __func__); -+ return ret; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("Unable to find private metadata partition, ret: %d\n\r", ret); -+ return ret; - } - -- int ret = FWU_METADATA_FLASH_DEV.EraseSector(part->start); -+ ret = FWU_METADATA_FLASH_DEV.EraseSector(part.start * TFM_GPT_BLOCK_SIZE); - if (ret != ARM_DRIVER_OK) { - FWU_LOG_MSG("%s: ERROR - Flash erase failed (ret = %d)\n\r", __func__, ret); - return PSA_ERROR_STORAGE_FAILURE; - } - -- ret = FWU_METADATA_FLASH_DEV.ProgramData(part->start, -+ ret = FWU_METADATA_FLASH_DEV.ProgramData(part.start * TFM_GPT_BLOCK_SIZE, - priv_metadata, sizeof(*priv_metadata)); - if (ret < 0) { - FWU_LOG_MSG("%s: ERROR - Flash write failed (ret = %d)\n\r", __func__, ret); -@@ -494,8 +523,10 @@ static psa_status_t metadata_validate(struct fwu_metadata *metadata) - return PSA_ERROR_INVALID_ARGUMENT; - } - -- uint32_t calculated_crc32 = crc32((uint8_t *)&(metadata->version), -- sizeof(*metadata) - sizeof(uint32_t)); -+ uint32_t calculated_crc32 = efi_soft_crc32_update( -+ 0, -+ (uint8_t *)&(metadata->version), -+ sizeof(*metadata) - sizeof(uint32_t)); - - if (metadata->crc_32 != calculated_crc32) { - FWU_LOG_MSG("%s: failed: crc32 calculated: 0x%x, given: 0x%x\n\r", __func__, -@@ -558,8 +589,8 @@ static psa_status_t metadata_read(struct fwu_metadata *metadata, uint8_t replica - #else - static psa_status_t metadata_read(struct fwu_metadata *metadata, uint8_t replica_num) - { -- uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID; -- partition_entry_t *part; -+ struct efi_guid_t metadata_uuid = FWU_METADATA_TYPE_UUID; -+ struct partition_entry_t part; - - FWU_LOG_FUNC_ENTER; - -@@ -568,24 +599,32 @@ static psa_status_t metadata_read(struct fwu_metadata *metadata, uint8_t replica - return PSA_ERROR_INVALID_ARGUMENT; - } - -- if (replica_num == 1) { -- part = get_partition_entry_by_type(&metadata_uuid); -- } else if (replica_num == 2) { -- part = get_partition_replica_by_type(&metadata_uuid); -- } else { -+ psa_status_t ret; -+ switch (replica_num) { -+ case 1: -+ case 2: -+ ret = gpt_entry_read_by_type(&metadata_uuid, replica_num - 1, &part); -+ break; -+ default: - FWU_LOG_MSG("%s: replica_num must be 1 or 2\n\r", __func__); - return PSA_ERROR_GENERIC_ERROR; - } - -- if (!part) { -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { - FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__); -- return PSA_ERROR_GENERIC_ERROR; -+ return ret; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: ERROR - flash failure reading private metadata\n\r", __func__); -+ return ret; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("%s: Unable to find FWU partition, ret: %d\n\r", __func__, ret); -+ return ret; - } - - FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- part->start, sizeof(*metadata)); -+ part.start * TFM_GPT_BLOCK_SIZE, sizeof(*metadata)); - -- int ret = FWU_METADATA_FLASH_DEV.ReadData(part->start, -+ ret = FWU_METADATA_FLASH_DEV.ReadData(part.start * TFM_GPT_BLOCK_SIZE, - metadata, sizeof(*metadata)); - if (ret < 0) { - FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, ret); -@@ -663,8 +702,8 @@ static psa_status_t metadata_write( - static psa_status_t metadata_write( - struct fwu_metadata *metadata, uint8_t replica_num) - { -- uuid_t metadata_uuid = FWU_METADATA_TYPE_UUID; -- partition_entry_t *part; -+ struct efi_guid_t metadata_uuid = FWU_METADATA_TYPE_UUID; -+ struct partition_entry_t part; - - FWU_LOG_FUNC_ENTER; - -@@ -673,30 +712,38 @@ static psa_status_t metadata_write( - return PSA_ERROR_INVALID_ARGUMENT; - } - -- if (replica_num == 1) { -- part = get_partition_entry_by_type(&metadata_uuid); -- } else if (replica_num == 2) { -- part = get_partition_replica_by_type(&metadata_uuid); -- } else { -+ psa_status_t ret; -+ switch (replica_num) { -+ case 1: -+ case 2: -+ ret = gpt_entry_read_by_type(&metadata_uuid, replica_num - 1, &part); -+ break; -+ default: - FWU_LOG_MSG("%s: replica_num must be 1 or 2\n\r", __func__); - return PSA_ERROR_GENERIC_ERROR; - } - -- if (!part) { -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { - FWU_LOG_MSG("%s: FWU metadata partition not found\n\r", __func__); -- return PSA_ERROR_GENERIC_ERROR; -+ return ret; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: ERROR - flash failure reading private metadata\n\r", __func__); -+ return PSA_ERROR_STORAGE_FAILURE; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("%s: Unable to find FWU partition, ret: %d\n\r", __func__, ret); -+ return ret; - } - - FWU_LOG_MSG("%s: enter: flash addr = %u, size = %d\n\r", __func__, -- part->start, sizeof(*metadata)); -+ part.start * TFM_GPT_BLOCK_SIZE, sizeof(*metadata)); - -- int ret = FWU_METADATA_FLASH_DEV.EraseSector(part->start); -+ ret = FWU_METADATA_FLASH_DEV.EraseSector(part.start * TFM_GPT_BLOCK_SIZE); - if (ret != ARM_DRIVER_OK) { - FWU_LOG_MSG("%s: ERROR - Flash erase failed (ret = %d)\n\r", __func__, ret); - return PSA_ERROR_STORAGE_FAILURE; - } - -- ret = FWU_METADATA_FLASH_DEV.ProgramData(part->start, -+ ret = FWU_METADATA_FLASH_DEV.ProgramData(part.start * TFM_GPT_BLOCK_SIZE, - metadata, sizeof(*metadata)); - if (ret < 0) { - FWU_LOG_MSG("%s: ERROR - Flash write failed (ret = %d)\n\r", __func__, ret); -@@ -733,8 +780,41 @@ static psa_status_t metadata_write_both_replica( - return PSA_SUCCESS; - } - -+#ifndef BL1_BUILD -+/* Ensure both GPT headers are valid */ -+psa_status_t ensure_gpt_headers_valid(void) -+{ -+ psa_status_t ret = gpt_validate(true); -+ if (ret == PSA_ERROR_INVALID_SIGNATURE) { -+ ret = gpt_restore(true); -+ if (ret == PSA_ERROR_INVALID_SIGNATURE) { -+ FWU_LOG_MSG("Invalid primary GPT\r\n"); -+ return ret; -+ } -+ } -+ -+ ret = gpt_validate(false); -+ if (ret == PSA_ERROR_INVALID_SIGNATURE) { -+ ret = gpt_restore(false); -+ if (ret == PSA_ERROR_INVALID_SIGNATURE) { -+ FWU_LOG_MSG("Invalid primary GPT\r\n"); -+ return ret; -+ } -+ } -+ -+ return PSA_SUCCESS; -+} -+#endif /* BL1_BUILD */ -+ - psa_status_t fwu_metadata_check_and_correct_integrity(void) - { -+#ifndef BL1_BUILD -+ psa_status_t ret = ensure_gpt_headers_valid(); -+ if (ret != PSA_SUCCESS) { -+ return ret; -+ } -+#endif -+ - psa_status_t ret_replica_1 = PSA_ERROR_GENERIC_ERROR; - psa_status_t ret_replica_2 = PSA_ERROR_GENERIC_ERROR; - -@@ -760,14 +840,22 @@ psa_status_t fwu_metadata_init(void) - psa_status_t ret; - ARM_FLASH_INFO* flash_info; - -+ if (is_initialized) { -+ return PSA_SUCCESS; -+ } -+ - #ifndef BL1_BUILD - plat_io_storage_init(); -- partition_init(PLATFORM_GPT_IMAGE); --#endif -+ ret = gpt_init(&io_gpt_flash_driver, PLAT_MAX_PARTITION_ENTRIES); -+ if (ret < 0) { -+ return ret; -+ } - -- if (is_initialized) { -- return PSA_SUCCESS; -+ ret = ensure_gpt_headers_valid(); -+ if (ret != PSA_SUCCESS) { -+ return ret; - } -+#endif - - /* Code assumes everything fits into a sector */ - if (sizeof(struct fwu_metadata) > FWU_METADATA_FLASH_SECTOR_SIZE) { -@@ -830,17 +918,19 @@ static psa_status_t fwu_metadata_configure(void) - - _metadata.fw_desc.img_entry[i].img_props[BANK_0].accepted = IMAGE_ACCEPTED; - _metadata.fw_desc.img_entry[i].img_props[BANK_0].version = image_version; -- memcpy(&(_metadata.fw_desc.img_entry[i].img_props[BANK_0].img_uuid), (const void *)&fwu_image[i].image_guid, sizeof(struct efi_guid)); -+ memcpy(&(_metadata.fw_desc.img_entry[i].img_props[BANK_0].img_uuid), (const void *)&fwu_image[i].image_type, sizeof(struct efi_guid_t)); - - _metadata.fw_desc.img_entry[i].img_props[BANK_1].accepted = INVALID_IMAGE; - _metadata.fw_desc.img_entry[i].img_props[BANK_1].version = INVALID_VERSION; -- memcpy(&(_metadata.fw_desc.img_entry[i].img_props[BANK_1].img_uuid), (const void *)&fwu_image[i].image_guid, sizeof(struct efi_guid)); -+ memcpy(&(_metadata.fw_desc.img_entry[i].img_props[BANK_1].img_uuid), (const void *)&fwu_image[i].image_type, sizeof(struct efi_guid_t)); - } - - /* Calculate CRC32 for fwu metadata. The first filed in the _metadata has to be the crc_32. - * This should be omited from the calculation. */ -- _metadata.crc_32 = crc32((uint8_t *)&_metadata.version, -- sizeof(struct fwu_metadata) - sizeof(uint32_t)); -+ _metadata.crc_32 = efi_soft_crc32_update( -+ 0, -+ (uint8_t *)&_metadata.version, -+ sizeof(struct fwu_metadata) - sizeof(uint32_t)); - - ret = metadata_write_both_replica(&_metadata); - if (ret) { -@@ -1045,8 +1135,10 @@ static psa_status_t fwu_select_previous( - if (ret) { - return ret; - } -- metadata->crc_32 = crc32((uint8_t *)&metadata->version, -- sizeof(struct fwu_metadata) - sizeof(uint32_t)); -+ metadata->crc_32 = efi_soft_crc32_update( -+ 0, -+ (uint8_t *)&metadata->version, -+ sizeof(struct fwu_metadata) - sizeof(uint32_t)); - - ret = metadata_write_both_replica(metadata); - if (ret) { -@@ -1243,7 +1335,7 @@ 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, -+ fmp_set_image_info(&fwu_image[i].image_type, - priv_metadata.fmp_version[i], - priv_metadata.fmp_last_attempt_version[i], - priv_metadata.fmp_last_attempt_status[i]); -@@ -1274,7 +1366,7 @@ psa_status_t corstone1000_fwu_host_ack(void) - if (ret == PSA_SUCCESS) { - disable_host_ack_timer(); - for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) { -- fmp_set_image_info(&fwu_image[i].image_guid, -+ fmp_set_image_info(&fwu_image[i].image_type, - priv_metadata.fmp_version[i], - priv_metadata.fmp_last_attempt_version[i], - priv_metadata.fmp_last_attempt_status[i]); -@@ -1428,7 +1520,7 @@ static psa_status_t get_esrt_data(struct fwu_esrt_data_wrapper *esrt) - - for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; i++) - { -- memcpy(&esrt->entries[i].fw_class, &fwu_image[i].image_guid, sizeof(struct efi_guid)); -+ memcpy(&esrt->entries[i].fw_class, &fwu_image[i].image_type, sizeof(struct efi_guid_t)); - esrt->entries[i].fw_version = priv_metadata.fmp_version[i]; - esrt->entries[i].lowest_supported_fw_version = FWU_IMAGE_INITIAL_VERSION; - esrt->entries[i].last_attempt_version = priv_metadata.fmp_last_attempt_version[i]; -@@ -1491,8 +1583,10 @@ static psa_status_t fwu_accept_image(struct fwu_metadata *metadata, - if (ret) { - return ret; - } -- metadata->crc_32 = crc32((uint8_t *)&metadata->version, -- sizeof(struct fwu_metadata) - sizeof(uint32_t)); -+ metadata->crc_32 = efi_soft_crc32_update( -+ 0, -+ (uint8_t *)&metadata->version, -+ sizeof(struct fwu_metadata) - sizeof(uint32_t)); - - ret = metadata_write_both_replica(metadata); - if (ret) { -@@ -1658,9 +1752,7 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component, - psa_status_t ret; - int drv_ret; - int image_index; -- uint32_t bank_offset; - uint32_t active_index; -- uint32_t previous_active_index; - uint32_t nr_images; - uint32_t current_state; - uint32_t image_offset; -@@ -1717,7 +1809,7 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component, - priv_metadata.fmp_last_attempt_status[fwu_image_index] = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; - private_metadata_write(&priv_metadata); - -- fmp_set_image_info(&fwu_image[fwu_image_index].image_guid, -+ fmp_set_image_info(&fwu_image[fwu_image_index].image_type, - priv_metadata.fmp_version[fwu_image_index], - priv_metadata.fmp_last_attempt_version[fwu_image_index], - priv_metadata.fmp_last_attempt_status[fwu_image_index]); -@@ -1727,11 +1819,11 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component, - goto out; - } - -+#ifdef BL1_BUILD -+ uint32_t bank_offset; - if (active_index == BANK_0) { -- previous_active_index = BANK_1; - bank_offset = BANK_1_PARTITION_OFFSET; - } else if (active_index == BANK_1) { -- previous_active_index = BANK_0; - bank_offset = BANK_0_PARTITION_OFFSET; - } else { - FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index); -@@ -1740,6 +1832,38 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component, - } - - image_offset = bank_offset + fwu_image[fwu_image_index].image_offset; -+#else -+ uint32_t previous_active_index; -+ struct partition_entry_t part; -+ -+ if (active_index == BANK_0) { -+ previous_active_index = BANK_1; -+ } else if (active_index == BANK_1) { -+ previous_active_index = BANK_0; -+ } else { -+ FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index); -+ ret = PSA_ERROR_DATA_INVALID; -+ goto out; -+ } -+ -+ ret = gpt_entry_read_by_type(&(fwu_image[fwu_image_index].image_type), 1, &part); -+ -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { -+ FWU_LOG_MSG("%s: Partition '%s' not found\n\r", -+ __func__, fwu_image[fwu_image_index].image_names[previous_active_index]); -+ goto out; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s : ERROR - flash failure reading partition '%s'\n\r", -+ __func__, fwu_image[fwu_image_index].image_names[previous_active_index]); -+ goto out; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("Unable to find partition '%s', ret: %d\n\r", -+ fwu_image[fwu_image_index].image_names[previous_active_index], ret); -+ goto out; -+ } -+ -+ image_offset = part.start * TFM_GPT_BLOCK_SIZE; -+#endif /* BL1_BUILD */ - - /* Firmware update process can only start in regular state. */ - current_state = get_fwu_image_state(&_metadata, &priv_metadata, fwu_image_index); -@@ -1762,7 +1886,7 @@ psa_status_t fwu_bootloader_load_image(psa_fwu_component_t component, - - private_metadata_write(&priv_metadata); - -- fmp_set_image_info(&fwu_image[fwu_image_index].image_guid, -+ fmp_set_image_info(&fwu_image[fwu_image_index].image_type, - priv_metadata.fmp_version[fwu_image_index], - priv_metadata.fmp_last_attempt_version[fwu_image_index], - priv_metadata.fmp_last_attempt_status[fwu_image_index]); -@@ -1828,8 +1952,10 @@ static psa_status_t fwu_update_metadata(const psa_fwu_component_t *candidates, u - _metadata.fw_desc.img_entry[fwu_image_index].img_props[previous_active_index].version = fmp_header_image_info[fwu_image_index].fmp_hdr.fw_version; - } - -- _metadata.crc_32 = crc32((uint8_t *)&_metadata.version, -- sizeof(struct fwu_metadata) - sizeof(uint32_t)); -+ _metadata.crc_32 = efi_soft_crc32_update( -+ 0, -+ (uint8_t *)&_metadata.version, -+ sizeof(struct fwu_metadata) - sizeof(uint32_t)); - - ret = metadata_write_both_replica(&_metadata); - if (ret) { -@@ -1960,8 +2086,10 @@ static psa_status_t maintain_bank_consistency(void) - goto out; - } - -- _metadata.crc_32 = crc32((uint8_t *)&_metadata.version, -- sizeof(struct fwu_metadata) - sizeof(uint32_t)); -+ _metadata.crc_32 = efi_soft_crc32_update( -+ 0, -+ (uint8_t *)&_metadata.version, -+ sizeof(struct fwu_metadata) - sizeof(uint32_t)); - - ret = metadata_write_both_replica(&_metadata); - if (ret) { -@@ -2057,7 +2185,7 @@ psa_status_t fwu_bootloader_mark_image_accepted(const psa_fwu_component_t *trial - - current_state = get_fwu_image_state(&_metadata, &priv_metadata, fwu_image_index); - if (current_state == PSA_FWU_READY) { -- fmp_set_image_info(&fwu_image[fwu_image_index].image_guid, -+ fmp_set_image_info(&fwu_image[fwu_image_index].image_type, - priv_metadata.fmp_version[fwu_image_index], - priv_metadata.fmp_last_attempt_version[fwu_image_index], - priv_metadata.fmp_last_attempt_status[fwu_image_index]); -@@ -2091,7 +2219,7 @@ psa_status_t fwu_bootloader_mark_image_accepted(const psa_fwu_component_t *trial - } - - fwu_image_index = trials[i] - FWU_FAKE_IMAGES_INDEX_COUNT; -- fmp_set_image_info(&fwu_image[fwu_image_index].image_guid, -+ fmp_set_image_info(&fwu_image[fwu_image_index].image_type, - priv_metadata.fmp_version[fwu_image_index], - priv_metadata.fmp_last_attempt_version[fwu_image_index], - priv_metadata.fmp_last_attempt_status[fwu_image_index]); -@@ -2107,7 +2235,6 @@ out: - /* Reject the staged image. */ - psa_status_t fwu_bootloader_reject_staged_image(psa_fwu_component_t component) - { -- - if (!is_image_index_valid(component)) { - FWU_LOG_MSG("%s: Invalid image index received \n\r", __func__); - return PSA_ERROR_INVALID_ARGUMENT; -@@ -2224,7 +2351,6 @@ psa_status_t fwu_bootloader_get_image_info(psa_fwu_component_t component, - - FWU_LOG_FUNC_ENTER; - -- - Select_Write_Mode_For_Shared_Flash(); - if (private_metadata_read(&priv_metadata)) { - ret = PSA_ERROR_GENERIC_ERROR; -diff --git a/platform/ext/target/arm/corstone1000/bootloader/mcuboot/uefi_fmp.c b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/uefi_fmp.c -index 3edd4ebd0..c41b1f9ea 100644 ---- a/platform/ext/target/arm/corstone1000/bootloader/mcuboot/uefi_fmp.c -+++ b/platform/ext/target/arm/corstone1000/bootloader/mcuboot/uefi_fmp.c -@@ -10,6 +10,7 @@ - #include "tfm_hal_device_header.h" - #include "uefi_fmp.h" - #include "flash_layout.h" -+#include "efi_guid_structs.h" - - /* The count will increase when partial update is supported. - * At present, only full WIC is considered as updatable image. -@@ -45,7 +46,7 @@ typedef uint8_t DescriptorCount_t; - - typedef __PACKED_STRUCT { - uint8_t ImageIndex; -- struct efi_guid ImageTypeId; -+ struct efi_guid_t ImageTypeId; - uint64_t ImageId; - uefi_ptr_t PtrImageIdName; - uint32_t Version; -@@ -101,7 +102,7 @@ struct corstone_image_info image_info[NUMBER_OF_FMP_IMAGES] = { - }; - static EFI_FIRMWARE_MANAGEMENT_PROTOCOL_IMAGE_INFO fmp_info[NUMBER_OF_FMP_IMAGES]; - --extern fwu_bank_image_info_t fwu_image[]; -+extern const fwu_image_info_t fwu_image[]; - - static bool is_fmp_info_initialized = false; - -@@ -127,8 +128,8 @@ static void init_fmp_info(void) - - fmp_info[i].ImageDescriptor.ImageIndex = i+1; - -- memcpy(&fmp_info[i].ImageDescriptor.ImageTypeId, &fwu_image[i].image_guid, -- sizeof(struct efi_guid)); -+ memcpy(&fmp_info[i].ImageDescriptor.ImageTypeId, &fwu_image[i].image_type, -+ sizeof(struct efi_guid_t)); - - fmp_info[i].ImageDescriptor.ImageId = i+1; - fmp_info[i].ImageDescriptor.Version = FWU_IMAGE_INITIAL_VERSION; -@@ -150,7 +151,7 @@ static void init_fmp_info(void) - return; - } - --psa_status_t fmp_set_image_info(struct efi_guid *guid, -+psa_status_t fmp_set_image_info(const struct efi_guid_t *guid, - uint32_t current_version, uint32_t attempt_version, - uint32_t last_attempt_status) - { -@@ -164,7 +165,7 @@ psa_status_t fmp_set_image_info(struct efi_guid *guid, - - for (int i = 0; i < NUMBER_OF_FMP_IMAGES; i++) { - if ((memcmp(guid, &fmp_info[i].ImageDescriptor.ImageTypeId, -- sizeof(struct efi_guid))) == 0) -+ sizeof(struct efi_guid_t))) == 0) - { - FWU_LOG_MSG("FMP image update: image id = %u\n\r", - fmp_info[i].ImageDescriptor.ImageId); -diff --git a/platform/ext/target/arm/corstone1000/bootloader/uefi_fmp.h b/platform/ext/target/arm/corstone1000/bootloader/uefi_fmp.h -index 36c604714..e185448ef 100644 ---- a/platform/ext/target/arm/corstone1000/bootloader/uefi_fmp.h -+++ b/platform/ext/target/arm/corstone1000/bootloader/uefi_fmp.h -@@ -11,7 +11,6 @@ - - #include - #include "fwu_agent.h" --#include "../fip_parser/external/uuid.h" - - /* - * Last Attempt Status Value -@@ -40,7 +39,7 @@ - * attempt_version: attempted versions for the image - * - */ --psa_status_t fmp_set_image_info(struct efi_guid *guid, -+psa_status_t fmp_set_image_info(const struct efi_guid_t *guid, - uint32_t current_version, uint32_t attempt_version, - uint32_t last_attempt_status); - -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 3b023c813..e92723026 100644 ---- a/platform/ext/target/arm/corstone1000/ci_regression_tests/CMakeLists.txt -+++ b/platform/ext/target/arm/corstone1000/ci_regression_tests/CMakeLists.txt -@@ -9,26 +9,18 @@ - - cmake_policy(SET CMP0079 NEW) - --include(${CMAKE_CURRENT_SOURCE_DIR}/s_test_config.cmake) -- - ####################### Secure ################################################# - - target_sources(tfm_test_suite_extra_s - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/s_test.c - ../Native_Driver/firewall.c -- ../io/io_storage.c -- ../io/io_block.c -- ../io/io_flash.c -- Driver_Flash_SRAM_Emu.c -- s_io_storage_test.c - ) - - target_include_directories(tfm_test_suite_extra_s - PRIVATE - ../Device/Include - ../Native_Driver -- ../io - ) - - target_link_libraries(tfm_test_suite_extra_s -@@ -39,10 +31,6 @@ target_link_libraries(tfm_test_suite_extra_s - target_compile_definitions(tfm_test_suite_extra_s - PRIVATE - $<$:PLATFORM_IS_FVP> -- TEST_FLASH_SIZE_IN_BYTES=${TEST_FLASH_SIZE_IN_BYTES} -- TEST_FLASH_SECTOR_SIZE_IN_BYTES=${TEST_FLASH_SECTOR_SIZE_IN_BYTES} -- 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/ci_regression_tests/Driver_Flash_SRAM_Emu.c b/platform/ext/target/arm/corstone1000/ci_regression_tests/Driver_Flash_SRAM_Emu.c -deleted file mode 100644 -index 06b6b51c0..000000000 ---- a/platform/ext/target/arm/corstone1000/ci_regression_tests/Driver_Flash_SRAM_Emu.c -+++ /dev/null -@@ -1,327 +0,0 @@ --/* -- * Copyright (c) 2013-2022 ARM Limited. All rights reserved. -- * -- * SPDX-License-Identifier: Apache-2.0 -- * -- * Licensed under the Apache License, Version 2.0 (the License); you may -- * not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- * -- * www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an AS IS BASIS, WITHOUT -- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#include --#include --#include "Driver_Flash.h" --#include "test_flash.h" --#include "tfm_sp_log.h" -- --#ifndef ARG_UNUSED --#define ARG_UNUSED(arg) ((void)arg) --#endif -- --/* Driver version */ --#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 1) --#define ARM_FLASH_DRV_ERASE_VALUE 0xFF -- -- --/** -- * There is no real flash memory. This driver just emulates a flash -- * interface and behaviour on top of the SRAM memory. -- */ -- --/** -- * Data width values for ARM_FLASH_CAPABILITIES::data_width -- * \ref ARM_FLASH_CAPABILITIES -- */ -- enum { -- DATA_WIDTH_8BIT = 0u, -- DATA_WIDTH_16BIT, -- DATA_WIDTH_32BIT, -- DATA_WIDTH_ENUM_SIZE --}; -- --static const uint32_t data_width_byte[DATA_WIDTH_ENUM_SIZE] = { -- sizeof(uint8_t), -- sizeof(uint16_t), -- sizeof(uint32_t), --}; -- -- --/* -- * ARM FLASH device structure -- * -- */ --struct arm_flash_dev_t { -- const uint8_t* memory_base; /*!< FLASH memory base address */ -- ARM_FLASH_INFO *data; /*!< FLASH data */ --}; -- --/* Flash emulated memory */ --static uint8_t flash_memory[TEST_FLASH_SIZE_IN_BYTES] -- __attribute__((aligned(TEST_FLASH_SECTOR_SIZE_IN_BYTES))); -- --/* Flash Status */ --static ARM_FLASH_STATUS FlashStatus = {0, 0, 0}; -- --/* Driver Version */ --static const ARM_DRIVER_VERSION DriverVersion = { -- ARM_FLASH_API_VERSION, -- ARM_FLASH_DRV_VERSION --}; -- --/* Driver Capabilities */ --static const ARM_FLASH_CAPABILITIES DriverCapabilities = { -- 0, /* event_ready */ -- 0, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */ -- 1 /* erase_chip */ --}; -- --static int32_t is_range_valid(struct arm_flash_dev_t *flash_dev, -- uint32_t offset) --{ -- uint32_t flash_limit = 0; -- int32_t rc = 0; -- -- flash_limit = (flash_dev->data->sector_count * flash_dev->data->sector_size); -- if (offset > flash_limit) { -- rc = -1; -- } -- return rc; --} -- --static int32_t is_write_aligned(struct arm_flash_dev_t *flash_dev, -- uint32_t param) --{ -- int32_t rc = 0; -- -- if ((param % flash_dev->data->program_unit) != 0) { -- rc = -1; -- } -- return rc; --} -- --static int32_t is_sector_aligned(struct arm_flash_dev_t *flash_dev, -- uint32_t offset) --{ -- int32_t rc = 0; -- -- if ((offset % flash_dev->data->sector_size) != 0) { -- rc = -1; -- } -- return rc; --} -- --static int32_t is_flash_ready_to_write(const uint8_t *start_addr, uint32_t cnt) --{ -- int32_t rc = 0; -- uint32_t i; -- -- for (i = 0; i < cnt; i++) { -- if(start_addr[i] != ARM_FLASH_DRV_ERASE_VALUE) { -- rc = -1; -- break; -- } -- } -- -- return rc; --} -- --static ARM_FLASH_INFO ARM_TEST_FLASH_DEV_DATA = { -- .sector_info = NULL,/* Uniform sector layout */ -- .sector_count = TEST_FLASH_SIZE_IN_BYTES / TEST_FLASH_SECTOR_SIZE_IN_BYTES, -- .sector_size = TEST_FLASH_SECTOR_SIZE_IN_BYTES, -- .page_size = TEST_FLASH_PAGE_SIZE, -- .program_unit = TEST_FLASH_PROGRAM_UNIT, -- .erased_value = ARM_FLASH_DRV_ERASE_VALUE}; -- --static struct arm_flash_dev_t ARM_TEST_FLASH_DEV = { -- .memory_base = flash_memory, -- .data = &(ARM_TEST_FLASH_DEV_DATA)}; -- --static struct arm_flash_dev_t *TEST_FLASH_DEV = &ARM_TEST_FLASH_DEV; -- --/* -- * Functions -- */ -- --static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void) --{ -- return DriverVersion; --} -- --static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void) --{ -- return DriverCapabilities; --} -- --static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event) --{ -- ARG_UNUSED(cb_event); -- -- if (DriverCapabilities.data_width >= DATA_WIDTH_ENUM_SIZE) { -- return ARM_DRIVER_ERROR; -- } -- -- /* Nothing to be done */ -- return ARM_DRIVER_OK; --} -- --static int32_t ARM_Flash_Uninitialize(void) --{ -- /* Nothing to be done */ -- return ARM_DRIVER_OK; --} -- --static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state) --{ -- switch (state) { -- case ARM_POWER_FULL: -- /* Nothing to be done */ -- return ARM_DRIVER_OK; -- break; -- -- case ARM_POWER_OFF: -- case ARM_POWER_LOW: -- default: -- return ARM_DRIVER_ERROR_UNSUPPORTED; -- } --} -- --static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt) --{ -- int32_t rc = 0; -- -- /* The addr given is a relative address*/ -- uint32_t offset = addr; -- addr += (uint32_t)(TEST_FLASH_DEV->memory_base); -- -- /* Conversion between data items and bytes */ -- cnt *= data_width_byte[DriverCapabilities.data_width]; -- -- /* Check flash memory boundaries */ -- rc = is_range_valid(TEST_FLASH_DEV, offset + cnt); -- if (rc != 0) { -- return ARM_DRIVER_ERROR_PARAMETER; -- } -- -- /* Flash interface just emulated over SRAM, use memcpy */ -- memcpy(data, (void *)addr, cnt); -- -- /* Conversion between bytes and data items */ -- cnt /= data_width_byte[DriverCapabilities.data_width]; -- -- return cnt; --} -- --static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, -- uint32_t cnt) --{ -- int32_t rc = 0; -- -- /* The addr given is a relative address*/ -- uint32_t offset = addr; -- addr += (uint32_t)(TEST_FLASH_DEV->memory_base); -- -- /* Conversion between data items and bytes */ -- cnt *= data_width_byte[DriverCapabilities.data_width]; -- -- /* Check flash memory boundaries and alignment with minimal write size */ -- rc = is_range_valid(TEST_FLASH_DEV, offset + cnt); -- rc |= is_write_aligned(TEST_FLASH_DEV, offset); -- rc |= is_write_aligned(TEST_FLASH_DEV, cnt); -- if (rc != 0) { -- return ARM_DRIVER_ERROR_PARAMETER; -- } -- -- /* Check if the flash area to write the data was erased previously */ -- rc = is_flash_ready_to_write((const uint8_t*)addr, cnt); -- if (rc != 0) { -- return ARM_DRIVER_ERROR; -- } -- -- /* Flash interface just emulated over SRAM, use memcpy */ -- memcpy((void *)addr, data, cnt); -- -- /* Conversion between bytes and data items */ -- cnt /= data_width_byte[DriverCapabilities.data_width]; -- -- return cnt; --} -- --static int32_t ARM_Flash_EraseSector(uint32_t addr) --{ -- uint32_t rc = 0; -- -- /* The addr given is a relative address*/ -- uint32_t offset = addr; -- addr += (uint32_t)(TEST_FLASH_DEV->memory_base); -- -- rc = is_range_valid(TEST_FLASH_DEV, offset); -- rc |= is_sector_aligned(TEST_FLASH_DEV, offset); -- if (rc != 0) { -- return ARM_DRIVER_ERROR_PARAMETER; -- } -- -- /* Flash interface just emulated over SRAM, use memset */ -- memset((void *)addr, -- TEST_FLASH_DEV->data->erased_value, -- TEST_FLASH_DEV->data->sector_size); -- return ARM_DRIVER_OK; --} -- --static int32_t ARM_Flash_EraseChip(void) --{ -- uint32_t i; -- uint32_t addr = TEST_FLASH_DEV->memory_base; -- int32_t rc = ARM_DRIVER_ERROR_UNSUPPORTED; -- -- /* Check driver capability erase_chip bit */ -- if (DriverCapabilities.erase_chip == 1) { -- for (i = 0; i < TEST_FLASH_DEV->data->sector_count; i++) { -- /* Flash interface just emulated over SRAM, use memset */ -- memset((void *)addr, -- TEST_FLASH_DEV->data->erased_value, -- TEST_FLASH_DEV->data->sector_size); -- -- addr += TEST_FLASH_DEV->data->sector_size; -- rc = ARM_DRIVER_OK; -- } -- } -- return rc; --} -- --static ARM_FLASH_STATUS ARM_Flash_GetStatus(void) --{ -- return FlashStatus; --} -- --static ARM_FLASH_INFO * ARM_Flash_GetInfo(void) --{ -- return TEST_FLASH_DEV->data; --} -- -- --/* Global Variables */ -- --ARM_DRIVER_FLASH Driver_TEST_FLASH = { -- ARM_Flash_GetVersion, -- ARM_Flash_GetCapabilities, -- ARM_Flash_Initialize, -- ARM_Flash_Uninitialize, -- ARM_Flash_PowerControl, -- ARM_Flash_ReadData, -- ARM_Flash_ProgramData, -- ARM_Flash_EraseSector, -- ARM_Flash_EraseChip, -- ARM_Flash_GetStatus, -- ARM_Flash_GetInfo --}; -- --uintptr_t flash_base_address = flash_memory; -diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.c b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.c -deleted file mode 100644 -index fb589c9d2..000000000 ---- a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.c -+++ /dev/null -@@ -1,147 +0,0 @@ --/* -- * Copyright (c) 2022, Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- * -- */ -- --#include --#include "s_io_storage_test.h" --#include "Driver_Flash.h" --#include "flash_layout.h" --#include "io_block.h" --#include "io_driver.h" --#include "io_flash.h" --#include "tfm_sp_log.h" -- --#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array))) -- --extern ARM_DRIVER_FLASH Driver_FLASH0; --extern ARM_DRIVER_FLASH Driver_TEST_FLASH; --extern uintptr_t flash_base_address; -- --void s_test_io_storage_multiple_flash_simultaneous(struct test_result_t *ret) { -- /* FLASH0 */ -- static io_dev_connector_t* flash0_dev_con; -- static uint8_t local_block_flash0[FLASH_SECTOR_SIZE]; -- ARM_FLASH_INFO* flash0_info = Driver_FLASH0.GetInfo(); -- size_t flash0_block_size = flash0_info->sector_size; -- io_flash_dev_spec_t flash0_dev_spec = { -- .buffer = local_block_flash0, -- .bufferlen = flash0_block_size, -- .base_addr = FLASH_BASE_ADDRESS, -- .flash_driver = &Driver_FLASH0, -- }; -- io_block_spec_t flash0_spec = { -- .offset = FLASH_BASE_ADDRESS, -- .length = flash0_info->sector_count * flash0_info->sector_size}; -- uintptr_t flash0_dev_handle = NULL; -- uintptr_t flash0_handle = NULL; -- -- /* EMU TEST FLASH */ -- static io_dev_connector_t* flash_emu_dev_con; -- static uint8_t local_block_flash_emu[TEST_FLASH_SECTOR_SIZE_IN_BYTES] -- __attribute__((aligned(TEST_FLASH_SECTOR_SIZE_IN_BYTES))); -- ARM_FLASH_INFO* flash_emu_info = Driver_TEST_FLASH.GetInfo(); -- size_t flash_emu_block_size = flash_emu_info->sector_size; -- io_flash_dev_spec_t flash_emu_dev_spec = { -- .buffer = local_block_flash_emu, -- .bufferlen = flash_emu_block_size, -- .base_addr = flash_base_address, -- .flash_driver = &Driver_TEST_FLASH, -- }; -- io_block_spec_t flash_emu_spec = { -- .offset = flash_base_address, -- .length = flash_emu_info->sector_count * flash_emu_info->sector_size}; -- uintptr_t flash_emu_dev_handle = NULL; -- uintptr_t flash_emu_handle = NULL; -- -- /* Common */ -- int rc = -1; -- static uint8_t test_data[] = {0xEE, 0xDD, 0xCC, 0xBB, 0xAA, -- 0x10, 0x50, 0xA0, 0xD0, 0x51, -- 0x55, 0x44, 0x33, 0x22, 0x11}; -- static uint8_t actual_data[15]; -- size_t bytes_written_count = 0; -- size_t bytes_read_count = 0; -- -- memset(local_block_flash0, -1, sizeof(local_block_flash0)); -- memset(local_block_flash_emu, -1, sizeof(local_block_flash_emu)); -- -- /* Register */ -- register_io_dev_flash(&flash0_dev_con); -- register_io_dev_flash(&flash_emu_dev_con); -- -- io_dev_open(flash0_dev_con, &flash0_dev_spec, &flash0_dev_handle); -- io_dev_open(flash_emu_dev_con, &flash_emu_dev_spec, &flash_emu_dev_handle); -- -- /* Write Data */ -- io_open(flash0_dev_handle, &flash0_spec, &flash0_handle); -- io_open(flash_emu_dev_handle, &flash_emu_spec, &flash_emu_handle); -- -- io_seek(flash0_handle, IO_SEEK_SET, -- BANK_1_PARTITION_OFFSET + flash0_info->sector_size - 7); -- io_seek(flash_emu_handle, IO_SEEK_SET, flash_emu_info->sector_size - 7); -- -- io_write(flash0_handle, test_data, ARRAY_LENGTH(test_data), -- &bytes_written_count); -- if (bytes_written_count != ARRAY_LENGTH(test_data)) { -- LOG_ERRFMT("io_write failed to write %d bytes for flash0", -- ARRAY_LENGTH(test_data)); -- LOG_ERRFMT("bytes_written_count %d for flash0", bytes_written_count); -- ret->val = TEST_FAILED; -- } -- io_write(flash_emu_handle, test_data, ARRAY_LENGTH(test_data), -- &bytes_written_count); -- if (bytes_written_count != ARRAY_LENGTH(test_data)) { -- LOG_ERRFMT("io_write failed to write %d bytes for flash emu", -- ARRAY_LENGTH(test_data)); -- LOG_ERRFMT("bytes_written_count %d for flash emu", bytes_written_count); -- ret->val = TEST_FAILED; -- } -- io_close(flash0_handle); -- io_close(flash_emu_handle); -- -- /* Read Data */ -- io_open(flash0_dev_handle, &flash0_spec, &flash0_handle); -- io_open(flash_emu_dev_handle, &flash_emu_spec, &flash_emu_handle); -- -- io_seek(flash0_handle, IO_SEEK_SET, -- BANK_1_PARTITION_OFFSET + flash0_info->sector_size - 7); -- io_seek(flash_emu_handle, IO_SEEK_SET, flash_emu_info->sector_size - 7); -- -- /* Flash0 */ -- io_read(flash0_handle, actual_data, ARRAY_LENGTH(actual_data), -- &bytes_read_count); -- if (bytes_read_count != ARRAY_LENGTH(test_data)) { -- LOG_ERRFMT("io_read failed to read %d bytes for flash0", -- ARRAY_LENGTH(test_data)); -- LOG_ERRFMT("bytes_read_count %d for flash0", bytes_read_count); -- ret->val = TEST_FAILED; -- } -- if (memcmp((uint8_t*)test_data, actual_data, ARRAY_LENGTH(actual_data)) != -- 0) { -- LOG_ERRFMT("Data written != Data read\r\n"); -- ret->val = TEST_FAILED; -- } -- -- memset(actual_data, -1, sizeof(actual_data)); -- -- /* Flash Emu */ -- io_read(flash_emu_handle, actual_data, ARRAY_LENGTH(actual_data), -- &bytes_read_count); -- if (bytes_read_count != ARRAY_LENGTH(test_data)) { -- LOG_ERRFMT("io_read failed to read %d bytes for flash emu", -- ARRAY_LENGTH(test_data)); -- LOG_ERRFMT("bytes_read_count %d for flash emu", bytes_read_count); -- ret->val = TEST_FAILED; -- } -- if (memcmp((uint8_t*)test_data, actual_data, ARRAY_LENGTH(actual_data)) != -- 0) { -- LOG_ERRFMT("Data written != Data read\r\n"); -- ret->val = TEST_FAILED; -- } -- -- LOG_INFFMT("PASS: %s\n\r", __func__); -- ret->val = TEST_PASSED; --} -diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.h b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.h -deleted file mode 100644 -index fa9012776..000000000 ---- a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_io_storage_test.h -+++ /dev/null -@@ -1,15 +0,0 @@ --/* -- * Copyright (c) 2022, Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- * -- */ -- --#ifndef __S_IO_STORAGE_TEST_H__ --#define __S_IO_STORAGE_TEST_H__ -- --#include "extra_s_tests.h" -- --void s_test_io_storage_multiple_flash_simultaneous(struct test_result_t *ret); -- --#endif /* __S_IO_STORAGE_TEST_H__ */ -\ No newline at end of file -diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test.c b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test.c -index 9a8453ff5..6bfdf2aeb 100644 ---- a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test.c -+++ b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test.c -@@ -10,8 +10,7 @@ - #include "extra_s_tests.h" - #include "platform_base_address.h" - #include "firewall.h" --#include "tfm_sp_log.h" --#include "s_io_storage_test.h" -+#include "tfm_log_unpriv.h" - - /* TODO: if needed each test function can be made as a separate test case, in - * such case EXTRA_TEST_XX definitions can be removed */ -diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test_config.cmake b/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test_config.cmake -deleted file mode 100644 -index 05b7cd785..000000000 ---- a/platform/ext/target/arm/corstone1000/ci_regression_tests/s_test_config.cmake -+++ /dev/null -@@ -1,13 +0,0 @@ --#------------------------------------------------------------------------------- --# Copyright (c) 2021-22, Arm Limited. All rights reserved. --# --# SPDX-License-Identifier: BSD-3-Clause --# --#------------------------------------------------------------------------------- -- --############ Define secure test specific cmake configurations here ############# -- --set (TEST_FLASH_SIZE_IN_BYTES 48U CACHE STRING "The size of the emulated flash used in io tests") --set (TEST_FLASH_SECTOR_SIZE_IN_BYTES 16U CACHE STRING "The sector size of the emulated flash used in io tests") --set (TEST_FLASH_PAGE_SIZE 8U CACHE STRING "The page size of the emulated flash used in io tests") --set (TEST_FLASH_PROGRAM_UNIT 1U CACHE STRING "The program unit of the emulated flash used in io tests") -diff --git a/platform/ext/target/arm/corstone1000/ci_regression_tests/test_flash.h b/platform/ext/target/arm/corstone1000/ci_regression_tests/test_flash.h -deleted file mode 100644 -index 4d073a1d7..000000000 ---- a/platform/ext/target/arm/corstone1000/ci_regression_tests/test_flash.h -+++ /dev/null -@@ -1,25 +0,0 @@ --/* -- * Copyright (c) 2017-2022 Arm Limited. All rights reserved. -- * -- * Licensed under the Apache License, Version 2.0 (the "License"); -- * you may not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an "AS IS" BASIS, -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef __TEST_FLASH_H__ --#define __TEST_FLASH_H__ -- --#define TEST_FLASH_SIZE_IN_BYTES (48) // 48 bytes --#define TEST_FLASH_SECTOR_SIZE_IN_BYTES (16) // 16 bytes --#define TEST_FLASH_PAGE_SIZE (8U) // 8 bytes --#define TEST_FLASH_PROGRAM_UNIT (1U) /* 1 B */ -- --#endif /* __TEST_FLASH_H__ */ -diff --git a/platform/ext/target/arm/corstone1000/config.cmake b/platform/ext/target/arm/corstone1000/config.cmake -index 032265cdf..ada6426e3 100644 ---- a/platform/ext/target/arm/corstone1000/config.cmake -+++ b/platform/ext/target/arm/corstone1000/config.cmake -@@ -47,6 +47,7 @@ set(DEFAULT_MCUBOOT_SECURITY_COUNTERS OFF CACHE BOOL "Whethe - # LOG LEVEL - set(TFM_SPM_LOG_LEVEL TFM_SPM_LOG_LEVEL_INFO CACHE STRING "Set default SPM log level as INFO level") - set(TFM_PARTITION_LOG_LEVEL TFM_PARTITION_LOG_LEVEL_INFO CACHE STRING "Set default Secure Partition log level as INFO level") -+set(GPT_LOG_LEVEL LOG_LEVEL_INFO CACHE STRING "Set default GPT library log level as INFO level") - - # Partition - set(TFM_PARTITION_PLATFORM ON CACHE BOOL "Enable Platform partition") -@@ -62,6 +63,9 @@ set(TFM_FWU_BOOTLOADER_LIB "${CMAKE_CURRENT_LIST_DIR}/bootloader/ - set(TFM_CONFIG_FWU_MAX_MANIFEST_SIZE 0 CACHE STRING "The maximum permitted size for manifest in psa_fwu_start(), in bytes.") - set(TFM_CONFIG_FWU_MAX_WRITE_SIZE 4096 CACHE STRING "The maximum permitted size for block in psa_fwu_write, in bytes.") - set(FWU_SUPPORT_TRIAL_STATE ON CACHE BOOL "Device support TRIAL component state.") -+set(PLATFORM_GPT_LIBRARY ON CACHE BOOL "Build the GPT library") -+set(TFM_GPT_BLOCK_SIZE 512 CACHE STRING "The block size of a device formatted as a GUID Partition Table.") -+set(PLAT_MAX_PARTITION_ENTRIES 16 CACHE STRING "The maximum number of GPT partition entries.") - - 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.") -diff --git a/platform/ext/target/arm/corstone1000/fip_parser/external/uuid.h b/platform/ext/target/arm/corstone1000/fip_parser/external/uuid.h -deleted file mode 100644 -index 2ced3a3fa..000000000 ---- a/platform/ext/target/arm/corstone1000/fip_parser/external/uuid.h -+++ /dev/null -@@ -1,74 +0,0 @@ --/*- -- * Copyright (c) 2002 Marcel Moolenaar -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- * -- * $FreeBSD$ -- */ -- --/* -- * Portions copyright (c) 2014-2020, ARM Limited and Contributors. -- * All rights reserved. -- */ -- --#ifndef UUID_H --#define UUID_H -- --/* Length of a node address (an IEEE 802 address). */ --#define _UUID_NODE_LEN 6 -- --/* Length of UUID string including dashes. */ --#define _UUID_STR_LEN 36 -- --/* -- * See also: -- * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt -- * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm -- * -- * A DCE 1.1 compatible source representation of UUIDs. -- */ --struct uuid { -- uint8_t time_low[4]; -- uint8_t time_mid[2]; -- uint8_t time_hi_and_version[2]; -- uint8_t clock_seq_hi_and_reserved; -- uint8_t clock_seq_low; -- uint8_t node[_UUID_NODE_LEN]; --}; -- --struct efi_guid { -- uint32_t time_low; -- uint16_t time_mid; -- uint16_t time_hi_and_version; -- uint8_t clock_seq_and_node[8]; --}; -- --union uuid_helper_t { -- struct uuid uuid_struct; -- struct efi_guid efi_guid; --}; -- --/* XXX namespace pollution? */ --typedef struct uuid uuid_t; -- --#endif /* UUID_H */ -diff --git a/platform/ext/target/arm/corstone1000/fip_parser/fip_parser.c b/platform/ext/target/arm/corstone1000/fip_parser/fip_parser.c -index 5d264b3a6..cce657fbb 100644 ---- a/platform/ext/target/arm/corstone1000/fip_parser/fip_parser.c -+++ b/platform/ext/target/arm/corstone1000/fip_parser/fip_parser.c -@@ -19,6 +19,8 @@ - #include "fip_parser.h" - #include "bootutil/bootutil_log.h" - -+#include "efi_guid_structs.h" -+ - #include - #include - -@@ -27,13 +29,14 @@ int parse_fip_and_extract_tfa_info(uint32_t address, uint32_t fip_size, - { - FIP_TOC_HEADER *toc_header = NULL; - FIP_TOC_ENTRY *toc_entry = NULL; -- uuid_t uuid_null = {0}; -- uuid_t tfa_uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2; -+ struct efi_guid_t uuid_null = NULL_GUID; -+ struct efi_guid_t tfa_uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2; - char *iter; - - toc_header = (FIP_TOC_HEADER *) address; - - if (toc_header->name != TOC_HEADER_NAME) { -+ BOOT_LOG_ERR("TOC header name does not match"); - return FIP_PARSER_ERROR; - } - -@@ -43,11 +46,11 @@ int parse_fip_and_extract_tfa_info(uint32_t address, uint32_t fip_size, - iter <= (char *)toc_header + fip_size; - iter = iter + sizeof(FIP_TOC_ENTRY), toc_entry++) { - -- if (!memcmp(iter, &uuid_null, sizeof(uuid_t))) { -+ if (efi_guid_cmp((struct efi_guid_t *)iter, &uuid_null) == 0) { - return FIP_PARSER_ERROR; - } - -- if (!memcmp(iter, &tfa_uuid, sizeof(uuid_t))) { -+ if (efi_guid_cmp((struct efi_guid_t *)iter, &tfa_uuid) == 0) { - BOOT_LOG_INF("TF-A FIP at : address = 0x%x : size = 0x%x \n\r", - toc_entry->address, - toc_entry->size); -@@ -57,5 +60,6 @@ int parse_fip_and_extract_tfa_info(uint32_t address, uint32_t fip_size, - } - } - -+ BOOT_LOG_ERR("Unable to find TF-A FIP\r\n"); - return FIP_PARSER_ERROR; - } -diff --git a/platform/ext/target/arm/corstone1000/fip_parser/fip_parser.h b/platform/ext/target/arm/corstone1000/fip_parser/fip_parser.h -index b01000e00..92f35459c 100644 ---- a/platform/ext/target/arm/corstone1000/fip_parser/fip_parser.h -+++ b/platform/ext/target/arm/corstone1000/fip_parser/fip_parser.h -@@ -24,8 +24,9 @@ extern "C" - { - #endif - -+#include "efi_guid_structs.h" -+ - #include --#include "external/uuid.h" - - /* Return code of fip parser APIs */ - #define FIP_PARSER_SUCCESS (0) -@@ -35,10 +36,13 @@ extern "C" - #define TOC_HEADER_NAME 0xAA640001 - - /* ToC Entry UUIDs */ --#define UUID_TRUSTED_BOOT_FIRMWARE_BL2 \ -- {{0x5f, 0xf9, 0xec, 0x0b}, {0x4d, 0x22}, \ -- {0x3e, 0x4d}, 0xa5, 0x44, \ -- {0xc3, 0x9d, 0x81, 0xc7, 0x3f, 0x0a} } -+#define UUID_TRUSTED_BOOT_FIRMWARE_BL2 \ -+ MAKE_EFI_GUID( \ -+ 0x0BECF95F, \ -+ 0x224D, \ -+ 0x4D3E, \ -+ 0xA5, 0x44, \ -+ 0xC3, 0x9D, 0x81, 0xC7, 0x3F, 0x0A) - - typedef struct _FIP_TOC_HEADER { - uint32_t name; -@@ -52,12 +56,12 @@ typedef struct _FIP_TOC_HEADER { - */ - - typedef struct _FIP_TOC_ENTRY { -- uuid_t uuid; -- uint32_t address; -- uint32_t pad1; -- uint32_t size; -- uint32_t pad2; -- uint64_t flags; -+ struct efi_guid_t uuid; -+ uint32_t address; -+ uint32_t pad1; -+ uint32_t size; -+ uint32_t pad2; -+ uint64_t flags; - } FIP_TOC_ENTRY; - - int parse_fip_and_extract_tfa_info(uint32_t address, uint32_t fip_size, -diff --git a/platform/ext/target/arm/corstone1000/io/io_block.c b/platform/ext/target/arm/corstone1000/io/io_block.c -deleted file mode 100644 -index a5c021ac5..000000000 ---- a/platform/ext/target/arm/corstone1000/io/io_block.c -+++ /dev/null -@@ -1,528 +0,0 @@ --/* -- * Copyright (c) 2022 Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: Apache-2.0 -- * -- * Licensed under the Apache License, Version 2.0 (the License); you may -- * not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an AS IS BASIS, WITHOUT -- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#include "io_block.h" -- --#include --#include --#include -- --#include "io_defs.h" --#include "io_driver.h" --#include "io_storage.h" -- --typedef struct { -- io_block_dev_spec_t *dev_spec; -- uintptr_t base; -- uint32_t file_pos; -- uint32_t size; --} block_dev_state_t; -- --#define is_power_of_2(x) (((x) != 0U) && (((x) & ((x)-1U)) == 0U)) -- --io_type_t device_type_block(void); -- --static int block_open(io_dev_info_t *dev_info, const uintptr_t spec, -- io_entity_t *entity); --static int block_seek(io_entity_t *entity, int mode, size_t offset); --static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length, -- size_t *length_read); --static int block_write(io_entity_t *entity, const uintptr_t buffer, -- size_t length, size_t *length_written); --static int block_close(io_entity_t *entity); --static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); --static int block_dev_close(io_dev_info_t *dev_info); -- --static const io_dev_connector_t block_dev_connector = {.dev_open = -- block_dev_open}; -- --static const io_dev_funcs_t block_dev_funcs = { -- .type = device_type_block, -- .open = block_open, -- .seek = block_seek, -- .size = NULL, -- .read = block_read, -- .write = block_write, -- .close = block_close, -- .dev_init = NULL, -- .dev_close = block_dev_close, --}; -- --static block_dev_state_t state_pool[MAX_IO_BLOCK_DEVICES]; --static io_dev_info_t dev_info_pool[MAX_IO_BLOCK_DEVICES]; -- --/* Track number of allocated block state */ --static unsigned int block_dev_count; -- --io_type_t device_type_block(void) { return IO_TYPE_BLOCK; } -- --/* Locate a block state in the pool, specified by address */ --static int find_first_block_state(const io_block_dev_spec_t *dev_spec, -- unsigned int *index_out) { -- unsigned int index; -- int result = -ENOENT; -- -- for (index = 0U; index < MAX_IO_BLOCK_DEVICES; ++index) { -- /* dev_spec is used as identifier since it's unique */ -- if (state_pool[index].dev_spec == dev_spec) { -- result = 0; -- *index_out = index; -- break; -- } -- } -- return result; --} -- --/* Allocate a device info from the pool and return a pointer to it */ --static int allocate_dev_info(io_dev_info_t **dev_info) { -- int result = -ENOMEM; -- assert(dev_info != NULL); -- -- if (block_dev_count < MAX_IO_BLOCK_DEVICES) { -- unsigned int index = 0; -- result = find_first_block_state(NULL, &index); -- assert(result == 0); -- /* initialize dev_info */ -- dev_info_pool[index].funcs = &block_dev_funcs; -- dev_info_pool[index].info = (uintptr_t)&state_pool[index]; -- *dev_info = &dev_info_pool[index]; -- ++block_dev_count; -- } -- -- return result; --} -- --/* Release a device info to the pool */ --static int free_dev_info(io_dev_info_t *dev_info) { -- int result; -- unsigned int index = 0; -- block_dev_state_t *state; -- assert(dev_info != NULL); -- -- state = (block_dev_state_t *)dev_info->info; -- result = find_first_block_state(state->dev_spec, &index); -- if (result == 0) { -- /* free if device info is valid */ -- memset(state, 0, sizeof(block_dev_state_t)); -- memset(dev_info, 0, sizeof(io_dev_info_t)); -- --block_dev_count; -- } -- -- return result; --} -- --static int block_open(io_dev_info_t *dev_info, const uintptr_t spec, -- io_entity_t *entity) { -- block_dev_state_t *cur; -- io_block_spec_t *region; -- -- assert((dev_info->info != (uintptr_t)NULL) && (spec != (uintptr_t)NULL) && -- (entity->info == (uintptr_t)NULL)); -- -- region = (io_block_spec_t *)spec; -- cur = (block_dev_state_t *)dev_info->info; -- assert(((region->offset % cur->dev_spec->block_size) == 0) && -- ((region->length % cur->dev_spec->block_size) == 0)); -- -- cur->base = region->offset; -- cur->size = region->length; -- cur->file_pos = 0; -- -- entity->info = (uintptr_t)cur; -- return 0; --} -- --/* parameter offset is relative address at here */ --static int block_seek(io_entity_t *entity, int mode, size_t offset) { -- block_dev_state_t *cur; -- -- assert(entity->info != (uintptr_t)NULL); -- -- cur = (block_dev_state_t *)entity->info; -- -- assert((offset >= 0) && ((uint32_t)offset < cur->size)); -- switch (mode) { -- case IO_SEEK_SET: -- cur->file_pos = (uint32_t)offset; -- break; -- case IO_SEEK_CUR: -- cur->file_pos += (uint32_t)offset; -- break; -- default: -- return -EINVAL; -- } -- assert(cur->file_pos < cur->size); -- return 0; --} -- --/* -- * This function allows the caller to read any number of bytes -- * from any position. It hides from the caller that the low level -- * driver only can read aligned blocks of data. For this reason -- * we need to handle the use case where the first byte to be read is not -- * aligned to start of the block, the last byte to be read is also not -- * aligned to the end of a block, and there are zero or more blocks-worth -- * of data in between. -- * -- * In such a case we need to read more bytes than requested (i.e. full -- * blocks) and strip-out the leading bytes (aka skip) and the trailing -- * bytes (aka padding). See diagram below -- * -- * cur->file_pos ------------ -- * | -- * cur->base | -- * | | -- * v v<---- length ----> -- * -------------------------------------------------------------- -- * | | block#1 | | block#n | -- * | block#0 | + | ... | + | -- * | | <- skip -> + | | + <- padding ->| -- * ------------------------+----------------------+-------------- -- * ^ ^ -- * | | -- * v iteration#1 iteration#n v -- * -------------------------------------------------- -- * | | | | -- * |<---- request ---->| ... |<----- request ---->| -- * | | | | -- * -------------------------------------------------- -- * / / | | -- * / / | | -- * / / | | -- * / / | | -- * / / | | -- * / / | | -- * / / | | -- * / / | | -- * / / | | -- * / / | | -- * <---- request ------> <------ request -----> -- * --------------------- ----------------------- -- * | | | | | | -- * |<-skip->|<-nbytes->| -------->|<-nbytes->|<-padding->| -- * | | | | | | | -- * --------------------- | ----------------------- -- * ^ \ \ | | | -- * | \ \ | | | -- * | \ \ | | | -- * buf->offset \ \ buf->offset | | -- * \ \ | | -- * \ \ | | -- * \ \ | | -- * \ \ | | -- * \ \ | | -- * \ \ | | -- * \ \ | | -- * -------------------------------- -- * | | | | -- * buffer-------------->| | ... | | -- * | | | | -- * -------------------------------- -- * <-count#1->| | -- * <---------- count#n --------> -- * <---------- length ----------> -- * -- * Additionally, the IO driver has an underlying buffer that is at least -- * one block-size and may be big enough to allow. -- */ --static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length, -- size_t *length_read) { -- block_dev_state_t *cur; -- io_block_spec_t *buf; -- io_block_ops_t *ops; -- int lba; -- size_t block_size, left; -- size_t nbytes; /* number of bytes read in one iteration */ -- size_t request; /* number of requested bytes in one iteration */ -- size_t count; /* number of bytes already read */ -- /* -- * number of leading bytes from start of the block -- * to the first byte to be read -- */ -- size_t skip; -- -- /* -- * number of trailing bytes between the last byte -- * to be read and the end of the block -- */ -- size_t padding; -- -- assert(entity->info != (uintptr_t)NULL); -- cur = (block_dev_state_t *)entity->info; -- ops = &(cur->dev_spec->ops); -- buf = &(cur->dev_spec->buffer); -- block_size = cur->dev_spec->block_size; -- assert((length <= cur->size) && (length > 0U) && (ops->read != 0)); -- -- /* -- * We don't know the number of bytes that we are going -- * to read in every iteration, because it will depend -- * on the low level driver. -- */ -- count = 0; -- for (left = length; left > 0U; left -= nbytes) { -- /* -- * We must only request operations aligned to the block -- * size. Therefore if file_pos is not block-aligned, -- * we have to request the operation to start at the -- * previous block boundary and skip the leading bytes. And -- * similarly, the number of bytes requested must be a -- * block size multiple -- */ -- skip = cur->file_pos & (block_size - 1U); -- -- /* -- * Calculate the block number containing file_pos -- * - e.g. block 3. -- */ -- lba = (cur->file_pos + cur->base) / block_size; -- -- if ((skip + left) > buf->length) { -- /* -- * The underlying read buffer is too small to -- * read all the required data - limit to just -- * fill the buffer, and then read again. -- */ -- request = buf->length; -- } else { -- /* -- * The underlying read buffer is big enough to -- * read all the required data. Calculate the -- * number of bytes to read to align with the -- * block size. -- */ -- request = skip + left; -- request = (request + (block_size - 1U)) & ~(block_size - 1U); -- } -- request = ops->read(lba, buf->offset, request); -- -- if (request <= skip) { -- /* -- * We couldn't read enough bytes to jump over -- * the skip bytes, so we should have to read -- * again the same block, thus generating -- * the same error. -- */ -- return -EIO; -- } -- -- /* -- * Need to remove skip and padding bytes,if any, from -- * the read data when copying to the user buffer. -- */ -- nbytes = request - skip; -- padding = (nbytes > left) ? nbytes - left : 0U; -- nbytes -= padding; -- -- memcpy((void *)(buffer + count), (void *)(buf->offset + skip), nbytes); -- -- cur->file_pos += nbytes; -- count += nbytes; -- } -- assert(count == length); -- *length_read = count; -- -- return 0; --} -- --/* -- * This function allows the caller to write any number of bytes -- * from any position. It hides from the caller that the low level -- * driver only can write aligned blocks of data. -- * See comments for block_read for more details. -- */ --static int block_write(io_entity_t *entity, const uintptr_t buffer, -- size_t length, size_t *length_written) { -- block_dev_state_t *cur; -- io_block_spec_t *buf; -- io_block_ops_t *ops; -- int lba; -- size_t block_size, left; -- size_t nbytes; /* number of bytes read in one iteration */ -- size_t request; /* number of requested bytes in one iteration */ -- size_t count; /* number of bytes already read */ -- /* -- * number of leading bytes from start of the block -- * to the first byte to be read -- */ -- size_t skip; -- -- /* -- * number of trailing bytes between the last byte -- * to be read and the end of the block -- */ -- size_t padding; -- assert(entity->info != (uintptr_t)NULL); -- cur = (block_dev_state_t *)entity->info; -- ops = &(cur->dev_spec->ops); -- buf = &(cur->dev_spec->buffer); -- block_size = cur->dev_spec->block_size; -- assert((length <= cur->size) && (length > 0U) && (ops->read != 0) && -- (ops->write != 0)); -- -- /* -- * We don't know the number of bytes that we are going -- * to write in every iteration, because it will depend -- * on the low level driver. -- */ -- count = 0; -- for (left = length; left > 0U; left -= nbytes) { -- /* -- * We must only request operations aligned to the block -- * size. Therefore if file_pos is not block-aligned, -- * we have to request the operation to start at the -- * previous block boundary and skip the leading bytes. And -- * similarly, the number of bytes requested must be a -- * block size multiple -- */ -- skip = cur->file_pos & (block_size - 1U); -- -- /* -- * Calculate the block number containing file_pos -- * - e.g. block 3. -- */ -- lba = (cur->file_pos + cur->base) / block_size; -- -- if ((skip + left) > buf->length) { -- /* -- * The underlying read buffer is too small to -- * read all the required data - limit to just -- * fill the buffer, and then read again. -- */ -- request = buf->length; -- } else { -- /* -- * The underlying read buffer is big enough to -- * read all the required data. Calculate the -- * number of bytes to read to align with the -- * block size. -- */ -- request = skip + left; -- request = (request + (block_size - 1U)) & ~(block_size - 1U); -- } -- -- /* -- * The number of bytes that we are going to write -- * from the user buffer will depend of the size -- * of the current request. -- */ -- nbytes = request - skip; -- padding = (nbytes > left) ? nbytes - left : 0U; -- nbytes -= padding; -- -- /* -- * If we have skip or padding bytes then we have to preserve -- * some content and it means that we have to read before -- * writing -- */ -- if ((skip > 0U) || (padding > 0U)) { -- request = ops->read(lba, buf->offset, request); -- /* -- * The read may return size less than -- * requested. Round down to the nearest block -- * boundary -- */ -- request &= ~(block_size - 1U); -- if (request <= skip) { -- /* -- * We couldn't read enough bytes to jump over -- * the skip bytes, so we should have to read -- * again the same block, thus generating -- * the same error. -- */ -- return -EIO; -- } -- nbytes = request - skip; -- padding = (nbytes > left) ? nbytes - left : 0U; -- nbytes -= padding; -- } -- -- memcpy((void *)(buf->offset + skip), (void *)(buffer + count), nbytes); -- -- request = ops->write(lba, buf->offset, request); -- if (request <= skip) return -EIO; -- -- /* -- * And the previous write operation may modify the size -- * of the request, so again, we have to calculate the -- * number of bytes that we consumed from the user -- * buffer -- */ -- nbytes = request - skip; -- padding = (nbytes > left) ? nbytes - left : 0U; -- nbytes -= padding; -- -- cur->file_pos += nbytes; -- count += nbytes; -- } -- assert(count == length); -- *length_written = count; -- -- return 0; --} -- --static int block_close(io_entity_t *entity) { -- entity->info = (uintptr_t)NULL; -- return 0; --} -- --static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) { -- block_dev_state_t *cur; -- io_block_spec_t *buffer; -- io_dev_info_t *info; -- size_t block_size; -- int result; -- assert(dev_info != NULL); -- result = allocate_dev_info(&info); -- if (result != 0) return -ENOENT; -- -- cur = (block_dev_state_t *)info->info; -- /* dev_spec is type of io_block_dev_spec_t. */ -- cur->dev_spec = (io_block_dev_spec_t *)dev_spec; -- buffer = &(cur->dev_spec->buffer); -- block_size = cur->dev_spec->block_size; -- -- assert((block_size > 0U) && (is_power_of_2(block_size) != 0U) && -- ((buffer->length % block_size) == 0U)); -- -- *dev_info = info; /* cast away const */ -- (void)block_size; -- (void)buffer; -- return 0; --} -- --static int block_dev_close(io_dev_info_t *dev_info) { -- return free_dev_info(dev_info); --} -- --/* Exported functions */ -- --/* Register the Block driver with the IO abstraction */ --int register_io_dev_block(const io_dev_connector_t **dev_con) { -- int result; -- -- assert(dev_con != NULL); -- -- /* -- * Since dev_info isn't really used in io_register_device, always -- * use the same device info at here instead. -- */ -- result = io_register_device(&dev_info_pool[0]); -- if (result == 0) *dev_con = &block_dev_connector; -- return result; --} -diff --git a/platform/ext/target/arm/corstone1000/io/io_block.h b/platform/ext/target/arm/corstone1000/io/io_block.h -deleted file mode 100644 -index 1603aa74c..000000000 ---- a/platform/ext/target/arm/corstone1000/io/io_block.h -+++ /dev/null -@@ -1,40 +0,0 @@ --/* -- * Copyright (c) 2022 Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: Apache-2.0 -- * -- * Licensed under the Apache License, Version 2.0 (the License); you may -- * not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an AS IS BASIS, WITHOUT -- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef __IO_BLOCK_H__ --#define __IO_BLOCK_H__ -- --#include "io_storage.h" -- --/* block devices ops */ --typedef struct io_block_ops { -- size_t (*read)(int lba, uintptr_t buf, size_t size); -- size_t (*write)(int lba, const uintptr_t buf, size_t size); --} io_block_ops_t; -- --typedef struct io_block_dev_spec { -- io_block_spec_t buffer; -- io_block_ops_t ops; -- size_t block_size; --} io_block_dev_spec_t; -- --struct io_dev_connector; -- --int register_io_dev_block(const struct io_dev_connector **dev_con); -- --#endif /* __IO_BLOCK_H__ */ -\ No newline at end of file -diff --git a/platform/ext/target/arm/corstone1000/io/io_defs.h b/platform/ext/target/arm/corstone1000/io/io_defs.h -deleted file mode 100644 -index acba969ed..000000000 ---- a/platform/ext/target/arm/corstone1000/io/io_defs.h -+++ /dev/null -@@ -1,27 +0,0 @@ --/* -- * Copyright (c) 2022 Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: Apache-2.0 -- * -- * Licensed under the Apache License, Version 2.0 (the License); you may -- * not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an AS IS BASIS, WITHOUT -- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef __IO_DEFS_H__ --#define __IO_DEFS_H__ -- --#define MAX_IO_DEVICES (2) --#define MAX_IO_HANDLES (2) --#define MAX_IO_BLOCK_DEVICES (2) --#define MAX_IO_FLASH_DEVICES (2) -- --#endif /* __IO_DEFS_H__ */ -\ No newline at end of file -diff --git a/platform/ext/target/arm/corstone1000/io/io_driver.h b/platform/ext/target/arm/corstone1000/io/io_driver.h -deleted file mode 100644 -index cf9e21a6d..000000000 ---- a/platform/ext/target/arm/corstone1000/io/io_driver.h -+++ /dev/null -@@ -1,54 +0,0 @@ --/* -- * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#ifndef __IO_DRIVER_H__ --#define __IO_DRIVER_H__ -- --#include --#include -- --/* Generic IO entity structure,representing an accessible IO construct on the -- * device, such as a file */ --typedef struct io_entity { -- struct io_dev_info *dev_handle; -- uintptr_t info; --} io_entity_t; -- --/* Device info structure, providing device-specific functions and a means of -- * adding driver-specific state */ --typedef struct io_dev_info { -- const struct io_dev_funcs *funcs; -- uintptr_t info; --} io_dev_info_t; -- --/* Structure used to create a connection to a type of device */ --typedef struct io_dev_connector { -- /* dev_open opens a connection to a particular device driver */ -- int (*dev_open)(const uintptr_t dev_spec, io_dev_info_t **dev_info); --} io_dev_connector_t; -- --/* Structure to hold device driver function pointers */ --typedef struct io_dev_funcs { -- io_type_t (*type)(void); -- int (*open)(io_dev_info_t *dev_info, const uintptr_t spec, -- io_entity_t *entity); -- int (*seek)(io_entity_t *entity, int mode, size_t offset); -- int (*size)(io_entity_t *entity, size_t *length); -- int (*read)(io_entity_t *entity, uintptr_t buffer, size_t length, -- size_t *length_read); -- int (*write)(io_entity_t *entity, const uintptr_t buffer, size_t length, -- size_t *length_written); -- int (*close)(io_entity_t *entity); -- int (*dev_init)(io_dev_info_t *dev_info, const uintptr_t init_params); -- int (*dev_close)(io_dev_info_t *dev_info); --} io_dev_funcs_t; -- --/* Operations intended to be performed during platform initialisation */ -- --/* Register an IO device */ --int io_register_device(const io_dev_info_t *dev_info); -- --#endif /* __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 -deleted file mode 100644 -index b90a81a48..000000000 ---- a/platform/ext/target/arm/corstone1000/io/io_flash.c -+++ /dev/null -@@ -1,183 +0,0 @@ --/* -- * Copyright (c) 2022 Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: Apache-2.0 -- * -- * Licensed under the Apache License, Version 2.0 (the License); you may -- * not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an AS IS BASIS, WITHOUT -- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#include "io_flash.h" -- --#include --#include -- --#include "Driver_Flash.h" --#include "io_block.h" --#include "io_defs.h" --#include "io_driver.h" --#include "io_storage.h" -- --#if MAX_IO_FLASH_DEVICES > MAX_IO_BLOCK_DEVICES --#error \ -- "FLASH devices are BLOCK devices .. MAX_IO_FLASH_DEVICES should be less or equal to MAX_IO_BLOCK_DEVICES" --#endif -- --/* Private Prototypes */ -- --static int flash_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); --static size_t flash_read(int lba, uintptr_t buf, size_t size, size_t flash_id); --static size_t flash_write(int lba, const uintptr_t buf, size_t size, -- size_t flash_id); --static size_t flash0_read(int lba, uintptr_t buf, size_t size); --static size_t flash0_write(int lba, uintptr_t buf, size_t size); --static size_t flash1_read(int lba, uintptr_t buf, size_t size); --static size_t flash1_write(int lba, uintptr_t buf, size_t size); -- --/** Private Data **/ -- --/* Flash device data */ --static const io_dev_connector_t flash_dev_connector = {.dev_open = -- flash_dev_open}; --static size_t flash_dev_count = 0; --static io_flash_dev_spec_t *flash_dev_specs[MAX_IO_FLASH_DEVICES]; -- --/* Block device data */ --static io_dev_connector_t block_dev_connectors[MAX_IO_FLASH_DEVICES]; --static io_block_dev_spec_t block_dev_spec[MAX_IO_FLASH_DEVICES]; -- --/* Flash devices read/write function pointers */ --static io_block_ops_t flashs_ops[MAX_IO_FLASH_DEVICES] = { -- [0] = {.read = flash0_read, .write = flash0_write}, -- [1] = {.read = flash1_read, .write = flash1_write}, --}; -- --/* Flash ops functions */ --static size_t flash_read(int lba, uintptr_t buf, size_t size, size_t flash_id) { -- ARM_DRIVER_FLASH *flash_driver = -- ((ARM_DRIVER_FLASH *)flash_dev_specs[flash_id]->flash_driver); -- ARM_FLASH_INFO *info = flash_driver->GetInfo(); -- uint32_t addr = info->sector_size * lba; -- uint32_t offset = addr - flash_dev_specs[flash_id]->base_addr; -- size_t rem = info->sector_count * info->sector_size - offset; -- size_t cnt = size < rem ? size : rem; -- -- return flash_driver->ReadData(offset, (void *)buf, cnt); --} -- --static size_t flash_write(int lba, const uintptr_t buf, size_t size, -- size_t flash_id) { -- ARM_DRIVER_FLASH *flash_driver = -- ((ARM_DRIVER_FLASH *)flash_dev_specs[flash_id]->flash_driver); -- ARM_FLASH_INFO *info = flash_driver->GetInfo(); -- int32_t rc = 0; -- uint32_t addr = info->sector_size * lba; -- uint32_t offset = addr - flash_dev_specs[flash_id]->base_addr; -- size_t rem = info->sector_count * info->sector_size - offset; -- size_t cnt = size < rem ? size : rem; -- -- flash_driver->EraseSector(offset); -- rc = flash_driver->ProgramData(offset, (const void *)buf, cnt); -- return rc; --} -- --/* Flash ops functions wrapper for each device */ -- --static size_t flash0_read(int lba, uintptr_t buf, size_t size) { -- return flash_read(lba, buf, size, 0); --} -- --static size_t flash0_write(int lba, uintptr_t buf, size_t size) { -- return flash_write(lba, buf, size, 0); --} -- --static size_t flash1_read(int lba, uintptr_t buf, size_t size) { -- return flash_read(lba, buf, size, 1); --} -- --static size_t flash1_write(int lba, uintptr_t buf, size_t size) { -- return flash_write(lba, buf, size, 1); --} -- --/** -- * Helper function to find the index of stored flash_dev_specs or -- * return a free slot in case of a new dev_spec -- */ --static int find_flash_dev_specs(const uintptr_t dev_spec) { -- /* Search in the saved ones */ -- for (int i = 0; i < flash_dev_count; ++i) { -- if (flash_dev_specs[i] != NULL && -- flash_dev_specs[i]->flash_driver == -- ((io_flash_dev_spec_t *)dev_spec)->flash_driver) { -- return i; -- } -- } -- /* Find the first empty flash_dev_specs to be used */ -- for (int i = 0; i < flash_dev_count; ++i) { -- if (flash_dev_specs[i] == NULL) { -- return i; -- } -- } -- return -1; --} -- --/** -- * This function should be called -- */ --static int flash_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) { -- ARM_DRIVER_FLASH *flash_driver; -- assert(dev_info != NULL); -- assert(dev_spec != NULL); -- -- size_t index = find_flash_dev_specs(dev_spec); -- -- /* Check if Flash ops functions are defined for this flash */ -- assert(flashs_ops[index].read && flashs_ops[index].write); -- -- 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; -- block_dev_spec[index].buffer.length = flash_dev_specs[index]->bufferlen; -- block_dev_spec[index].ops = flashs_ops[index]; -- -- flash_driver->Initialize(NULL); -- -- block_dev_connectors[index].dev_open((uintptr_t)&block_dev_spec[index], dev_info); -- -- return 0; --} -- --/* Exported functions */ -- --/** -- * Register the flash device. -- * Internally it register a block device. -- */ --int register_io_dev_flash(const io_dev_connector_t **dev_con) { -- int result; -- -- if (flash_dev_count >= MAX_IO_FLASH_DEVICES) { -- return -ENOENT; -- } -- assert(dev_con != NULL); -- -- result = register_io_dev_block(dev_con); -- if (result == 0) { -- /* Store the block dev connector */ -- block_dev_connectors[flash_dev_count++] = **dev_con; -- /* Override dev_con with the flash dev connector */ -- *dev_con = &flash_dev_connector; -- } -- return result; --} -diff --git a/platform/ext/target/arm/corstone1000/io/io_flash.h b/platform/ext/target/arm/corstone1000/io/io_flash.h -deleted file mode 100644 -index 8bc38b582..000000000 ---- a/platform/ext/target/arm/corstone1000/io/io_flash.h -+++ /dev/null -@@ -1,37 +0,0 @@ --/* -- * Copyright (c) 2022 Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: Apache-2.0 -- * -- * Licensed under the Apache License, Version 2.0 (the License); you may -- * not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an AS IS BASIS, WITHOUT -- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef __IO_FLASH_H__ --#define __IO_FLASH_H__ -- --#include "io_storage.h" -- --typedef struct io_flash_dev_spec { -- uintptr_t buffer; -- size_t bufferlen; -- uint32_t base_addr; -- uintptr_t flash_driver; --} io_flash_dev_spec_t; -- --struct io_dev_connector; -- --/* Register the flash driver with the IO abstraction internally it register a -- * block device*/ --int register_io_dev_flash(const struct io_dev_connector **dev_con); -- --#endif /* __IO_FLASH_H__ */ -diff --git a/platform/ext/target/arm/corstone1000/io/io_gpt.c b/platform/ext/target/arm/corstone1000/io/io_gpt.c -new file mode 100644 -index 000000000..513c77016 ---- /dev/null -+++ b/platform/ext/target/arm/corstone1000/io/io_gpt.c -@@ -0,0 +1,179 @@ -+/* -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "io_gpt.h" -+ -+#include "Driver_Flash.h" -+#include "gpt_flash.h" -+#include "flash_layout.h" -+ -+/* Check if globals in module have been initialised */ -+#define CHECK_INIT \ -+ do { \ -+ if (!flash_driver) { \ -+ return GPT_FLASH_NOT_INIT; \ -+ } \ -+ } while (0) -+ -+/* Check the given flash access is valid */ -+#define CHECK_BOUNDS(addr, size) \ -+ do { \ -+ if (size > FLASH_TOTAL_SIZE || addr > FLASH_TOTAL_SIZE - size) { \ -+ return GPT_FLASH_BAD_PARAM; \ -+ } \ -+ } while (0) -+ -+/* Aligns address to flash sector sizes */ -+#define ALIGN_TO_SECTOR(addr) (((addr) / FLASH_SECTOR_SIZE) * FLASH_SECTOR_SIZE) -+ -+/* Number of LBAs per sector of flash */ -+#define LBAS_PER_SECTOR (FLASH_SECTOR_SIZE / TFM_GPT_BLOCK_SIZE) -+ -+/* Returns the offset within a sector for the given lba */ -+static inline uint64_t sector_offset(uint64_t lba) -+{ -+ return (lba % LBAS_PER_SECTOR) * TFM_GPT_BLOCK_SIZE; -+} -+ -+/* The actual flash driver under the hood */ -+static ARM_DRIVER_FLASH *flash_driver = NULL; -+ -+/* Buffer used to store sector of flash data */ -+static uint8_t sector_buf[FLASH_SECTOR_SIZE]; -+ -+/* From io_gpt.h - the driver given to the GPT library */ -+struct gpt_flash_driver_t io_gpt_flash_driver = {0}; -+ -+/* Erases TFM_GPT_BLOCK_SIZE bytes from offset within the sector beginning at -+ * sector_addr. This is done via a read-erase-write pattern whereby data is read, -+ * the sector is erased, and data written back to the parts of the sector that -+ * shouldn't have been erased -+ */ -+static gpt_flash_err_t partially_erase_sector(uint32_t sector_addr, -+ uint32_t offset) -+{ -+ if (flash_driver->ReadData( -+ sector_addr, -+ sector_buf, -+ FLASH_SECTOR_SIZE) != FLASH_SECTOR_SIZE) -+ { -+ return GPT_FLASH_GENERIC_ERROR; -+ } -+ -+ if (flash_driver->EraseSector(sector_addr) != ARM_DRIVER_OK) { -+ return GPT_FLASH_GENERIC_ERROR; -+ } -+ -+ memset(sector_buf + offset, flash_driver->GetInfo()->erased_value, TFM_GPT_BLOCK_SIZE); -+ if (flash_driver->ProgramData( -+ sector_addr, -+ sector_buf, -+ FLASH_SECTOR_SIZE) != FLASH_SECTOR_SIZE) -+ { -+ return GPT_FLASH_GENERIC_ERROR; -+ } -+ -+ return GPT_FLASH_SUCCESS; -+} -+ -+/* Reads the requested LBA into the given buffer */ -+static ssize_t flash_read(uint64_t lba, void *buf) -+{ -+ CHECK_INIT; -+ -+ uint64_t read_addr = lba * TFM_GPT_BLOCK_SIZE; -+ CHECK_BOUNDS(read_addr, TFM_GPT_BLOCK_SIZE); -+ -+ if (flash_driver->ReadData(read_addr, buf, TFM_GPT_BLOCK_SIZE) != TFM_GPT_BLOCK_SIZE) { -+ return GPT_FLASH_GENERIC_ERROR; -+ } -+ -+ return TFM_GPT_BLOCK_SIZE; -+} -+ -+/* Writes the given buffer to the requested LBA */ -+static ssize_t flash_write(uint64_t lba, const void *buf) -+{ -+ CHECK_INIT; -+ -+ uint64_t write_addr = lba * TFM_GPT_BLOCK_SIZE; -+ CHECK_BOUNDS(write_addr, TFM_GPT_BLOCK_SIZE); -+ -+ if (flash_driver->ProgramData(write_addr, buf, TFM_GPT_BLOCK_SIZE) != TFM_GPT_BLOCK_SIZE) { -+ return GPT_FLASH_GENERIC_ERROR; -+ } -+ -+ return TFM_GPT_BLOCK_SIZE; -+} -+ -+/* Erases a consecutive number of blocks, beginning with the given LBA */ -+static ssize_t flash_erase(uint64_t lba, size_t num_blocks) -+{ -+ CHECK_INIT; -+ -+ if (num_blocks == 0) { -+ return GPT_FLASH_BAD_PARAM; -+ } -+ -+ /* Convert blocks to sectors. The first and final sectors may be partially erased */ -+ size_t num_sectors = num_blocks / LBAS_PER_SECTOR; -+ if (num_sectors == 0) { -+ /* Partially erase first sector and thats it */ -+ num_sectors = 1; -+ } -+ -+ uint64_t erase_addr = ALIGN_TO_SECTOR(lba * TFM_GPT_BLOCK_SIZE); -+ CHECK_BOUNDS(erase_addr, FLASH_SECTOR_SIZE); -+ -+ uint64_t last_erase_addr = erase_addr + ((num_sectors - 1) * FLASH_SECTOR_SIZE); -+ CHECK_BOUNDS(last_erase_addr, FLASH_SECTOR_SIZE); -+ -+ /* Whole sector erases until last sector */ -+ for (size_t i = 0; i < num_sectors - 1; ++i) { -+ int32_t ret = flash_driver->EraseSector(erase_addr + i * FLASH_SECTOR_SIZE); -+ if (ret != ARM_DRIVER_OK) { -+ return i; -+ } -+ } -+ -+ if (num_blocks % LBAS_PER_SECTOR == 0 && lba % LBAS_PER_SECTOR == 0) { -+ /* Fully erase final sector */ -+ if (flash_driver->EraseSector(last_erase_addr) != ARM_DRIVER_OK) { -+ return (num_sectors - 1) * LBAS_PER_SECTOR; -+ } -+ } else { -+ /* Partial erase of final sector */ -+ if (partially_erase_sector( -+ last_erase_addr, -+ sector_offset(lba)) != GPT_FLASH_SUCCESS) -+ { -+ return num_sectors == 0 ? GPT_FLASH_GENERIC_ERROR : (num_sectors - 1) * LBAS_PER_SECTOR; -+ } -+ } -+ -+ return num_blocks; -+} -+ -+int register_flash_io_gpt(ARM_DRIVER_FLASH *driver) -+{ -+ /* Initialise the driver */ -+ driver->Initialize(NULL); -+ -+ /* Store everything needed */ -+ flash_driver = driver; -+ -+ io_gpt_flash_driver.read = flash_read; -+ io_gpt_flash_driver.write = flash_write; -+ io_gpt_flash_driver.erase = flash_erase; -+ -+ return 0; -+} -diff --git a/platform/ext/target/arm/corstone1000/io/io_gpt.h b/platform/ext/target/arm/corstone1000/io/io_gpt.h -new file mode 100644 -index 000000000..96dcda04e ---- /dev/null -+++ b/platform/ext/target/arm/corstone1000/io/io_gpt.h -@@ -0,0 +1,25 @@ -+/* -+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ * -+ */ -+ -+#ifndef __IO_GPT_H__ -+#define __IO_GPT_H__ -+ -+#include "io_gpt.h" -+ -+#include "Driver_Flash.h" -+#include "gpt_flash.h" -+ -+/* The pseudo flash driver used by the GPT library. Each LBA maps -+ * FLASH_SECTOR_SIZE:TFM_GPT_BLOCK_SIZE to a sector of flash (so 1024:512 means -+ * two LBAs per sector of flash) -+ */ -+extern struct gpt_flash_driver_t io_gpt_flash_driver; -+ -+/* Sets up the gpt_flash_driver with the given driver and initialises the latter */ -+int register_flash_io_gpt(ARM_DRIVER_FLASH *driver); -+ -+#endif /* __IO_GPT_H__ */ -diff --git a/platform/ext/target/arm/corstone1000/io/io_storage.c b/platform/ext/target/arm/corstone1000/io/io_storage.c -deleted file mode 100644 -index f26f4980f..000000000 ---- a/platform/ext/target/arm/corstone1000/io/io_storage.c -+++ /dev/null -@@ -1,289 +0,0 @@ --/* -- * Copyright (c) 2022 Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: Apache-2.0 -- * -- * Licensed under the Apache License, Version 2.0 (the License); you may -- * not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an AS IS BASIS, WITHOUT -- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#include --#include --#include -- --#include "io_defs.h" --#include "io_driver.h" -- --/* Storage for a fixed maximum number of IO entities, definable by platform */ --static io_entity_t entity_pool[MAX_IO_HANDLES]; -- --/* Simple way of tracking used storage - each entry is NULL or a pointer to an -- * entity */ --static io_entity_t *entity_map[MAX_IO_HANDLES]; -- --/* Track number of allocated entities */ --static unsigned int entity_count; -- --/* Array of fixed maximum of registered devices, definable by platform */ --static const io_dev_info_t *devices[MAX_IO_DEVICES]; -- --/* Number of currently registered devices */ --static unsigned int dev_count; -- --/* Return a boolean value indicating whether a device connector is valid */ --static bool is_valid_dev_connector(const io_dev_connector_t *dev_con) { -- return (dev_con != NULL) && (dev_con->dev_open != NULL); --} -- --/* Return a boolean value indicating whether a device handle is valid */ --static bool is_valid_dev(const uintptr_t dev_handle) { -- const io_dev_info_t *dev = (io_dev_info_t *)dev_handle; -- -- return (dev != NULL) && (dev->funcs != NULL) && -- (dev->funcs->type != NULL) && (dev->funcs->type() < IO_TYPE_MAX); --} -- --/* Return a boolean value indicating whether an IO entity is valid */ --static bool is_valid_entity(const uintptr_t handle) { -- const io_entity_t *entity = (io_entity_t *)handle; -- -- return (entity != NULL) && (is_valid_dev((uintptr_t)entity->dev_handle)); --} -- --/* Return a boolean value indicating whether a seek mode is valid */ --static bool is_valid_seek_mode(io_seek_mode_t mode) { -- return ((mode != IO_SEEK_INVALID) && (mode < IO_SEEK_MAX)); --} -- --/* Open a connection to a specific device */ --static int io_storage_dev_open(const io_dev_connector_t *dev_con, -- const uintptr_t dev_spec, -- io_dev_info_t **dev_info) { -- assert(dev_info != NULL); -- assert(is_valid_dev_connector(dev_con)); -- -- return dev_con->dev_open(dev_spec, dev_info); --} -- --/* Set a handle to track an entity */ --static void set_handle(uintptr_t *handle, io_entity_t *entity) { -- assert(handle != NULL); -- *handle = (uintptr_t)entity; --} -- --/* Locate an entity in the pool, specified by address */ --static int find_first_entity(const io_entity_t *entity, -- unsigned int *index_out) { -- int result = -ENOENT; -- for (unsigned int index = 0; index < MAX_IO_HANDLES; ++index) { -- if (entity_map[index] == entity) { -- result = 0; -- *index_out = index; -- break; -- } -- } -- return result; --} -- --/* Allocate an entity from the pool and return a pointer to it */ --static int allocate_entity(io_entity_t **entity) { -- int result = -ENOMEM; -- assert(entity != NULL); -- -- if (entity_count < MAX_IO_HANDLES) { -- unsigned int index = 0; -- result = find_first_entity(NULL, &index); -- assert(result == 0); -- *entity = &entity_pool[index]; -- entity_map[index] = &entity_pool[index]; -- ++entity_count; -- } -- -- return result; --} -- --/* Release an entity back to the pool */ --static int free_entity(const io_entity_t *entity) { -- int result; -- unsigned int index = 0; -- assert(entity != NULL); -- -- result = find_first_entity(entity, &index); -- if (result == 0) { -- entity_map[index] = NULL; -- --entity_count; -- } -- -- return result; --} -- --/* Exported API */ -- --/* Register an io device */ --int io_register_device(const io_dev_info_t *dev_info) { -- int result = -ENOMEM; -- assert(dev_info != NULL); -- -- if (dev_count < MAX_IO_DEVICES) { -- devices[dev_count] = dev_info; -- dev_count++; -- result = 0; -- } -- -- return result; --} -- --/* Open a connection to an IO device */ --int io_dev_open(const io_dev_connector_t *dev_con, const uintptr_t dev_spec, -- uintptr_t *handle) { -- assert(handle != NULL); -- return io_storage_dev_open(dev_con, dev_spec, (io_dev_info_t **)handle); --} -- --/* Initialise an IO device explicitly - to permit lazy initialisation or -- * re-initialisation */ --int io_dev_init(uintptr_t dev_handle, const uintptr_t init_params) { -- int result = 0; -- assert(dev_handle != (uintptr_t)NULL); -- assert(is_valid_dev(dev_handle)); -- -- io_dev_info_t *dev = (io_dev_info_t *)dev_handle; -- -- /* Absence of registered function implies NOP here */ -- if (dev->funcs->dev_init != NULL) { -- result = dev->funcs->dev_init(dev, init_params); -- } -- -- return result; --} -- --/* Close a connection to a device */ --int io_dev_close(uintptr_t dev_handle) { -- int result = 0; -- assert(dev_handle != (uintptr_t)NULL); -- assert(is_valid_dev(dev_handle)); -- -- io_dev_info_t *dev = (io_dev_info_t *)dev_handle; -- -- /* Absence of registered function implies NOP here */ -- if (dev->funcs->dev_close != NULL) { -- result = dev->funcs->dev_close(dev); -- } -- -- return result; --} -- --/* Synchronous operations */ -- --/* Open an IO entity */ --int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle) { -- int result; -- assert((spec != (uintptr_t)NULL) && (handle != NULL)); -- assert(is_valid_dev(dev_handle)); -- -- io_dev_info_t *dev = (io_dev_info_t *)dev_handle; -- io_entity_t *entity; -- -- result = allocate_entity(&entity); -- -- if (result == 0) { -- assert(dev->funcs->open != NULL); -- result = dev->funcs->open(dev, spec, entity); -- -- if (result == 0) { -- entity->dev_handle = dev; -- set_handle(handle, entity); -- } else -- free_entity(entity); -- } -- return result; --} -- --/* Seek to a specific position in an IO entity */ --int io_seek(uintptr_t handle, io_seek_mode_t mode, int32_t offset) { -- int result = -ENODEV; -- assert(is_valid_entity(handle) && is_valid_seek_mode(mode)); -- -- io_entity_t *entity = (io_entity_t *)handle; -- -- io_dev_info_t *dev = entity->dev_handle; -- -- if (dev->funcs->seek != NULL) -- result = dev->funcs->seek(entity, mode, offset); -- -- return result; --} -- --/* Determine the length of an IO entity */ --int io_size(uintptr_t handle, size_t *length) { -- int result = -ENODEV; -- assert(is_valid_entity(handle) && (length != NULL)); -- -- io_entity_t *entity = (io_entity_t *)handle; -- -- io_dev_info_t *dev = entity->dev_handle; -- -- if (dev->funcs->size != NULL) result = dev->funcs->size(entity, length); -- -- return result; --} -- --/* Read data from an IO entity */ --int io_read(uintptr_t handle, uintptr_t buffer, size_t length, -- size_t *length_read) { -- int result = -ENODEV; -- assert(is_valid_entity(handle)); -- -- io_entity_t *entity = (io_entity_t *)handle; -- -- io_dev_info_t *dev = entity->dev_handle; -- -- if (dev->funcs->read != NULL) -- result = dev->funcs->read(entity, buffer, length, length_read); -- -- return result; --} -- --/* Write data to an IO entity */ --int io_write(uintptr_t handle, const uintptr_t buffer, size_t length, -- size_t *length_written) { -- int result = -ENODEV; -- assert(is_valid_entity(handle)); -- -- io_entity_t *entity = (io_entity_t *)handle; -- -- io_dev_info_t *dev = entity->dev_handle; -- -- if (dev->funcs->write != NULL) { -- result = dev->funcs->write(entity, buffer, length, length_written); -- } -- -- return result; --} -- --/* Close an IO entity */ --int io_close(uintptr_t handle) { -- int result = 0; -- assert(is_valid_entity(handle)); -- -- io_entity_t *entity = (io_entity_t *)handle; -- -- io_dev_info_t *dev = entity->dev_handle; -- -- /* Absence of registered function implies NOP here */ -- if (dev->funcs->close != NULL) result = dev->funcs->close(entity); -- -- /* Ignore improbable free_entity failure */ -- (void)free_entity(entity); -- -- return result; --} -diff --git a/platform/ext/target/arm/corstone1000/io/io_storage.h b/platform/ext/target/arm/corstone1000/io/io_storage.h -deleted file mode 100644 -index 0cdca5b26..000000000 ---- a/platform/ext/target/arm/corstone1000/io/io_storage.h -+++ /dev/null -@@ -1,92 +0,0 @@ --/* -- * Copyright (c) 2022 Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: Apache-2.0 -- * -- * Licensed under the Apache License, Version 2.0 (the License); you may -- * not use this file except in compliance with the License. -- * You may obtain a copy of the License at -- * -- * http://www.apache.org/licenses/LICENSE-2.0 -- * -- * Unless required by applicable law or agreed to in writing, software -- * distributed under the License is distributed on an AS IS BASIS, WITHOUT -- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- * See the License for the specific language governing permissions and -- * limitations under the License. -- */ -- --#ifndef __IO_STORAGE_H__ --#define __IO_STORAGE_H__ -- --#include --#include -- --/* Access modes used when accessing data on a device */ --#define IO_MODE_INVALID (0) --#define IO_MODE_RO (1 << 0) --#define IO_MODE_RW (1 << 1) -- --/* Device type which can be used to enable policy decisions about which device -- * to access */ --typedef enum { -- IO_TYPE_INVALID, -- IO_TYPE_SEMIHOSTING, -- IO_TYPE_MEMMAP, -- IO_TYPE_DUMMY, -- IO_TYPE_FIRMWARE_IMAGE_PACKAGE, -- IO_TYPE_BLOCK, -- IO_TYPE_MTD, -- IO_TYPE_MMC, -- IO_TYPE_STM32IMAGE, -- IO_TYPE_ENCRYPTED, -- IO_TYPE_MAX --} io_type_t; -- --/* Modes used when seeking data on a supported device */ --typedef enum { -- IO_SEEK_INVALID, -- IO_SEEK_SET, -- IO_SEEK_END, -- IO_SEEK_CUR, -- IO_SEEK_MAX --} io_seek_mode_t; -- --/* Connector type, providing a means of identifying a device to open */ --struct io_dev_connector; -- --/* Block specification - used to refer to data on a device supporting -- * block-like entities */ --typedef struct io_block_spec { -- size_t offset; -- size_t length; --} io_block_spec_t; -- -- --/* Open a connection to a device */ --int io_dev_open(const struct io_dev_connector *dev_con, -- const uintptr_t dev_spec, uintptr_t *handle); -- --/* Initialise a device explicitly - to permit lazy initialisation or -- * re-initialisation */ --int io_dev_init(uintptr_t dev_handle, const uintptr_t init_params); -- --/* Close a connection to a device */ --int io_dev_close(uintptr_t dev_handle); -- --/* Synchronous operations */ --int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle); -- --int io_seek(uintptr_t handle, io_seek_mode_t mode, int32_t offset); -- --int io_size(uintptr_t handle, size_t *length); -- --int io_read(uintptr_t handle, uintptr_t buffer, size_t length, -- size_t *length_read); -- --int io_write(uintptr_t handle, const uintptr_t buffer, size_t length, -- size_t *length_written); -- --int io_close(uintptr_t handle); -- --#endif /* __IO_STORAGE_H__ */ -diff --git a/platform/ext/target/arm/corstone1000/partition/efi.h b/platform/ext/target/arm/corstone1000/partition/efi.h -deleted file mode 100644 -index 7e6a4bc88..000000000 ---- a/platform/ext/target/arm/corstone1000/partition/efi.h -+++ /dev/null -@@ -1,37 +0,0 @@ --/* -- * Copyright (c) 2021, Linaro Limited -- * -- * SPDX-License-Identifier: BSD-3-Clause -- * -- */ -- --#ifndef DRIVERS_PARTITION_EFI_H --#define DRIVERS_PARTITION_EFI_H -- --#include --#include -- --#include "uuid.h" -- --#define EFI_NAMELEN 36 -- --static inline int guidcmp(const void *g1, const void *g2) { -- return memcmp(g1, g2, sizeof(struct efi_guid)); --} -- --static inline void *guidcpy(void *dst, const void *src) { -- return memcpy(dst, src, sizeof(struct efi_guid)); --} -- --#define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ -- { \ -- (a) & 0xffffffff, (b)&0xffff, (c)&0xffff, { \ -- (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) \ -- } \ -- } -- --#define NULL_GUID \ -- EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ -- 0x00, 0x00) -- --#endif /* DRIVERS_PARTITION_EFI_H */ -diff --git a/platform/ext/target/arm/corstone1000/partition/gpt.c b/platform/ext/target/arm/corstone1000/partition/gpt.c -deleted file mode 100644 -index 8549785e3..000000000 ---- a/platform/ext/target/arm/corstone1000/partition/gpt.c -+++ /dev/null -@@ -1,58 +0,0 @@ --/* -- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#include "gpt.h" -- --#include --#include --#include -- --#include "efi.h" -- --static int unicode_to_ascii(unsigned short *str_in, unsigned char *str_out) { -- uint8_t *name; -- int i; -- -- assert((str_in != NULL) && (str_out != NULL)); -- -- name = (uint8_t *)str_in; -- -- assert(name[0] != '\0'); -- -- /* check whether the unicode string is valid */ -- for (i = 1; i < (EFI_NAMELEN << 1); i += 2) { -- if (name[i] != '\0') return -EINVAL; -- } -- /* convert the unicode string to ascii string */ -- for (i = 0; i < (EFI_NAMELEN << 1); i += 2) { -- str_out[i >> 1] = name[i]; -- if (name[i] == '\0') break; -- } -- return 0; --} -- --int parse_gpt_entry(gpt_entry_t *gpt_entry, partition_entry_t *entry) { -- int result; -- -- assert((gpt_entry != NULL) && (entry != NULL)); -- -- if ((gpt_entry->first_lba == 0) && (gpt_entry->last_lba == 0)) { -- return -EINVAL; -- } -- -- memset(entry, 0, sizeof(partition_entry_t)); -- result = unicode_to_ascii(gpt_entry->name, (uint8_t *)entry->name); -- if (result != 0) { -- return result; -- } -- entry->start = (uint64_t)gpt_entry->first_lba * PLAT_PARTITION_BLOCK_SIZE; -- entry->length = (uint64_t)(gpt_entry->last_lba - gpt_entry->first_lba + 1) * -- PLAT_PARTITION_BLOCK_SIZE; -- guidcpy(&entry->part_guid, &gpt_entry->unique_uuid); -- guidcpy(&entry->type_guid, &gpt_entry->type_uuid); -- -- return 0; --} -diff --git a/platform/ext/target/arm/corstone1000/partition/gpt.h b/platform/ext/target/arm/corstone1000/partition/gpt.h -deleted file mode 100644 -index b528fc05c..000000000 ---- a/platform/ext/target/arm/corstone1000/partition/gpt.h -+++ /dev/null -@@ -1,51 +0,0 @@ --/* -- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#ifndef GPT_H --#define GPT_H -- --#include "efi.h" --#include "partition.h" --#include "uuid.h" -- --#define PARTITION_TYPE_GPT 0xee --#define GPT_HEADER_OFFSET PLAT_PARTITION_BLOCK_SIZE --#define GPT_ENTRY_OFFSET (GPT_HEADER_OFFSET + PLAT_PARTITION_BLOCK_SIZE) -- --#define GPT_SIGNATURE "EFI PART" -- --typedef struct gpt_entry { -- struct efi_guid type_uuid; -- struct efi_guid unique_uuid; -- unsigned long long first_lba; -- unsigned long long last_lba; -- unsigned long long attr; -- unsigned short name[EFI_NAMELEN]; --} gpt_entry_t; -- --typedef struct gpt_header { -- unsigned char signature[8]; -- unsigned int revision; -- unsigned int size; -- unsigned int header_crc; -- unsigned int reserved; -- unsigned long long current_lba; -- unsigned long long backup_lba; -- unsigned long long first_lba; -- unsigned long long last_lba; -- struct efi_guid disk_uuid; -- /* starting LBA of array of partition entries */ -- unsigned long long part_lba; -- /* number of partition entries in array */ -- unsigned int list_num; -- /* size of a single partition entry (usually 128) */ -- unsigned int part_size; -- unsigned int part_crc; --} gpt_header_t; -- --int parse_gpt_entry(gpt_entry_t *gpt_entry, partition_entry_t *entry); -- --#endif /* GPT_H */ -diff --git a/platform/ext/target/arm/corstone1000/partition/mbr.h b/platform/ext/target/arm/corstone1000/partition/mbr.h -deleted file mode 100644 -index e77f36701..000000000 ---- a/platform/ext/target/arm/corstone1000/partition/mbr.h -+++ /dev/null -@@ -1,29 +0,0 @@ --/* -- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#ifndef MBR_H --#define MBR_H -- --#define MBR_OFFSET 0 -- --#define MBR_PRIMARY_ENTRY_OFFSET 0x1be --#define MBR_PRIMARY_ENTRY_SIZE 0x10 --#define MBR_PRIMARY_ENTRY_NUMBER 4 --#define MBR_CHS_ADDRESS_LEN 3 -- --#define MBR_SIGNATURE_FIRST 0x55 --#define MBR_SIGNATURE_SECOND 0xAA -- --typedef struct mbr_entry { -- unsigned char status; -- unsigned char first_sector[MBR_CHS_ADDRESS_LEN]; -- unsigned char type; -- unsigned char last_sector[MBR_CHS_ADDRESS_LEN]; -- unsigned int first_lba; -- unsigned int sector_nums; --} mbr_entry_t; -- --#endif /* MBR_H */ -diff --git a/platform/ext/target/arm/corstone1000/partition/partition.c b/platform/ext/target/arm/corstone1000/partition/partition.c -deleted file mode 100644 -index d76e123d7..000000000 ---- a/platform/ext/target/arm/corstone1000/partition/partition.c -+++ /dev/null -@@ -1,324 +0,0 @@ --/* -- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#include "partition.h" -- --#include --#include --#include --#include --#include -- --#include "efi.h" --#include "gpt.h" --#include "mbr.h" -- --#include "io_storage.h" --#include "platform.h" --#include "soft_crc.h" -- --#define PLAT_LOG_MODULE_NAME "partition" --#include "platform_log.h" -- --static uint8_t mbr_sector[PLAT_PARTITION_BLOCK_SIZE]; --static partition_entry_list_t list; -- --#if LOG_LEVEL >= LOG_LEVEL_DEBUG --static void dump_entries(int num) { -- char name[EFI_NAMELEN]; -- int i, j, len; -- -- VERBOSE("Partition table with %d entries:", num); -- for (i = 0; i < num; i++) { -- len = snprintf(name, EFI_NAMELEN, "%s", list.list[i].name); -- for (j = 0; j < EFI_NAMELEN - len - 1; j++) { -- name[len + j] = ' '; -- } -- name[EFI_NAMELEN - 1] = '\0'; -- VERBOSE("%d: %s %x%x %d", i + 1, name, -- (uint32_t)(list.list[i].start >> 32), -- (uint32_t)list.list[i].start, -- (uint32_t)(list.list[i].start + list.list[i].length - 4)); -- } --} --#else --#define dump_entries(num) ((void)num) --#endif -- --/* -- * Load the first sector that carries MBR header. -- * The MBR boot signature should be always valid whether it's MBR or GPT. -- */ --static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry) { -- size_t bytes_read; -- uintptr_t offset; -- int result; -- -- assert(mbr_entry != NULL); -- /* MBR partition table is in LBA0. */ -- result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET); -- if (result != 0) { -- WARN("Failed to seek (%i)\n", result); -- return result; -- } -- result = io_read(image_handle, (uintptr_t)&mbr_sector, -- PLAT_PARTITION_BLOCK_SIZE, &bytes_read); -- if (result != 0) { -- WARN("Failed to read data (%i)\n", result); -- return result; -- } -- -- /* Check MBR boot signature. */ -- if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) || -- (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) { -- ERROR("MBR signature isn't correct"); -- return -ENOENT; -- } -- offset = (uintptr_t)&mbr_sector + MBR_PRIMARY_ENTRY_OFFSET; -- memcpy(mbr_entry, (void *)offset, sizeof(mbr_entry_t)); -- return 0; --} -- --/* -- * Load GPT header and check the GPT signature and header CRC. -- * If partition numbers could be found, check & update it. -- */ --static int load_gpt_header(uintptr_t image_handle) { -- gpt_header_t header; -- size_t bytes_read; -- int result; -- uint32_t header_crc, calc_crc; -- -- result = io_seek(image_handle, IO_SEEK_SET, GPT_HEADER_OFFSET); -- if (result != 0) { -- return result; -- } -- result = io_read(image_handle, (uintptr_t)&header, sizeof(gpt_header_t), -- &bytes_read); -- if ((result != 0) || (sizeof(gpt_header_t) != bytes_read)) { -- return result; -- } -- if (memcmp(header.signature, GPT_SIGNATURE, sizeof(header.signature)) != -- 0) { -- return -EINVAL; -- } -- -- /* -- * UEFI Spec 2.8 March 2019 Page 119: HeaderCRC32 value is -- * computed by setting this field to 0, and computing the -- * 32-bit CRC for HeaderSize bytes. -- */ -- header_crc = header.header_crc; -- header.header_crc = 0U; -- -- calc_crc = crc32((uint8_t *)&header, DEFAULT_GPT_HEADER_SIZE); -- if (header_crc != calc_crc) { -- ERROR("Invalid GPT Header CRC: Expected 0x%x but got 0x%x.\n", -- header_crc, calc_crc); -- return -EINVAL; -- } -- -- header.header_crc = header_crc; -- -- /* partition numbers can't exceed PLAT_PARTITION_MAX_ENTRIES */ -- list.entry_count = header.list_num; -- if (list.entry_count > PLAT_PARTITION_MAX_ENTRIES) { -- list.entry_count = PLAT_PARTITION_MAX_ENTRIES; -- } -- return 0; --} -- --static int load_mbr_entry(uintptr_t image_handle, mbr_entry_t *mbr_entry, -- int part_number) { -- size_t bytes_read; -- uintptr_t offset; -- int result; -- -- assert(mbr_entry != NULL); -- /* MBR partition table is in LBA0. */ -- result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET); -- if (result != 0) { -- WARN("Failed to seek (%i)\n", result); -- return result; -- } -- result = io_read(image_handle, (uintptr_t)&mbr_sector, -- PLAT_PARTITION_BLOCK_SIZE, &bytes_read); -- if (result != 0) { -- WARN("Failed to read data (%i)\n", result); -- return result; -- } -- -- /* Check MBR boot signature. */ -- if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) || -- (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) { -- return -ENOENT; -- } -- offset = (uintptr_t)&mbr_sector + MBR_PRIMARY_ENTRY_OFFSET + -- MBR_PRIMARY_ENTRY_SIZE * part_number; -- memcpy(mbr_entry, (void *)offset, sizeof(mbr_entry_t)); -- -- return 0; --} -- --static int load_mbr_entries(uintptr_t image_handle) { -- mbr_entry_t mbr_entry; -- int i; -- -- list.entry_count = MBR_PRIMARY_ENTRY_NUMBER; -- -- for (i = 0; i < list.entry_count; i++) { -- load_mbr_entry(image_handle, &mbr_entry, i); -- list.list[i].start = mbr_entry.first_lba * 512; -- list.list[i].length = mbr_entry.sector_nums * 512; -- list.list[i].name[0] = mbr_entry.type; -- } -- -- return 0; --} -- --static int load_gpt_entry(uintptr_t image_handle, gpt_entry_t *entry) { -- size_t bytes_read; -- int result; -- -- assert(entry != NULL); -- result = io_read(image_handle, (uintptr_t)entry, sizeof(gpt_entry_t), -- &bytes_read); -- if (sizeof(gpt_entry_t) != bytes_read) return -EINVAL; -- return result; --} -- --static int verify_partition_gpt(uintptr_t image_handle) { -- gpt_entry_t entry; -- int result, i; -- -- for (i = 0; i < list.entry_count; i++) { -- result = load_gpt_entry(image_handle, &entry); -- assert(result == 0); -- if (result != 0) { -- break; -- } -- result = parse_gpt_entry(&entry, &list.list[i]); -- if (result != 0) { -- break; -- } -- } -- if (i == 0) { -- return -EINVAL; -- } -- /* -- * Only records the valid partition number that is loaded from -- * partition table. -- */ -- list.entry_count = i; -- dump_entries(list.entry_count); -- -- return 0; --} -- --int load_partition_table(unsigned int image_id) { -- uintptr_t dev_handle, image_handle, image_spec = 0; -- mbr_entry_t mbr_entry; -- int result; -- -- result = plat_get_image_source(image_id, &dev_handle, &image_spec); -- if (result != 0) { -- WARN("Failed to obtain reference to image id=%u (%i)\n", image_id, -- result); -- return result; -- } -- -- result = io_open(dev_handle, image_spec, &image_handle); -- if (result != 0) { -- WARN("Failed to open image id=%u (%i)\n", image_id, result); -- return result; -- } -- -- result = load_mbr_header(image_handle, &mbr_entry); -- if (result != 0) { -- ERROR("Loading mbr header failed with image id=%u (%i)\n", image_id, -- result); -- return result; -- } -- if (mbr_entry.type == PARTITION_TYPE_GPT) { -- INFO("Loading gpt header"); -- result = load_gpt_header(image_handle); -- assert(result == 0); -- if (result != 0) { -- ERROR("Failed load gpt header! %i", result); -- goto load_partition_table_exit; -- } -- result = io_seek(image_handle, IO_SEEK_SET, GPT_ENTRY_OFFSET); -- assert(result == 0); -- if (result != 0) { -- ERROR("Failed seek gpt header! %i", result); -- goto load_partition_table_exit; -- } -- result = verify_partition_gpt(image_handle); -- if (result != 0) { -- ERROR("Failed verify gpt partition %i", result); -- goto load_partition_table_exit; -- } -- } else { -- result = load_mbr_entries(image_handle); -- } -- --load_partition_table_exit: -- io_close(image_handle); -- return result; --} -- --const partition_entry_t *get_partition_entry(const char *name) { -- int i; -- -- for (i = 0; i < list.entry_count; i++) { -- if (strcmp(name, list.list[i].name) == 0) { -- return &list.list[i]; -- } -- } -- return NULL; --} -- --const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_uuid) { -- int i; -- -- for (i = 0; i < list.entry_count; i++) { -- if (guidcmp(type_uuid, &list.list[i].type_guid) == 0) { -- return &list.list[i]; -- } -- } -- -- return NULL; --} -- --const partition_entry_t *get_partition_replica_by_type(const uuid_t *type_uuid) { -- int count = 0; -- int i; -- -- for (i = 0; i < list.entry_count; i++) { -- if (guidcmp(type_uuid, &list.list[i].type_guid) == 0) { -- if (++count == 2) -- return &list.list[i]; -- } -- } -- -- return NULL; --} -- --const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid) { -- int i; -- -- for (i = 0; i < list.entry_count; i++) { -- if (guidcmp(part_uuid, &list.list[i].part_guid) == 0) { -- return &list.list[i]; -- } -- } -- -- return NULL; --} -- --const partition_entry_list_t *get_partition_entry_list(void) { return &list; } -- --void partition_init(unsigned int image_id) { load_partition_table(image_id); } -diff --git a/platform/ext/target/arm/corstone1000/partition/partition.h b/platform/ext/target/arm/corstone1000/partition/partition.h -deleted file mode 100644 -index 450cf20a0..000000000 ---- a/platform/ext/target/arm/corstone1000/partition/partition.h -+++ /dev/null -@@ -1,48 +0,0 @@ --/* -- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- */ -- --#ifndef PARTITION_H --#define PARTITION_H -- --#include -- --#include "efi.h" --#include "uuid.h" -- --#if !PLAT_PARTITION_MAX_ENTRIES --#define PLAT_PARTITION_MAX_ENTRIES 16 --#endif /* PLAT_PARTITION_MAX_ENTRIES */ -- --#if !PLAT_PARTITION_BLOCK_SIZE --#define PLAT_PARTITION_BLOCK_SIZE 512 --#endif /* PLAT_PARTITION_BLOCK_SIZE */ -- --#define LEGACY_PARTITION_BLOCK_SIZE 512 -- --#define DEFAULT_GPT_HEADER_SIZE 92 -- --typedef struct partition_entry { -- uint64_t start; -- uint64_t length; -- char name[EFI_NAMELEN]; -- struct efi_guid part_guid; -- struct efi_guid type_guid; --} partition_entry_t; -- --typedef struct partition_entry_list { -- partition_entry_t list[PLAT_PARTITION_MAX_ENTRIES]; -- int entry_count; --} partition_entry_list_t; -- --int load_partition_table(unsigned int image_id); --const partition_entry_t *get_partition_entry(const char *name); --const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_guid); --const partition_entry_t *get_partition_replica_by_type(const uuid_t *type_uuid); --const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid); --const partition_entry_list_t *get_partition_entry_list(void); --void partition_init(unsigned int image_id); -- --#endif /* PARTITION_H */ -diff --git a/platform/ext/target/arm/corstone1000/partition/uuid.h b/platform/ext/target/arm/corstone1000/partition/uuid.h -deleted file mode 100644 -index 06fec5a3c..000000000 ---- a/platform/ext/target/arm/corstone1000/partition/uuid.h -+++ /dev/null -@@ -1,76 +0,0 @@ --/*- -- * Copyright (c) 2002 Marcel Moolenaar -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- * -- * $FreeBSD$ -- */ -- --/* -- * Portions copyright (c) 2014-2020, ARM Limited and Contributors. -- * All rights reserved. -- */ -- --#ifndef UUID_H --#define UUID_H -- --#include -- --/* Length of a node address (an IEEE 802 address). */ --#define _UUID_NODE_LEN 6 -- --/* Length of UUID string including dashes. */ --#define _UUID_STR_LEN 36 -- --/* -- * See also: -- * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt -- * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm -- * -- * A DCE 1.1 compatible source representation of UUIDs. -- */ --struct uuid { -- uint8_t time_low[4]; -- uint8_t time_mid[2]; -- uint8_t time_hi_and_version[2]; -- uint8_t clock_seq_hi_and_reserved; -- uint8_t clock_seq_low; -- uint8_t node[_UUID_NODE_LEN]; --}; -- --struct efi_guid { -- uint32_t time_low; -- uint16_t time_mid; -- uint16_t time_hi_and_version; -- uint8_t clock_seq_and_node[8]; --}; -- --union uuid_helper_t { -- struct uuid uuid_struct; -- struct efi_guid efi_guid; --}; -- --/* XXX namespace pollution? */ --typedef struct uuid uuid_t; -- --#endif /* UUID_H */ -diff --git a/platform/ext/target/arm/corstone1000/platform.c b/platform/ext/target/arm/corstone1000/platform.c -index 32fdc55aa..c8157752a 100644 ---- a/platform/ext/target/arm/corstone1000/platform.c -+++ b/platform/ext/target/arm/corstone1000/platform.c -@@ -10,90 +10,25 @@ - #include "Driver_Flash.h" - #include "flash_layout.h" - --#include "io_driver.h" --#include "io_flash.h" --#include "io_storage.h" -+#include "io_gpt.h" - - #include "platform.h" - - #define PLAT_LOG_MODULE_NAME "platform" - #include "platform_log.h" - --typedef struct { -- uintptr_t dev_handle; -- uintptr_t image_spec; --} platform_image_source_t; -- - 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 = (uintptr_t)local_block_flash, -- .bufferlen = FLASH_SECTOR_SIZE, -- .base_addr = FLASH_BASE_ADDRESS, -- .flash_driver = (uintptr_t)&FLASH_DEV_NAME, --}; --static io_block_spec_t flash_spec = { -- .offset = FLASH_BASE_ADDRESS, -- .length = FLASH_TOTAL_SIZE --}; -- --static platform_image_source_t platform_image_source[] = { -- [PLATFORM_GPT_IMAGE] = { -- .dev_handle = (uintptr_t)NULL, -- .image_spec = (uintptr_t)&flash_spec, -- } --}; - - /* Initialize io storage of the platform */ - int32_t plat_io_storage_init(void) - { -- int rc = -1; -- uintptr_t flash_dev_handle = (uintptr_t)NULL; -- uintptr_t flash_handle = (uintptr_t)NULL; - -- rc = register_io_dev_flash((const io_dev_connector_t **) &flash_dev_con); -+ /* The GPT library requires a flash driver in order to do I/O */ -+ int rc = register_flash_io_gpt(&FLASH_DEV_NAME); - if (rc != 0) { - ERROR("Failed to register io flash rc: %d", rc); -- return rc; - } - -- rc = io_dev_open(flash_dev_con, (const uintptr_t)&flash_dev_spec, &flash_dev_handle); -- if (rc != 0) { -- ERROR("Failed to open io flash dev rc: %d", rc); -- return rc; -- } -- -- VERBOSE("Flash_dev_handle = %p",flash_dev_handle); -- -- rc = io_open(flash_dev_handle, (const uintptr_t)&flash_spec, &flash_handle); -- if (rc != 0) { -- ERROR("Failed to open io flash rc: %d", rc); -- return rc; -- } -- -- VERBOSE("Flash_handle = %p",flash_handle); -- -- rc = io_close(flash_handle); -- if (rc != 0) { -- ERROR("Failed to close io flash rc: %d", rc); -- return rc; -- } -- /* Update the platform image source that uses the flash with dev handles */ -- platform_image_source[PLATFORM_GPT_IMAGE].dev_handle = flash_dev_handle; -- - return rc; - } -- --/* Return an IO device handle and specification which can be used to access -- * an image. This has to be implemented for the GPT parser. */ --int32_t plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, -- uintptr_t *image_spec) { -- if (image_id >= PLATFORM_IMAGE_COUNT) { -- return -1; -- } -- *dev_handle = platform_image_source[image_id].dev_handle; -- *image_spec = platform_image_source[image_id].image_spec; -- return 0; --} -diff --git a/platform/ext/target/arm/corstone1000/platform.h b/platform/ext/target/arm/corstone1000/platform.h -index 906a8f9ae..96bee50dc 100644 ---- a/platform/ext/target/arm/corstone1000/platform.h -+++ b/platform/ext/target/arm/corstone1000/platform.h -@@ -8,22 +8,28 @@ - #ifndef __PLATFORM_H__ - #define __PLATFORM_H__ - --typedef enum { -- PLATFORM_GPT_IMAGE = 0, -- PLATFORM_IMAGE_COUNT, --}platform_image_id_t; -+#include "efi_guid_structs.h" - --#define FWU_METADATA_TYPE_UUID \ -- ((uuid_t){{0xa0, 0x84, 0x7a, 0x8a}, {0x87, 0x83}, {0xf6, 0x40}, 0xab, 0x41, {0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23}}) --#define PRIVATE_METADATA_TYPE_UUID \ -- ((uuid_t){{0xc3, 0x5d, 0xb5, 0xec}, {0xb7, 0x8a}, {0x84, 0x4a}, 0xab, 0x56, {0xeb, 0x0a, 0x99, 0x74, 0xdb, 0x42}}) -+#if !PLAT_GPT_MAX_PARTITIONS -+#define PLAT_GPT_MAX_PARTITIONS 16 -+#endif /* PLAT_GPT_MAX_PARTITIONS */ -+ -+#define FWU_METADATA_TYPE_UUID \ -+ MAKE_EFI_GUID( \ -+ 0x8A7A84A0, \ -+ 0x8387, \ -+ 0x40F6, \ -+ 0xAB, 0x41, \ -+ 0xA8, 0xB9, 0xA5, 0xA6, 0x0D, 0x23) -+#define PRIVATE_METADATA_TYPE_UUID \ -+ MAKE_EFI_GUID( \ -+ 0xECB55DC3, \ -+ 0x8AB7, \ -+ 0x4A84, \ -+ 0xAB, 0x56, \ -+ 0xEB, 0x0A, 0x99, 0x74, 0xDB, 0x42) - - /* Initialize io storage of the platform */ - int32_t plat_io_storage_init(void); - --/* Return an IO device handle and specification which can be used to access -- * an image. This has to be implemented for the GPT parser. */ --int32_t plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, -- uintptr_t *image_spec); -- - #endif /*__PLATFORM_H__*/ -diff --git a/platform/ext/target/arm/corstone1000/soft_crc/soft_crc.c b/platform/ext/target/arm/corstone1000/soft_crc/soft_crc.c -deleted file mode 100644 -index 85f1e30d9..000000000 ---- a/platform/ext/target/arm/corstone1000/soft_crc/soft_crc.c -+++ /dev/null -@@ -1,121 +0,0 @@ --/* Copyright (C) 1986 Gary S. Brown. You may use this program, or -- code or tables extracted from it, as desired without restriction.*/ -- --/* First, the polynomial itself and its table of feedback terms. The */ --/* polynomial is */ --/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ --/* Note that we take it "backwards" and put the highest-order term in */ --/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ --/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ --/* the MSB being 1. */ -- --/* Note that the usual hardware shift register implementation, which */ --/* is what we're using (we're merely optimizing it by doing eight-bit */ --/* chunks at a time) shifts bits into the lowest-order term. In our */ --/* implementation, that means shifting towards the right. Why do we */ --/* do it this way? Because the calculated CRC must be transmitted in */ --/* order from highest-order term to lowest-order term. UARTs transmit */ --/* characters in order from LSB to MSB. By storing the CRC this way, */ --/* we hand it to the UART in the order low-byte to high-byte; the UART */ --/* sends each low-bit to hight-bit; and the result is transmission bit */ --/* by bit from highest- to lowest-order term without requiring any bit */ --/* shuffling on our part. Reception works similarly. */ -- --/* The feedback terms table consists of 256, 32-bit entries. Notes: */ --/* */ --/* 1. The table can be generated at runtime if desired; code to do so */ --/* is shown later. It might not be obvious, but the feedback */ --/* terms simply represent the results of eight shift/xor opera- */ --/* tions for all combinations of data and CRC register values. */ --/* */ --/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ --/* be they sixteen or thirty-two bits wide. You simply choose the */ --/* appropriate table. Alternatively, because the table can be */ --/* generated at runtime, you can start by generating the table for */ --/* the polynomial in question and use exactly the same "updcrc", */ --/* if your application needn't simultaneously handle two CRC */ --/* polynomials. (Note, however, that XMODEM is strange.) */ --/* */ --/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ --/* of course, 32-bit entries work OK if the high 16 bits are zero. */ --/* */ --/* 4. The values must be right-shifted by eight bits by the "updcrc" */ --/* logic; the shift must be unsigned (bring in zeroes). On some */ --/* hardware you could probably optimize the shift in assembler by */ --/* using byte-swap instructions. */ -- --/** -- * The code derived from work by Gary S. Brown. --*/ -- --#include "soft_crc.h" -- -- --const static uint32_t crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ --0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, --0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, --0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, --0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, --0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, --0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, --0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, --0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, --0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, --0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, --0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, --0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, --0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, --0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, --0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, --0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, --0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, --0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, --0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, --0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, --0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, --0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, --0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, --0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, --0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, --0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, --0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, --0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, --0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, --0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, --0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, --0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, --0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, --0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, --0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, --0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, --0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, --0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, --0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, --0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, --0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, --0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, --0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d --}; -- --#define UPDC32(octet,crc) (crc_32_tab[((crc)\ -- ^ ((uint8_t)octet)) & 0xff] ^ ((crc) >> 8)) -- --static inline uint32_t crc32buf(char *buf, size_t len) --{ -- register uint32_t oldcrc32; -- -- oldcrc32 = 0xFFFFFFFF; -- -- for ( ; len; --len, ++buf) -- { -- oldcrc32 = UPDC32(*buf, oldcrc32); -- } -- -- return ~oldcrc32; --} -- --/* Calculate crc32 */ --uint32_t crc32(const void *buf, size_t len) { -- return crc32buf(buf, len); --} -- -diff --git a/platform/ext/target/arm/corstone1000/soft_crc/soft_crc.h b/platform/ext/target/arm/corstone1000/soft_crc/soft_crc.h -deleted file mode 100644 -index e5b06075c..000000000 ---- a/platform/ext/target/arm/corstone1000/soft_crc/soft_crc.h -+++ /dev/null -@@ -1,18 +0,0 @@ --/* -- * Copyright (c) 2023, Arm Limited. All rights reserved. -- * -- * SPDX-License-Identifier: BSD-3-Clause -- * -- */ -- --#ifndef __SOFT_CRC_H__ --#define __SOFT_CRC_H__ -- --#include --#include -- --/* Calculate crc32 */ --uint32_t crc32(const void *buf, size_t len); -- --#endif /* __SOFT_CRC_H__ */ -- diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0042-plat-cs1k-Move-variable-from-stack-to-data.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0042-plat-cs1k-Move-variable-from-stack-to-data.patch deleted file mode 100644 index d5921afa..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0042-plat-cs1k-Move-variable-from-stack-to-data.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 201166be49ca4c0079cf804f208534f201cb4b65 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Fri, 13 Mar 2026 16:53:54 +0000 -Subject: [PATCH] plat: cs1k: Move variable from stack to data - -The firmware update secure partition stack is only 0x600 bytes in size. -The variable moved is a buffer of size 0x200, consituting one third of -the available stack. Moving this to the much larger .data section allows -much more stack space if required. - -Change-Id: I59d68e80acefaeea36c7060442e005998217d923 -Signed-off-by: Frazer Carsley -Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/49430] ---- - .../arm/corstone1000/bootloader/mcuboot/tfm_mcuboot_fwu.c | 6 +++--- - 1 file changed, 3 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 5e1c4ecc5..a35125b00 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 -@@ -39,6 +39,7 @@ - * This is used when bank consistency is maintained during partial capsule update - */ - #define FLASH_CHUNK_SIZE 512 -+static uint8_t flash_data_buf[FLASH_CHUNK_SIZE]; - - /* Possible states of the bank. - * Naming convention here matches the implementation in U-Boot -@@ -1978,7 +1979,6 @@ static psa_status_t copy_image_from_other_bank(int image_index, - FWU_LOG_FUNC_ENTER; - - uint32_t bank_offset[NR_OF_FW_BANKS] = {BANK_0_PARTITION_OFFSET, BANK_1_PARTITION_OFFSET}; -- uint8_t data[FLASH_CHUNK_SIZE]; - size_t remaining_size = fwu_image[image_index].image_size; - size_t data_size; - size_t offset_read = bank_offset[active_index] + fwu_image[image_index].image_offset; -@@ -1997,7 +1997,7 @@ static psa_status_t copy_image_from_other_bank(int image_index, - data_size = (remaining_size > FLASH_CHUNK_SIZE) ? FLASH_CHUNK_SIZE : remaining_size; - - /* read image data from flash */ -- data_transferred_count = FWU_METADATA_FLASH_DEV.ReadData(offset_read, data, data_size); -+ data_transferred_count = FWU_METADATA_FLASH_DEV.ReadData(offset_read, flash_data_buf, data_size); - if (data_transferred_count < 0) { - FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, data_transferred_count); - return PSA_ERROR_STORAGE_FAILURE; -@@ -2012,7 +2012,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); -+ data_transferred_count = FWU_METADATA_FLASH_DEV.ProgramData(offset_write, flash_data_buf, data_size); - if (data_transferred_count < 0) { - FWU_LOG_MSG("%s: ERROR - Flash read failed (ret = %d)\n\r", __func__, data_transferred_count); - return PSA_ERROR_STORAGE_FAILURE; diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0043-plat-cs1k-Create-and-remove-FWU-image-partitions.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0043-plat-cs1k-Create-and-remove-FWU-image-partitions.patch deleted file mode 100644 index 513765e9..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0043-plat-cs1k-Create-and-remove-FWU-image-partitions.patch +++ /dev/null @@ -1,521 +0,0 @@ -From 93101e6de045c0c4d633c502616ccf184c07e70a Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Fri, 13 Mar 2026 13:42:16 +0000 -Subject: [PATCH] plat: cs1k: Create and remove FWU image partitions - -Previous to this commit, the GPT library was used only to read each -firmware update image partition. However, the library now is used to -create new partitions, if they don't exist, at the start of an update -and remove the unused partitions at the end of an update, regardless of -whether the images were accepted or rejected. - -The images are not moved and are still placed in fixed offsets, so the -idea of a ping-pong between banks still persists. - -Change-Id: Ie2a2f0246a500c01019e3b498ac131466a2b3c84 -Signed-off-by: Frazer Carsley -Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/49431] ---- - .../arm/corstone1000/bootloader/fwu_agent.h | 7 +- - .../bootloader/mcuboot/tfm_mcuboot_fwu.c | 313 +++++++++++++++++- - 2 files changed, 302 insertions(+), 18 deletions(-) - -diff --git a/platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h b/platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h -index 4393f5f7b..729e1594c 100644 ---- a/platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h -+++ b/platform/ext/target/arm/corstone1000/bootloader/fwu_agent.h -@@ -8,6 +8,7 @@ - #ifndef FWU_AGENT_H - #define FWU_AGENT_H - -+#include "flash_layout.h" - #include "psa/error.h" - #include "efi_guid_structs.h" - #include "gpt.h" -@@ -47,7 +48,7 @@ typedef struct { - size_t image_size_recvd; - } __packed fmp_header_image_info_t; - --/* Image information common for both the banks */ -+/* Image information for each bank */ - typedef struct { - /* Total size of the image */ - uint32_t image_size; -@@ -55,8 +56,8 @@ typedef struct { - /* Offset of image within a bank. */ - uint32_t image_offset; - -- /* Name of the image in ascii */ -- char image_name[FWU_IMAGE_NAME_LENGTH]; -+ /* Names of the image in ascii, one for each bank */ -+ const char image_names[NR_OF_FW_BANKS][FWU_IMAGE_NAME_LENGTH]; - - /* Image-type GUID */ - struct efi_guid_t image_type; -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 a35125b00..71a91ade5 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 -@@ -214,7 +214,7 @@ const fwu_image_info_t fwu_image[NR_OF_IMAGES_IN_FW_BANK] = { - #if PLATFORM_IS_FVP - // FVP payloads GUIDs - { -- .image_name = "bl2_secondary", -+ .image_names = {"bl2_primary", "bl2_secondary"}, - .image_size = SE_BL2_PARTITION_SIZE, - .image_offset = SE_BL2_PARTITION_BANK_OFFSET, - .image_type = { -@@ -227,7 +227,7 @@ const fwu_image_info_t fwu_image[NR_OF_IMAGES_IN_FW_BANK] = { - }, - }, - { -- .image_name = "tfm_secondary", -+ .image_names = {"tfm_primary", "tfm_secondary"}, - .image_size = TFM_PARTITION_SIZE, - .image_offset = TFM_PARTITION_BANK_OFFSET, - .image_type = { -@@ -240,7 +240,7 @@ const fwu_image_info_t fwu_image[NR_OF_IMAGES_IN_FW_BANK] = { - }, - }, - { -- .image_name = "FIP_B", -+ .image_names = {"FIP_A", "FIP_B"}, - .image_size = FIP_PARTITION_SIZE, - .image_offset = FIP_PARTITION_BANK_OFFSET, - .image_type = { -@@ -253,7 +253,7 @@ const fwu_image_info_t fwu_image[NR_OF_IMAGES_IN_FW_BANK] = { - }, - }, - { -- .image_name = "kernel_secondary", -+ .image_names = {"kernel_primary", "kernel_secondary"}, - .image_size = INITRAMFS_PARTITION_SIZE, - .image_offset = INITRAMFS_PARTITION_BANK_OFFSET, - .image_type = { -@@ -268,7 +268,7 @@ const fwu_image_info_t fwu_image[NR_OF_IMAGES_IN_FW_BANK] = { - #else - // MPS3 payloads GUIDs - { -- .image_name = "bl2_secondary", -+ .image_names = {"bl2_primary", "bl2_secondary"}, - .image_size = SE_BL2_PARTITION_SIZE, - .image_offset = SE_BL2_PARTITION_BANK_OFFSET, - .image_type = { -@@ -281,7 +281,7 @@ const fwu_image_info_t fwu_image[NR_OF_IMAGES_IN_FW_BANK] = { - }, - }, - { -- .image_name = "tfm_secondary", -+ .image_names = {"tfm_primary", "tfm_secondary"}, - .image_size = TFM_PARTITION_SIZE, - .image_offset = TFM_PARTITION_BANK_OFFSET, - .image_type = { -@@ -294,7 +294,7 @@ const fwu_image_info_t fwu_image[NR_OF_IMAGES_IN_FW_BANK] = { - } - }, - { -- .image_name = "FIP_B", -+ .image_names = {"FIP_A", "FIP_B"}, - .image_size = FIP_PARTITION_SIZE, - .image_offset = FIP_PARTITION_BANK_OFFSET, - .image_type = { -@@ -307,7 +307,7 @@ const fwu_image_info_t fwu_image[NR_OF_IMAGES_IN_FW_BANK] = { - } - }, - { -- .image_name = "kernel_secondary", -+ .image_names = {"kernel_primary", "kernel_secondary"}, - .image_size = INITRAMFS_PARTITION_SIZE, - .image_offset = INITRAMFS_PARTITION_BANK_OFFSET, - .image_type = { -@@ -354,6 +354,15 @@ extern ARM_DRIVER_FLASH FWU_METADATA_FLASH_DEV; - * This is the value decided after monitoring the total time - * taken by the host to boot both on FVP and FPGA. - */ -+#ifndef BL1_BUILD -+static void ascii_to_unicode(const char *ascii, char *unicode) -+{ -+ for (int i = 0; i < strlen(ascii) + 1; ++i) { -+ unicode[i << 1] = ascii[i]; -+ unicode[(i << 1) + 1] = '\0'; -+ } -+} -+#endif - - #ifdef BL1_BUILD - static psa_status_t private_metadata_read( -@@ -856,6 +865,11 @@ psa_status_t fwu_metadata_init(void) - if (ret != PSA_SUCCESS) { - return ret; - } -+ -+ ret = psa_crypto_init(); -+ if (ret != PSA_SUCCESS) { -+ return ret; -+ } - #endif - - /* Code assumes everything fits into a sector */ -@@ -1146,6 +1160,45 @@ static psa_status_t fwu_select_previous( - return ret; - } - -+#ifndef BL1_BUILD -+ /* Remove the GPT partitions for the rejected images. It is always the newer -+ * (second) partitions that are rejected, as they are created during the -+ * fwu process -+ */ -+ for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; ++i) { -+ struct partition_entry_t part; -+ ret = gpt_entry_read_by_type(&(fwu_image[i].image_type), 1, &part); -+ -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { -+ FWU_LOG_MSG("%s: Unable to find partition '%s'\r\n", -+ __func__, fwu_image[i].image_names[index]); -+ return ret; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: Flash error whilst reading GPT partition '%s'\r\n", -+ __func__, fwu_image[i].image_names[index]); -+ return ret; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("%s: Unable to read partition '%s'\r\n", -+ __func__, fwu_image[i].image_names[index]); -+ return ret; -+ } -+ -+ ret = gpt_entry_remove(&(part.partition_guid)); -+ if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: Flash error whilst removing GPT partition '%s'\r\n", -+ __func__, fwu_image[i].image_names[index]); -+ return ret; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("%s: Unable to remove partition '%s'\r\n", -+ __func__, fwu_image[i].image_names[index]); -+ return ret; -+ } -+ -+ FWU_LOG_MSG("%s: Removed GPT partition '%s'\r\n", -+ __func__, fwu_image[i].image_names[index]); -+ } -+#endif /* BL1_BUILD */ -+ - FWU_LOG_MSG("%s: in regular state by choosing previous active bank\n\r", - __func__); - -@@ -1594,6 +1647,47 @@ static psa_status_t fwu_accept_image(struct fwu_metadata *metadata, - return ret; - } - -+#ifndef BL1_BUILD -+ /* Remove the old (first) partitions from the GPT header. It is always the -+ * older images to be removed, as they were not created by the update -+ * process but existed before -+ */ -+ uint32_t previous_bank_index = metadata->previous_active_index; -+ -+ for (int i = 0; i < NR_OF_IMAGES_IN_FW_BANK; ++i) { -+ struct partition_entry_t part; -+ -+ ret = gpt_entry_read_by_type( -+ &(fwu_image[i].image_type), -+ 0, -+ &part); -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { -+ FWU_LOG_MSG("%s: Unable to find partition '%s'\r\n", -+ __func__, fwu_image[i].image_names[previous_bank_index]); -+ return ret; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: Flash error whilst reading GPT partition '%s'\r\n", -+ __func__, fwu_image[i].image_names[previous_bank_index]); -+ return ret; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("%s: Unable to read partition '%s'\r\n", -+ __func__, fwu_image[i].image_names[previous_bank_index]); -+ return ret; -+ } -+ -+ ret = gpt_entry_remove(&(part.partition_guid)); -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { -+ FWU_LOG_MSG("%s: Flash error whilst removing GPT partition '%s'\r\n", -+ __func__, fwu_image[i].image_names[previous_bank_index]); -+ return ret; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("%s: Unable to remove partition '%s'\r\n", -+ __func__, fwu_image[i].image_names[previous_bank_index]); -+ return ret; -+ } -+ } -+#endif -+ - FWU_LOG_MSG("%s: success: fwu state is changed to regular\n\r", __func__); - return PSA_SUCCESS; - } -@@ -1635,21 +1729,81 @@ static psa_status_t erase_staging_area(struct fwu_metadata* metadata, psa_fwu_co - } - - uint32_t active_index = metadata->active_index; -+ uint32_t previous_active_index; - uint32_t bank_offset; - uint32_t image_offset; -+ uint32_t image_size; - uint8_t fwu_image_index = component - FWU_FAKE_IMAGES_INDEX_COUNT; /* Decrement to get the correct fwu image index */ - - if (active_index == BANK_0) { - bank_offset = BANK_1_PARTITION_OFFSET; -+ previous_active_index = BANK_1; - } else if (active_index == BANK_1) { - bank_offset = BANK_0_PARTITION_OFFSET; -+ previous_active_index = BANK_0; - } else { - FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index); - return PSA_ERROR_GENERIC_ERROR; - } - -+#ifdef BL1_BUILD - image_offset = bank_offset + fwu_image[fwu_image_index].image_offset; -- if (erase_image(image_offset, fwu_image[fwu_image_index].image_size)) { -+ image_size = fwu_image[fwu_image_index].image_size; -+#else -+ /* Use GPT to find partition instead */ -+ struct partition_entry_t part; -+ -+ psa_status_t ret = gpt_entry_read_by_type(&(fwu_image[fwu_image_index].image_type), 1, &part); -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { -+ /* Create the partition in the expected space */ -+ struct efi_guid_t new_guid = {0}; -+ char unicode_name[GPT_ENTRY_NAME_LENGTH] = {'\0'}; -+ ascii_to_unicode(fwu_image[fwu_image_index].image_names[previous_active_index], unicode_name); -+ -+ ret = gpt_entry_create(&(fwu_image[fwu_image_index].image_type), -+ (bank_offset + fwu_image[fwu_image_index].image_offset) / TFM_GPT_BLOCK_SIZE, -+ 1 + ((fwu_image[fwu_image_index].image_size - 1) / TFM_GPT_BLOCK_SIZE), -+ 0, -+ unicode_name, -+ &new_guid); -+ if (ret == PSA_ERROR_INSUFFICIENT_STORAGE) { -+ FWU_LOG_MSG("%s: No space left on device!\r\n", __func__); -+ return ret; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: Flash error whilst creating GPT partition '%s'!\r\n", -+ __func__, fwu_image[fwu_image_index].image_names[previous_active_index]); -+ return ret; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("%s: Unable to create GPT partition '%s': %d\r\n", __func__, -+ fwu_image[fwu_image_index].image_names[previous_active_index], ret); -+ return ret; -+ } -+ -+ ret = gpt_entry_read(&new_guid, &part); -+ if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: Flash error whilst reading GPT partition '%s'\r\n", -+ __func__, fwu_image[fwu_image_index].image_names[previous_active_index]); -+ return ret; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("%s: Unable to read GPT partition '%s': %d\r\n", __func__, -+ fwu_image[fwu_image_index].image_names[previous_active_index], ret); -+ return ret; -+ } -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: Flash error whilst reading GPT partition '%s'\r\n", -+ __func__, fwu_image[fwu_image_index].image_names[previous_active_index]); -+ return ret; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("%s: Unable to read GPT partition '%s': %d\r\n", __func__, -+ fwu_image[fwu_image_index].image_names[previous_active_index], ret); -+ return ret; -+ } -+ -+ image_offset = part.start * TFM_GPT_BLOCK_SIZE; -+ image_size = part.size * TFM_GPT_BLOCK_SIZE; -+#endif /* BL1_BUILD */ -+ -+ if (erase_image(image_offset, image_size)) { - return PSA_ERROR_GENERIC_ERROR; - } - -@@ -1924,7 +2078,6 @@ static psa_status_t fwu_update_metadata(const psa_fwu_component_t *candidates, u - goto out; - } - active_index = _metadata.active_index; -- - if (active_index == BANK_0) { - previous_active_index = BANK_1; - } else if (active_index == BANK_1) { -@@ -1979,15 +2132,89 @@ static psa_status_t copy_image_from_other_bank(int image_index, - FWU_LOG_FUNC_ENTER; - - uint32_t bank_offset[NR_OF_FW_BANKS] = {BANK_0_PARTITION_OFFSET, BANK_1_PARTITION_OFFSET}; -+ psa_status_t ret; -+ -+#ifdef BL1_BUILD -+ /* Use offsets directly */ - size_t remaining_size = fwu_image[image_index].image_size; - size_t data_size; - size_t offset_read = bank_offset[active_index] + fwu_image[image_index].image_offset; - size_t offset_write = bank_offset[previous_active_index] + fwu_image[image_index].image_offset; - int data_transferred_count; -+#else -+ /* Use GPT to find the correct image */ -+ struct partition_entry_t active_part; -+ ret = gpt_entry_read_by_type( -+ &(fwu_image[image_index].image_type), -+ 0, -+ &active_part); -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { -+ FWU_LOG_MSG("%s: Unable to find partition '%s'\r\n", -+ __func__, fwu_image[image_index].image_names[active_index]); -+ return ret; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: Flash error whilst reading GPT partition '%s'\r\n", -+ __func__, fwu_image[image_index].image_names[active_index]); -+ return ret; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("%s: Unable to read partition '%s'\r\n", -+ __func__, fwu_image[image_index].image_names[active_index]); -+ return ret; -+ } - -- FWU_LOG_MSG("%s: Enter \n\r", __func__); -+ struct partition_entry_t prev_active_part; -+ ret = gpt_entry_read_by_type( -+ &(fwu_image[image_index].image_type), -+ 1, -+ &prev_active_part); - -- psa_status_t ret = erase_image(offset_write, fwu_image[image_index].image_size); -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { -+ /* Create the partition in the expected space */ -+ struct efi_guid_t new_guid = {0}; -+ char unicode_name[GPT_ENTRY_NAME_LENGTH] = {'\0'}; -+ ascii_to_unicode(fwu_image[image_index].image_names[previous_active_index], unicode_name); -+ -+ ret = gpt_entry_create(&(fwu_image[image_index].image_type), -+ (bank_offset[previous_active_index] + fwu_image[image_index].image_offset) / TFM_GPT_BLOCK_SIZE, -+ 1 + ((fwu_image[image_index].image_size - 1) / TFM_GPT_BLOCK_SIZE), -+ 0, -+ unicode_name, -+ &new_guid); -+ if (ret == PSA_ERROR_INSUFFICIENT_STORAGE) { -+ FWU_LOG_MSG("%s: No space left on device!\r\n", __func__); -+ return ret; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: Flash error whilst creating GPT partition '%s'!\r\n", -+ __func__, fwu_image[image_index].image_names[previous_active_index]); -+ return ret; -+ } else if (ret < 0) { -+ return ret; -+ } -+ -+ ret = gpt_entry_read(&new_guid, &prev_active_part); -+ if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: Flash error whilst reading GPT partition '%s'\r\n", -+ __func__, fwu_image[image_index].image_names[previous_active_index]); -+ return ret; -+ } else if (ret < 0) { -+ return ret; -+ } -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: Flash error whilst reading GPT partition '%s'\r\n", -+ __func__, fwu_image[image_index].image_names[previous_active_index]); -+ return ret; -+ } else if (ret < 0) { -+ return ret; -+ } -+ -+ size_t remaining_size = prev_active_part.size * TFM_GPT_BLOCK_SIZE; -+ size_t data_size; -+ size_t offset_read = active_part.start * TFM_GPT_BLOCK_SIZE; -+ size_t offset_write = prev_active_part.start * TFM_GPT_BLOCK_SIZE; -+ int data_transferred_count; -+#endif /* BL1_BUILD */ -+ -+ ret = erase_image(offset_write, remaining_size); - if (ret != PSA_SUCCESS) { - FWU_LOG_MSG("%s: ERROR - Flash erase failed for Image: %d\n\r", __func__, image_index); - return ret; -@@ -2244,10 +2471,10 @@ psa_status_t fwu_bootloader_reject_staged_image(psa_fwu_component_t component) - return PSA_ERROR_BAD_STATE; - } - -- int ret; -+ psa_status_t ret; - uint32_t active_index;; -- uint32_t bank_offset; - uint32_t image_offset; -+ uint32_t image_size; - uint8_t image_index = component - FWU_FAKE_IMAGES_INDEX_COUNT; /* Decrement to get the correct fwu image index */ - - FWU_LOG_FUNC_ENTER; -@@ -2259,6 +2486,8 @@ psa_status_t fwu_bootloader_reject_staged_image(psa_fwu_component_t component) - } - active_index = _metadata.active_index; - -+#ifdef BL1_BUILD -+ uint32_t bank_offset; - if (active_index == BANK_0) { - bank_offset = BANK_1_PARTITION_OFFSET; - } else if (active_index == BANK_1) { -@@ -2270,8 +2499,62 @@ psa_status_t fwu_bootloader_reject_staged_image(psa_fwu_component_t component) - } - - image_offset = bank_offset + fwu_image[image_index].image_offset; -+ image_size = fwu_image[image_index].image_size; -+#else -+ uint32_t previous_active_index; -+ struct partition_entry_t part; -+ -+ if (active_index == BANK_0) { -+ previous_active_index = BANK_1; -+ } else if (active_index == BANK_1) { -+ previous_active_index = BANK_0; -+ } else { -+ FWU_LOG_MSG("ERROR: %s: active_index %d\n\r",__func__,active_index); -+ ret = PSA_ERROR_GENERIC_ERROR; -+ goto out; -+ } -+ -+ /* The newer entry of the same type is the staged image, as it was created -+ * during the fwu process -+ */ -+ ret = gpt_entry_read_by_type( -+ &(fwu_image[image_index].image_type), -+ 1, -+ &part); -+ -+ if (ret == PSA_ERROR_DOES_NOT_EXIST) { -+ FWU_LOG_MSG("%s: Partition '%s' not found\n\r", -+ __func__, fwu_image[image_index].image_names[previous_active_index]); -+ goto out; -+ } else if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s : ERROR - flash failure reading partition '%s'\n\r", -+ __func__, fwu_image[image_index].image_names[previous_active_index]); -+ goto out; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("Unable to find partition '%s', ret: %d\n\r", -+ fwu_image[image_index].image_names[previous_active_index], ret); -+ goto out; -+ } -+ -+ /* Remove the partition. This only removes the entry from the header and -+ * does not erase the actual data the partition referred to -+ */ -+ ret = gpt_entry_remove(&(part.partition_guid)); -+ if (ret == PSA_ERROR_STORAGE_FAILURE) { -+ FWU_LOG_MSG("%s: Flash error whilst removing GPT partition '%s'\r\n", -+ __func__, fwu_image[image_index].image_names[previous_active_index]); -+ goto out; -+ } else if (ret < 0) { -+ FWU_LOG_MSG("%s: Unable to remove partition '%s'\r\n", -+ __func__, fwu_image[image_index].image_names[previous_active_index]); -+ goto out; -+ } -+ -+ image_offset = part.start * TFM_GPT_BLOCK_SIZE; -+ image_size = part.size * TFM_GPT_BLOCK_SIZE; -+#endif /* BL1_BUILD */ - -- if (erase_image(image_offset, fwu_image[image_index].image_size)) { -+ if (erase_image(image_offset, image_size)) { - return PSA_ERROR_GENERIC_ERROR; - } - diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0044-plat-cs1k-Derive-host-base-addresses-from-offsets.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0044-plat-cs1k-Derive-host-base-addresses-from-offsets.patch deleted file mode 100644 index a83ca6e9..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0044-plat-cs1k-Derive-host-base-addresses-from-offsets.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 37cac6c86f10340382ff950e5e0323f2efbe5ed3 Mon Sep 17 00:00:00 2001 -From: Michael Safwat -Date: Wed, 8 Apr 2026 13:02:47 +0100 -Subject: [PATCH 1/2] plat: cs1k: Derive host base addresses from offsets - -Define explicit host register offsets and compute base addresses -from the common host address space base. This keeps the map -consistent, and also makes it easy to relocate all addresses if the -base addresses change. - -Define External System Reset Control bitfields and use them to -de-assert CPUWAIT when booting the external system, so we can touch -only the bit of interest instead of zeroing the whole register. - -Change-Id: Id228351926fc846d28d5bf4e4180a995057154b1 -Signed-off-by: Michael Safwat -Upstream-Status: Backport [d73cc1dbc2eb72af02de740926f7b3c889bbac4b] ---- - .../Device/Include/platform_base_address.h | 52 ++++++++++++++----- - .../arm/corstone1000/tfm_hal_multi_core.c | 5 +- - 2 files changed, 41 insertions(+), 16 deletions(-) - -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 3908d69bc..62ee7d049 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 -@@ -68,23 +68,49 @@ - /* Host base addresses from the SE perspective - partial list, only the ones - * required by the SE are defined here */ - #define CORSTONE1000_HOST_ADDRESS_SPACE_BASE (0x60000000U) /* Host Address Space */ --#define CORSTONE1000_HOST_BIR_BASE (0x60000000U) /* Boot Instruction Register */ --#define CORSTONE1000_HOST_TRUSTED_RAM_BASE (0x62000000U) /* Secure RAM */ --#define CORSTONE1000_HOST_XNVM_BASE (0x68000000U) /* XNVM */ --#define CORSTONE1000_HOST_BASE_SYSTEM_CONTROL_BASE (0x7A010000U) /* Host SCB */ --#define CORSTONE1000_EXT_SYS_RESET_REG (0x7A010310U) /* external system (cortex-M3) */ --#define CORSTONE1000_HOST_FIREWALL_BASE (0x7A800000U) /* Host Firewall */ --#define CORSTONE1000_HOST_INT_APBCOM_BASE (0x7B900000U) /* Internal APBCOM */ --#define CORSTONE1000_HOST_FPGA_SCC_REGISTERS (0x80000000U) /* FPGA SCC Registers */ --#define CORSTONE1000_HOST_SE_SECURE_FLASH_BASE_FVP (0x80010000U) /* SE Flash */ --#define CORSTONE1000_HOST_AXI_QSPI_CTRL_REG_BASE (0x80050000U) /* AXI QSPI Controller */ --#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 */ - -+/* Registers offsets - partial list, only the ones -+ * required by the SE are defined here */ -+#define CORSTONE1000_HOST_BIR_OFFSET (0x00000000U) -+#define CORSTONE1000_HOST_CVM_OFFSET (0x02000000U) -+#define CORSTONE1000_HOST_XNVM_OFFSET (0x08000000U) -+#define CORSTONE1000_HOST_BASE_SYSTEM_CONTROL_BASE_OFFSET (0x1A010000U) -+#define CORSTONE1000_HOST_EXT_SYS0_RST_CTRL_OFFSET (0x310U) -+#define CORSTONE1000_HOST_FIREWALL_BASE_OFFSET (0x1A800000U) -+#define CORSTONE1000_HOST_INT_APBCOM_BASE_OFFSET (0x1B900000U) -+/* The below offsets have been derived from the reserved section.*/ -+#define CORSTONE1000_HOST_FPGA_SCC_REGISTERS_OFFSET (0x20000000U) -+#define CORSTONE1000_HOST_SE_SECURE_FLASH_BASE_FVP_OFFSET (0x20010000U) -+#define CORSTONE1000_HOST_AXI_QSPI_CTRL_REG_BASE_OFFSET (0x20050000U) -+#define CORSTONE1000_HOST_AXI_QSPI_CTRL_REG_BASE_SE_SECURE_FLASH_OFFSET (0x30010000U) -+#define CORSTONE1000_HOST_DRAM_UEFI_CAPSULE_OFFSET (0x40000000U) -+#define CORSTONE1000_HOST_DSU_120T_BASE_OFFSET (0x60910000U) -+ -+/* Register Addresses */ -+#define CORSTONE1000_HOST_BIR_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_BIR_OFFSET) /* Boot Instruction Register */ -+#define CORSTONE1000_HOST_TRUSTED_RAM_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_CVM_OFFSET) /* On-chip Volatile Memory */ -+#define CORSTONE1000_HOST_XNVM_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_XNVM_OFFSET) /* eXecute-in-place Non-volatile Memory */ -+#define CORSTONE1000_HOST_BASE_SYSTEM_CONTROL_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_BASE_SYSTEM_CONTROL_BASE_OFFSET) /* Security Control Bits */ -+#define CORSTONE1000_EXT_SYS_RESET_REG (CORSTONE1000_HOST_BASE_SYSTEM_CONTROL_BASE + CORSTONE1000_HOST_EXT_SYS0_RST_CTRL_OFFSET) /* External System (Cortex-M3) */ -+#define CORSTONE1000_HOST_FIREWALL_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_FIREWALL_BASE_OFFSET) /* System Firewall */ -+#define CORSTONE1000_HOST_INT_APBCOM_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_INT_APBCOM_BASE_OFFSET) /* Internal Advanced Peripheral Bus Communication */ -+#define CORSTONE1000_HOST_FPGA_SCC_REGISTERS (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_FPGA_SCC_REGISTERS_OFFSET) /* FPGA Serial Communication Controller Registers */ -+#define CORSTONE1000_HOST_SE_SECURE_FLASH_BASE_FVP (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_SE_SECURE_FLASH_BASE_FVP_OFFSET) /* Secure Enclave Flash */ -+#define CORSTONE1000_HOST_AXI_QSPI_CTRL_REG_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_AXI_QSPI_CTRL_REG_BASE_OFFSET) /* AXI QSPI Controller */ -+#define CORSTONE1000_HOST_AXI_QSPI_CTRL_REG_BASE_SE_SECURE_FLASH (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_AXI_QSPI_CTRL_REG_BASE_SE_SECURE_FLASH_OFFSET) /* AXI QSPI Controller for SE FLash */ -+#define CORSTONE1000_HOST_DRAM_UEFI_CAPSULE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_DRAM_UEFI_CAPSULE_OFFSET) /* DDR RAM (1.5 GB) */ - #ifdef CORSTONE1000_DSU_120T --#define CORSTONE1000_HOST_DSU_120T_BASE (0xC0910000U) /* DSU-120T PPU */ -+#define CORSTONE1000_HOST_DSU_120T_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_DSU_120T_BASE_OFFSET) /* DynamIQ Shared Unit-120 Power Policy Units */ - #endif - -+/* Bit definition for External System Reset Control register */ -+#define CORSTONE1000_EXT_SYS_RESET_REG_CPUWAIT_Pos (0U) // CPU Wait Control. 0b0 - External System's CPUWAIT signal is de-asserted. 0b1 - External System's CPUWAIT signal is asserted. -+#define CORSTONE1000_EXT_SYS_RESET_REG_CPUWAIT_Msk (0x1UL << CORSTONE1000_EXT_SYS_RESET_REG_CPUWAIT_Pos) // 1 bit -+#define CORSTONE1000_EXT_SYS_RESET_REG_RST_REQ_Pos (1U) // Reset Request for External System. 0b0 - No Reset Requested. 0b1 - Reset Requested. -+#define CORSTONE1000_EXT_SYS_RESET_REG_RST_REQ_Msk (0x1UL << CORSTONE1000_EXT_SYS_RESET_REG_RST_REQ_Pos) // 1 bit -+#define CORSTONE1000_EXT_SYS_RESET_REG_Reserved_Pos (2U) // Reserved. -+#define CORSTONE1000_EXT_SYS_RESET_REG_Reserved_Msk (0x3FFFFFFFUL << CORSTONE1000_EXT_SYS_RESET_REG_Reserved_Pos) // 30 bits -+ - /* Map Component definitions to Corstone definitions */ - #define CC3XX_BASE_S CORSTONE1000_CRYPTO_ACCELERATOR_BASE - -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 9a785bfa0..76360b507 100644 ---- a/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c -+++ b/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c -@@ -26,12 +26,11 @@ - #define AA64nAA32_MASK (1 << 3) - - #ifdef EXTERNAL_SYSTEM_SUPPORT --void tfm_external_system_boot() -+void tfm_external_system_boot(void) - { - volatile uint32_t *ext_sys_reset_ctl_reg = (uint32_t *)(CORSTONE1000_EXT_SYS_RESET_REG); - -- /* de-assert CPU_WAIT signal*/ -- *ext_sys_reset_ctl_reg = 0x0; -+ *ext_sys_reset_ctl_reg &= ~(CORSTONE1000_EXT_SYS_RESET_REG_CPUWAIT_Msk); - } - #endif - --- -2.43.0 - diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0045-plat-cs1k-Drive-NPU-via-external-system-reset-contro.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0045-plat-cs1k-Drive-NPU-via-external-system-reset-contro.patch deleted file mode 100644 index c8fb8e4e..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0045-plat-cs1k-Drive-NPU-via-external-system-reset-contro.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 334e5513db08f6ebdd7e59429849d442b7b43446 Mon Sep 17 00:00:00 2001 -From: Michael Safwat -Date: Thu, 19 Mar 2026 11:12:19 +0000 -Subject: [PATCH 2/2] plat: cs1k: Drive NPU via external system reset control - -On Corstone-1000 with Cortex-A320, the NPU reset was previously tied -to the host boot flow, so the NPU was powered on when the Secure -Enclave powered on the host. Now the NPU is tied to the External -System Reset Control register to control the power state. - -Reuse the existing external-system boot control mechanism for NPU. - -Change-Id: I74f9d57e8cbe5cb38db352d706885f9a37db0183 -Signed-off-by: Michael Safwat -Upstream-Status: Backport [6010d3b509e51cf10a711596e7d6058bde1568dc] ---- - platform/ext/target/arm/corstone1000/CMakeLists.txt | 5 +++++ - .../arm/corstone1000/Device/Include/platform_base_address.h | 2 +- - platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c | 4 ++-- - 3 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/platform/ext/target/arm/corstone1000/CMakeLists.txt b/platform/ext/target/arm/corstone1000/CMakeLists.txt -index e543c4b6b..739a6a086 100644 ---- a/platform/ext/target/arm/corstone1000/CMakeLists.txt -+++ b/platform/ext/target/arm/corstone1000/CMakeLists.txt -@@ -484,6 +484,11 @@ if (CORSTONE1000_CORTEX_A320) - PUBLIC - CORSTONE1000_CORTEX_A320 - ) -+ -+ target_compile_definitions(platform_s -+ PUBLIC -+ CORSTONE1000_CORTEX_A320 -+ ) - endif() - - #========================= tfm_adac ============================================# -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 62ee7d049..631592b34 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 -@@ -91,7 +91,7 @@ - #define CORSTONE1000_HOST_TRUSTED_RAM_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_CVM_OFFSET) /* On-chip Volatile Memory */ - #define CORSTONE1000_HOST_XNVM_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_XNVM_OFFSET) /* eXecute-in-place Non-volatile Memory */ - #define CORSTONE1000_HOST_BASE_SYSTEM_CONTROL_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_BASE_SYSTEM_CONTROL_BASE_OFFSET) /* Security Control Bits */ --#define CORSTONE1000_EXT_SYS_RESET_REG (CORSTONE1000_HOST_BASE_SYSTEM_CONTROL_BASE + CORSTONE1000_HOST_EXT_SYS0_RST_CTRL_OFFSET) /* External System (Cortex-M3) */ -+#define CORSTONE1000_EXT_SYS_RESET_REG (CORSTONE1000_HOST_BASE_SYSTEM_CONTROL_BASE + CORSTONE1000_HOST_EXT_SYS0_RST_CTRL_OFFSET) /* External System (Cortex-M3/NPU) */ - #define CORSTONE1000_HOST_FIREWALL_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_FIREWALL_BASE_OFFSET) /* System Firewall */ - #define CORSTONE1000_HOST_INT_APBCOM_BASE (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_INT_APBCOM_BASE_OFFSET) /* Internal Advanced Peripheral Bus Communication */ - #define CORSTONE1000_HOST_FPGA_SCC_REGISTERS (CORSTONE1000_HOST_ADDRESS_SPACE_BASE + CORSTONE1000_HOST_FPGA_SCC_REGISTERS_OFFSET) /* FPGA Serial Communication Controller Registers */ -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 76360b507..ff65228bf 100644 ---- a/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c -+++ b/platform/ext/target/arm/corstone1000/tfm_hal_multi_core.c -@@ -25,7 +25,7 @@ - - #define AA64nAA32_MASK (1 << 3) - --#ifdef EXTERNAL_SYSTEM_SUPPORT -+#if defined(EXTERNAL_SYSTEM_SUPPORT) || defined(CORSTONE1000_CORTEX_A320) - void tfm_external_system_boot(void) - { - volatile uint32_t *ext_sys_reset_ctl_reg = (uint32_t *)(CORSTONE1000_EXT_SYS_RESET_REG); -@@ -123,7 +123,7 @@ void tfm_hal_boot_ns_cpu(uintptr_t start_addr) - #endif - #endif - --#ifdef EXTERNAL_SYSTEM_SUPPORT -+#if defined(EXTERNAL_SYSTEM_SUPPORT) || defined(CORSTONE1000_CORTEX_A320) - /*release EXT SYS out of reset*/ - tfm_external_system_boot(); - #endif --- -2.43.0 - diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0046-lib-gpt-Fix-final-entry-not-being-removed.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0046-lib-gpt-Fix-final-entry-not-being-removed.patch deleted file mode 100644 index f7e7179d..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0046-lib-gpt-Fix-final-entry-not-being-removed.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 4f11567a0152f1ecd98159ca555d8663ee8e5ce0 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Fri, 10 Apr 2026 17:20:39 +0100 -Subject: [PATCH] lib: gpt: Fix final entry not being removed - -The final entry would not be removed due to the removals being hidden -behind a check on whether the removed entry was not the final entry, -causing it to be a no-op. Removal operation is no longer hidden behind -that condition. - -Change-Id: Ib264d988d57cb39098f2783c4a001fcf3b004270 -Signed-off-by: Frazer Carsley -Upstream-Status: Backport [f3cf6bda1534b8893620c7b7c0d9ff647b44603e] ---- - lib/gpt/src/gpt.c | 64 +++++++++++++++++++++++------------------------ - 1 file changed, 32 insertions(+), 32 deletions(-) - -diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c -index a9dbb918e..e4e7fde32 100644 ---- a/lib/gpt/src/gpt.c -+++ b/lib/gpt/src/gpt.c -@@ -648,6 +648,7 @@ psa_status_t gpt_entry_remove(const struct efi_guid_t *guid) - * to be modified if the last entry in the array was moved or if it is - * the only LBA used by the partition array - */ -+ const uint64_t array_end_lba = partition_array_last_lba(&primary_gpt);; - if (cached_index != primary_gpt.num_used_partitions - 1 || - cached_index < gpt_entry_per_lba_count()) - { -@@ -669,7 +670,6 @@ psa_status_t gpt_entry_remove(const struct efi_guid_t *guid) - * 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) -@@ -705,45 +705,45 @@ psa_status_t gpt_entry_remove(const struct efi_guid_t *guid) - 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); -+ /* 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; - } -- } 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); -+ } -+ 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 */ diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0047-lib-gpt-Replace-warnings-with-errors.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0047-lib-gpt-Replace-warnings-with-errors.patch deleted file mode 100644 index 93b1fb3f..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0047-lib-gpt-Replace-warnings-with-errors.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 68874e58811c5d4004492f15b3ac46d2cca186c0 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Thu, 16 Apr 2026 09:54:55 +0100 -Subject: [PATCH] lib: gpt: Replace warnings with errors - -These warnings return errors, so it makes more sense to output an error -message. - -Change-Id: I589e24ba8aba2502a3fc86d2aeb648d125c022bd -Signed-off-by: Frazer Carsley -Upstream-Status: Backport [68874e58811c5d4004492f15b3ac46d2cca186c0] ---- - lib/gpt/src/gpt.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c -index 16bda8aba..32c7277bd 100644 ---- a/lib/gpt/src/gpt.c -+++ b/lib/gpt/src/gpt.c -@@ -830,7 +830,7 @@ psa_status_t gpt_defragment(void) - */ - psa_status_t ret = sort_partition_array(&primary_gpt); - if (ret != PSA_SUCCESS) { -- WARN("Unable to defragment flash!\n"); -+ ERROR("Unable to defragment flash!\n"); - return ret; - } - -@@ -926,7 +926,7 @@ psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, uint64_t max_part - if (mbr.partitions[0].os_type == MBR_TYPE_GPT) { - ret = read_table_from_flash(&primary_gpt, true); - } else { -- WARN("Unsupported legacy MBR in use\n"); -+ ERROR("Unsupported legacy MBR in use\n"); - ret = PSA_ERROR_NOT_SUPPORTED; - } - diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0048-lib-gpt-Enforce-entry-size-of-128-bytes.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0048-lib-gpt-Enforce-entry-size-of-128-bytes.patch deleted file mode 100644 index 4cba9e32..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0048-lib-gpt-Enforce-entry-size-of-128-bytes.patch +++ /dev/null @@ -1,268 +0,0 @@ -From ff08a9d998c545a6152789f8ce55bd4200a937cf Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Wed, 15 Apr 2026 10:59:28 +0100 -Subject: [PATCH] lib: gpt: Enforce entry size of 128 bytes - -Previous to this, the entry size could have been set to any number, even -those deemed illegal by the UEFI spec 2.10 [1], as the library did not -validate it. 128 bytes is the minimum size for a partition entry and -most standard tools that create GPTs will use this. - -[1] https://uefi.org/specs/UEFI/2.10/05_GUID_Partition_Table_Format.html - -Change-Id: Ib6c436353a4b8e00e6c6e63b933a49f11c0a7340 -Signed-off-by: Frazer Carsley -Upstream-Status: Backport [ff08a9d998c545a6152789f8ce55bd4200a937cf] ---- - lib/gpt/inc/gpt.h | 2 + - lib/gpt/src/gpt.c | 65 +++++++++++++++++++++----------- - lib/gpt/unittests/gpt/test_gpt.c | 40 ++++++++++++++++++++ - 3 files changed, 85 insertions(+), 22 deletions(-) - -diff --git a/lib/gpt/inc/gpt.h b/lib/gpt/inc/gpt.h -index baf4767f9..34ce67580 100644 ---- a/lib/gpt/inc/gpt.h -+++ b/lib/gpt/inc/gpt.h -@@ -214,6 +214,7 @@ psa_status_t gpt_entry_remove(const struct efi_guid_t *guid); - * - * \retval PSA_SUCCESS GPT is valid. - * \retval PSA_ERROR_STORAGE_FAILURE I/O error. -+ * \retval PSA_ERROR_NOT_SUPPORTED Entry size is not 128 bytes - * \retval PSA_ERROR_INVALID_SIGNATURE GPT is invalid. - */ - psa_status_t gpt_validate(bool is_primary); -@@ -249,6 +250,7 @@ psa_status_t gpt_defragment(void); - * functions defined by \p flash_driver is NULL. The init - * and uninit functions may be NULL if not required. - * \retval PSA_ERROR_NOT_SUPPORTED Legacy MBR is used and not GPT. -+ * \retval PSA_ERROR_NOT_SUPPORTED Entry size is not 128 bytes - */ - __attribute__((nonnull(1))) - psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, -diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c -index 32c7277bd..200e21599 100644 ---- a/lib/gpt/src/gpt.c -+++ b/lib/gpt/src/gpt.c -@@ -459,7 +459,7 @@ psa_status_t gpt_entry_move(const struct efi_guid_t *guid, - - /* 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); -+ memcpy(&entry, lba_buf + (i * GPT_ENTRY_SIZE), GPT_ENTRY_SIZE); - - const struct efi_guid_t ent_guid = entry.unique_guid; - if (efi_guid_cmp(&ent_guid, guid) == 0) { -@@ -658,9 +658,9 @@ psa_status_t gpt_entry_remove(const struct efi_guid_t *guid) - 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); -+ lba_buf + lba_index * GPT_ENTRY_SIZE, -+ lba_buf + (lba_index + 1) * GPT_ENTRY_SIZE, -+ (gpt_entry_per_lba_count() - lba_index - 1) * GPT_ENTRY_SIZE); - } - - /* If this is not the last LBA, then read the next LBA into memory and -@@ -683,7 +683,7 @@ psa_status_t gpt_entry_remove(const struct efi_guid_t *guid) - } - - memcpy( -- lba_buf + primary_gpt.header.entry_size * (gpt_entry_per_lba_count() - 1), -+ lba_buf + GPT_ENTRY_SIZE * (gpt_entry_per_lba_count() - 1), - array_buf, - GPT_ENTRY_SIZE); - -@@ -701,8 +701,8 @@ psa_status_t gpt_entry_remove(const struct efi_guid_t *guid) - - memmove( - array_buf, -- array_buf + primary_gpt.header.entry_size, -- sizeof(array_buf) - primary_gpt.header.entry_size); -+ array_buf + GPT_ENTRY_SIZE, -+ sizeof(array_buf) - GPT_ENTRY_SIZE); - memcpy(lba_buf, array_buf, TFM_GPT_BLOCK_SIZE); - } - } -@@ -731,9 +731,9 @@ psa_status_t gpt_entry_remove(const struct efi_guid_t *guid) - } else { - /* Zero what is not needed anymore */ - memset( -- lba_buf + primary_gpt.header.entry_size * entries_in_last_lba, -+ lba_buf + GPT_ENTRY_SIZE * entries_in_last_lba, - 0, -- (gpt_entry_per_lba_count() - entries_in_last_lba) * primary_gpt.header.entry_size); -+ (gpt_entry_per_lba_count() - entries_in_last_lba) * GPT_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) { -@@ -934,6 +934,14 @@ psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, uint64_t max_part - goto fail_load; - } - -+ /* Ensure entry size is supported. */ -+ if (primary_gpt.header.entry_size != GPT_ENTRY_SIZE) { -+ ERROR("Unsupported entry size 0x%08x, must be 0x%08x\n", -+ primary_gpt.header.entry_size, GPT_ENTRY_SIZE); -+ ret = PSA_ERROR_NOT_SUPPORTED; -+ goto fail_load; -+ } -+ - /* Count the number of used entries, assuming the array is not sparese */ - ret = count_used_partitions(&primary_gpt, &primary_gpt.num_used_partitions); - if (ret != PSA_SUCCESS) { -@@ -948,6 +956,12 @@ psa_status_t gpt_init(struct gpt_flash_driver_t *flash_driver, uint64_t max_part - if (ret != PSA_SUCCESS) { - goto fail_load; - } -+ if (backup_gpt.header.entry_size != GPT_ENTRY_SIZE) { -+ ERROR("Unsupported entry size 0x%08x, must be 0x%08x\n", -+ backup_gpt.header.entry_size, GPT_ENTRY_SIZE); -+ ret = PSA_ERROR_NOT_SUPPORTED; -+ goto fail_load; -+ } - backup_gpt_array_lba = backup_gpt.header.array_lba; - } else { - WARN("Backup GPT location is unknown!\n"); -@@ -999,11 +1013,7 @@ psa_status_t gpt_uninit(void) - /* Returns the number of partition entries in each LBA */ - static inline uint64_t gpt_entry_per_lba_count(void) - { -- static uint64_t num_entries = 0; -- if (num_entries == 0) { -- num_entries = TFM_GPT_BLOCK_SIZE / primary_gpt.header.entry_size; -- } -- return num_entries; -+ return TFM_GPT_BLOCK_SIZE / GPT_ENTRY_SIZE; - } - - /* Copies information from the entry to the user visible structure */ -@@ -1129,15 +1139,15 @@ static psa_status_t update_header(uint32_t num_partitions) - /* 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); -+ uint8_t entry_buf[GPT_ENTRY_SIZE]; -+ memset(entry_buf, 0, GPT_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); -+ crc = efi_soft_crc32_update(crc, entry_buf, GPT_ENTRY_SIZE); - } - header->array_crc = crc; - -@@ -1268,7 +1278,7 @@ static psa_status_t read_entry_from_flash(const struct gpt_t *table, - - memcpy( - entry, -- lba_buf + ((array_index % gpt_entry_per_lba_count()) * table->header.entry_size), -+ lba_buf + ((array_index % gpt_entry_per_lba_count()) * GPT_ENTRY_SIZE), - GPT_ENTRY_SIZE); - - return PSA_SUCCESS; -@@ -1415,7 +1425,7 @@ static psa_status_t write_entry(uint32_t array_index, - - /* 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); -+ memcpy(lba_buf + index_in_lba * GPT_ENTRY_SIZE, entry, GPT_ENTRY_SIZE); - - /* Write on every nth operation. */ - if (++num_writes == gpt_entry_per_lba_count()) { -@@ -1519,18 +1529,29 @@ static psa_status_t validate_table(struct gpt_t *table, bool is_primary) - return PSA_ERROR_INVALID_SIGNATURE; - } - -+ /* Check the entry size. This is not a part of the spec but ensures the -+ * library only supports entry sizes equal to 128. Otherwise, the backup -+ * could be used to restore the primary with an entry size that is different -+ * and break that assumption, or vise-versa -+ */ -+ if (header->entry_size != GPT_ENTRY_SIZE) { -+ ERROR("Unsupported entry size 0x%08x, must be 0x%08x\n", -+ header->entry_size, GPT_ENTRY_SIZE); -+ return PSA_ERROR_NOT_SUPPORTED; -+ } -+ - /* 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); -+ uint8_t entry_buf[GPT_ENTRY_SIZE]; -+ memset(entry_buf, 0, GPT_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); -+ calc_crc = efi_soft_crc32_update(calc_crc, (uint8_t *)entry, GPT_ENTRY_SIZE); - } - - if (calc_crc != header->array_crc) { -diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c -index 2f05a6b4a..db897b967 100644 ---- a/lib/gpt/unittests/gpt/test_gpt.c -+++ b/lib/gpt/unittests/gpt/test_gpt.c -@@ -351,6 +351,30 @@ void test_gpt_init_should_failWhenMbrTypeInvalid(void) - TEST_ASSERT_EQUAL(PSA_ERROR_NOT_SUPPORTED, setup_test_gpt()); - } - -+void test_gpt_init_should_failWhenEntrySizeBad(void) -+{ -+ test_header.entry_size--; -+ /* Expect first a valid MBR read */ -+ register_mocked_read(&test_mbr, sizeof(test_mbr)); -+ -+ /* Expect a GPT header read second */ -+ register_mocked_read(&test_header, sizeof(test_header)); -+ -+ TEST_ASSERT_EQUAL(PSA_ERROR_NOT_SUPPORTED, gpt_init(&mock_driver, TEST_MAX_PARTITIONS)); -+ test_header.entry_size = default_header.entry_size; -+ -+ /* Now do the backup. */ -+ register_mocked_read(&test_mbr, sizeof(test_mbr)); -+ register_mocked_read(&test_header, sizeof(test_header)); -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ -+ /* Expect fourth the backup to be read. Make the entry size bad */ -+ test_header.entry_size = 0; -+ setup_backup_gpt(); -+ -+ TEST_ASSERT_EQUAL(PSA_ERROR_NOT_SUPPORTED, gpt_init(&mock_driver, TEST_MAX_PARTITIONS)); -+} -+ - void test_gpt_init_should_failWhenFlashDriverNotFullyDefined(void) - { - gpt_flash_read_t read_fn = mock_driver.read; -@@ -433,6 +457,22 @@ void test_gpt_validate_should_failWhenLbaPointerBad(void) - TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(false)); - } - -+void test_gpt_validate_should_failWhenBackupEntrySizeInvalid(void) -+{ -+ /* The entry size for the primary GPT is validated on gpt_init and kept -+ * in memory. Therefore, the entry size can only be validated on gpt_validate -+ * for the backup table, which is read -+ */ -+ setup_test_gpt(); -+ struct gpt_header_t backup_header; -+ MAKE_BACKUP_HEADER(backup_header, test_header); -+ backup_header.entry_size--; -+ register_mocked_read(&backup_header, sizeof(backup_header)); -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ -+ TEST_ASSERT_EQUAL(PSA_ERROR_NOT_SUPPORTED, gpt_validate(false)); -+} -+ - void test_gpt_validate_should_failWhenArrayCrcBad(void) - { - test_header.array_crc--; diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0049-lib-gpt-Ensure-block-size-complies-with-spec.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0049-lib-gpt-Ensure-block-size-complies-with-spec.patch deleted file mode 100644 index d2258fba..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0049-lib-gpt-Ensure-block-size-complies-with-spec.patch +++ /dev/null @@ -1,38 +0,0 @@ -From c07da31be4551ee9b3ce546a1f6adccb19bc3b59 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Wed, 15 Apr 2026 11:17:25 +0100 -Subject: [PATCH] lib: gpt: Ensure block size complies with spec - -The UEFI spec 2.10 [1] implicitly requires a block size of at least 512 -in order to fit a legacy Master Boot Record. - -[1] https://uefi.org/specs/UEFI/2.10/05_GUID_Partition_Table_Format.html#legacy-master-boot-record-mbr - -Change-Id: I8218ef3d883b51d8fa14835e0ed884139fdebc7d -Signed-off-by: Frazer Carsley -Upstream-Status: Backport [c07da31be4551ee9b3ce546a1f6adccb19bc3b59] ---- - lib/gpt/src/gpt.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c -index 200e21599..cda9fe358 100644 ---- a/lib/gpt/src/gpt.c -+++ b/lib/gpt/src/gpt.c -@@ -20,11 +20,15 @@ - #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) -+ * the number of bytes in a Logical Block Address (LBA). It also must be at least -+ * 512. - */ - #ifndef TFM_GPT_BLOCK_SIZE - #error "TFM_GPT_BLOCK_SIZE must be defined if using GPT library!" - #endif -+#if TFM_GPT_BLOCK_SIZE < 512 -+#error "TFM_GPT_BLOCK_SIZE must be at least 512!" -+#endif - - /* Where Master Boot Record (MBR) is on flash */ - #define MBR_LBA 0ULL diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0050-lib-gpt-Expand-table-validation.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0050-lib-gpt-Expand-table-validation.patch deleted file mode 100644 index aefd898b..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/0050-lib-gpt-Expand-table-validation.patch +++ /dev/null @@ -1,352 +0,0 @@ -From bcce0ce881817b36ad52df550bcbf41b4f0d4938 Mon Sep 17 00:00:00 2001 -From: Frazer Carsley -Date: Wed, 15 Apr 2026 15:09:03 +0100 -Subject: [PATCH] lib: gpt: Expand table validation - -It is implied by the UEFI spec 2.10 [1] that the backup GPT must be -located at the end of storage. To this effect, ensure that it is the -largest known LBA value. - -Additionally, it is also implied that the partition entry arrays, both -primary and backup, must be before or after usable space respectively. - -[1] https://uefi.org/specs/UEFI/2.10/05_GUID_Partition_Table_Format.html - -Change-Id: I5042836822f990a21fbf48b19422879384a844aa -Signed-off-by: Frazer Carsley -Upstream-Status: Backport [bcce0ce881817b36ad52df550bcbf41b4f0d4938] ---- - lib/gpt/src/gpt.c | 115 ++++++++++++++++++++ - lib/gpt/unittests/gpt/test_gpt.c | 179 +++++++++++++++++++++++++++++++ - 2 files changed, 294 insertions(+) - -diff --git a/lib/gpt/src/gpt.c b/lib/gpt/src/gpt.c -index cda9fe358..0335befa7 100644 ---- a/lib/gpt/src/gpt.c -+++ b/lib/gpt/src/gpt.c -@@ -229,6 +229,12 @@ 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_backup_gpt_lba(const uint64_t backup_lba, -+ const uint64_t primary_lba, -+ const uint64_t partition_array_end, -+ const struct gpt_header_t *header); -+static psa_status_t validate_array_lba(const uint64_t partition_array_end, -+ const uint64_t usable_lba_start); - 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(const struct gpt_t *table); -@@ -1498,6 +1504,73 @@ static inline void swap_headers(const struct gpt_header_t *src, struct gpt_heade - primary_gpt.header.array_lba); - } - -+/* Validate that the backup GPT LBA is greater than all other LBAs in the header -+ */ -+static psa_status_t validate_backup_gpt_lba(const uint64_t backup_lba, -+ const uint64_t primary_lba, -+ const uint64_t partition_array_end, -+ const struct gpt_header_t *header) -+{ -+ if (backup_lba <= primary_lba) { -+ ERROR("Backup LBA (0x%08x%08x) must be final LBA on flash, " -+ "primary LBA at 0x%08x%08x\n", -+ (uint32_t)(backup_lba >> 32), -+ (uint32_t)(backup_lba), -+ (uint32_t)(primary_lba >> 32), -+ (uint32_t)(primary_lba)); -+ return PSA_ERROR_INVALID_SIGNATURE; -+ } -+ -+ if (backup_lba <= header->first_lba) { -+ ERROR("Backup LBA (0x%08x%08x) must be final LBA on flash, " -+ "first usable LBA at 0x%08x%08x\n", -+ (uint32_t)(backup_lba >> 32), -+ (uint32_t)(backup_lba), -+ (uint32_t)(header->first_lba >> 32), -+ (uint32_t)(header->first_lba)); -+ return PSA_ERROR_INVALID_SIGNATURE; -+ } -+ -+ if (backup_lba <= header->last_lba) { -+ ERROR("Backup LBA (0x%08x%08x) must be final LBA on flash, " -+ "last usable LBA at 0x%08x%08x\n", -+ (uint32_t)(backup_lba >> 32), -+ (uint32_t)(backup_lba), -+ (uint32_t)(header->last_lba >> 32), -+ (uint32_t)(header->last_lba)); -+ return PSA_ERROR_INVALID_SIGNATURE; -+ } -+ -+ if (backup_lba <= partition_array_end) { -+ ERROR("Backup LBA (0x%08x%08x) must be final LBA on flash, " -+ "partition array ends at LBA at 0x%08x%08x\n", -+ (uint32_t)(backup_lba >> 32), -+ (uint32_t)(backup_lba), -+ (uint32_t)(partition_array_end >> 32), -+ (uint32_t)(partition_array_end)); -+ return PSA_ERROR_INVALID_SIGNATURE; -+ } -+ -+ return PSA_SUCCESS; -+} -+ -+/* Validate partition array is outside the area of usable flash */ -+static psa_status_t validate_array_lba(const uint64_t partition_array_end, -+ const uint64_t usable_lba_start) -+{ -+ if (partition_array_end >= usable_lba_start) { -+ ERROR("GPT partition array must not be in usable space: " -+ "0x%08x%08x >= 0x%08x%08x\n", -+ (uint32_t)(partition_array_end >> 32), -+ (uint32_t)partition_array_end, -+ (uint32_t)(usable_lba_start >> 32), -+ (uint32_t)usable_lba_start); -+ return PSA_ERROR_INVALID_SIGNATURE; -+ } -+ -+ return PSA_SUCCESS; -+} -+ - /* Validates a specific GPT. */ - static psa_status_t validate_table(struct gpt_t *table, bool is_primary) - { -@@ -1564,6 +1637,48 @@ static psa_status_t validate_table(struct gpt_t *table, bool is_primary) - return PSA_ERROR_INVALID_SIGNATURE; - } - -+ /* Check the backup LBA is greater than all other LBAs. Check also -+ * the partition array cannot be overritten by data by ensuring -+ * that it is not between the first and last usable LBAs -+ */ -+ if (is_primary) { -+ psa_status_t ret = validate_backup_gpt_lba( -+ header->backup_lba, -+ header->current_lba, -+ partition_entry_lba(table, header->num_partitions - 1), -+ header); -+ if (ret != PSA_SUCCESS) { -+ return ret; -+ } -+ -+ /* Go to the final LBA of the partition array, including unused entries */ -+ ret = validate_array_lba( -+ partition_entry_lba(table, header->num_partitions - 1), -+ header->first_lba); -+ if (ret != PSA_SUCCESS) { -+ return ret; -+ } -+ } else { -+ psa_status_t ret = validate_backup_gpt_lba( -+ header->current_lba, -+ header->backup_lba, -+ partition_entry_lba(table, header->num_partitions - 1), -+ header); -+ if (ret != PSA_SUCCESS) { -+ return ret; -+ } -+ -+ /* To flip the condition, negate the parameters passed: it becomes -+ * -array_lba >= -last_lba (equivalent to) array_lba < last_lba -+ * (equivalent to) last_lba >= array_lba. This is because the backup array is -+ * after the last_lba -+ */ -+ ret = validate_array_lba(~(header->array_lba), ~(header->last_lba)); -+ if (ret != PSA_SUCCESS) { -+ return ret; -+ } -+ } -+ - if (is_primary) { - /* Any time the primary table is considered valid, cache the backup - * LBA field -diff --git a/lib/gpt/unittests/gpt/test_gpt.c b/lib/gpt/unittests/gpt/test_gpt.c -index db897b967..bd161ec74 100644 ---- a/lib/gpt/unittests/gpt/test_gpt.c -+++ b/lib/gpt/unittests/gpt/test_gpt.c -@@ -493,6 +493,185 @@ void test_gpt_validate_should_failWhenArrayCrcBad(void) - TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(false)); - } - -+void test_gpt_validate_should_failWhenBackupLbaNotAtEndOfDisk(void) -+{ -+ /* First test when the backup lba is before usable disk */ -+ test_header.backup_lba = test_header.first_lba - 1; -+ 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)); -+ -+ /* Then test when the backup is before in usable disk space */ -+ test_header.backup_lba = test_header.first_lba; -+ setup_test_gpt(); -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true)); -+ -+ test_header.backup_lba = test_header.first_lba + 1; -+ setup_test_gpt(); -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true)); -+ -+ test_header.backup_lba = test_header.last_lba - 1; -+ setup_test_gpt(); -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true)); -+ -+ test_header.backup_lba = test_header.last_lba; -+ setup_test_gpt(); -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true)); -+ -+ /* Finally, test when the backup is before the end of the partition entry array */ -+ test_header.backup_lba = test_header.array_lba - 1; -+ setup_test_gpt(); -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true)); -+ -+ /* For this scenario, manually setup the backup header so that the array LBA -+ * (also the backup header LBA) is valid on init and can then be validated -+ * with gpt_validate -+ */ -+ test_header.backup_lba = test_header.array_lba; -+ -+ /* Expect first a valid MBR read */ -+ register_mocked_read(&test_mbr, sizeof(test_mbr)); -+ -+ /* Expect a GPT header read second */ -+ register_mocked_read(&test_header, sizeof(test_header)); -+ -+ /* Expect third each partition is read to find the number in use. This is -+ * also the backup header, which will be cached -+ */ -+ setup_backup_gpt(); -+ -+ TEST_ASSERT_EQUAL(PSA_SUCCESS, gpt_init(&mock_driver, TEST_MAX_PARTITIONS)); -+ -+ /* Backup partition array read for 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 gpt header */ -+ struct gpt_header_t backup_header; -+ test_header.backup_lba = test_header.first_lba - 1; -+ MAKE_BACKUP_HEADER(backup_header, test_header); -+ -+ setup_test_gpt(); -+ 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_validate(false)); -+ -+ test_header.backup_lba = backup_header.first_lba; -+ backup_header.current_lba = backup_header.first_lba; -+ setup_test_gpt(); -+ 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_validate(false)); -+ -+ test_header.backup_lba = backup_header.first_lba + 1; -+ backup_header.current_lba = backup_header.first_lba + 1; -+ setup_test_gpt(); -+ 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_validate(false)); -+ -+ test_header.backup_lba = backup_header.last_lba - 1; -+ backup_header.current_lba = backup_header.last_lba - 1; -+ setup_test_gpt(); -+ 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_validate(false)); -+ -+ test_header.backup_lba = backup_header.last_lba; -+ backup_header.current_lba = backup_header.last_lba; -+ setup_test_gpt(); -+ 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_validate(false)); -+ -+ test_header.backup_lba = backup_header.array_lba - 1; -+ backup_header.current_lba = backup_header.array_lba - 1; -+ setup_test_gpt(); -+ 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_validate(false)); -+ -+ test_header.backup_lba = backup_header.array_lba; -+ backup_header.current_lba = backup_header.array_lba; -+ setup_test_gpt(); -+ register_mocked_read(&backup_header, sizeof(backup_header)); -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(false)); -+} -+ -+void test_gpt_validate_should_failWhenPartitionArrayInUsableDiskSpace(void) -+{ -+ /* First test when the primary partition array is in usable disk space */ -+ test_header.array_lba = test_header.first_lba; -+ 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)); -+ -+ test_header.array_lba = test_header.first_lba + 1; -+ setup_test_gpt(); -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true)); -+ -+ test_header.array_lba = test_header.last_lba - 1; -+ setup_test_gpt(); -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true)); -+ -+ test_header.array_lba = test_header.last_lba; -+ setup_test_gpt(); -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true)); -+ -+ /* Then test when the primary partition array is after usable disk space */ -+ test_header.array_lba = test_header.last_lba + 1; -+ setup_test_gpt(); -+ register_mocked_read(&test_partition_array, sizeof(test_partition_array)); -+ TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, gpt_validate(true)); -+ -+ /* Now do the backup gpt header, ensuring it is always after usable space */ -+ struct gpt_header_t backup_header; -+ MAKE_BACKUP_HEADER(backup_header, test_header); -+ -+ backup_header.array_lba = test_header.first_lba - 1; -+ setup_test_gpt(); -+ 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_validate(false)); -+ -+ /* Then test that the backup partition array is after usable disk space */ -+ backup_header.array_lba = test_header.first_lba; -+ setup_test_gpt(); -+ 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_validate(false)); -+ -+ backup_header.array_lba = test_header.first_lba + 1; -+ setup_test_gpt(); -+ 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_validate(false)); -+ -+ backup_header.array_lba = test_header.last_lba - 1; -+ setup_test_gpt(); -+ 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_validate(false)); -+ -+ backup_header.array_lba = test_header.last_lba; -+ setup_test_gpt(); -+ 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_validate(false)); -+} -+ - void test_gpt_restore_should_restorePrimaryFromBackup(void) - { - /* Start with a valid GPT */ diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0001-Build-Fix-compiler-warnings.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0001-Build-Fix-compiler-warnings.patch deleted file mode 100644 index 9fa1c42a..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0001-Build-Fix-compiler-warnings.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 6391a6189ee2024f0ef956f56373f79128576230 Mon Sep 17 00:00:00 2001 -From: Maulik Patel -Date: Tue, 23 Sep 2025 21:26:44 +0100 -Subject: [PATCH] Build: Fix compiler warnings - -- Add header crypto_hw for crypto_hw_apply_debug_permissions() -- Add header int_com_port_driver.h for IComPortRxIntInit() -- Move psa_adac_platform_init() declaration to psa_adac_platform.h -- Add include path for psa-adac/transport_layer/transports/sdc-600 - -Signed-off-by: Maulik Patel -Change-Id: I34f774a9843f7a3a62ad447fa0ae607184bd800a - -Upstream-Status: Backport [6391a6189ee2024f0ef956f56373f79128576230] -Signed-off-by: Jon Mason - ---- - .../platform/arm/corstone1000/CMakeLists.txt | 2 ++ - .../platform/arm/corstone1000/corstone1000.c | 7 ++++++- - .../platform/arm/corstone1000/include/platform/platform.h | 1 - - .../platform/arm/corstone1000/include/psa_adac_platform.h | 6 ++++++ - .../platform/arm/rse/common/CMakeLists.txt | 1 + - .../platform/arm/rse/common/include/platform/platform.h | 1 - - .../platform/arm/rse/common/include/psa_adac_platform.h | 7 +++++++ - .../platform/arm/rse/common/psa_adac_platform.c | 5 +++++ - 8 files changed, 27 insertions(+), 3 deletions(-) - -diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/CMakeLists.txt b/target/trusted-firmware-m/platform/arm/corstone1000/CMakeLists.txt -index c36259e0b31f..604c9b72745d 100644 ---- a/target/trusted-firmware-m/platform/arm/corstone1000/CMakeLists.txt -+++ b/target/trusted-firmware-m/platform/arm/corstone1000/CMakeLists.txt -@@ -20,6 +20,8 @@ target_include_directories(${PROJECT_NAME} - ${CMAKE_CURRENT_SOURCE_DIR} - ${PSA_ADAC_MBEDTLS_INCLUDE} - ${PSA_ADAC_ROOT}/transport_layer/transports -+ ${PSA_ADAC_ROOT}/transport_layer/transports/sdc-600 -+ - ) - - target_compile_definitions(${PROJECT_NAME} -diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/corstone1000.c b/target/trusted-firmware-m/platform/arm/corstone1000/corstone1000.c -index e629eed97236..e979b3246e12 100644 ---- a/target/trusted-firmware-m/platform/arm/corstone1000/corstone1000.c -+++ b/target/trusted-firmware-m/platform/arm/corstone1000/corstone1000.c -@@ -12,6 +12,11 @@ - #include "platform/msg_interface.h" - #include "demo-anchors.h" - #include -+#include "crypto_hw.h" -+ -+#ifdef PSA_ADAC_AS_TFM_RUNTIME_SERVICE -+#include "int_com_port_driver.h" -+#endif /* PSA_ADAC_AS_TFM_RUNTIME_SERVICE */ - - extern uint8_t discovery_template[]; - extern size_t discovery_template_len; -@@ -70,7 +75,7 @@ int psa_adac_platform_check_certificate(uint8_t *crt, size_t crt_size) - - int psa_adac_to_tfm_apply_permissions(uint8_t permissions_mask[16]) - { -- /* This implementation only support coarse-grained secure debug -+ /* This implementation only support coarse-grained secure debug - * unlock (closed/open). Fine-grained access-control can be - * supported by defining a mapping from permissions_mask to - * dcu_reg_values. -diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/include/platform/platform.h b/target/trusted-firmware-m/platform/arm/corstone1000/include/platform/platform.h -index e99d0d55f624..82b416f5f67f 100644 ---- a/target/trusted-firmware-m/platform/arm/corstone1000/include/platform/platform.h -+++ b/target/trusted-firmware-m/platform/arm/corstone1000/include/platform/platform.h -@@ -31,7 +31,6 @@ adac_status_t psa_adac_change_life_cycle_state(uint8_t *input, size_t input_size - void psa_adac_close_session(void); - void psa_adac_resume(void); - void psa_adac_platform_lock(void); --void psa_adac_platform_init(void); - int psa_adac_detect_debug_request(void); - void psa_adac_acknowledge_debug_request(void); - -diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/include/psa_adac_platform.h b/target/trusted-firmware-m/platform/arm/corstone1000/include/psa_adac_platform.h -index 26f10f8999ca..2ae4569f5ff1 100644 ---- a/target/trusted-firmware-m/platform/arm/corstone1000/include/psa_adac_platform.h -+++ b/target/trusted-firmware-m/platform/arm/corstone1000/include/psa_adac_platform.h -@@ -30,5 +30,11 @@ int tfm_to_psa_adac_corstone1000_secure_debug(uint8_t *secure_debug_rotpk, uint3 - */ - int psa_adac_to_tfm_apply_permissions(uint8_t permissions_mask[16]); - -+/* -+ * Platform initialization function for PSA ADAC. -+ * This function should be called during runtime service init to initialize -+ * the PSA ADAC platform-specific components. -+ */ -+void psa_adac_platform_init(void); - - #endif /* __PSA_ADAC_PLATFORM_H__ */ -diff --git a/target/trusted-firmware-m/platform/arm/rse/common/CMakeLists.txt b/target/trusted-firmware-m/platform/arm/rse/common/CMakeLists.txt -index 67214bb3f354..d1b9718a8183 100644 ---- a/target/trusted-firmware-m/platform/arm/rse/common/CMakeLists.txt -+++ b/target/trusted-firmware-m/platform/arm/rse/common/CMakeLists.txt -@@ -23,6 +23,7 @@ target_include_directories(${PROJECT_NAME} - ${PSA_ADAC_MBEDTLS_INCLUDE} - ${PSA_ADAC_ROOT}/transport_layer/transports - ${TFM_SRC_DIR}/platform/ext/target/arm/rse/common/partition -+ ${PSA_ADAC_ROOT}/transport_layer/transports/sdc-600 - ) - - target_compile_definitions(${PROJECT_NAME} -diff --git a/target/trusted-firmware-m/platform/arm/rse/common/include/platform/platform.h b/target/trusted-firmware-m/platform/arm/rse/common/include/platform/platform.h -index 57044f05a67a..afd4b3033a4b 100644 ---- a/target/trusted-firmware-m/platform/arm/rse/common/include/platform/platform.h -+++ b/target/trusted-firmware-m/platform/arm/rse/common/include/platform/platform.h -@@ -32,7 +32,6 @@ void psa_adac_resume(void); - void psa_adac_platform_lock(void); - int psa_adac_platform_check_token(uint8_t *token, size_t token_size); - int psa_adac_platform_check_certificate(uint8_t *crt, size_t crt_size); --void psa_adac_platform_init(void); - int psa_adac_detect_debug_request(void); - void psa_adac_acknowledge_debug_request(void); - int psa_adac_apply_permissions(uint8_t permissions_mask[16]); -diff --git a/target/trusted-firmware-m/platform/arm/rse/common/include/psa_adac_platform.h b/target/trusted-firmware-m/platform/arm/rse/common/include/psa_adac_platform.h -index a47788566aec..3e1dc73c4e0e 100644 ---- a/target/trusted-firmware-m/platform/arm/rse/common/include/psa_adac_platform.h -+++ b/target/trusted-firmware-m/platform/arm/rse/common/include/psa_adac_platform.h -@@ -34,6 +34,13 @@ int tfm_to_psa_adac_rse_secure_debug(uint8_t *secure_debug_rotpk, uint32_t len); - */ - int psa_adac_to_tfm_apply_permissions(uint8_t permissions_mask[16]); - -+/* -+ * Platform initialization function for PSA ADAC. -+ * This function should be called during runtime service init to initialize -+ * the PSA ADAC platform-specific components. -+ */ -+void psa_adac_platform_init(void); -+ - #ifdef __cplusplus - } - #endif -diff --git a/target/trusted-firmware-m/platform/arm/rse/common/psa_adac_platform.c b/target/trusted-firmware-m/platform/arm/rse/common/psa_adac_platform.c -index fa2e7c023ef4..5c5cfd1529a3 100644 ---- a/target/trusted-firmware-m/platform/arm/rse/common/psa_adac_platform.c -+++ b/target/trusted-firmware-m/platform/arm/rse/common/psa_adac_platform.c -@@ -21,6 +21,11 @@ - #include "rse_debug_after_reset.h" - #include "lcm_drv.h" - #include "device_definition.h" -+ -+#ifdef PSA_ADAC_AS_TFM_RUNTIME_SERVICE -+#include "int_com_port_driver.h" -+#endif /* PSA_ADAC_AS_TFM_RUNTIME_SERVICE */ -+ - #define ROTPK_ANCHOR_ALG PSA_ALG_SHA_512 - #define UINT8_SIZE_IN_BITS 8 - diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0002-Fix-psa_key_handle_t-initialization.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0002-Fix-psa_key_handle_t-initialization.patch deleted file mode 100644 index ea171e2a..00000000 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0002-Fix-psa_key_handle_t-initialization.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 972bf711ad884607409c225f9338bf25206e29e8 Mon Sep 17 00:00:00 2001 -From: Bence Balogh -Date: Wed, 31 Jul 2024 15:56:51 +0200 -Subject: [PATCH] Fix psa_key_handle_t initialization - -If the MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER macro is defined in the -mbedcrypto configuration header file then the psa_key_handle_t is a -struct. In this case, it is defined in the used configuration header -so the struct cannot be initialized with -1. - -Signed-off-by: Bence Balogh -Upstream-Status: Inappropriate [mbedcrypto configs have to be fixed to build secure-debug mps3 without this patch] ---- - psa_crypto/adac_crypto_psa_mac.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/psa_crypto/adac_crypto_psa_mac.c b/psa_crypto/adac_crypto_psa_mac.c -index 046fef7..93ab8f9 100644 ---- a/psa_crypto/adac_crypto_psa_mac.c -+++ b/psa_crypto/adac_crypto_psa_mac.c -@@ -198,7 +198,7 @@ psa_status_t psa_adac_verify_mac(uint8_t key_type, - size_t mac_size) - { - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; -- psa_key_handle_t handle = -1; -+ psa_key_handle_t handle = {0}; - psa_status_t ret = PSA_ERROR_NOT_SUPPORTED; - psa_key_type_t type = 0; - size_t bits = 0; --- -2.25.1 - diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0003-cmake-Update-psa_adac_psa_crypto-dependencies.patch b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0002-cmake-Update-psa_adac_psa_crypto-dependencies.patch similarity index 100% rename from meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0003-cmake-Update-psa_adac_psa_crypto-dependencies.patch rename to meta-arm-bsp/recipes-bsp/trusted-firmware-m/files/corstone1000/psa-adac/0002-cmake-Update-psa_adac_psa_crypto-dependencies.patch diff --git a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/trusted-firmware-m-corstone1000.inc b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/trusted-firmware-m-corstone1000.inc index 2f96cb90..0ecb75a2 100644 --- a/meta-arm-bsp/recipes-bsp/trusted-firmware-m/trusted-firmware-m-corstone1000.inc +++ b/meta-arm-bsp/recipes-bsp/trusted-firmware-m/trusted-firmware-m-corstone1000.inc @@ -32,75 +32,27 @@ EXTRA_OECMAKE:append:corstone1000-mps3 = " -DPLATFORM_PSA_ADAC_SOURCE_PATH=${S}/ FILESEXTRAPATHS:prepend := "${THISDIR}/files:" SRC_URI:append:corstone1000 = " \ - file://0001-arm-trusted-firmware-m-disable-address-warnings-into.patch \ - file://0002-Platform-CS1000-Remove-unused-BL1-files.patch \ - file://0003-Platform-Corstone1000-Fix-BL1-compiler-switch-and-re.patch \ - file://0004-CC312-alignment-of-cc312-differences-between-fvp-and.patch \ - file://0005-Platform-Corstone1000-Enable-FWU-partition.patch \ - file://0006-Platform-Corstone1000-Implement-Bootloader-Abstracti.patch \ - file://0007-Platform-Corstone1000-Increase-buffer-sizes.patch \ - file://0008-Platform-Corstone1000-Remove-duplicate-configuration.patch \ - file://0009-plat-corstone1000-Add-support-for-Cortex-A320-varian.patch \ - file://0010-Corstone-1000-Enable-different-DRBG-configurations.patch \ - file://0011-bl2-corstone-1000-Remove-psa_adac_to_tfm_apply_permi.patch \ - file://0012-bl2-corstone-1000-secure-debug-waiting-in-CM-LCS.patch \ - file://0013-Build-adjust-CS1000-platform-for-GCC-v14.2.patch \ - file://0014-Workaround-compile-errors-in-AES.patch \ - file://0015-CC312-Add-barrier-before-first-AO-lock-write.patch \ - file://0016-Platform-CS1K-make-mutlicore-support-platform-generi.patch \ - file://0017-lib-efi_guid-Added-EFI-GUID-library.patch \ - file://0018-lib-efi_soft_crc-Added-EFI-CRC-library.patch \ - file://0019-lib-gpt-Implemented-generic-GPT-parser-for-flash.patch \ - file://0020-lib-gpt-Expanded-how-GPT-partition-can-be-identified.patch \ - file://0021-lib-gpt-Added-operations-to-modify-partitions.patch \ - file://0022-lib-gpt-Added-operation-to-move-entry.patch \ - file://0023-lib-gpt-Added-ability-to-create-and-remove-partition.patch \ - file://0024-lib-gpt-Added-table-validation-operations.patch \ - file://0025-lib-gpt-Added-defragmentation-operation.patch \ - file://0026-lib-GPT-Fix-cppcheck-warnings.patch \ - file://0027-lib-efi_guid-Remove-unecessary-include-folder.patch \ - file://0028-lib-efi_guid-Correct-included-folder.patch \ - file://0029-lib-efi_soft_crc-Correct-include-directory.patch \ - file://0030-lib-gpt-Add-missing-link-library.patch \ - file://0031-lib-gpt-Correct-variable-name-used.patch \ - file://0032-lib-gpt-Correct-include-directory.patch \ - file://0033-lib-gpt-Move-contents-of-CMake-config-file.patch \ - file://0034-plat-cs1k-Fixed-formatting-errors.patch \ - file://0035-plat-cs1k-Removed-unused-variables.patch \ - file://0036-plat-cs1k-Fixed-bad-function-returns.patch \ - file://0037-plat-cs1k-Improved-logging-in-function.patch \ - file://0038-plat-cs1k-Remove-unused-function.patch \ - file://0039-plat-cs1k-Reduce-BL1-binary-size.patch \ - file://0040-plat-cs1k-Update-license-identifier.patch \ - file://0041-plat-cs1k-Changed-to-use-new-GPT-library.patch \ - file://0042-plat-cs1k-Move-variable-from-stack-to-data.patch \ - file://0043-plat-cs1k-Create-and-remove-FWU-image-partitions.patch \ - file://0044-plat-cs1k-Derive-host-base-addresses-from-offsets.patch \ - file://0045-plat-cs1k-Drive-NPU-via-external-system-reset-contro.patch \ - file://0046-lib-gpt-Fix-final-entry-not-being-removed.patch \ - file://0047-lib-gpt-Replace-warnings-with-errors.patch \ - file://0048-lib-gpt-Enforce-entry-size-of-128-bytes.patch \ - file://0049-lib-gpt-Ensure-block-size-complies-with-spec.patch \ - file://0050-lib-gpt-Expand-table-validation.patch \ - file://0051-lib-gpt-Show-intent-of-GUIDs-in-unittests-more-clear.patch \ - file://0052-lib-gpt-Provide-macro-identifying-free-space.patch \ - file://0053-lib-gpt-Add-operation-to-duplicate-entries.patch \ - file://0054-lib-gpt-Consecutively-erase-blocks-when-moving-parti.patch \ - file://0055-lib-gpt-Clarify-API-operation.patch \ - file://0056-lib-gpt-Add-metadata-only-API-operations.patch \ - file://0057-plat-cs1k-Add-flash-erase-protection.patch \ - file://0058-plat-cs1k-Remove-unused-FWU-partitions-upon-version-.patch \ - file://0059-plat-cs1k-Duplicate-old-images-in-FWU.patch \ - file://0060-platform-corstone1000-Increase-FIP-partition-size.patch \ + file://0001-CC312-alignment-of-cc312-differences-between-fvp-and.patch \ + file://0002-Corstone-1000-Enable-different-DRBG-configurations.patch \ + file://0003-bl2-corstone-1000-secure-debug-waiting-in-CM-LCS.patch \ + file://0004-Workaround-compile-errors-in-AES.patch \ + file://0005-plat-cs1k-Removed-unused-variables.patch \ + file://0006-lib-gpt-Show-intent-of-GUIDs-in-unittests-more-clear.patch \ + file://0007-lib-gpt-Provide-macro-identifying-free-space.patch \ + file://0008-lib-gpt-Add-operation-to-duplicate-entries.patch \ + file://0009-lib-gpt-Consecutively-erase-blocks-when-moving-parti.patch \ + file://0010-lib-gpt-Clarify-API-operation.patch \ + file://0011-lib-gpt-Add-metadata-only-API-operations.patch \ + file://0012-plat-cs1k-Add-flash-erase-protection.patch \ + file://0013-plat-cs1k-Remove-unused-FWU-partitions-upon-version-.patch \ + file://0014-plat-cs1k-Duplicate-old-images-in-FWU.patch \ + file://0015-platform-corstone1000-Increase-FIP-partition-size.patch \ " -SRCREV_tfm-psa-adac:corstone1000 = "f2809ae231be33a1afcd7714f40756c67d846c88" FILESEXTRAPATHS:prepend:corstone1000-mps3 := "${THISDIR}/files/corstone1000/psa-adac:" SRC_URI:append:corstone1000-mps3 = " \ file://0001-PSA-revert-header-versions.patch;patchdir=external/tfm-psa-adac \ - file://0002-Fix-psa_key_handle_t-initialization.patch;patchdir=external/tfm-psa-adac \ - file://0003-cmake-Update-psa_adac_psa_crypto-dependencies.patch;patchdir=external/tfm-psa-adac \ - file://0001-Build-Fix-compiler-warnings.patch;patchdir=external/tfm-psa-adac \ + file://0002-cmake-Update-psa_adac_psa_crypto-dependencies.patch;patchdir=external/tfm-psa-adac \ " create_bl1_image(){