diff mbox series

[05/13] arm-bsp/trusted-services: corstone1000: PSA FWU implementation

Message ID 20250730115327.3671160-6-harsimransingh.tungal@arm.com
State New
Headers show
Series Add PSA FWU support and capsule generation via EDK2 tooling | expand

Commit Message

Harsimran Singh Tungal July 30, 2025, 11:53 a.m. UTC
This commit implement the required changes in Trusted-Services in order
to incorporate PSA FWU implementation. It involves the following changes:

1. Integrate IPC framework for PSA FWU calls between Cortex-A 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.

2. 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.

3. Define PSA FWU image mapping structure.
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.

4. 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.

5. Add ESRT support
Add ESRT 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 ESRT data structures.
2. Modify image_directory_read() to include ESRT data read support
3. Modify psa_fwu_m_update_agent_init to initialize ESRT image
attributes

6. 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.

7. 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

8. Define GUID for each payloads
Define GUID's for all the 4 payloads for FVP and
MPS3.

Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Signed-off-by: Ali Can Ozaslan <ali.oezaslan@arm.com>
Signed-off-by: Imre Kis <imre.kis@arm.com>
---
 ...-FWU-IPC-framework-for-Corstone-1000.patch | 436 ++++++++++++++++++
 ...mage-state-in-PSA-FWU-M-update-agent.patch | 188 ++++++++
 ...fine-PSA-FWU-image-mapping-structure.patch | 128 +++++
 ...C-psa_fwu_install-return-value-check.patch |  31 ++
 .../0022-fwu-Add-EFI-ESRT-v1-support.patch    | 178 +++++++
 ...orm-corstone1000-Enable-ESRT-support.patch | 129 ++++++
 ...orstone1000-Add-event-provider-proxy.patch | 268 +++++++++++
 ...ne1000-Define-GUID-for-each-payloads.patch | 141 ++++++
 .../trusted-services/ts-arm-platforms.inc     |   8 +
 9 files changed, 1507 insertions(+)
 create mode 100644 meta-arm-bsp/recipes-security/trusted-services/corstone1000/0018-Integrate-PSA-FWU-IPC-framework-for-Corstone-1000.patch
 create mode 100644 meta-arm-bsp/recipes-security/trusted-services/corstone1000/0019-Load-initial-image-state-in-PSA-FWU-M-update-agent.patch
 create mode 100644 meta-arm-bsp/recipes-security/trusted-services/corstone1000/0020-Corstone1000-Define-PSA-FWU-image-mapping-structure.patch
 create mode 100644 meta-arm-bsp/recipes-security/trusted-services/corstone1000/0021-Fix-PSA-FWU-IPC-psa_fwu_install-return-value-check.patch
 create mode 100644 meta-arm-bsp/recipes-security/trusted-services/corstone1000/0022-fwu-Add-EFI-ESRT-v1-support.patch
 create mode 100644 meta-arm-bsp/recipes-security/trusted-services/corstone1000/0023-platform-corstone1000-Enable-ESRT-support.patch
 create mode 100644 meta-arm-bsp/recipes-security/trusted-services/corstone1000/0024-platform-corstone1000-Add-event-provider-proxy.patch
 create mode 100644 meta-arm-bsp/recipes-security/trusted-services/corstone1000/0025-platform-corstone1000-Define-GUID-for-each-payloads.patch
diff mbox series

Patch

diff --git a/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0018-Integrate-PSA-FWU-IPC-framework-for-Corstone-1000.patch b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0018-Integrate-PSA-FWU-IPC-framework-for-Corstone-1000.patch
new file mode 100644
index 00000000..2c2bb428
--- /dev/null
+++ b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0018-Integrate-PSA-FWU-IPC-framework-for-Corstone-1000.patch
@@ -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
+
diff --git a/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0019-Load-initial-image-state-in-PSA-FWU-M-update-agent.patch b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0019-Load-initial-image-state-in-PSA-FWU-M-update-agent.patch
new file mode 100644
index 00000000..2f43369f
--- /dev/null
+++ b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0019-Load-initial-image-state-in-PSA-FWU-M-update-agent.patch
@@ -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
+
diff --git a/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0020-Corstone1000-Define-PSA-FWU-image-mapping-structure.patch b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0020-Corstone1000-Define-PSA-FWU-image-mapping-structure.patch
new file mode 100644
index 00000000..17b1f87e
--- /dev/null
+++ b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0020-Corstone1000-Define-PSA-FWU-image-mapping-structure.patch
@@ -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
+
diff --git a/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0021-Fix-PSA-FWU-IPC-psa_fwu_install-return-value-check.patch b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0021-Fix-PSA-FWU-IPC-psa_fwu_install-return-value-check.patch
new file mode 100644
index 00000000..da948bd0
--- /dev/null
+++ b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0021-Fix-PSA-FWU-IPC-psa_fwu_install-return-value-check.patch
@@ -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
+
diff --git a/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0022-fwu-Add-EFI-ESRT-v1-support.patch b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0022-fwu-Add-EFI-ESRT-v1-support.patch
new file mode 100644
index 00000000..ce810a35
--- /dev/null
+++ b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0022-fwu-Add-EFI-ESRT-v1-support.patch
@@ -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
+
diff --git a/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0023-platform-corstone1000-Enable-ESRT-support.patch b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0023-platform-corstone1000-Enable-ESRT-support.patch
new file mode 100644
index 00000000..18581440
--- /dev/null
+++ b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0023-platform-corstone1000-Enable-ESRT-support.patch
@@ -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
+
diff --git a/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0024-platform-corstone1000-Add-event-provider-proxy.patch b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0024-platform-corstone1000-Add-event-provider-proxy.patch
new file mode 100644
index 00000000..8de9f081
--- /dev/null
+++ b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0024-platform-corstone1000-Add-event-provider-proxy.patch
@@ -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
+
diff --git a/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0025-platform-corstone1000-Define-GUID-for-each-payloads.patch b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0025-platform-corstone1000-Define-GUID-for-each-payloads.patch
new file mode 100644
index 00000000..61ab4680
--- /dev/null
+++ b/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0025-platform-corstone1000-Define-GUID-for-each-payloads.patch
@@ -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
+
diff --git a/meta-arm-bsp/recipes-security/trusted-services/ts-arm-platforms.inc b/meta-arm-bsp/recipes-security/trusted-services/ts-arm-platforms.inc
index ed40ca7f..060725f1 100644
--- a/meta-arm-bsp/recipes-security/trusted-services/ts-arm-platforms.inc
+++ b/meta-arm-bsp/recipes-security/trusted-services/ts-arm-platforms.inc
@@ -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"