mirror of
https://git.yoctoproject.org/meta-arm
synced 2026-05-07 04:58:57 +00:00
arm-bsp/trusted-firmware-m:cs1k: Use new GPT duplicate functionality
Uses the new GPT duplicate operation during a firmware update. This also adds flash erase protections so that the operation is not too slow and erasing flash multiple times redundantly. Signed-off-by: Frazer Carsley <frazer.carsley@arm.com> Signed-off-by: Jon Mason <jon.mason@arm.com>
This commit is contained in:
committed by
Jon Mason
parent
1eaa431ff3
commit
78354ba272
+98
@@ -0,0 +1,98 @@
|
||||
From 60277832aa6d4a205a5b1180f0513de0eb7c84c6 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Tue, 17 Mar 2026 11:05:45 +0000
|
||||
Subject: [PATCH] plat: cs1k: Add flash erase protection
|
||||
|
||||
The GPT library deals in blocks, whereas flash deals in sectors. On
|
||||
cs1k, eight blocks make up a sector. So, when the GPT library requests a
|
||||
block erase from the platform driver, it actually erases the entire
|
||||
sector, and then rewrites the data that was there for the blocks that
|
||||
weren't being erased.
|
||||
|
||||
This means that if all eight blocks in a sector were erased in a row,
|
||||
then the same sector would be erased eight times, which is both slow and
|
||||
also redundant, wearing out the flash device without need. These
|
||||
protections prevent flash erasure if the data is already equal to the
|
||||
erased value.
|
||||
|
||||
Change-Id: Id8efe515647f45ac8e65cc95ef1bf58f9160aca2
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/50259/1]
|
||||
---
|
||||
.../ext/target/arm/corstone1000/io/io_gpt.c | 42 +++++++++++++++++--
|
||||
1 file changed, 39 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/platform/ext/target/arm/corstone1000/io/io_gpt.c b/platform/ext/target/arm/corstone1000/io/io_gpt.c
|
||||
index 513c77016..f7c3d79d2 100644
|
||||
--- a/platform/ext/target/arm/corstone1000/io/io_gpt.c
|
||||
+++ b/platform/ext/target/arm/corstone1000/io/io_gpt.c
|
||||
@@ -53,6 +53,32 @@ static uint8_t sector_buf[FLASH_SECTOR_SIZE];
|
||||
/* From io_gpt.h - the driver given to the GPT library */
|
||||
struct gpt_flash_driver_t io_gpt_flash_driver = {0};
|
||||
|
||||
+/* Read the bytes that need to be erased. If they are already erased_value,
|
||||
+ * report that an erase is not required. This is to reduce the number of flash
|
||||
+ * erase cyles. If the read fails in any way, report erase required.
|
||||
+ */
|
||||
+static bool erase_required(uint32_t erase_addr,
|
||||
+ size_t num_bytes)
|
||||
+{
|
||||
+ if (num_bytes > FLASH_SECTOR_SIZE) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ int32_t ret = flash_driver->ReadData(erase_addr, sector_buf, num_bytes);
|
||||
+ if (ret < 0 || (uint32_t)ret != num_bytes) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ uint8_t erased_value = flash_driver->GetInfo()->erased_value;
|
||||
+ for (size_t offset = 0; offset < num_bytes; ++offset) {
|
||||
+ if (sector_buf[offset] != erased_value) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
/* 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
|
||||
@@ -61,6 +87,10 @@ struct gpt_flash_driver_t io_gpt_flash_driver = {0};
|
||||
static gpt_flash_err_t partially_erase_sector(uint32_t sector_addr,
|
||||
uint32_t offset)
|
||||
{
|
||||
+ if (!erase_required(sector_addr + offset, TFM_GPT_BLOCK_SIZE)) {
|
||||
+ return GPT_FLASH_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
if (flash_driver->ReadData(
|
||||
sector_addr,
|
||||
sector_buf,
|
||||
@@ -139,6 +169,10 @@ static ssize_t flash_erase(uint64_t lba, size_t num_blocks)
|
||||
|
||||
/* Whole sector erases until last sector */
|
||||
for (size_t i = 0; i < num_sectors - 1; ++i) {
|
||||
+ if (!erase_required(erase_addr + i * FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
int32_t ret = flash_driver->EraseSector(erase_addr + i * FLASH_SECTOR_SIZE);
|
||||
if (ret != ARM_DRIVER_OK) {
|
||||
return i;
|
||||
@@ -146,9 +180,11 @@ static ssize_t flash_erase(uint64_t lba, size_t num_blocks)
|
||||
}
|
||||
|
||||
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;
|
||||
+ /* Fully erase final sector if required */
|
||||
+ if (erase_required(last_erase_addr, FLASH_SECTOR_SIZE)) {
|
||||
+ if (flash_driver->EraseSector(last_erase_addr) != ARM_DRIVER_OK) {
|
||||
+ return (num_sectors - 1) * LBAS_PER_SECTOR;
|
||||
+ }
|
||||
}
|
||||
} else {
|
||||
/* Partial erase of final sector */
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
From 281f6799d6de19e63cbcf175ad848b8c8f2cc220 Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Fri, 10 Apr 2026 17:15:36 +0100
|
||||
Subject: [PATCH] plat: cs1k: Remove unused FWU partitions upon version
|
||||
rejection
|
||||
|
||||
If a firmware update (FWU) is attempted and the version of any image is
|
||||
lower or equal to the current version, the entire capsule is rejected
|
||||
and the previous bank used to continue booting. The partitions created
|
||||
during staging for the to-be images therefore can be removed and the
|
||||
space free'd up.
|
||||
|
||||
Change-Id: I9b74c2ed5efee938c14dbdd0380d8d094e71c10e
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/50260/1]
|
||||
---
|
||||
.../bootloader/mcuboot/tfm_mcuboot_fwu.c | 108 ++++++++++++------
|
||||
1 file changed, 75 insertions(+), 33 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 d85590c71..557e48d07 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
|
||||
@@ -1105,6 +1105,54 @@ static psa_status_t erase_image(uint32_t image_offset, uint32_t image_size)
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
+#ifndef BL1_BUILD
|
||||
+/* stale index is the index of the partition to remove within the partition entry
|
||||
+ * array, which could be representing either bank 0 or bank 1. name_index is the
|
||||
+ * index of partition to remove within the fwu_images image_names index, which is
|
||||
+ * fixed at compile time in the structure
|
||||
+ */
|
||||
+static psa_status_t remove_all_stale_partitions(const uint32_t stale_index,
|
||||
+ const uint32_t name_index)
|
||||
+{
|
||||
+ psa_status_t ret;
|
||||
+
|
||||
+ 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), stale_index, &part);
|
||||
+
|
||||
+ if (ret == PSA_ERROR_DOES_NOT_EXIST) {
|
||||
+ FWU_LOG_MSG("%s: Unable to find partition '%s', skipping removal\r\n",
|
||||
+ __func__, fwu_image[i].image_names[name_index]);
|
||||
+ continue;
|
||||
+ } 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[name_index]);
|
||||
+ return ret;
|
||||
+ } else if (ret < 0) {
|
||||
+ FWU_LOG_MSG("%s: Unable to read partition '%s'\r\n",
|
||||
+ __func__, fwu_image[i].image_names[name_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[name_index]);
|
||||
+ return ret;
|
||||
+ } else if (ret < 0) {
|
||||
+ FWU_LOG_MSG("%s: Unable to remove partition '%s'\r\n",
|
||||
+ __func__, fwu_image[i].image_names[name_index]);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ FWU_LOG_MSG("%s: Removed GPT partition '%s'\r\n",
|
||||
+ __func__, fwu_image[i].image_names[name_index]);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static psa_status_t fwu_select_previous(
|
||||
struct fwu_metadata *metadata,
|
||||
struct fwu_private_metadata *priv_metadata)
|
||||
@@ -1162,40 +1210,12 @@ static psa_status_t fwu_select_previous(
|
||||
|
||||
#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
|
||||
+ * (previous active) 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]);
|
||||
+ ret = remove_all_stale_partitions(1, metadata->previous_active_index);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ return ret;
|
||||
}
|
||||
#endif /* BL1_BUILD */
|
||||
|
||||
@@ -1971,6 +1991,28 @@ 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__);
|
||||
+
|
||||
+#ifndef BL1_BUILD
|
||||
+ /* The FWU process short circuits at this point, so remove all images,
|
||||
+ * effecitvely treating them all as rejected. Ignore return code and
|
||||
+ * in order to return PSA_OPERATION_INCOMPLETE as per PSA FWU API.
|
||||
+ */
|
||||
+ uint32_t previous_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;
|
||||
+ }
|
||||
+
|
||||
+ /* The newer index should be removed as that was just created in the
|
||||
+ * staging phase.
|
||||
+ */
|
||||
+ (void)remove_all_stale_partitions(1, previous_active_index);
|
||||
+#endif
|
||||
ret = PSA_OPERATION_INCOMPLETE;
|
||||
goto out;
|
||||
}
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
From 3c7cb3432084df3b75b6382e543f3fc2352e32cf Mon Sep 17 00:00:00 2001
|
||||
From: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Date: Fri, 13 Mar 2026 13:42:16 +0000
|
||||
Subject: [PATCH] plat: cs1k: Duplicate old images in FWU
|
||||
|
||||
When copying existing partitions during a partial firmware update, the
|
||||
GPT library is now used to duplicate the old partitions and then rename
|
||||
them accordingly. This streamlines the steps of
|
||||
1. creating a new partition for the image to be copied into and
|
||||
2. the copying itself
|
||||
into a single library call.
|
||||
|
||||
Change-Id: Ibd169dcc14ed1c946bbd6c30b6962c89055d0e8e
|
||||
Signed-off-by: Frazer Carsley <frazer.carsley@arm.com>
|
||||
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/50261/1]
|
||||
---
|
||||
.../bootloader/mcuboot/tfm_mcuboot_fwu.c | 144 +++++++++---------
|
||||
1 file changed, 68 insertions(+), 76 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 557e48d07..c48d51b32 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,7 +39,6 @@
|
||||
* 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
|
||||
@@ -2171,94 +2170,24 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifdef BL1_BUILD
|
||||
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;
|
||||
|
||||
+ /* Use offsets directly */
|
||||
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 */
|
||||
+ 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;
|
||||
-#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;
|
||||
- }
|
||||
-
|
||||
- struct partition_entry_t prev_active_part;
|
||||
- ret = gpt_entry_read_by_type(
|
||||
- &(fwu_image[image_index].image_type),
|
||||
- 1,
|
||||
- &prev_active_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[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) {
|
||||
@@ -2270,7 +2199,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, flash_data_buf, data_size);
|
||||
+ 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;
|
||||
@@ -2285,7 +2214,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, flash_data_buf, data_size);
|
||||
+ 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;
|
||||
@@ -2304,6 +2233,69 @@ static psa_status_t copy_image_from_other_bank(int image_index,
|
||||
FWU_LOG_MSG("%s: exit \n\r", __func__);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
+#else
|
||||
+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;
|
||||
+
|
||||
+ /* Use GPT to find and copy the correct image */
|
||||
+ uint32_t bank_offset[NR_OF_FW_BANKS] = {BANK_0_PARTITION_OFFSET, BANK_1_PARTITION_OFFSET};
|
||||
+ uint64_t new_lba =
|
||||
+ (bank_offset[previous_active_index] + fwu_image[image_index].image_offset) / TFM_GPT_BLOCK_SIZE;
|
||||
+
|
||||
+ struct partition_entry_t active_part;
|
||||
+ psa_status_t 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;
|
||||
+ }
|
||||
+
|
||||
+ struct efi_guid_t new_guid;
|
||||
+ ret = gpt_entry_duplicate(&(active_part.partition_guid), new_lba, &new_guid);
|
||||
+ 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) {
|
||||
+ FWU_LOG_MSG("%s: Unable to create partition '%s'\r\n",
|
||||
+ __func__, fwu_image[image_index].image_names[previous_active_index]);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ 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_rename(&new_guid, unicode_name);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ FWU_LOG_MSG("%s: Unable to rename partition to '%s'\r\n",
|
||||
+ __func__, fwu_image[image_index].image_names[previous_active_index]);
|
||||
+
|
||||
+ /* Delete the newly created partition as there is code that relies on the naming */
|
||||
+ ret = gpt_entry_remove(&new_guid);
|
||||
+ if (ret != PSA_SUCCESS) {
|
||||
+ FWU_LOG_MSG("%s: Catastrophic failure: unable to remove duplicate partition '%s'\r\n",
|
||||
+ __func__, fwu_image[image_index].image_names[active_index]);
|
||||
+ }
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ FWU_LOG_MSG("%s: exit \n\r", __func__);
|
||||
+ return PSA_SUCCESS;
|
||||
+}
|
||||
+#endif /* BL1_BUILD */
|
||||
|
||||
static psa_status_t maintain_bank_consistency(void)
|
||||
{
|
||||
@@ -88,6 +88,9 @@ SRC_URI:append:corstone1000 = " \
|
||||
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 \
|
||||
"
|
||||
|
||||
SRCREV_tfm-psa-adac:corstone1000 = "f2809ae231be33a1afcd7714f40756c67d846c88"
|
||||
|
||||
Reference in New Issue
Block a user