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 +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 +--- + 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#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 ++#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 + #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 + #include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h" + #include +@@ -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 +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 +Change-Id: I150e4fdb4584c8d07f5f1f642ee88197f9cff49b +Signed-off-by: Harsimran Singh Tungal +--- + .../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 +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 +Signed-off-by: Ali Can Ozaslan +--- + .../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 + #include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h" + #include ++#include "corstone1000_config.h" + + /* backends */ + #include +@@ -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 +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 +--- + .../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 +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 +--- + .../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 +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 +--- + .../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 + #include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h" ++#include + #include + #include "corstone1000_config.h" + +@@ -26,9 +27,17 @@ + #include + #include + ++/* 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 +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 +--- + .../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 ++#include ++#include ++ ++#include ++#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 ++#include ++#include ++ ++#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 + #include + #include "corstone1000_config.h" ++#include "corstone1000_event_handling.h" + + /* backends */ + #include +@@ -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 +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 +Signed-off-by: Harsimran Singh Tungal +--- + .../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 + #include + +-/* 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"