Add FWU metadata V2 support
Adds metadata serialization support for the FWU-A V2 metadata
structure.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I482b81a69cadf8c5e60033ab4852858abc298ec6
diff --git a/components/service/fwu/fw_store/banked/metadata_serializer/v2/component.cmake b/components/service/fwu/fw_store/banked/metadata_serializer/v2/component.cmake
new file mode 100644
index 0000000..1a274e3
--- /dev/null
+++ b/components/service/fwu/fw_store/banked/metadata_serializer/v2/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/metadata_serializer_v2.c"
+ )
diff --git a/components/service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.c b/components/service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.c
new file mode 100644
index 0000000..c5a6688
--- /dev/null
+++ b/components/service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <string.h>
+#include <common/uuid/uuid.h>
+#include <protocols/service/fwu/packed-c/metadata_v2.h>
+#include <protocols/service/fwu/packed-c/status.h>
+#include <media/volume/volume.h>
+#include <media/volume/index/volume_index.h>
+#include <service/fwu/agent/fw_directory.h>
+#include <service/fwu/fw_store/banked/bank_tracker.h>
+#include <service/fwu/fw_store/banked/volume_id.h>
+#include <service/fwu/fw_store/banked/metadata_serializer/metadata_serializer.h>
+#include "metadata_serializer_v2.h"
+
+
+static size_t metadata_serializer_size(
+ const struct fw_directory *fw_dir)
+{
+ return
+ sizeof(struct fwu_metadata) +
+ offsetof(struct fwu_fw_store_desc, img_entry) +
+ sizeof(struct fwu_image_entry) * fw_directory_num_images(fw_dir);
+}
+
+static size_t metadata_serializer_max_size(void)
+{
+ return
+ sizeof(struct fwu_metadata) +
+ offsetof(struct fwu_fw_store_desc, img_entry) +
+ sizeof(struct fwu_image_entry) * FWU_MAX_FW_DIRECTORY_ENTRIES;
+}
+
+static int serialize_image_entries(
+ struct fwu_fw_store_desc *fw_store_desc,
+ const struct fw_directory *fw_dir,
+ const struct bank_tracker *bank_tracker)
+{
+ for (size_t image_index = 0; image_index < fw_store_desc->num_images; image_index++) {
+
+ /* Image entry indices in the fw_store_desc correspond to the image index
+ * of the associate entry in the fw_directory.
+ */
+ const struct image_info *image_info =
+ fw_directory_get_image_info(fw_dir, image_index);
+
+ assert(image_info);
+
+ /* Information about storage for the image is retrieved from the configured
+ * volume objects that provide access to the banked storage. Both volumes
+ * are assumed to have the same parent location, identified by the location
+ * uuid.
+ */
+ struct uuid_octets location_uuid = {0};
+ struct fwu_image_entry *entry = &fw_store_desc->img_entry[image_index];
+
+ /* Serialize bank storage info */
+ for (size_t bank_index = 0;
+ bank_index < BANK_SCHEME_NUM_BANKS; bank_index++) {
+
+ struct uuid_octets img_uuid = {0};
+ struct volume *volume = NULL;
+
+ int status = volume_index_find(
+ banked_volume_id(
+ image_info->location_id,
+ banked_usage_id(bank_index)),
+ &volume);
+
+ if (!status && volume) {
+ /* A concrete volume may not support retrieving storage IDs. If
+ * this is the case, volume_get_storage_ids() will return an error,
+ * which is deliberately ignored and UUIDs left in their default state.
+ * To ensure that all banks reflect the same parent location, the
+ * location uuid returned by the volume holding the first bank is
+ * used as the parent.
+ */
+ struct uuid_octets *parent_uuid = (bank_index == 0) ?
+ &location_uuid : NULL;
+
+ volume_get_storage_ids(volume, &img_uuid, parent_uuid);
+ }
+
+ struct fwu_img_bank_info *bank_info = &entry->img_bank_info[bank_index];
+
+ memcpy(bank_info->img_uuid, img_uuid.octets, OSF_UUID_OCTET_LEN);
+ bank_info->reserved = 0;
+ bank_info->accepted = bank_tracker_is_accepted(
+ bank_tracker, bank_index, image_index) ? 1 : 0;
+ }
+
+ /* Serialize per-image UUIDs */
+ memcpy(entry->img_type_uuid,
+ image_info->img_type_uuid.octets, OSF_UUID_OCTET_LEN);
+ memcpy(entry->location_uuid,
+ location_uuid.octets, OSF_UUID_OCTET_LEN);
+ }
+
+ return FWU_STATUS_SUCCESS;
+}
+
+static int serialize_fw_store_desc(
+ const struct fw_directory *fw_dir,
+ const struct bank_tracker *bank_tracker,
+ uint8_t *buf)
+{
+ struct fwu_fw_store_desc *fw_store_desc = (struct fwu_fw_store_desc *)buf;
+
+ fw_store_desc->num_banks = BANK_SCHEME_NUM_BANKS;
+ fw_store_desc->num_images = fw_directory_num_images(fw_dir);
+ fw_store_desc->img_entry_size = sizeof(struct fwu_image_entry);
+ fw_store_desc->bank_entry_size = sizeof(struct fwu_img_bank_info);
+
+ return serialize_image_entries(fw_store_desc, fw_dir, bank_tracker);
+}
+
+static int metadata_serializer_serialize(
+ uint32_t active_index,
+ uint32_t previous_active_index,
+ const struct fw_directory *fw_dir,
+ const struct bank_tracker *bank_tracker,
+ uint8_t *buf,
+ size_t buf_size,
+ size_t *metadata_len)
+{
+ int status = FWU_STATUS_UNKNOWN;
+ size_t serialized_size = metadata_serializer_size(fw_dir);
+
+ *metadata_len = 0;
+
+ if (serialized_size <= buf_size) {
+
+ struct fwu_metadata *metadata = (struct fwu_metadata *)buf;
+
+ /* Serialize metadata header */
+ metadata->crc_32 = 0;
+ metadata->version = 2;
+ metadata->metadata_size = (uint32_t)serialized_size;
+ metadata->header_size = (uint16_t)sizeof(struct fwu_metadata);
+ metadata->active_index = active_index;
+ metadata->previous_active_index = previous_active_index;
+
+ for (unsigned int bank_index = 0;
+ bank_index < FWU_METADATA_V2_NUM_BANK_STATES; bank_index++) {
+
+ if (bank_index < BANK_SCHEME_NUM_BANKS) {
+
+ if (bank_tracker_is_all_accepted(
+ bank_tracker,
+ bank_index,
+ fw_directory_num_images(fw_dir)))
+ metadata->bank_state[bank_index] =
+ FWU_METADATA_V2_BANK_STATE_ACCEPTED;
+ else if (bank_tracker_is_content(
+ bank_tracker,
+ bank_index))
+ metadata->bank_state[bank_index] =
+ FWU_METADATA_V2_BANK_STATE_VALID;
+ else
+ metadata->bank_state[bank_index] =
+ FWU_METADATA_V2_BANK_STATE_INVALID;
+
+ } else
+ metadata->bank_state[bank_index] =
+ FWU_METADATA_V2_BANK_STATE_INVALID;
+ }
+
+ /* Serialize optional fw store descriptor if required */
+ if (serialized_size > metadata->header_size)
+ status = serialize_fw_store_desc(
+ fw_dir,
+ bank_tracker,
+ &buf[metadata->header_size]);
+ else
+ status = FWU_STATUS_SUCCESS;
+
+ if (status == FWU_STATUS_SUCCESS)
+ *metadata_len = serialized_size;
+ }
+
+ return status;
+}
+
+static void metadata_serializer_deserialize_bank_info(
+ struct bank_tracker *bank_tracker,
+ const uint8_t *serialized_metadata,
+ size_t metadata_len)
+{
+ const struct fwu_metadata *metadata = (const struct fwu_metadata *)serialized_metadata;
+
+ /* Sanity check size values in header */
+ if ((metadata->header_size > metadata_len) ||
+ (metadata->metadata_size > metadata_len))
+ return;
+
+ /* Deserialize bank state in header and update bank_tracker to reflect the same state */
+ for (unsigned int bank_index = 0; bank_index < BANK_SCHEME_NUM_BANKS; bank_index++) {
+
+ if (metadata->bank_state[bank_index] == FWU_METADATA_V2_BANK_STATE_ACCEPTED)
+ bank_tracker_set_holds_accepted_content(bank_tracker, bank_index);
+ else if (metadata->bank_state[bank_index] == FWU_METADATA_V2_BANK_STATE_VALID)
+ bank_tracker_set_holds_content(bank_tracker, bank_index);
+ }
+
+ /* If present, deserialize the fw_store_desc */
+ if (metadata->metadata_size >=
+ metadata->header_size + offsetof(struct fwu_fw_store_desc, img_entry)) {
+
+ const struct fwu_fw_store_desc *fw_store_desc =
+ (const struct fwu_fw_store_desc *)(serialized_metadata + metadata->header_size);
+
+ size_t fw_store_desc_size =
+ metadata->metadata_size - metadata->header_size;
+ size_t total_img_entries_size =
+ fw_store_desc_size - offsetof(struct fwu_fw_store_desc, img_entry);
+ size_t per_img_entry_bank_info_size =
+ fw_store_desc->num_banks * fw_store_desc->bank_entry_size;
+
+ /* Sanity check fw_store_desc values */
+ if ((fw_store_desc->img_entry_size <
+ sizeof(struct fwu_image_entry)) ||
+ (fw_store_desc->bank_entry_size <
+ sizeof(struct fwu_img_bank_info)) ||
+ (fw_store_desc->num_banks >
+ BANK_SCHEME_NUM_BANKS) ||
+ (fw_store_desc->img_entry_size <
+ offsetof(struct fwu_image_entry, img_bank_info) +
+ per_img_entry_bank_info_size) ||
+ (fw_store_desc->num_images >
+ FWU_MAX_FW_DIRECTORY_ENTRIES) ||
+ (total_img_entries_size <
+ fw_store_desc->num_images * fw_store_desc->img_entry_size))
+ return;
+
+ /* Deserialize per-image info */
+ for (size_t image_index = 0;
+ image_index < fw_store_desc->num_images; image_index++) {
+
+ const struct fwu_image_entry *image_entry = (const struct fwu_image_entry *)
+ ((const uint8_t *)fw_store_desc->img_entry +
+ image_index * fw_store_desc->img_entry_size);
+
+ for (size_t bank_index = 0;
+ bank_index < fw_store_desc->num_banks; bank_index++) {
+
+ const struct fwu_img_bank_info *bank_info =(const struct fwu_img_bank_info *)
+ ((const uint8_t *)image_entry->img_bank_info +
+ bank_index * fw_store_desc->bank_entry_size);
+
+ if (bank_info->accepted)
+ bank_tracker_accept(bank_tracker, bank_index, image_index);
+ }
+ }
+ }
+}
+
+static void metadata_serializer_deserialize_active_indices(
+ uint32_t *active_index,
+ uint32_t *previous_active_index,
+ const uint8_t *serialized_metadata,
+ size_t metadata_len)
+{
+ const struct fwu_metadata *metadata = (const struct fwu_metadata *)serialized_metadata;
+
+ assert(metadata_len >= sizeof(struct fwu_metadata));
+
+ *active_index = metadata->active_index;
+ *previous_active_index = metadata->previous_active_index;
+}
+
+const struct metadata_serializer *metadata_serializer_v2(void)
+{
+ static const struct metadata_serializer serializer = {
+ metadata_serializer_serialize,
+ metadata_serializer_size,
+ metadata_serializer_max_size,
+ metadata_serializer_deserialize_bank_info,
+ metadata_serializer_deserialize_active_indices
+ };
+
+ return &serializer;
+}
diff --git a/components/service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.h b/components/service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.h
new file mode 100644
index 0000000..c095cc9
--- /dev/null
+++ b/components/service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef METADATA_SERIALIZER_V2_H
+#define METADATA_SERIALIZER_V2_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Interface dependencies
+ */
+struct metadata_serializer;
+
+/**
+ * \brief Return a metadata_serializer for version 2 serialization
+ *
+ */
+const struct metadata_serializer *metadata_serializer_v2(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* METADATA_SERIALIZER_V2_H */
diff --git a/components/service/fwu/test/fwu_dut/fwu_dut.cpp b/components/service/fwu/test/fwu_dut/fwu_dut.cpp
index bfe2cef..7fccd6a 100644
--- a/components/service/fwu/test/fwu_dut/fwu_dut.cpp
+++ b/components/service/fwu/test/fwu_dut/fwu_dut.cpp
@@ -9,6 +9,7 @@
#include <string>
#include <common/endian/le.h>
#include <service/fwu/test/metadata_checker/metadata_checker_v1.h>
+#include <service/fwu/test/metadata_checker/metadata_checker_v2.h>
#include <CppUTest/TestHarness.h>
#include "fwu_dut.h"
@@ -151,6 +152,9 @@
if (m_metadata_version == 1)
return new metadata_checker_v1(metadata_fetcher, num_images);
+ if (m_metadata_version == 2)
+ return new metadata_checker_v2(metadata_fetcher, num_images);
+
/* Unsupported metadata version */
assert(false);
diff --git a/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.cpp b/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.cpp
index 413f0de..89b2a5e 100644
--- a/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.cpp
+++ b/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,13 +7,13 @@
#include <cassert>
#include <service/fwu/test/fwu_client/remote/remote_fwu_client.h>
#include <service/fwu/test/metadata_fetcher/client/client_metadata_fetcher.h>
-#include <service/fwu/test/metadata_checker/metadata_checker_v1.h>
#include "proxy_fwu_dut.h"
proxy_fwu_dut::proxy_fwu_dut(
unsigned int num_locations,
+ unsigned int metadata_version,
fwu_dut *remote_dut) :
- fwu_dut(),
+ fwu_dut(metadata_version),
m_num_locations(num_locations),
m_remote_dut(remote_dut)
{
@@ -52,7 +52,7 @@
fwu_client *fwu_client = new remote_fwu_client;
metadata_fetcher *metadata_fetcher = new client_metadata_fetcher(fwu_client);
- return new metadata_checker_v1(metadata_fetcher, m_num_locations);
+ return fwu_dut::create_metadata_checker(metadata_fetcher, m_num_locations);
}
fwu_client *proxy_fwu_dut::create_fwu_client(void)
diff --git a/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.h b/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.h
index 298da5d..7fe0a81 100644
--- a/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.h
+++ b/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,10 +23,12 @@
* \brief proxy_fwu_dut constructor
*
* \param[in] num_locations The number of updatable fw locations
+ * \param[in] metadata_version FWU metadata version supported by bootloader
* \param[in] remote_dut The associated remote fwu dut
*/
proxy_fwu_dut(
unsigned int num_locations,
+ unsigned int metadata_version,
fwu_dut *remote_dut);
~proxy_fwu_dut();
diff --git a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
index 3ae06de..fded211 100644
--- a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
+++ b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <cassert>
#include <cstring>
#include <sstream>
#include <CppUTest/TestHarness.h>
@@ -14,6 +15,7 @@
#include <service/fwu/installer/installer_index.h>
#include <service/fwu/fw_store/banked/volume_id.h>
#include <service/fwu/fw_store/banked/metadata_serializer/v1/metadata_serializer_v1.h>
+#include <service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.h>
#include <service/fwu/inspector/direct/direct_fw_inspector.h>
#include <service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.h>
#include <service/fwu/test/fwu_client/direct/direct_fwu_client.h>
@@ -22,8 +24,9 @@
sim_fwu_dut::sim_fwu_dut(
unsigned int num_locations,
+ unsigned int metadata_version,
bool allow_partial_updates) :
- fwu_dut(),
+ fwu_dut(metadata_version),
m_is_booted(false),
m_is_first_boot(true),
m_boot_info(),
@@ -130,7 +133,7 @@
/* Performs the generic update agent initialization that occurs on
* each system boot.
*/
- int status = banked_fw_store_init(&m_fw_store, metadata_serializer_v1());
+ int status = banked_fw_store_init(&m_fw_store, select_metadata_serializer());
LONGS_EQUAL(0, status);
status = update_agent_init(
@@ -465,3 +468,19 @@
LONGS_EQUAL(0, status);
}
}
+
+const struct metadata_serializer *sim_fwu_dut::select_metadata_serializer(void) const
+{
+ unsigned int version = metadata_version();
+
+ if (version == 1)
+ return metadata_serializer_v1();
+
+ if (version == 2)
+ return metadata_serializer_v2();
+
+ /* Metadata version not supported */
+ assert(false);
+
+ return NULL;
+}
diff --git a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
index b30e32b..9929733 100644
--- a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
+++ b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -40,10 +40,12 @@
* \brief sim_fwu_dut constructor
*
* \param[in] num_locations The number of updatable fw locations
+ * \param[in] metadata_version FWU metadata version supported by bootloader
* \param[in] allow_partial_updates True if updating a subset of locations is permitted
*/
sim_fwu_dut(
unsigned int num_locations,
+ unsigned int metadata_version,
bool allow_partial_updates = false);
~sim_fwu_dut();
@@ -98,6 +100,8 @@
void install_factory_images(unsigned int num_locations);
void verify_boot_images(unsigned int boot_index);
+ const struct metadata_serializer *select_metadata_serializer(void) const;
+
bool m_is_booted;
bool m_is_first_boot;
struct boot_info m_boot_info;
diff --git a/components/service/fwu/test/fwu_dut_factory/fwu_dut_factory.h b/components/service/fwu/test/fwu_dut_factory/fwu_dut_factory.h
index c0c99af..aac99a7 100644
--- a/components/service/fwu/test/fwu_dut_factory/fwu_dut_factory.h
+++ b/components/service/fwu/test/fwu_dut_factory/fwu_dut_factory.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,6 +30,10 @@
static fwu_dut *create(
unsigned int num_locations,
bool allow_partial_updates = false);
+
+private:
+
+ static const unsigned int FWU_METADATA_VERSION = 2;
};
#endif /* FWU_DUT_FACTORY_H */
diff --git a/components/service/fwu/test/fwu_dut_factory/remote_sim/fwu_dut_factory.cpp b/components/service/fwu/test/fwu_dut_factory/remote_sim/fwu_dut_factory.cpp
index 2e22977..bbd2f45 100644
--- a/components/service/fwu/test/fwu_dut_factory/remote_sim/fwu_dut_factory.cpp
+++ b/components/service/fwu/test/fwu_dut_factory/remote_sim/fwu_dut_factory.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,12 +25,14 @@
/* Construct and set the simulated dut that provides the configured
* device and fwu service provider.
*/
- sim_fwu_dut *sim_dut = new sim_fwu_dut(num_locations, allow_partial_updates);
+ sim_fwu_dut *sim_dut = new sim_fwu_dut(num_locations,
+ FWU_METADATA_VERSION, allow_partial_updates);
fwu_service_context_set_provider(sim_dut->get_service_interface());
/* Construct a proxy_fwu_dut chained to the sim_fwu_dut. On deletion,
* the proxy_fwu_dut deletes the associated sim_fwu_dut.
*/
- return new proxy_fwu_dut(num_locations, sim_dut);
+ return new proxy_fwu_dut(num_locations,
+ FWU_METADATA_VERSION, sim_dut);
}
\ No newline at end of file
diff --git a/components/service/fwu/test/fwu_dut_factory/sim/fwu_dut_factory.cpp b/components/service/fwu/test/fwu_dut_factory/sim/fwu_dut_factory.cpp
index be7dff8..a4e3799 100644
--- a/components/service/fwu/test/fwu_dut_factory/sim/fwu_dut_factory.cpp
+++ b/components/service/fwu/test/fwu_dut_factory/sim/fwu_dut_factory.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,5 +17,6 @@
unsigned int num_locations,
bool allow_partial_updates)
{
- return new sim_fwu_dut(num_locations, allow_partial_updates);
+ return new sim_fwu_dut(num_locations,
+ FWU_METADATA_VERSION, allow_partial_updates);
}
\ No newline at end of file
diff --git a/components/service/fwu/test/metadata_checker/component.cmake b/components/service/fwu/test/metadata_checker/component.cmake
index 033925f..a76655a 100644
--- a/components/service/fwu/test/metadata_checker/component.cmake
+++ b/components/service/fwu/test/metadata_checker/component.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -11,4 +11,5 @@
target_sources(${TGT} PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/metadata_checker.cpp"
"${CMAKE_CURRENT_LIST_DIR}/metadata_checker_v1.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/metadata_checker_v2.cpp"
)
diff --git a/components/service/fwu/test/metadata_checker/metadata_checker_v1.cpp b/components/service/fwu/test/metadata_checker/metadata_checker_v1.cpp
index 57a545e..042226f 100644
--- a/components/service/fwu/test/metadata_checker/metadata_checker_v1.cpp
+++ b/components/service/fwu/test/metadata_checker/metadata_checker_v1.cpp
@@ -4,10 +4,16 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <service/fwu/agent/fw_directory.h>
#include <protocols/service/fwu/packed-c/metadata_v1.h>
#include <CppUTest/TestHarness.h>
#include "metadata_checker_v1.h"
+const size_t metadata_checker_v1::MAX_FWU_METADATA_SIZE =
+ offsetof(struct fwu_metadata, img_entry) +
+ FWU_MAX_FW_DIRECTORY_ENTRIES * sizeof(struct fwu_image_entry);
+
+
metadata_checker_v1::metadata_checker_v1(
metadata_fetcher *metadata_fetcher,
unsigned int num_images) :
diff --git a/components/service/fwu/test/metadata_checker/metadata_checker_v1.h b/components/service/fwu/test/metadata_checker/metadata_checker_v1.h
index f705987..81be66a 100644
--- a/components/service/fwu/test/metadata_checker/metadata_checker_v1.h
+++ b/components/service/fwu/test/metadata_checker/metadata_checker_v1.h
@@ -7,8 +7,6 @@
#ifndef METADATA_CHECKER_V1_H
#define METADATA_CHECKER_V1_H
-#include <service/fwu/agent/fw_directory.h>
-#include <protocols/service/fwu/packed-c/metadata_v1.h>
#include "metadata_checker.h"
/*
@@ -36,9 +34,7 @@
private:
- static const size_t MAX_FWU_METADATA_SIZE =
- offsetof(struct fwu_metadata, img_entry) +
- FWU_MAX_FW_DIRECTORY_ENTRIES * sizeof(struct fwu_image_entry);
+ static const size_t MAX_FWU_METADATA_SIZE;
bool is_all_accepted(unsigned int boot_index) const;
diff --git a/components/service/fwu/test/metadata_checker/metadata_checker_v2.cpp b/components/service/fwu/test/metadata_checker/metadata_checker_v2.cpp
new file mode 100644
index 0000000..dadcba4
--- /dev/null
+++ b/components/service/fwu/test/metadata_checker/metadata_checker_v2.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <service/fwu/agent/fw_directory.h>
+#include <protocols/service/fwu/packed-c/metadata_v2.h>
+#include <CppUTest/TestHarness.h>
+#include "metadata_checker_v2.h"
+
+const size_t metadata_checker_v2::MAX_FWU_METADATA_SIZE =
+ sizeof(struct fwu_metadata) +
+ offsetof(struct fwu_fw_store_desc, img_entry) +
+ sizeof(struct fwu_image_entry) * FWU_MAX_FW_DIRECTORY_ENTRIES;
+
+
+metadata_checker_v2::metadata_checker_v2(
+ metadata_fetcher *metadata_fetcher,
+ unsigned int num_images) :
+ metadata_checker(MAX_FWU_METADATA_SIZE, metadata_fetcher)
+{
+
+}
+
+metadata_checker_v2::~metadata_checker_v2()
+{
+
+}
+
+void metadata_checker_v2::get_active_indices(
+ uint32_t *active_index,
+ uint32_t *previous_active_index)
+{
+ load_metadata();
+
+ struct fwu_metadata *metadata = reinterpret_cast<struct fwu_metadata *>(m_meta_buf);
+
+ *active_index = metadata->active_index;
+ *previous_active_index = metadata->previous_active_index;
+}
+
+void metadata_checker_v2::check_regular(unsigned int boot_index)
+{
+ load_metadata();
+
+ struct fwu_metadata *metadata = reinterpret_cast<struct fwu_metadata *>(m_meta_buf);
+
+ UNSIGNED_LONGS_EQUAL(boot_index, metadata->active_index);
+
+ BYTES_EQUAL(FWU_METADATA_V2_BANK_STATE_ACCEPTED,
+ metadata->bank_state[boot_index]);
+}
+
+void metadata_checker_v2::check_ready_for_staging(unsigned int boot_index)
+{
+ load_metadata();
+
+ struct fwu_metadata *metadata = reinterpret_cast<struct fwu_metadata *>(m_meta_buf);
+
+ UNSIGNED_LONGS_EQUAL(boot_index, metadata->active_index);
+
+ BYTES_EQUAL(FWU_METADATA_V2_BANK_STATE_ACCEPTED,
+ metadata->bank_state[boot_index]);
+ BYTES_EQUAL(FWU_METADATA_V2_BANK_STATE_INVALID,
+ metadata->bank_state[alternate_bank_index(boot_index)]);
+}
+
+void metadata_checker_v2::check_ready_to_activate(unsigned int boot_index)
+{
+ load_metadata();
+
+ struct fwu_metadata *metadata = reinterpret_cast<struct fwu_metadata *>(m_meta_buf);
+
+ UNSIGNED_LONGS_EQUAL(boot_index, metadata->previous_active_index);
+ CHECK_TRUE(metadata->active_index != boot_index);
+
+ BYTES_EQUAL(FWU_METADATA_V2_BANK_STATE_VALID,
+ metadata->bank_state[metadata->active_index]);
+}
+
+void metadata_checker_v2::check_trial(unsigned int boot_index)
+{
+ load_metadata();
+
+ struct fwu_metadata *metadata = reinterpret_cast<struct fwu_metadata *>(m_meta_buf);
+
+ UNSIGNED_LONGS_EQUAL(boot_index, metadata->active_index);
+ CHECK_TRUE(metadata->previous_active_index != boot_index);
+
+ BYTES_EQUAL(FWU_METADATA_V2_BANK_STATE_VALID,
+ metadata->bank_state[boot_index]);
+}
+
+void metadata_checker_v2::check_fallback_to_previous(unsigned int boot_index)
+{
+ load_metadata();
+
+ struct fwu_metadata *metadata = reinterpret_cast<struct fwu_metadata *>(m_meta_buf);
+
+ UNSIGNED_LONGS_EQUAL(boot_index, metadata->previous_active_index);
+ CHECK_TRUE(metadata->active_index != boot_index);
+
+ BYTES_EQUAL(FWU_METADATA_V2_BANK_STATE_ACCEPTED,
+ metadata->bank_state[boot_index]);
+}
+
+unsigned int metadata_checker_v2::alternate_bank_index(unsigned int bank_index)
+{
+ return (bank_index == 0) ? 1 : 0;
+}
\ No newline at end of file
diff --git a/components/service/fwu/test/metadata_checker/metadata_checker_v2.h b/components/service/fwu/test/metadata_checker/metadata_checker_v2.h
new file mode 100644
index 0000000..76e001d
--- /dev/null
+++ b/components/service/fwu/test/metadata_checker/metadata_checker_v2.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef METADATA_CHECKER_V2_H
+#define METADATA_CHECKER_V2_H
+
+#include "metadata_checker.h"
+
+/*
+ * A metadata_checker for FWU-A V2 metadata
+ */
+class metadata_checker_v2 : public metadata_checker
+{
+public:
+
+ metadata_checker_v2(
+ metadata_fetcher *metadata_fetcher,
+ unsigned int num_images);
+
+ virtual ~metadata_checker_v2();
+
+ void get_active_indices(
+ uint32_t *active_index,
+ uint32_t *previous_active_index);
+
+ void check_regular(unsigned int boot_index);
+ void check_ready_for_staging(unsigned int boot_index);
+ void check_ready_to_activate(unsigned int boot_index);
+ void check_trial(unsigned int boot_index);
+ void check_fallback_to_previous(unsigned int boot_index);
+
+private:
+
+ static unsigned int alternate_bank_index(unsigned int bank_index);
+
+ static const size_t MAX_FWU_METADATA_SIZE;
+};
+
+#endif /* METADATA_CHECKER_V2_H */
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index 7f8806c..9414af2 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -112,6 +112,7 @@
"components/service/fwu/agent"
"components/service/fwu/fw_store/banked"
"components/service/fwu/fw_store/banked/metadata_serializer/v1"
+ "components/service/fwu/fw_store/banked/metadata_serializer/v2"
"components/service/fwu/fw_store/banked/test"
"components/service/fwu/installer"
"components/service/fwu/installer/raw"
diff --git a/deployments/ts-service-test/linux-pc/CMakeLists.txt b/deployments/ts-service-test/linux-pc/CMakeLists.txt
index 6014e5d..dc93aa2 100644
--- a/deployments/ts-service-test/linux-pc/CMakeLists.txt
+++ b/deployments/ts-service-test/linux-pc/CMakeLists.txt
@@ -106,6 +106,7 @@
"components/service/fwu/agent"
"components/service/fwu/fw_store/banked"
"components/service/fwu/fw_store/banked/metadata_serializer/v1"
+ "components/service/fwu/fw_store/banked/metadata_serializer/v2"
"components/service/fwu/installer"
"components/service/fwu/installer/raw"
"components/service/fwu/installer/copy"