From 050be6fdfee656b0556766cc1db30f4c0ea87c79 Mon Sep 17 00:00:00 2001 From: Julian Hall Date: Tue, 12 Oct 2021 15:45:41 +0100 Subject: [PATCH 13/20] Add stub capsule update service components To facilitate development of a capsule update service provider, stub components are added to provide a starting point for an implementation. The capsule update service provider is integrated into the se-proxy/common deployment. Upstream-Status: Pending Signed-off-by: Vishnu Banavath Signed-off-by: Julian Hall Change-Id: I0d4049bb4de5af7ca80806403301692507085d28 Signed-off-by: Rui Miguel Silva --- .../backend/capsule_update_backend.h | 24 ++++ .../provider/capsule_update_provider.c | 133 ++++++++++++++++++ .../provider/capsule_update_provider.h | 51 +++++++ .../capsule_update/provider/component.cmake | 13 ++ deployments/se-proxy/common/se_proxy_sp.c | 3 + .../se-proxy/common/service_proxy_factory.c | 16 +++ .../se-proxy/common/service_proxy_factory.h | 1 + deployments/se-proxy/se-proxy.cmake | 1 + deployments/se-proxy/se_proxy_interfaces.h | 9 +- .../capsule_update/capsule_update_proto.h | 13 ++ protocols/service/capsule_update/opcodes.h | 17 +++ protocols/service/capsule_update/parameters.h | 15 ++ 12 files changed, 292 insertions(+), 4 deletions(-) create mode 100644 components/service/capsule_update/backend/capsule_update_backend.h create mode 100644 components/service/capsule_update/provider/capsule_update_provider.c create mode 100644 components/service/capsule_update/provider/capsule_update_provider.h create mode 100644 components/service/capsule_update/provider/component.cmake create mode 100644 protocols/service/capsule_update/capsule_update_proto.h create mode 100644 protocols/service/capsule_update/opcodes.h create mode 100644 protocols/service/capsule_update/parameters.h diff --git a/components/service/capsule_update/backend/capsule_update_backend.h b/components/service/capsule_update/backend/capsule_update_backend.h new file mode 100644 index 000000000000..f3144ff1d7d5 --- /dev/null +++ b/components/service/capsule_update/backend/capsule_update_backend.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CAPSULE_UPDATE_BACKEND_H +#define CAPSULE_UPDATE_BACKEND_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Defines the common capsule update backend interface. Concrete backends + * implement this interface for different types of platform. + */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CAPSULE_UPDATE_BACKEND_H */ diff --git a/components/service/capsule_update/provider/capsule_update_provider.c b/components/service/capsule_update/provider/capsule_update_provider.c new file mode 100644 index 000000000000..e133753f8560 --- /dev/null +++ b/components/service/capsule_update/provider/capsule_update_provider.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include "capsule_update_provider.h" + + +#define CAPSULE_UPDATE_REQUEST (0x1) +#define KERNEL_STARTED_EVENT (0x2) + +enum corstone1000_ioctl_id_t { + IOCTL_CORSTONE1000_FWU_FLASH_IMAGES = 0, + IOCTL_CORSTONE1000_FWU_HOST_ACK, +}; + +/* Service request handlers */ +static rpc_status_t update_capsule_handler(void *context, struct call_req *req); +static rpc_status_t boot_confirmed_handler(void *context, struct call_req *req); + +/* Handler mapping table for service */ +static const struct service_handler handler_table[] = { + {CAPSULE_UPDATE_OPCODE_UPDATE_CAPSULE, update_capsule_handler}, + {CAPSULE_UPDATE_OPCODE_BOOT_CONFIRMED, boot_confirmed_handler} +}; + +struct rpc_interface *capsule_update_provider_init( + struct capsule_update_provider *context) +{ + struct rpc_interface *rpc_interface = NULL; + + if (context) { + + service_provider_init( + &context->base_provider, + context, + handler_table, + sizeof(handler_table)/sizeof(struct service_handler)); + + rpc_interface = service_provider_get_rpc_interface(&context->base_provider); + } + + return rpc_interface; +} + +void capsule_update_provider_deinit(struct capsule_update_provider *context) +{ + (void)context; +} + +static rpc_status_t event_handler(uint32_t opcode, struct rpc_caller *caller) +{ + uint32_t ioctl_id; + psa_handle_t handle; + 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 CAPSULE_UPDATE_REQUEST: + /* Openamp call with IOCTL for firmware update*/ + ioctl_id = IOCTL_CORSTONE1000_FWU_FLASH_IMAGES; + handle = psa_connect(caller, TFM_SP_PLATFORM_IOCTL_SID, + TFM_SP_PLATFORM_IOCTL_VERSION); + if (handle <= 0) { + EMSG("%s Invalid handle", __func__); + rpc_status = TS_RPC_ERROR_INVALID_PARAMETER; + return rpc_status; + } + psa_call(caller,handle, PSA_IPC_CALL, + in_vec,IOVEC_LEN(in_vec), NULL, 0); + break; + + case KERNEL_STARTED_EVENT: + ioctl_id = IOCTL_CORSTONE1000_FWU_HOST_ACK; + /*openamp call with IOCTL for kernel start*/ + handle = psa_connect(caller, TFM_SP_PLATFORM_IOCTL_SID, + TFM_SP_PLATFORM_IOCTL_VERSION); + if (handle <= 0) { + EMSG("%s Invalid handle", __func__); + rpc_status = TS_RPC_ERROR_INVALID_PARAMETER; + return rpc_status; + } + psa_call(caller,handle, PSA_IPC_CALL, + 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; + } + return rpc_status; + +} + +static rpc_status_t update_capsule_handler(void *context, struct call_req *req) +{ + struct capsule_update_provider *this_instance = (struct capsule_update_provider*)context; + struct rpc_caller *caller = this_instance->client.caller; + uint32_t opcode = req->opcode; + rpc_status_t rpc_status = TS_RPC_ERROR_NOT_READY; + + rpc_status = event_handler(opcode, caller); + return rpc_status; +} + +static rpc_status_t boot_confirmed_handler(void *context, struct call_req *req) +{ + struct capsule_update_provider *this_instance = (struct capsule_update_provider*)context; + struct rpc_caller *caller = this_instance->client.caller; + uint32_t opcode = req->opcode; + rpc_status_t rpc_status = TS_RPC_ERROR_NOT_READY; + + rpc_status = event_handler(opcode, caller); + + return rpc_status; +} diff --git a/components/service/capsule_update/provider/capsule_update_provider.h b/components/service/capsule_update/provider/capsule_update_provider.h new file mode 100644 index 000000000000..3de49854ea90 --- /dev/null +++ b/components/service/capsule_update/provider/capsule_update_provider.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CAPSULE_UPDATE_PROVIDER_H +#define CAPSULE_UPDATE_PROVIDER_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The capsule_update_provider is a service provider that accepts update capsule + * requests and delegates them to a suitable backend that applies the update. + */ +struct capsule_update_provider +{ + struct service_provider base_provider; + struct service_client client; +}; + +/** + * \brief Initialize an instance of the capsule update service provider + * + * @param[in] context The instance to initialize + * + * \return An rpc_interface or NULL on failure + */ +struct rpc_interface *capsule_update_provider_init( + struct capsule_update_provider *context); + +/** + * \brief Cleans up when the instance is no longer needed + * + * \param[in] context The instance to de-initialize + */ +void capsule_update_provider_deinit( + struct capsule_update_provider *context); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CAPSULE_UPDATE_PROVIDER_H */ diff --git a/components/service/capsule_update/provider/component.cmake b/components/service/capsule_update/provider/component.cmake new file mode 100644 index 000000000000..1d412eb234d9 --- /dev/null +++ b/components/service/capsule_update/provider/component.cmake @@ -0,0 +1,13 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2021, 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}/capsule_update_provider.c" + ) diff --git a/deployments/se-proxy/common/se_proxy_sp.c b/deployments/se-proxy/common/se_proxy_sp.c index a37396f4454b..a38ad6ca3f56 100644 --- a/deployments/se-proxy/common/se_proxy_sp.c +++ b/deployments/se-proxy/common/se_proxy_sp.c @@ -77,6 +77,9 @@ void __noreturn sp_main(struct ffa_init_info *init_info) } rpc_demux_attach(&rpc_demux, SE_PROXY_INTERFACE_ID_ATTEST, rpc_iface); + rpc_iface = capsule_update_proxy_create(); + rpc_demux_attach(&rpc_demux, SE_PROXY_INTERFACE_ID_CAPSULE_UPDATE, rpc_iface); + /* End of boot phase */ result = sp_msg_wait(&req_msg); if (result != SP_RESULT_OK) { diff --git a/deployments/se-proxy/common/service_proxy_factory.c b/deployments/se-proxy/common/service_proxy_factory.c index 7edeef8b434a..591cc9eeb59e 100644 --- a/deployments/se-proxy/common/service_proxy_factory.c +++ b/deployments/se-proxy/common/service_proxy_factory.c @@ -13,6 +13,7 @@ #include #include #include +#include /* Stub backends */ #include @@ -93,3 +94,18 @@ struct rpc_interface *its_proxy_create(void) return secure_storage_provider_init(&its_provider, backend); } + +struct rpc_interface *capsule_update_proxy_create(void) +{ + static struct capsule_update_provider capsule_update_provider; + static struct rpc_caller *capsule_update_caller; + + capsule_update_caller = openamp_caller_init(&openamp); + + if (!capsule_update_caller) + return NULL; + + capsule_update_provider.client.caller = capsule_update_caller; + + return capsule_update_provider_init(&capsule_update_provider); +} diff --git a/deployments/se-proxy/common/service_proxy_factory.h b/deployments/se-proxy/common/service_proxy_factory.h index 298d407a2371..02aa7fe2550d 100644 --- a/deployments/se-proxy/common/service_proxy_factory.h +++ b/deployments/se-proxy/common/service_proxy_factory.h @@ -17,6 +17,7 @@ struct rpc_interface *attest_proxy_create(void); struct rpc_interface *crypto_proxy_create(void); struct rpc_interface *ps_proxy_create(void); struct rpc_interface *its_proxy_create(void); +struct rpc_interface *capsule_update_proxy_create(void); #ifdef __cplusplus } diff --git a/deployments/se-proxy/se-proxy.cmake b/deployments/se-proxy/se-proxy.cmake index 3dbbc36c968d..f0db2d43f443 100644 --- a/deployments/se-proxy/se-proxy.cmake +++ b/deployments/se-proxy/se-proxy.cmake @@ -51,6 +51,7 @@ add_components(TARGET "se-proxy" "components/service/attestation/provider/serializer/packed-c" "components/service/attestation/reporter/psa_ipc" "components/service/attestation/client/psa_ipc" + "components/service/capsule_update/provider" "components/rpc/openamp/caller/sp" # Stub service provider backends diff --git a/deployments/se-proxy/se_proxy_interfaces.h b/deployments/se-proxy/se_proxy_interfaces.h index 48908f846990..3d4a7c204785 100644 --- a/deployments/se-proxy/se_proxy_interfaces.h +++ b/deployments/se-proxy/se_proxy_interfaces.h @@ -8,9 +8,10 @@ #define SE_PROXY_INTERFACES_H /* Interface IDs from service endpoints available from an se-proxy deployment */ -#define SE_PROXY_INTERFACE_ID_ITS (0) -#define SE_PROXY_INTERFACE_ID_PS (1) -#define SE_PROXY_INTERFACE_ID_CRYPTO (2) -#define SE_PROXY_INTERFACE_ID_ATTEST (3) +#define SE_PROXY_INTERFACE_ID_ITS (0) +#define SE_PROXY_INTERFACE_ID_PS (1) +#define SE_PROXY_INTERFACE_ID_CRYPTO (2) +#define SE_PROXY_INTERFACE_ID_ATTEST (3) +#define SE_PROXY_INTERFACE_ID_CAPSULE_UPDATE (4) #endif /* SE_PROXY_INTERFACES_H */ diff --git a/protocols/service/capsule_update/capsule_update_proto.h b/protocols/service/capsule_update/capsule_update_proto.h new file mode 100644 index 000000000000..8f326cd387fb --- /dev/null +++ b/protocols/service/capsule_update/capsule_update_proto.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CAPSULE_UPDATE_PROTO_H +#define CAPSULE_UPDATE_PROTO_H + +#include +#include + +#endif /* CAPSULE_UPDATE_PROTO_H */ diff --git a/protocols/service/capsule_update/opcodes.h b/protocols/service/capsule_update/opcodes.h new file mode 100644 index 000000000000..8185a0902378 --- /dev/null +++ b/protocols/service/capsule_update/opcodes.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CAPSULE_UPDATE_OPCODES_H +#define CAPSULE_UPDATE_OPCODES_H + +/** + * Opcode definitions for the capsule update service + */ + +#define CAPSULE_UPDATE_OPCODE_UPDATE_CAPSULE 1 +#define CAPSULE_UPDATE_OPCODE_BOOT_CONFIRMED 2 + +#endif /* CAPSULE_UPDATE_OPCODES_H */ diff --git a/protocols/service/capsule_update/parameters.h b/protocols/service/capsule_update/parameters.h new file mode 100644 index 000000000000..285d924186be --- /dev/null +++ b/protocols/service/capsule_update/parameters.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CAPSULE_UPDATE_PARAMETERS_H +#define CAPSULE_UPDATE_PARAMETERS_H + +/** + * Operation parameter definitions for the capsule update service access protocol. + */ + + +#endif /* CAPSULE_UPDATE_PARAMETERS_H */ -- 2.38.1