new file mode 100644
@@ -0,0 +1,436 @@
+From fcc7701baf4246e5ceebe4d50db223cb70a0c00f Mon Sep 17 00:00:00 2001
+From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+Date: Thu, 28 Nov 2024 12:02:28 +0000
+Subject: [PATCH 1/8] Integrate PSA FWU IPC framework for Corstone-1000
+
+Integrate IPC framework for PSA FWU calls between Cortex-A side and Cortex-M subsystems.
+
+IPC framework is required to bridge the PSA FWU calls for the platforms which have
+both Cortex-A and Cortex-M subsystems. Corstone-1000 falls under this category of
+platforms. In these platforms, the PSA FWU client and PSA FWU provider exist on
+Cortex-A and all the PSA FWU services are implemented on Cortex-M side. This IPC
+framework forwards the PSA FWU calls from Cortex-A to Cortex-M subsystem.
+
+Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TS/trusted-services/+/33826]
+Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+---
+ components/service/common/include/psa/sid.h | 6 +-
+ .../interface/psa_ipc/component.cmake | 13 +
+ .../psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.c | 253 ++++++++++++++++++
+ .../psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.h | 49 ++++
+ .../se-proxy/infra/corstone1000/infra.cmake | 2 +-
+ .../corstone1000/service_proxy_factory.c | 16 ++
+ 6 files changed, 337 insertions(+), 2 deletions(-)
+ create mode 100644 components/service/fwu/psa_fwu_m/interface/psa_ipc/component.cmake
+ create mode 100644 components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.c
+ create mode 100644 components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.h
+
+diff --git a/components/service/common/include/psa/sid.h b/components/service/common/include/psa/sid.h
+index fc3a4fb0..4830f438 100644
+--- a/components/service/common/include/psa/sid.h
++++ b/components/service/common/include/psa/sid.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
++ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+@@ -65,6 +65,10 @@ extern "C" {
+ #define TFM_ATTEST_GET_TOKEN_SIZE 1002
+
+ /******** TFM_SP_FWU ********/
++#define TFM_FIRMWARE_UPDATE_SERVICE_SID (0x000000A0U)
++#define TFM_FIRMWARE_UPDATE_SERVICE_VERSION (1U)
++#define TFM_FIRMWARE_UPDATE_SERVICE_HANDLE (0x40000104U)
++
+ #define TFM_FWU_WRITE_SID (0x000000A0U)
+ #define TFM_FWU_WRITE_VERSION (1U)
+ #define TFM_FWU_INSTALL_SID (0x000000A1U)
+diff --git a/components/service/fwu/psa_fwu_m/interface/psa_ipc/component.cmake b/components/service/fwu/psa_fwu_m/interface/psa_ipc/component.cmake
+new file mode 100644
+index 00000000..cdc653a6
+--- /dev/null
++++ b/components/service/fwu/psa_fwu_m/interface/psa_ipc/component.cmake
+@@ -0,0 +1,13 @@
++#-------------------------------------------------------------------------------
++# Copyright (c) 2024, 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}/psa_fwu_ipc.c"
++)
+diff --git a/components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.c b/components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.c
+new file mode 100644
+index 00000000..a47ae539
+--- /dev/null
++++ b/components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.c
+@@ -0,0 +1,253 @@
++/*
++ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ */
++
++#include <stddef.h>
++#include <string.h>
++#include <trace.h>
++
++#include <protocols/rpc/common/packed-c/status.h>
++#include <psa/client.h>
++#include <psa/sid.h>
++#include <service/common/client/service_client.h>
++#include "service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.h"
++#include "service/fwu/psa_fwu_m/interface/tfm_fwu_defs.h"
++#include "service/fwu/psa_fwu_m/interface/update.h"
++
++/**
++ * @brief The singleton psa_fwu_ipc instance
++ *
++ * The psa attestation C API assumes a single backend service provider.
++ */
++static struct service_client instance;
++
++psa_status_t psa_fwu_ipc_init(struct rpc_caller_session *session)
++{
++ return service_client_init(&instance, session);
++}
++
++void psa_fwu_ipc_deinit(void)
++{
++ service_client_deinit(&instance);
++}
++
++int psa_fwu_rpc_status(void)
++{
++ return instance.rpc_status;
++}
++
++psa_status_t psa_fwu_query(psa_fwu_component_t component,
++ psa_fwu_component_info_t *info)
++{
++ if (!instance.session)
++ return PSA_ERROR_BAD_STATE;
++ if (!info)
++ return PSA_ERROR_INVALID_ARGUMENT;
++
++ psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
++ struct rpc_caller_interface *caller = instance.session->caller;
++ struct psa_invec in_vec[] = {
++ { .base = psa_ptr_to_u32(&component), .len = sizeof(component) },
++ };
++ struct psa_outvec out_vec[] = {
++ { .base = psa_ptr_to_u32(info), .len = sizeof(*info) },
++ };
++
++ status = psa_call(caller, TFM_FIRMWARE_UPDATE_SERVICE_HANDLE,
++ TFM_FWU_QUERY, in_vec, IOVEC_LEN(in_vec),
++ out_vec, IOVEC_LEN(out_vec));
++ if (status != PSA_SUCCESS)
++ EMSG("failed to psa_call: %d", status);
++
++ return status;
++}
++
++psa_status_t psa_fwu_start(psa_fwu_component_t component,
++ const void *manifest,
++ size_t manifest_size)
++{
++ if(manifest_size > UINT32_MAX)
++ return PSA_ERROR_INVALID_ARGUMENT;
++ if (!instance.session)
++ return PSA_ERROR_BAD_STATE;
++
++ psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
++ struct rpc_caller_interface *caller = instance.session->caller;
++ struct psa_invec in_vec[] = {
++ { .base = psa_ptr_to_u32(&component), .len = sizeof(component) },
++ { .base = psa_ptr_const_to_u32(manifest), .len = manifest_size },
++ };
++
++ status = psa_call(caller, TFM_FIRMWARE_UPDATE_SERVICE_HANDLE,
++ TFM_FWU_START, in_vec, IOVEC_LEN(in_vec),
++ NULL, 0);
++ if (status != PSA_SUCCESS)
++ EMSG("failed to psa_call: %d", status);
++
++ return status;
++}
++
++psa_status_t psa_fwu_write(psa_fwu_component_t component,
++ size_t image_offset,
++ const void *block,
++ size_t block_size)
++{
++ if (!instance.session)
++ return PSA_ERROR_BAD_STATE;
++ if (!block || !block_size)
++ return PSA_ERROR_INVALID_ARGUMENT;
++ if((image_offset > UINT32_MAX) || (block_size > UINT32_MAX))
++ return PSA_ERROR_INVALID_ARGUMENT;
++
++ psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
++ struct rpc_caller_interface *caller = instance.session->caller;
++ struct psa_invec in_vec[] = {
++ { .base = psa_ptr_to_u32(&component), .len = sizeof(component) },
++ { .base = psa_ptr_to_u32(&image_offset), .len = sizeof(uint32_t) },
++ { .base = psa_ptr_const_to_u32(block), .len = block_size },
++ };
++
++ status = psa_call(caller, TFM_FIRMWARE_UPDATE_SERVICE_HANDLE,
++ TFM_FWU_WRITE, in_vec, IOVEC_LEN(in_vec),
++ NULL, 0);
++ if (status != PSA_SUCCESS)
++ EMSG("failed to psa_call: %d", status);
++
++ return status;
++}
++
++psa_status_t psa_fwu_finish(psa_fwu_component_t component)
++{
++ if (!instance.session)
++ return PSA_ERROR_BAD_STATE;
++
++ psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
++ struct rpc_caller_interface *caller = instance.session->caller;
++ struct psa_invec in_vec[] = {
++ { .base = psa_ptr_to_u32(&component), .len = sizeof(component) },
++ };
++
++ status = psa_call(caller, TFM_FIRMWARE_UPDATE_SERVICE_HANDLE,
++ TFM_FWU_FINISH, in_vec, IOVEC_LEN(in_vec),
++ NULL, 0);
++ if (status != PSA_SUCCESS)
++ EMSG("failed to psa_call: %d", status);
++
++ return status;
++}
++
++psa_status_t psa_fwu_cancel(psa_fwu_component_t component)
++{
++ if (!instance.session)
++ return PSA_ERROR_BAD_STATE;
++
++ psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
++ struct rpc_caller_interface *caller = instance.session->caller;
++ struct psa_invec in_vec[] = {
++ { .base = psa_ptr_to_u32(&component), .len = sizeof(component) },
++ };
++
++ status = psa_call(caller, TFM_FIRMWARE_UPDATE_SERVICE_HANDLE,
++ TFM_FWU_CANCEL, in_vec, IOVEC_LEN(in_vec),
++ NULL, 0);
++ if (status != PSA_SUCCESS)
++ EMSG("failed to psa_call: %d", status);
++
++ return status;
++}
++
++psa_status_t psa_fwu_clean(psa_fwu_component_t component)
++{
++ if (!instance.session)
++ return PSA_ERROR_BAD_STATE;
++
++ psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
++ struct rpc_caller_interface *caller = instance.session->caller;
++ struct psa_invec in_vec[] = {
++ { .base = psa_ptr_to_u32(&component), .len = sizeof(component) },
++ };
++
++ status = psa_call(caller, TFM_FIRMWARE_UPDATE_SERVICE_HANDLE,
++ TFM_FWU_CLEAN, in_vec, IOVEC_LEN(in_vec),
++ NULL, 0);
++ if (status != PSA_SUCCESS)
++ EMSG("failed to psa_call: %d", status);
++
++ return status;
++}
++
++psa_status_t psa_fwu_install(void)
++{
++ if (!instance.session)
++ return PSA_ERROR_BAD_STATE;
++
++ psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
++ struct rpc_caller_interface *caller = instance.session->caller;
++ struct psa_invec in_vec[] = {};
++
++ status = psa_call(caller, TFM_FIRMWARE_UPDATE_SERVICE_HANDLE,
++ TFM_FWU_INSTALL, in_vec, 0,
++ NULL, 0);
++ if (status != PSA_SUCCESS)
++ EMSG("failed to psa_call: %d", status);
++
++ return status;
++}
++
++psa_status_t psa_fwu_request_reboot(void)
++{
++ if (!instance.session)
++ return PSA_ERROR_BAD_STATE;
++
++ psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
++ struct rpc_caller_interface *caller = instance.session->caller;
++ struct psa_invec in_vec[] = {};
++
++ status = psa_call(caller, TFM_FIRMWARE_UPDATE_SERVICE_HANDLE,
++ TFM_FWU_REQUEST_REBOOT, in_vec, 0,
++ NULL, 0);
++ if (status != PSA_SUCCESS)
++ EMSG("failed to psa_call: %d", status);
++
++ return status;
++}
++
++psa_status_t psa_fwu_reject(psa_status_t error)
++{
++ if (!instance.session)
++ return PSA_ERROR_BAD_STATE;
++
++ psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
++ struct rpc_caller_interface *caller = instance.session->caller;
++ struct psa_invec in_vec[] = {
++ { .base = psa_ptr_to_u32(&error), .len = sizeof(error) },
++ };
++
++ status = psa_call(caller, TFM_FIRMWARE_UPDATE_SERVICE_HANDLE,
++ TFM_FWU_REJECT, in_vec, IOVEC_LEN(in_vec),
++ NULL, 0);
++ if (status != PSA_SUCCESS)
++ EMSG("failed to psa_call: %d", status);
++
++ return status;
++}
++
++psa_status_t psa_fwu_accept(void)
++{
++ if (!instance.session)
++ return PSA_ERROR_BAD_STATE;
++
++ psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
++ struct rpc_caller_interface *caller = instance.session->caller;
++ struct psa_invec in_vec[] = {};
++
++ status = psa_call(caller, TFM_FIRMWARE_UPDATE_SERVICE_HANDLE,
++ TFM_FWU_ACCEPT, in_vec, 0,
++ NULL, 0);
++ if (status != PSA_SUCCESS)
++ EMSG("failed to psa_call: %d", status);
++
++ return status;
++}
+diff --git a/components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.h b/components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.h
+new file mode 100644
+index 00000000..867a1c9c
+--- /dev/null
++++ b/components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.h
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ */
++
++#ifndef PSA_FWU_IPC_H
++#define PSA_FWU_IPC_H
++
++#include <psa/error.h>
++#include "rpc_caller_session.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/**
++ * @brief Initialize a PSA FWU ipc client
++ *
++ * A PSA FWU ipc client makes RPC calls to a remote FWU service.
++ *
++ * @param[in] rpc_caller RPC caller instance
++ *
++ * @return A status indicating the success/failure of the operation
++ */
++psa_status_t psa_fwu_ipc_init(struct rpc_caller_session *session);
++
++/**
++ * @brief Deinitialize a PSA FWU ipc client
++ *
++ */
++void psa_fwu_ipc_deinit(void);
++
++/**
++ * @brief Return the most recent RPC status
++ *
++ * May be used to obtain information about an RPC error that resulted
++ * in an API operation failure
++ *
++ * @return Most recent RPC operation status
++ */
++int psa_fwu_rpc_status(void);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* PSA_FWU_IPC_H */
++
+diff --git a/deployments/se-proxy/infra/corstone1000/infra.cmake b/deployments/se-proxy/infra/corstone1000/infra.cmake
+index 27af8a33..0b04149a 100644
+--- a/deployments/se-proxy/infra/corstone1000/infra.cmake
++++ b/deployments/se-proxy/infra/corstone1000/infra.cmake
+@@ -26,7 +26,7 @@ add_components(TARGET "se-proxy"
+ "components/service/fwu/provider"
+ "components/service/fwu/provider/serializer"
+ "components/service/fwu/psa_fwu_m/agent"
+- "components/service/fwu/psa_fwu_m/interface/stub"
++ "components/service/fwu/psa_fwu_m/interface/psa_ipc"
+ "components/service/capsule_update/provider"
+ "components/service/secure_storage/backend/secure_storage_ipc"
+ )
+diff --git a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+index 8872abcb..ef91efe0 100644
+--- a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
++++ b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+@@ -15,6 +15,7 @@
+ #include <service/crypto/factory/crypto_provider_factory.h>
+ #include "service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.h"
+ #include "service/fwu/provider/fwu_provider.h"
++#include "service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.h"
+ #include <service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h>
+ #include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
+ #include <trace.h>
+@@ -135,10 +136,25 @@ struct rpc_service_interface *its_proxy_create(void)
+
+ struct rpc_service_interface *fwu_proxy_create(void)
+ {
++ rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+ static struct update_agent *agent;
+ static struct fwu_provider fwu_provider = { 0 };
+
++ /* Static objects for proxy instance */
++ static struct rpc_caller_interface rss_comms = { 0 };
++ static struct rpc_caller_session rpc_session = { 0 };
++
++ rpc_status = rss_comms_caller_init(&rss_comms);
++ if (rpc_status != RPC_SUCCESS)
++ return NULL;
++
++ rpc_status = rpc_caller_session_open(&rpc_session, &rss_comms, &dummy_uuid, 0, 0);
++ if (rpc_status != RPC_SUCCESS)
++ return NULL;
++
+ agent = psa_fwu_m_update_agent_init(NULL, 0, 4096);
++ if (psa_fwu_ipc_init(&rpc_session) != PSA_SUCCESS)
++ return NULL;
+
+ return fwu_provider_init(&fwu_provider, agent);
+ }
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,188 @@
+From 6fb3bead9e0eea3640ad1209347691c2b40512a2 Mon Sep 17 00:00:00 2001
+From: Imre Kis <imre.kis@arm.com>
+Date: Wed, 5 Feb 2025 14:27:45 +0100
+Subject: [PATCH 2/8] Load initial image state in PSA FWU M update agent
+
+Set initial image state based on the image state returned by
+psa_fwu_query. This way the update agent has the correct view of images
+after reboot and it can accept or reject them.
+
+Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TS/trusted-services/+/35155]
+Signed-off-by: Imre Kis <imre.kis@arm.com>
+Change-Id: I150e4fdb4584c8d07f5f1f642ee88197f9cff49b
+Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+---
+ .../psa_fwu_m/agent/psa_fwu_m_update_agent.c | 23 +++++++--
+ .../test/test_psa_fwu_m_update_agent.cpp | 49 ++++++++++++++++++-
+ docs/services/fwu/psa-fwu-m.rst | 14 +++++-
+ 3 files changed, 80 insertions(+), 6 deletions(-)
+
+diff --git a/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.c b/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.c
+index 6de9ba71..48b86f6e 100644
+--- a/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.c
++++ b/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2024, Arm Limited. All rights reserved.
++ * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+@@ -609,8 +609,11 @@ struct update_agent *psa_fwu_m_update_agent_init(
+ const struct psa_fwu_m_image_mapping image_mapping[], size_t image_count,
+ uint32_t max_payload_size)
+ {
++ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct psa_fwu_m_update_agent *context = NULL;
++ struct psa_fwu_component_info_t info = { 0 };
+ struct psa_fwu_m_image *images = NULL;
++ enum psa_fwu_m_state state = regular;
+ struct update_agent *agent = NULL;
+ size_t i = 0;
+
+@@ -637,9 +640,23 @@ struct update_agent *psa_fwu_m_update_agent_init(
+ }
+
+ for (i = 0; i < image_count; i++) {
++ psa_status = psa_fwu_query(image_mapping[i].component, &info);
++ if (psa_status != PSA_SUCCESS) {
++ free(images);
++ free(context);
++ free(agent);
++ return NULL;
++ }
++
+ images[i].uuid = image_mapping[i].uuid;
+ images[i].component = image_mapping[i].component;
+- images[i].selected_for_staging = false;
++ if (info.state == PSA_FWU_TRIAL) {
++ images[i].selected_for_staging = true;
++ state = trial;
++ } else {
++ images[i].selected_for_staging = false;
++ }
++
+ images[i].read = NULL; /* Cannot read images */
+ images[i].write = image_write;
+ }
+@@ -654,7 +671,7 @@ struct update_agent *psa_fwu_m_update_agent_init(
+ context->images = images;
+ context->image_count = image_count + 1;
+ context->max_payload_size = max_payload_size;
+- context->state = regular;
++ context->state = state;
+
+ agent->context = context;
+ agent->interface = &interface;
+diff --git a/components/service/fwu/psa_fwu_m/agent/test/test_psa_fwu_m_update_agent.cpp b/components/service/fwu/psa_fwu_m/agent/test/test_psa_fwu_m_update_agent.cpp
+index de289fff..3805d182 100644
+--- a/components/service/fwu/psa_fwu_m/agent/test/test_psa_fwu_m_update_agent.cpp
++++ b/components/service/fwu/psa_fwu_m/agent/test/test_psa_fwu_m_update_agent.cpp
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2024, Arm Limited. All rights reserved.
++ * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+@@ -14,6 +14,9 @@
+
+ TEST_GROUP(psa_fwu_m_update_agent) {
+ TEST_SETUP() {
++ psa_fwu_component_info_t info = {0};
++ expect_mock_psa_fwu_query(mapping[0].component, &info, PSA_SUCCESS);
++ expect_mock_psa_fwu_query(mapping[1].component, &info, PSA_SUCCESS);
+ agent = psa_fwu_m_update_agent_init(mapping, 2, 4096);
+ handle = 0;
+ progress = 0;
+@@ -667,4 +670,46 @@ TEST(psa_fwu_m_update_agent, select_previous)
+
+ expect_mock_psa_fwu_reject(0, PSA_SUCCESS);
+ LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_select_previous(agent));
+-}
+\ No newline at end of file
++}
++
++TEST(psa_fwu_m_update_agent, boot_in_trial_mode_query_fail) {
++ psa_fwu_component_info_t info = {0};
++
++ expect_mock_psa_fwu_query(mapping[0].component, &info, PSA_ERROR_GENERIC_ERROR);
++ POINTERS_EQUAL(NULL, psa_fwu_m_update_agent_init(mapping, 2, 4096));
++}
++
++TEST(psa_fwu_m_update_agent, boot_in_trial_mode_select_previous) {
++ psa_fwu_component_info_t info0 = {0};
++ psa_fwu_component_info_t info1 = {0};
++
++ info1.state = PSA_FWU_TRIAL;
++
++ expect_mock_psa_fwu_query(mapping[0].component, &info0, PSA_SUCCESS);
++ expect_mock_psa_fwu_query(mapping[1].component, &info1, PSA_SUCCESS);
++
++ update_agent *agent = psa_fwu_m_update_agent_init(mapping, 2, 4096);
++
++ expect_mock_psa_fwu_reject(0, PSA_SUCCESS);
++ LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_select_previous(agent));
++
++ psa_fwu_m_update_agent_deinit(agent);
++}
++
++TEST(psa_fwu_m_update_agent, boot_in_trial_mode_accept) {
++ psa_fwu_component_info_t info0 = {0};
++ psa_fwu_component_info_t info1 = {0};
++
++ info1.state = PSA_FWU_TRIAL;
++
++ expect_mock_psa_fwu_query(mapping[0].component, &info0, PSA_SUCCESS);
++ expect_mock_psa_fwu_query(mapping[1].component, &info1, PSA_SUCCESS);
++
++ update_agent *agent = psa_fwu_m_update_agent_init(mapping, 2, 4096);
++
++ expect_mock_psa_fwu_accept(PSA_SUCCESS);
++ LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_accept_image(agent, &mapping[0].uuid));
++ LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_accept_image(agent, &mapping[1].uuid));
++
++ psa_fwu_m_update_agent_deinit(agent);
++}
+diff --git a/docs/services/fwu/psa-fwu-m.rst b/docs/services/fwu/psa-fwu-m.rst
+index 26ffed09..1358015f 100644
+--- a/docs/services/fwu/psa-fwu-m.rst
++++ b/docs/services/fwu/psa-fwu-m.rst
+@@ -44,6 +44,11 @@ The solutions to these differences:
+ * Convert the image query result returned by FWU-M to FWU-A format. There are similar field, but this imposes some
+ limitations.
+
++Initialization
++```````````````
++
++The initial image and agent state is determined based on the image state returned by ``psa_fwu_query()``.
++
+
+ ``fwu_discover()``
+ ``````````````````
+@@ -71,6 +76,10 @@ agent switches to trial state, so the client can validate the new set of images
+
+ On calling ``fwu_end_staging()`` the agent calls ``psa_fwu_finish()`` on each selected image, then calls
+ ``psa_fwu_install()``. If all images have been accepted (see ``fwu_commit()``) it also calls ``psa_fwu_accept()``.
++The implementation treats ``PSA_SUCCESS_REBOOT`` and ``PSA_SUCCESS_RESTART`` status values as error. In an A+M system the M
++class side shouldn't restart the system, so calling ``psa_fwu_request_reboot()`` does not fit the system. There's also no
++PSA FWU A return code for inidicating the restart request to the normal world. If the normal world has to restart the
++system after ending the staging phase, it has to do it in an implementation defined way.
+
+ .. uml:: ../uml/psa_fwu_m_update_agent/fwu_end_staging.puml
+
+@@ -136,7 +145,10 @@ calls ``psa_fwu_accept()`` when all images have been accepted. This results in a
+ `````````````````````````
+
+ Selects previous working state (i.e. rejects the firmware update) and transitions back to regular state after calling
+-``psa_fwu_reject()``.
++``psa_fwu_reject()``. The implementation treats ``PSA_SUCCESS_REBOOT`` and ``PSA_SUCCESS_RESTART`` status values as error.
++In an A+M system the M class side shouldn't restart the system, so calling ``psa_fwu_request_reboot()`` does not fit the
++system. There's also no PSA FWU A return code for inidicating the restart request to the normal world. If the normal
++world has to restart the system when rejecting the installed firmware, it has to do it in an implementation defined way.
+
+ .. uml:: ../uml/psa_fwu_m_update_agent/fwu_select_previous.puml
+
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,128 @@
+From 5344d7d0580ca7f2f2569f388dd6e3cd17a372f2 Mon Sep 17 00:00:00 2001
+From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+Date: Thu, 6 Feb 2025 10:26:04 +0000
+Subject: [PATCH 3/8] Corstone1000: Define PSA FWU image mapping structure
+
+This commit involves following changes
+
+1. Define PSA FWU image mapping structure for Corstone-1000.
+This structure is responsible to map specific image guid with
+component number.
+To enable platform-specific handling, service_proxy_factory.c now
+conditionally selects the appropriate image mapping
+based on PLATFORM_IS_FVP. This ensures that both FVP and MPS3
+platforms use the correct GUID and firmware update configuration.
+
+2. Rename RSS to RSE
+
+Upstream-Status: Pending
+Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+Signed-off-by: Ali Can Ozaslan <ali.oezaslan@arm.com>
+---
+ .../infra/corstone1000/corstone1000_config.h | 28 +++++++++++++++++++
+ .../corstone1000/service_proxy_factory.c | 25 +++++++++++++----
+ 2 files changed, 48 insertions(+), 5 deletions(-)
+ create mode 100644 deployments/se-proxy/infra/corstone1000/corstone1000_config.h
+
+diff --git a/deployments/se-proxy/infra/corstone1000/corstone1000_config.h b/deployments/se-proxy/infra/corstone1000/corstone1000_config.h
+new file mode 100644
+index 00000000..319401f3
+--- /dev/null
++++ b/deployments/se-proxy/infra/corstone1000/corstone1000_config.h
+@@ -0,0 +1,28 @@
++/*
++ * Copyright (c) 2025, Arm Limited. All rights reserved.
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ *
++ */
++
++#ifndef CORSTONE1000_CONFIG_H
++#define CORSTONE1000_CONFIG_H
++
++#define FWU_IMAGE_COUNT 1
++
++/* Maximum payload size to be transferred at once to Secure Enclave */
++#define MAX_PAYLOAD_SIZE 4096
++
++#define CORSTONE1000_FVP_FULL_CAPSULE_UUID \
++{ 0x4e, 0x3a, 0x9f, 0x98, 0xe0, 0x46, 0xd0, 0x4c, 0x98, 0x77, 0xa2, 0x5c, 0x70, 0xc0, 0x13, 0x29, }
++
++#define CORSTONE1000_MPS3_FULL_CAPSULE_UUID \
++{ 0xd1, 0x65, 0x18, 0xdf, 0xfb, 0x90, 0x59, 0x4d, 0x9c, 0x38, 0xc9, 0xf2, 0xc1, 0xbb, 0xa8, 0xcc, }
++
++/* Image indexes in the UEFI capsule */
++enum fwu_image_index
++{
++ FWU_IMAGE_INDEX_FULL_CAPSULE = 1,
++};
++
++#endif /* CORSTONE1000_CONFIG_H */
+diff --git a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+index ef91efe0..6e5f1221 100644
+--- a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
++++ b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
++ * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, Linaro Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+@@ -19,6 +19,7 @@
+ #include <service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h>
+ #include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
+ #include <trace.h>
++#include "corstone1000_config.h"
+
+ /* backends */
+ #include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
+@@ -27,6 +28,20 @@
+
+ static const struct rpc_uuid dummy_uuid = { 0 };
+
++static const struct psa_fwu_m_image_mapping img_mapping[FWU_IMAGE_COUNT] = {
++#if PLATFORM_IS_FVP
++ {
++ .uuid = CORSTONE1000_FVP_FULL_CAPSULE_UUID,
++ .component = FWU_IMAGE_INDEX_FULL_CAPSULE
++ },
++#else
++ {
++ .uuid = CORSTONE1000_MPS3_FULL_CAPSULE_UUID,
++ .component = FWU_IMAGE_INDEX_FULL_CAPSULE
++ },
++#endif
++};
++
+ struct rpc_service_interface *attest_proxy_create(void)
+ {
+ struct rpc_service_interface *attest_iface = NULL;
+@@ -141,20 +156,20 @@ struct rpc_service_interface *fwu_proxy_create(void)
+ static struct fwu_provider fwu_provider = { 0 };
+
+ /* Static objects for proxy instance */
+- static struct rpc_caller_interface rss_comms = { 0 };
++ static struct rpc_caller_interface rse_comms = { 0 };
+ static struct rpc_caller_session rpc_session = { 0 };
+
+- rpc_status = rss_comms_caller_init(&rss_comms);
++ rpc_status = rse_comms_caller_init(&rse_comms);
+ if (rpc_status != RPC_SUCCESS)
+ return NULL;
+
+- rpc_status = rpc_caller_session_open(&rpc_session, &rss_comms, &dummy_uuid, 0, 0);
++ rpc_status = rpc_caller_session_open(&rpc_session, &rse_comms, &dummy_uuid, 0, 0);
+ if (rpc_status != RPC_SUCCESS)
+ return NULL;
+
+- agent = psa_fwu_m_update_agent_init(NULL, 0, 4096);
+ if (psa_fwu_ipc_init(&rpc_session) != PSA_SUCCESS)
+ return NULL;
++ agent = psa_fwu_m_update_agent_init(img_mapping, FWU_IMAGE_COUNT, MAX_PAYLOAD_SIZE);
+
+ return fwu_provider_init(&fwu_provider, agent);
+ }
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,31 @@
+From d43ec82f7e419e6f1e9f5bd002c324b788ee901f Mon Sep 17 00:00:00 2001
+From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+Date: Thu, 6 Feb 2025 11:32:04 +0000
+Subject: [PATCH 4/8] Fix PSA FWU IPC psa_fwu_install() return value check
+
+This change adds support to validate if the return type in psa_fwu_install()
+is either PSA_SUCCESS or PSA_SUCCESS_REBOOT. Both the return values are expected.
+Earlier, only PSA_SUCCESS is validated.
+
+Upstream-Status: Pending
+Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+---
+ .../service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.c b/components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.c
+index a47ae539..3947a809 100644
+--- a/components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.c
++++ b/components/service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.c
+@@ -190,7 +190,7 @@ psa_status_t psa_fwu_install(void)
+ status = psa_call(caller, TFM_FIRMWARE_UPDATE_SERVICE_HANDLE,
+ TFM_FWU_INSTALL, in_vec, 0,
+ NULL, 0);
+- if (status != PSA_SUCCESS)
++ if (status != PSA_SUCCESS && status != PSA_SUCCESS_REBOOT)
+ EMSG("failed to psa_call: %d", status);
+
+ return status;
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,178 @@
+From 740359ba2a73f5ce0015c9023cc1aa69506f99bf Mon Sep 17 00:00:00 2001
+From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+Date: Fri, 28 Feb 2025 21:12:25 +0000
+Subject: [PATCH 5/8] fwu: Add EFI ESRT v1 support
+
+Add EFI ESRT v1 support for PSA FWU M agent.
+ESRT functionality is implemented using unique image dedicated
+for ESRT data having its own UUID. In PSA FWU M agent's context,
+this image has read only attributes. The ESRT data can be read
+using image_read_directory by using ESRT image UUID handle. The
+ESRT data is queried from Secure Enclave using psa_fwu_query()
+and ESRT data can be read from psa_fwu_impl_info_t structure
+object defined in psa_fwu_component_info_t.
+
+This commit includes the following changes:
+1. Declare EFI ESRT v1 data structures.
+2. Modify image_directory_read() to include EFI ESRT data read support
+3. Modify psa_fwu_m_update_agent_init to initialize ESRT image
+attributes
+
+The ESRT v1 details can be found here :
+https://uefi.org/specs/UEFI/2.9_A/23_Firmware_Update_and_Reporting.html#efi-system-resource-table
+
+Upstream-Status: Pending
+Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+---
+ .../psa_fwu_m/agent/psa_fwu_m_update_agent.c | 50 +++++++++++++++++--
+ protocols/service/fwu/fwu_proto.h | 29 +++++++++--
+ 2 files changed, 71 insertions(+), 8 deletions(-)
+
+diff --git a/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.c b/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.c
+index 48b86f6e..d0464bf5 100644
+--- a/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.c
++++ b/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.c
+@@ -115,13 +115,22 @@ uint32_t image_version_to_uint(psa_fwu_image_version_t version)
+ return result;
+ }
+
++/* image_directory_read
++ * This function is used for two purposes:
++ * -> Send the details of firmware images to update client when read request is made for FWU_DIRECTORY_CANONICAL_UUID
++ * -> Send ESRT data to update client when read request is made for EFI_SYSTEM_RESOURCE_TABLE_CANONICAL_UUID
++ */
+ int image_directory_read(struct psa_fwu_m_update_agent *agent, struct psa_fwu_m_image *image,
+ uint8_t *buf, size_t buf_size, size_t *read_len, size_t *total_len)
+ {
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ psa_fwu_component_info_t component_info = { 0 };
+ struct fwu_image_directory *directory = NULL;
+- size_t image_count = agent->image_count - 1; /* Do not return Image directory */
++ uint8_t esrt_image_uuid[OSF_UUID_OCTET_LEN];
++ size_t image_count = agent->image_count - 1; /* Do not return Image directory
++ * If update client uses ESRT UUID for ESRT data, then ESRT image UUID
++ * is considered as a separate image included in this count
++ */
+ size_t image_info_size = 0;
+ size_t i = 0;
+
+@@ -136,12 +145,36 @@ int image_directory_read(struct psa_fwu_m_update_agent *agent, struct psa_fwu_m_
+ return FWU_STATUS_DENIED; /* LCOV_EXCL_LINE */
+
+ /*
+- * If the directory structure doesn't fit into the buffer return SUCCESS with total_len set
++ * If the data to be read doesn't fit into the buffer return SUCCESS with total_len set
+ * and read_len = 0.
+ */
+ if (*total_len > buf_size)
+ return FWU_STATUS_SUCCESS;
+
++ /* Query ESRT data from Secure Enclave and Copy the ESRT entries from component_info.impl.candidate_digest
++ * to buf in case of ESRT image UUID.
++ * This is needed because Secure Enclave fills component_info.impl.candidate_digest with ESRT data
++ * which needs to be transferred to normal world buffer
++ */
++ uuid_octets_from_canonical((struct uuid_octets *)&esrt_image_uuid, EFI_SYSTEM_RESOURCE_TABLE_CANONICAL_UUID);
++ if (!memcmp(&esrt_image_uuid, &image->uuid, sizeof(esrt_image_uuid))) {
++ /* Query ESRT data */
++ psa_status = psa_fwu_query(image->component, &component_info);
++ if (psa_status != PSA_SUCCESS)
++ return psa_status_to_fwu_status(psa_status);
++
++ struct efi_system_resource_table *esrt = (struct efi_system_resource_table *)component_info.impl.candidate_digest;
++ size_t esrt_size_recv = (esrt->fw_resource_count * sizeof(struct efi_system_resource_entry) ) + sizeof(struct efi_system_resource_table);
++ if(esrt_size_recv > TFM_FWU_MAX_DIGEST_SIZE)
++ return FWU_STATUS_OUT_OF_BOUNDS;
++
++ /* Copy the ESRT entries to the buf */
++ memcpy(buf, &component_info.impl.candidate_digest, esrt_size_recv);
++ *total_len = esrt_size_recv;
++ *read_len = *total_len;
++ return FWU_STATUS_SUCCESS;
++ }
++
+ directory = (struct fwu_image_directory *)buf;
+ directory->directory_version = FWU_IMAGE_DIRECTORY_VERSION;
+ directory->img_info_offset = offsetof(struct fwu_image_directory, img_info_entry);
+@@ -615,6 +648,7 @@ struct update_agent *psa_fwu_m_update_agent_init(
+ struct psa_fwu_m_image *images = NULL;
+ enum psa_fwu_m_state state = regular;
+ struct update_agent *agent = NULL;
++ uint8_t esrt_image_uuid[OSF_UUID_OCTET_LEN];
+ size_t i = 0;
+
+ /* Allocate +1 image for the Image directory */
+@@ -657,8 +691,16 @@ struct update_agent *psa_fwu_m_update_agent_init(
+ images[i].selected_for_staging = false;
+ }
+
+- images[i].read = NULL; /* Cannot read images */
+- images[i].write = image_write;
++ uuid_octets_from_canonical((struct uuid_octets *)&esrt_image_uuid, EFI_SYSTEM_RESOURCE_TABLE_CANONICAL_UUID);
++ if (!memcmp(&esrt_image_uuid, &images[i].uuid, sizeof(esrt_image_uuid))) {
++ images[i].read = image_directory_read;
++ images[i].write = NULL;
++ images[i].selected_for_staging = false;
++ }
++ else {
++ images[i].read = NULL; /* Cannot read images */
++ images[i].write = image_write;
++ }
+ }
+
+ /* Insert Image directory as the last image */
+diff --git a/protocols/service/fwu/fwu_proto.h b/protocols/service/fwu/fwu_proto.h
+index 4bcacb1f..aa5d2561 100644
+--- a/protocols/service/fwu/fwu_proto.h
++++ b/protocols/service/fwu/fwu_proto.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
++ * Copyright (c) 2022-2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+@@ -28,9 +28,10 @@
+ /**
+ * Protocol GUIDs defined in FWU-A specification
+ */
+-#define FWU_UPDATE_AGENT_CANONICAL_UUID "6823a838-1b06-470e-9774-0cce8bfb53fd"
+-#define FWU_DIRECTORY_CANONICAL_UUID "deee58d9-5147-4ad3-a290-77666e2341a5"
+-#define FWU_METADATA_CANONICAL_UUID "8a7a84a0-8387-40f6-ab41-a8b9a5a60d23"
++#define FWU_UPDATE_AGENT_CANONICAL_UUID "6823a838-1b06-470e-9774-0cce8bfb53fd"
++#define FWU_DIRECTORY_CANONICAL_UUID "deee58d9-5147-4ad3-a290-77666e2341a5"
++#define FWU_METADATA_CANONICAL_UUID "8a7a84a0-8387-40f6-ab41-a8b9a5a60d23"
++#define EFI_SYSTEM_RESOURCE_TABLE_CANONICAL_UUID "63a222b1-6136-684f-9929-78f8b0d62180"
+
+ #define FWU_OPEN_OP_TYPE_READ (0)
+ #define FWU_OPEN_OP_TYPE_WRITE (1)
+@@ -40,6 +41,26 @@
+ */
+ #define FWU_IMAGE_DIRECTORY_VERSION (2)
+
++/**
++ * @brief Information about the ESRT v1.
++ */
++struct __attribute__((__packed__)) efi_system_resource_entry {
++ uint8_t fw_class[OSF_UUID_OCTET_LEN];
++ 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[];
++};
++
+ struct __attribute__((__packed__)) fwu_image_info_entry {
+ uint8_t img_type_uuid[OSF_UUID_OCTET_LEN];
+ uint32_t client_permissions;
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,129 @@
+From 27d3ce79128478cd163a2db113326c873bda8d08 Mon Sep 17 00:00:00 2001
+From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+Date: Fri, 28 Feb 2025 21:12:56 +0000
+Subject: [PATCH 6/8] platform: corstone1000: Enable ESRT support
+
+Enable ESRT support for Corstone-1000.
+Introduce ESRT image UUID and its component number and
+set TFM_FWU_MAX_DIGEST_SIZE to ESRT data size.
+
+Upstream-Status: Pending
+Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+---
+ .../infra/corstone1000/corstone1000_config.h | 3 +--
+ .../corstone1000/service_proxy_factory.c | 22 +++++++++++++++++--
+ .../providers/arm/corstone1000/platform.cmake | 9 ++++++++
+ 3 files changed, 30 insertions(+), 4 deletions(-)
+
+diff --git a/deployments/se-proxy/infra/corstone1000/corstone1000_config.h b/deployments/se-proxy/infra/corstone1000/corstone1000_config.h
+index 319401f3..4a68c2fa 100644
+--- a/deployments/se-proxy/infra/corstone1000/corstone1000_config.h
++++ b/deployments/se-proxy/infra/corstone1000/corstone1000_config.h
+@@ -8,8 +8,6 @@
+ #ifndef CORSTONE1000_CONFIG_H
+ #define CORSTONE1000_CONFIG_H
+
+-#define FWU_IMAGE_COUNT 1
+-
+ /* Maximum payload size to be transferred at once to Secure Enclave */
+ #define MAX_PAYLOAD_SIZE 4096
+
+@@ -23,6 +21,7 @@
+ enum fwu_image_index
+ {
+ FWU_IMAGE_INDEX_FULL_CAPSULE = 1,
++ FWU_IMAGE_INDEX_ESRT,
+ };
+
+ #endif /* CORSTONE1000_CONFIG_H */
+diff --git a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+index 6e5f1221..f0a4853e 100644
+--- a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
++++ b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+@@ -18,6 +18,7 @@
+ #include "service/fwu/psa_fwu_m/interface/psa_ipc/psa_fwu_ipc.h"
+ #include <service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h>
+ #include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
++#include <protocols/service/fwu/fwu_proto.h>
+ #include <trace.h>
+ #include "corstone1000_config.h"
+
+@@ -26,9 +27,17 @@
+ #include <service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h>
+ #include <service/attestation/client/psa/iat_client.h>
+
++/* IMAGE_MAPPING_ELEMENT_COUNT includes the number of images to be updated and ESRT image */
++#define IMAGE_MAPPING_ELEMENT_COUNT (FWU_IMAGE_CAPSULE_COUNT + 1)
++
++/* The index to access the ESRT image in the psa_fwu_m_image_mapping structure
++ * collection. The ESRT image is always accessed at the end of the collection.
++ */
++#define IMAGE_MAPPING_ESRT_INDEX (IMAGE_MAPPING_ELEMENT_COUNT - 1)
++
+ static const struct rpc_uuid dummy_uuid = { 0 };
+
+-static const struct psa_fwu_m_image_mapping img_mapping[FWU_IMAGE_COUNT] = {
++static struct psa_fwu_m_image_mapping img_mapping[IMAGE_MAPPING_ELEMENT_COUNT] = {
+ #if PLATFORM_IS_FVP
+ {
+ .uuid = CORSTONE1000_FVP_FULL_CAPSULE_UUID,
+@@ -42,6 +51,13 @@ static const struct psa_fwu_m_image_mapping img_mapping[FWU_IMAGE_COUNT] = {
+ #endif
+ };
+
++/* Every platform needs to define esrt image mapping, if ESRT image UUID is to be used to extract ESRT data */
++static void define_esrt_image_mapping()
++{
++ uuid_octets_from_canonical(&img_mapping[IMAGE_MAPPING_ESRT_INDEX].uuid, EFI_SYSTEM_RESOURCE_TABLE_CANONICAL_UUID);
++ img_mapping[IMAGE_MAPPING_ESRT_INDEX].component = FWU_IMAGE_INDEX_ESRT;
++}
++
+ struct rpc_service_interface *attest_proxy_create(void)
+ {
+ struct rpc_service_interface *attest_iface = NULL;
+@@ -169,7 +185,9 @@ struct rpc_service_interface *fwu_proxy_create(void)
+
+ if (psa_fwu_ipc_init(&rpc_session) != PSA_SUCCESS)
+ return NULL;
+- agent = psa_fwu_m_update_agent_init(img_mapping, FWU_IMAGE_COUNT, MAX_PAYLOAD_SIZE);
++
++ define_esrt_image_mapping();
++ agent = psa_fwu_m_update_agent_init(img_mapping, IMAGE_MAPPING_ELEMENT_COUNT, MAX_PAYLOAD_SIZE);
+
+ return fwu_provider_init(&fwu_provider, agent);
+ }
+diff --git a/platform/providers/arm/corstone1000/platform.cmake b/platform/providers/arm/corstone1000/platform.cmake
+index 60bc208b..db1e9743 100644
+--- a/platform/providers/arm/corstone1000/platform.cmake
++++ b/platform/providers/arm/corstone1000/platform.cmake
+@@ -6,11 +6,18 @@
+ # Platform definition for the Corstone-1000 platform.
+ #-------------------------------------------------------------------------------
+
++# For ESRT v1 details : https://uefi.org/specs/UEFI/2.9_A/23_Firmware_Update_and_Reporting.html#efi-system-resource-table
++set(FWU_IMAGE_CAPSULE_COUNT 4 CACHE STRING "Maximum number of FWU Images in a capsule to be updated")
++set(ESRT_IMAGE_ENTRY_SIZE 40 CACHE STRING "Size of one ESRT v1 Image entry structure object")
++set(ESRT_REMAINING_FIELDS_SIZE 16 CACHE STRING "Size of remaining fields of ESRT v1 table structure")
++math(EXPR TOTAL_ESRT_SIZE "${FWU_IMAGE_CAPSULE_COUNT} * ${ESRT_IMAGE_ENTRY_SIZE} + ${ESRT_REMAINING_FIELDS_SIZE}" OUTPUT_FORMAT DECIMAL)
++
+ set(SMM_GATEWAY_MAX_UEFI_VARIABLES 80 CACHE STRING "Maximum UEFI variable count")
+ set(SMM_RPC_CALLER_SESSION_SHARED_MEMORY_SIZE 4*4096 CACHE STRING "RPC caller buffer size in SMMGW")
+ set(SMM_SP_HEAP_SIZE 80*1024 CACHE STRING "SMM gateway SP heap size")
+ set(PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE 0x43C0 CACHE STRING "Size of the RSE_COMMS_PAYLOAD buffer")
+ set(COMMS_MHU_MSG_SIZE 0x4500 CACHE STRING "Max message size that can be transfered via MHU")
++set(TFM_FWU_MAX_DIGEST_SIZE ${TOTAL_ESRT_SIZE} CACHE STRING "Maximum size of ESRT entries of all the images in a bank")
+
+ target_compile_definitions(${TGT} PRIVATE
+ SMM_VARIABLE_INDEX_STORAGE_UID=0x787
+@@ -18,6 +25,8 @@ target_compile_definitions(${TGT} PRIVATE
+ COMMS_MHU_MSG_SIZE=${COMMS_MHU_MSG_SIZE}
+ MBEDTLS_ECP_DP_SECP521R1_ENABLED
+ PLATFORM_IS_FVP=${PLATFORM_IS_FVP}
++ TFM_FWU_MAX_DIGEST_SIZE=${TFM_FWU_MAX_DIGEST_SIZE}
++ FWU_IMAGE_CAPSULE_COUNT=${FWU_IMAGE_CAPSULE_COUNT}
+ )
+
+ get_property(_platform_driver_dependencies TARGET ${TGT}
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,268 @@
+From dde0ca3260ae3b7e7c3390ef03f9f484e9189626 Mon Sep 17 00:00:00 2001
+From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+Date: Tue, 11 Mar 2025 13:33:36 +0000
+Subject: [PATCH 7/8] platform: corstone1000: Add event provider proxy
+
+Normal world needs to send boot confirmation event
+to Secure Enclave and Trusted-Services is responsible
+to transfer the event to Secure Enclave.
+This commit implements the event handling framework in
+SE-proxy-SP and develops event provider proxy which
+forwards the event to Secure Enclave via psa calls.
+This change is introduced for Corstone-1000
+
+Upstream-Status: Pending
+Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+---
+ .../se-proxy/env/commonsp/se_proxy_sp.c | 16 +++-
+ .../corstone1000_event_handling.c | 91 +++++++++++++++++++
+ .../corstone1000_event_handling.h | 42 +++++++++
+ .../se-proxy/infra/corstone1000/infra.cmake | 1 +
+ .../corstone1000/service_proxy_factory.c | 27 ++++++
+ 5 files changed, 175 insertions(+), 2 deletions(-)
+ create mode 100644 deployments/se-proxy/infra/corstone1000/corstone1000_event_handling.c
+ create mode 100644 deployments/se-proxy/infra/corstone1000/corstone1000_event_handling.h
+
+diff --git a/deployments/se-proxy/env/commonsp/se_proxy_sp.c b/deployments/se-proxy/env/commonsp/se_proxy_sp.c
+index 7da489ca..7d2ade5e 100644
+--- a/deployments/se-proxy/env/commonsp/se_proxy_sp.c
++++ b/deployments/se-proxy/env/commonsp/se_proxy_sp.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: BSD-3-Clause
+ /*
+- * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
++ * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
+ */
+
+ #include "components/rpc/common/endpoint/rpc_service_interface.h"
+@@ -40,7 +40,7 @@ void __noreturn sp_main(union ffa_boot_info *boot_info)
+ goto fatal_error;
+ }
+
+- rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 7, 16);
++ rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 8, 16);
+ if (rpc_status != RPC_SUCCESS) {
+ EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
+ goto fatal_error;
+@@ -95,6 +95,18 @@ void __noreturn sp_main(union ffa_boot_info *boot_info)
+ goto fatal_error;
+ }
+
++ rpc_iface = event_handler_proxy_create();
++ if (!rpc_iface) {
++ EMSG("Failed to create Capsule Update proxy");
++ goto fatal_error;
++ }
++
++ rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, rpc_iface);
++ if (rpc_status != RPC_SUCCESS) {
++ EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
++ goto fatal_error;
++ }
++
+ rpc_iface = capsule_update_proxy_create();
+ if (!rpc_iface) {
+ EMSG("Failed to create Capsule Update proxy");
+diff --git a/deployments/se-proxy/infra/corstone1000/corstone1000_event_handling.c b/deployments/se-proxy/infra/corstone1000/corstone1000_event_handling.c
+new file mode 100644
+index 00000000..faf450f2
+--- /dev/null
++++ b/deployments/se-proxy/infra/corstone1000/corstone1000_event_handling.c
+@@ -0,0 +1,91 @@
++/*
++ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ */
++
++#include <psa/client.h>
++#include <psa/sid.h>
++#include <trace.h>
++
++#include <protocols/rpc/common/packed-c/status.h>
++#include "corstone1000_event_handling.h"
++
++#define BOOT_CONFIRMED_EVENT (0x3)
++#define OPCODE_BOOT_CONFIRMED BOOT_CONFIRMED_EVENT
++
++enum corstone1000_ioctl_id {
++ IOCTL_CORSTONE1000_FWU_HOST_ACK = 1,
++};
++
++/* Service request handlers */
++static rpc_status_t boot_confirmed_handler(void *context, struct rpc_request *req);
++
++/* Handler mapping table for service */
++static const struct service_handler handler_table[] = {
++ {OPCODE_BOOT_CONFIRMED, boot_confirmed_handler}
++};
++
++struct rpc_service_interface *corstone1000_event_provider_init(
++ struct event_provider *context)
++{
++ struct rpc_service_interface *rpc_interface = NULL;
++ const struct rpc_uuid dummy_uuid = { .uuid = { 0 }};
++ if (!context)
++ return NULL;
++
++ service_provider_init(
++ &context->base_provider,
++ context,
++ &dummy_uuid,
++ handler_table,
++ sizeof(handler_table)/sizeof(struct service_handler));
++
++ rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
++
++ return rpc_interface;
++}
++
++static rpc_status_t event_handler(uint32_t opcode, struct rpc_caller_interface *caller)
++{
++ uint32_t ioctl_id;
++ rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
++
++ struct psa_invec in_vec[] = {
++ { .base = &ioctl_id, .len = sizeof(ioctl_id) }
++ };
++
++ if(!caller) {
++ EMSG("event_handler rpc_caller is NULL");
++ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
++ return rpc_status;
++ }
++
++ IMSG("event handler opcode %x", opcode);
++ switch(opcode) {
++ case OPCODE_BOOT_CONFIRMED:
++ ioctl_id = IOCTL_CORSTONE1000_FWU_HOST_ACK;
++ /* Boot Confirmed event from Normal World */
++
++ psa_call(caller,TFM_PLATFORM_SERVICE_HANDLE, TFM_PLATFORM_API_ID_IOCTL,
++ in_vec,IOVEC_LEN(in_vec), NULL, 0);
++ break;
++ default:
++ EMSG("%s unsupported opcode", __func__);
++ rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
++ }
++ return rpc_status;
++
++}
++
++static rpc_status_t boot_confirmed_handler(void *context, struct rpc_request *req)
++{
++ struct event_provider *this_instance = (struct event_provider*)context;
++ struct rpc_caller_interface *caller = this_instance->client.session->caller;
++ uint32_t opcode = req->opcode;
++ rpc_status_t rpc_status;
++
++ rpc_status = event_handler(opcode, caller);
++
++ return rpc_status;
++}
+diff --git a/deployments/se-proxy/infra/corstone1000/corstone1000_event_handling.h b/deployments/se-proxy/infra/corstone1000/corstone1000_event_handling.h
+new file mode 100644
+index 00000000..e8e60dae
+--- /dev/null
++++ b/deployments/se-proxy/infra/corstone1000/corstone1000_event_handling.h
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ */
++
++#ifndef CORSTONE1000_EVENT_HANDLING_H
++#define CORSTONE1000_EVENT_HANDLING_H
++
++#include <rpc/common/endpoint/rpc_service_interface.h>
++#include <service/common/provider/service_provider.h>
++#include <service/common/client/service_client.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/**
++ * The event_provider is a service provider that accepts events
++ * and delegates them to a suitable backend.
++ */
++struct event_provider
++{
++ struct service_provider base_provider;
++ struct service_client client;
++};
++
++/**
++ * \brief Initialize an instance of the event handler
++ *
++ * @param[in] context The instance to initialize
++ *
++ * \return An rpc_service_interface or NULL on failure
++ */
++struct rpc_service_interface *corstone1000_event_provider_init(
++ struct event_provider *context);
++
++#ifdef __cplusplus
++} /* extern "C" */
++#endif
++
++#endif /* CORSTONE1000_EVENT_HANDLING_H */
+diff --git a/deployments/se-proxy/infra/corstone1000/infra.cmake b/deployments/se-proxy/infra/corstone1000/infra.cmake
+index 0b04149a..b95801de 100644
+--- a/deployments/se-proxy/infra/corstone1000/infra.cmake
++++ b/deployments/se-proxy/infra/corstone1000/infra.cmake
+@@ -34,4 +34,5 @@ add_components(TARGET "se-proxy"
+ target_sources(se-proxy PRIVATE
+
+ ${CMAKE_CURRENT_LIST_DIR}/service_proxy_factory.c
++ ${CMAKE_CURRENT_LIST_DIR}/corstone1000_event_handling.c
+ )
+diff --git a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+index f0a4853e..ed42e2cb 100644
+--- a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
++++ b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+@@ -21,6 +21,7 @@
+ #include <protocols/service/fwu/fwu_proto.h>
+ #include <trace.h>
+ #include "corstone1000_config.h"
++#include "corstone1000_event_handling.h"
+
+ /* backends */
+ #include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
+@@ -165,6 +166,32 @@ struct rpc_service_interface *its_proxy_create(void)
+ return secure_storage_provider_init(&its_provider, backend, &its_uuid);
+ }
+
++struct rpc_service_interface *event_handler_proxy_create(void)
++{
++ static struct event_provider event_provider = {0};
++ rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
++
++ /* Static objects for proxy instance */
++ static struct rpc_caller_interface rse_comms = { 0 };
++ static struct rpc_caller_session rpc_session = { 0 };
++
++ rpc_status = rse_comms_caller_init(&rse_comms);
++ if (rpc_status != RPC_SUCCESS)
++ return NULL;
++
++ rpc_status = rpc_caller_session_open(&rpc_session, &rse_comms, &dummy_uuid, 0, 0);
++ if (rpc_status != RPC_SUCCESS)
++ return NULL;
++
++
++ event_provider.client.session = &rpc_session;
++ event_provider.client.rpc_status = RPC_SUCCESS;
++ event_provider.client.service_info.supported_encodings = 0;
++ event_provider.client.service_info.max_payload = 4096;
++
++ return corstone1000_event_provider_init(&event_provider);
++}
++
+ struct rpc_service_interface *fwu_proxy_create(void)
+ {
+ rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,141 @@
+From 6a26d67c0b531af07537aefcbe7a46fc71471d4f Mon Sep 17 00:00:00 2001
+From: Ali Can Ozaslan <ali.oezaslan@arm.com>
+Date: Thu, 27 Mar 2025 13:42:03 +0000
+Subject: [PATCH 8/8] platform: corstone1000: Define GUID for FWU payloads
+
+Specify the Global Unique Identifiers (GUIDs) for firmware update (FWU)
+payloads, which include BL2, TFM_S, FIP, and INITRAMFS.
+Note that the GUIDs differ between FVP and MPS3 platforms.
+
+Upstream-Status: Pending
+Signed-off-by: Ali Can Ozaslan <ali.oezaslan@arm.com>
+Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
+---
+ .../infra/corstone1000/corstone1000_config.h | 43 ++++++++++++++++---
+ .../corstone1000/service_proxy_factory.c | 41 +++++++++++++++---
+ 2 files changed, 73 insertions(+), 11 deletions(-)
+
+diff --git a/deployments/se-proxy/infra/corstone1000/corstone1000_config.h b/deployments/se-proxy/infra/corstone1000/corstone1000_config.h
+index 4a68c2fa..c4bd9c2c 100644
+--- a/deployments/se-proxy/infra/corstone1000/corstone1000_config.h
++++ b/deployments/se-proxy/infra/corstone1000/corstone1000_config.h
+@@ -11,17 +11,48 @@
+ /* Maximum payload size to be transferred at once to Secure Enclave */
+ #define MAX_PAYLOAD_SIZE 4096
+
+-#define CORSTONE1000_FVP_FULL_CAPSULE_UUID \
+-{ 0x4e, 0x3a, 0x9f, 0x98, 0xe0, 0x46, 0xd0, 0x4c, 0x98, 0x77, 0xa2, 0x5c, 0x70, 0xc0, 0x13, 0x29, }
++/*
++ * GUIDs for capsule updatable firmware images
++ *
++ * The GUIDs are generated with the UUIDv5 format with the following configurations:
++ * Namespace (for FVP GUIDs): 989f3a4e-46e0-4cd0-9877-a25c70c01329
++ * Namespace (for MPS3 GUIDs): df1865d1-90fb-4d59-9c38-c9f2c1bba8cc
++ * Names: in the `fw_name` field: `BL2`, `TFM_S`, `FIP`, `INITRAMFS`
++ * Note: Using the same namespace and `fw_name` values should generate the same GUIDs.
++ */
++
++#define FWU_FVP_BL2_CAPSULE_UUID \
++{ 0xf9, 0x83, 0xd8, 0xf1, 0xeb, 0xdf, 0x63, 0x53, 0x98, 0xd8, 0x68, 0x6e, 0xe3, 0xb6, 0x9f, 0x4f, }
++
++#define FWU_FVP_TFM_S_CAPSULE_UUID \
++{ 0x0e, 0x47, 0xad, 0x7f, 0xc5, 0x5e, 0x03, 0x5c, 0xa2, 0xc1, 0x47, 0x56, 0xb4, 0x95, 0xde, 0x61, }
++
++#define FWU_FVP_FIP_CAPSULE_UUID \
++{ 0x75, 0x36, 0x93, 0xf1, 0x8c, 0x5a, 0x6d, 0x5b, 0x9e, 0xf4, 0x84, 0x67, 0x39, 0xe8, 0x9b, 0xc8, }
++
++#define FWU_FVP_INITRAMFS_CAPSULE_UUID \
++{ 0xf9, 0xaf, 0x71, 0xf7, 0xe9, 0xc7, 0x99, 0x5f, 0x9e, 0xda, 0x23, 0x69, 0xdd, 0x69, 0x4f, 0x61, }
++
++#define FWU_MPS3_BL2_CAPSULE_UUID \
++{ 0xaa, 0xef, 0xfb, 0xfb, 0x56, 0x0a, 0xd5, 0x50, 0xb6, 0x51, 0x74, 0x09, 0x1d, 0x3d, 0x62, 0xcf, }
++
++#define FWU_MPS3_TFM_S_CAPSULE_UUID \
++{ 0xad, 0xc7, 0x4c, 0xaf, 0x2e, 0xee, 0x39, 0x5a, 0xaa, 0xd5, 0xfa, 0xc8, 0xa1, 0xe6, 0x17, 0x3c, }
++
++#define FWU_MPS3_FIP_CAPSULE_UUID \
++{ 0x96, 0x2f, 0x30, 0x55, 0xf0, 0xc4, 0xf9, 0x5c, 0x86, 0x24, 0xe7, 0xcc, 0x38, 0x8f, 0x2b, 0x68, }
+
+-#define CORSTONE1000_MPS3_FULL_CAPSULE_UUID \
+-{ 0xd1, 0x65, 0x18, 0xdf, 0xfb, 0x90, 0x59, 0x4d, 0x9c, 0x38, 0xc9, 0xf2, 0xc1, 0xbb, 0xa8, 0xcc, }
++#define FWU_MPS3_INITRAMFS_CAPSULE_UUID \
++{ 0x72, 0xc9, 0x8a, 0x3e, 0x3c, 0xc3, 0xc9, 0x5c, 0x90, 0xa0, 0xcd, 0xd3, 0x15, 0x96, 0x83, 0xea, }
+
+ /* Image indexes in the UEFI capsule */
+ enum fwu_image_index
+ {
+- FWU_IMAGE_INDEX_FULL_CAPSULE = 1,
+- FWU_IMAGE_INDEX_ESRT,
++ FWU_IMAGE_INDEX_CAPSULE_BL2 = 1,
++ FWU_IMAGE_INDEX_CAPSULE_TFM_S,
++ FWU_IMAGE_INDEX_CAPSULE_FIP,
++ FWU_IMAGE_INDEX_CAPSULE_INITRAMFS,
++ FWU_IMAGE_INDEX_ESRT ,
+ };
+
+ #endif /* CORSTONE1000_CONFIG_H */
+diff --git a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+index ed42e2cb..43a9ac37 100644
+--- a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
++++ b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+@@ -28,7 +28,14 @@
+ #include <service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h>
+ #include <service/attestation/client/psa/iat_client.h>
+
+-/* IMAGE_MAPPING_ELEMENT_COUNT includes the number of images to be updated and ESRT image */
++/* IMAGE_MAPPING_ELEMENT_COUNT includes the number of images to be updated and ESRT image.
++ * It includes:
++ * - BL2
++ * - TFM_S
++ * - FIP
++ * - INITRAMFS
++ * - ESRT
++ */
+ #define IMAGE_MAPPING_ELEMENT_COUNT (FWU_IMAGE_CAPSULE_COUNT + 1)
+
+ /* The index to access the ESRT image in the psa_fwu_m_image_mapping structure
+@@ -41,13 +48,37 @@ static const struct rpc_uuid dummy_uuid = { 0 };
+ static struct psa_fwu_m_image_mapping img_mapping[IMAGE_MAPPING_ELEMENT_COUNT] = {
+ #if PLATFORM_IS_FVP
+ {
+- .uuid = CORSTONE1000_FVP_FULL_CAPSULE_UUID,
+- .component = FWU_IMAGE_INDEX_FULL_CAPSULE
++ .uuid = FWU_FVP_BL2_CAPSULE_UUID,
++ .component = FWU_IMAGE_INDEX_CAPSULE_BL2
++ },
++ {
++ .uuid = FWU_FVP_TFM_S_CAPSULE_UUID,
++ .component = FWU_IMAGE_INDEX_CAPSULE_TFM_S
++ },
++ {
++ .uuid = FWU_FVP_FIP_CAPSULE_UUID,
++ .component = FWU_IMAGE_INDEX_CAPSULE_FIP
++ },
++ {
++ .uuid = FWU_FVP_INITRAMFS_CAPSULE_UUID,
++ .component = FWU_IMAGE_INDEX_CAPSULE_INITRAMFS
+ },
+ #else
+ {
+- .uuid = CORSTONE1000_MPS3_FULL_CAPSULE_UUID,
+- .component = FWU_IMAGE_INDEX_FULL_CAPSULE
++ .uuid = FWU_MPS3_BL2_CAPSULE_UUID,
++ .component = FWU_IMAGE_INDEX_CAPSULE_BL2
++ },
++ {
++ .uuid = FWU_MPS3_TFM_S_CAPSULE_UUID,
++ .component = FWU_IMAGE_INDEX_CAPSULE_TFM_S
++ },
++ {
++ .uuid = FWU_MPS3_FIP_CAPSULE_UUID,
++ .component = FWU_IMAGE_INDEX_CAPSULE_FIP
++ },
++ {
++ .uuid = FWU_MPS3_INITRAMFS_CAPSULE_UUID,
++ .component = FWU_IMAGE_INDEX_CAPSULE_INITRAMFS
+ },
+ #endif
+ };
+--
+2.25.1
+
@@ -20,6 +20,14 @@ SRC_URI:append:corstone1000 = " \
file://0021-Align-PSA-Crypto-structs-with-TF-Mv2.1.1.patch \
file://0016-Add-the-com-buffer-address-and-page-count.patch \
file://0017-Platform-Corstone1000-Add-PLATFORM_IS_FVP-toggle-for.patch \
+ file://0018-Integrate-PSA-FWU-IPC-framework-for-Corstone-1000.patch \
+ file://0019-Load-initial-image-state-in-PSA-FWU-M-update-agent.patch \
+ file://0020-Corstone1000-Define-PSA-FWU-image-mapping-structure.patch \
+ file://0021-Fix-PSA-FWU-IPC-psa_fwu_install-return-value-check.patch \
+ file://0022-fwu-Add-EFI-ESRT-v1-support.patch \
+ file://0023-platform-corstone1000-Enable-ESRT-support.patch \
+ file://0024-platform-corstone1000-Add-event-provider-proxy.patch \
+ file://0025-platform-corstone1000-Define-GUID-for-each-payloads.patch \
"
# The patches above introduce errors with GCC 14.1, silence them for now
CFLAGS:append:corstone1000 = " -Wno-int-conversion -Wno-implicit-function-declaration"