blob: 943568c8c6efe369ce3cf01bbed90407ffd48bbf [file] [log] [blame]
Brad Bishopbec4ebc2022-08-03 09:55:16 -04001From eb1beb0f4f3a0d97a1ee941b068fb1f3b7ba7d7b Mon Sep 17 00:00:00 2001
2From: Julian Hall <julian.hall@arm.com>
3Date: Tue, 12 Oct 2021 15:45:41 +0100
4Subject: [PATCH] Add stub capsule update service components
5
6To facilitate development of a capsule update service provider,
7stub components are added to provide a starting point for an
8implementation. The capsule update service provider is integrated
9into the se-proxy/opteesp deployment.
10
11Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
12Signed-off-by: Julian Hall <julian.hall@arm.com>
13Change-Id: I0d4049bb4de5af7ca80806403301692507085d28
14
15Upstream-Status: Pending [Not submitted to upstream yet]
16Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
17
18
19---
20 .../backend/capsule_update_backend.h | 24 ++++
21 .../provider/capsule_update_provider.c | 133 ++++++++++++++++++
22 .../provider/capsule_update_provider.h | 51 +++++++
23 .../capsule_update/provider/component.cmake | 13 ++
24 deployments/se-proxy/opteesp/CMakeLists.txt | 1 +
25 deployments/se-proxy/opteesp/se_proxy_sp.c | 3 +
26 .../se-proxy/opteesp/service_proxy_factory.c | 16 +++
27 .../se-proxy/opteesp/service_proxy_factory.h | 1 +
28 deployments/se-proxy/se_proxy_interfaces.h | 9 +-
29 .../capsule_update/capsule_update_proto.h | 13 ++
30 protocols/service/capsule_update/opcodes.h | 17 +++
31 protocols/service/capsule_update/parameters.h | 15 ++
32 12 files changed, 292 insertions(+), 4 deletions(-)
33 create mode 100644 components/service/capsule_update/backend/capsule_update_backend.h
34 create mode 100644 components/service/capsule_update/provider/capsule_update_provider.c
35 create mode 100644 components/service/capsule_update/provider/capsule_update_provider.h
36 create mode 100644 components/service/capsule_update/provider/component.cmake
37 create mode 100644 protocols/service/capsule_update/capsule_update_proto.h
38 create mode 100644 protocols/service/capsule_update/opcodes.h
39 create mode 100644 protocols/service/capsule_update/parameters.h
40
41diff --git a/components/service/capsule_update/backend/capsule_update_backend.h b/components/service/capsule_update/backend/capsule_update_backend.h
42new file mode 100644
43index 00000000..f3144ff1
44--- /dev/null
45+++ b/components/service/capsule_update/backend/capsule_update_backend.h
46@@ -0,0 +1,24 @@
47+/*
48+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
49+ *
50+ * SPDX-License-Identifier: BSD-3-Clause
51+ */
52+
53+#ifndef CAPSULE_UPDATE_BACKEND_H
54+#define CAPSULE_UPDATE_BACKEND_H
55+
56+#ifdef __cplusplus
57+extern "C" {
58+#endif
59+
60+/**
61+ * Defines the common capsule update backend interface. Concrete backends
62+ * implement this interface for different types of platform.
63+ */
64+
65+
66+#ifdef __cplusplus
67+} /* extern "C" */
68+#endif
69+
70+#endif /* CAPSULE_UPDATE_BACKEND_H */
71diff --git a/components/service/capsule_update/provider/capsule_update_provider.c b/components/service/capsule_update/provider/capsule_update_provider.c
72new file mode 100644
73index 00000000..9bbd7abc
74--- /dev/null
75+++ b/components/service/capsule_update/provider/capsule_update_provider.c
76@@ -0,0 +1,133 @@
77+/*
78+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
79+ *
80+ * SPDX-License-Identifier: BSD-3-Clause
81+ */
82+
83+#include <psa/client.h>
84+#include <psa/sid.h>
85+#include <trace.h>
86+
87+#include <protocols/service/capsule_update/capsule_update_proto.h>
88+#include <protocols/rpc/common/packed-c/status.h>
89+#include "capsule_update_provider.h"
90+
91+
92+#define CAPSULE_UPDATE_REQUEST (0x1)
93+#define KERNEL_STARTED_EVENT (0x2)
94+
95+enum corstone1000_ioctl_id_t {
96+ IOCTL_CORSTONE1000_FWU_FLASH_IMAGES = 0,
97+ IOCTL_CORSTONE1000_FWU_HOST_ACK,
98+};
99+
100+/* Service request handlers */
101+static rpc_status_t update_capsule_handler(void *context, struct call_req *req);
102+static rpc_status_t boot_confirmed_handler(void *context, struct call_req *req);
103+
104+/* Handler mapping table for service */
105+static const struct service_handler handler_table[] = {
106+ {CAPSULE_UPDATE_OPCODE_UPDATE_CAPSULE, update_capsule_handler},
107+ {CAPSULE_UPDATE_OPCODE_BOOT_CONFIRMED, boot_confirmed_handler}
108+};
109+
110+struct rpc_interface *capsule_update_provider_init(
111+ struct capsule_update_provider *context)
112+{
113+ struct rpc_interface *rpc_interface = NULL;
114+
115+ if (context) {
116+
117+ service_provider_init(
118+ &context->base_provider,
119+ context,
120+ handler_table,
121+ sizeof(handler_table)/sizeof(struct service_handler));
122+
123+ rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
124+ }
125+
126+ return rpc_interface;
127+}
128+
129+void capsule_update_provider_deinit(struct capsule_update_provider *context)
130+{
131+ (void)context;
132+}
133+
134+static rpc_status_t event_handler(uint32_t opcode, struct rpc_caller *caller)
135+{
136+ uint32_t ioctl_id;
137+ psa_handle_t handle;
138+ rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
139+
140+ struct psa_invec in_vec[] = {
141+ { .base = &ioctl_id, .len = sizeof(ioctl_id) }
142+ };
143+
144+ if(!caller) {
145+ EMSG("event_handler rpc_caller is NULL");
146+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
147+ return rpc_status;
148+ }
149+
150+ MSG("event handler opcode %x", opcode);
151+ switch(opcode) {
152+ case CAPSULE_UPDATE_REQUEST:
153+ /* Openamp call with IOCTL for firmware update*/
154+ ioctl_id = IOCTL_CORSTONE1000_FWU_FLASH_IMAGES;
155+ handle = psa_connect(caller, TFM_SP_PLATFORM_IOCTL_SID,
156+ TFM_SP_PLATFORM_IOCTL_VERSION);
157+ if (handle <= 0) {
158+ EMSG("%s Invalid handle", __func__);
159+ rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
160+ return rpc_status;
161+ }
162+ psa_call(caller,handle, PSA_IPC_CALL,
163+ in_vec,IOVEC_LEN(in_vec), NULL, 0);
164+ break;
165+
166+ case KERNEL_STARTED_EVENT:
167+ ioctl_id = IOCTL_CORSTONE1000_FWU_HOST_ACK;
168+ /*openamp call with IOCTL for kernel start*/
169+ handle = psa_connect(caller, TFM_SP_PLATFORM_IOCTL_SID,
170+ TFM_SP_PLATFORM_IOCTL_VERSION);
171+ if (handle <= 0) {
172+ EMSG("%s Invalid handle", __func__);
173+ rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
174+ return rpc_status;
175+ }
176+ psa_call(caller,handle, PSA_IPC_CALL,
177+ in_vec,IOVEC_LEN(in_vec), NULL, 0);
178+ break;
179+ default:
180+ EMSG("%s unsupported opcode", __func__);
181+ rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
182+ return rpc_status;
183+ }
184+ return rpc_status;
185+
186+}
187+
188+static rpc_status_t update_capsule_handler(void *context, struct call_req *req)
189+{
190+ struct capsule_update_provider *this_instance = (struct capsule_update_provider*)context;
191+ struct rpc_caller *caller = this_instance->client.caller;
192+ uint32_t opcode = req->opcode;
193+ rpc_status_t rpc_status = TS_RPC_ERROR_NOT_READY;
194+
195+ rpc_status = event_handler(opcode, caller);
196+ return rpc_status;
197+}
198+
199+static rpc_status_t boot_confirmed_handler(void *context, struct call_req *req)
200+{
201+ struct capsule_update_provider *this_instance = (struct capsule_update_provider*)context;
202+ struct rpc_caller *caller = this_instance->client.caller;
203+ uint32_t opcode = req->opcode;
204+ rpc_status_t rpc_status = TS_RPC_ERROR_NOT_READY;
205+
206+ rpc_status = event_handler(opcode, caller);
207+
208+ return rpc_status;
209+}
210diff --git a/components/service/capsule_update/provider/capsule_update_provider.h b/components/service/capsule_update/provider/capsule_update_provider.h
211new file mode 100644
212index 00000000..3de49854
213--- /dev/null
214+++ b/components/service/capsule_update/provider/capsule_update_provider.h
215@@ -0,0 +1,51 @@
216+/*
217+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
218+ *
219+ * SPDX-License-Identifier: BSD-3-Clause
220+ */
221+
222+#ifndef CAPSULE_UPDATE_PROVIDER_H
223+#define CAPSULE_UPDATE_PROVIDER_H
224+
225+#include <rpc/common/endpoint/rpc_interface.h>
226+#include <service/common/provider/service_provider.h>
227+#include <service/common/client/service_client.h>
228+#include <service/capsule_update/backend/capsule_update_backend.h>
229+
230+#ifdef __cplusplus
231+extern "C" {
232+#endif
233+
234+/**
235+ * The capsule_update_provider is a service provider that accepts update capsule
236+ * requests and delegates them to a suitable backend that applies the update.
237+ */
238+struct capsule_update_provider
239+{
240+ struct service_provider base_provider;
241+ struct service_client client;
242+};
243+
244+/**
245+ * \brief Initialize an instance of the capsule update service provider
246+ *
247+ * @param[in] context The instance to initialize
248+ *
249+ * \return An rpc_interface or NULL on failure
250+ */
251+struct rpc_interface *capsule_update_provider_init(
252+ struct capsule_update_provider *context);
253+
254+/**
255+ * \brief Cleans up when the instance is no longer needed
256+ *
257+ * \param[in] context The instance to de-initialize
258+ */
259+void capsule_update_provider_deinit(
260+ struct capsule_update_provider *context);
261+
262+#ifdef __cplusplus
263+} /* extern "C" */
264+#endif
265+
266+#endif /* CAPSULE_UPDATE_PROVIDER_H */
267diff --git a/components/service/capsule_update/provider/component.cmake b/components/service/capsule_update/provider/component.cmake
268new file mode 100644
269index 00000000..1d412eb2
270--- /dev/null
271+++ b/components/service/capsule_update/provider/component.cmake
272@@ -0,0 +1,13 @@
273+#-------------------------------------------------------------------------------
274+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
275+#
276+# SPDX-License-Identifier: BSD-3-Clause
277+#
278+#-------------------------------------------------------------------------------
279+if (NOT DEFINED TGT)
280+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
281+endif()
282+
283+target_sources(${TGT} PRIVATE
284+ "${CMAKE_CURRENT_LIST_DIR}/capsule_update_provider.c"
285+ )
286diff --git a/deployments/se-proxy/opteesp/CMakeLists.txt b/deployments/se-proxy/opteesp/CMakeLists.txt
287index 21904283..953bb716 100644
288--- a/deployments/se-proxy/opteesp/CMakeLists.txt
289+++ b/deployments/se-proxy/opteesp/CMakeLists.txt
290@@ -80,6 +80,7 @@ add_components(TARGET "se-proxy"
291 "components/service/attestation/reporter/psa_ipc"
292 "components/service/attestation/client/psa_ipc"
293 "components/rpc/openamp/caller/sp"
294+ "components/service/capsule_update/provider"
295
296 # Stub service provider backends
297 "components/rpc/dummy"
298diff --git a/deployments/se-proxy/opteesp/se_proxy_sp.c b/deployments/se-proxy/opteesp/se_proxy_sp.c
299index ef90d9ee..11b014b2 100644
300--- a/deployments/se-proxy/opteesp/se_proxy_sp.c
301+++ b/deployments/se-proxy/opteesp/se_proxy_sp.c
302@@ -48,6 +48,9 @@ void __noreturn sp_main(struct ffa_init_info *init_info)
303 rpc_iface = attest_proxy_create();
304 rpc_demux_attach(&rpc_demux, SE_PROXY_INTERFACE_ID_ATTEST, rpc_iface);
305
306+ rpc_iface = capsule_update_proxy_create();
307+ rpc_demux_attach(&rpc_demux, SE_PROXY_INTERFACE_ID_CAPSULE_UPDATE, rpc_iface);
308+
309 /* End of boot phase */
310 sp_msg_wait(&req_msg);
311
312diff --git a/deployments/se-proxy/opteesp/service_proxy_factory.c b/deployments/se-proxy/opteesp/service_proxy_factory.c
313index 7edeef8b..591cc9ee 100644
314--- a/deployments/se-proxy/opteesp/service_proxy_factory.c
315+++ b/deployments/se-proxy/opteesp/service_proxy_factory.c
316@@ -13,6 +13,7 @@
317 #include <service/crypto/factory/crypto_provider_factory.h>
318 #include <service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h>
319 #include <trace.h>
320+#include <service/capsule_update/provider/capsule_update_provider.h>
321
322 /* Stub backends */
323 #include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
324@@ -93,3 +94,18 @@ struct rpc_interface *its_proxy_create(void)
325
326 return secure_storage_provider_init(&its_provider, backend);
327 }
328+
329+struct rpc_interface *capsule_update_proxy_create(void)
330+{
331+ static struct capsule_update_provider capsule_update_provider;
332+ static struct rpc_caller *capsule_update_caller;
333+
334+ capsule_update_caller = openamp_caller_init(&openamp);
335+
336+ if (!capsule_update_caller)
337+ return NULL;
338+
339+ capsule_update_provider.client.caller = capsule_update_caller;
340+
341+ return capsule_update_provider_init(&capsule_update_provider);
342+}
343diff --git a/deployments/se-proxy/opteesp/service_proxy_factory.h b/deployments/se-proxy/opteesp/service_proxy_factory.h
344index 298d407a..02aa7fe2 100644
345--- a/deployments/se-proxy/opteesp/service_proxy_factory.h
346+++ b/deployments/se-proxy/opteesp/service_proxy_factory.h
347@@ -17,6 +17,7 @@ struct rpc_interface *attest_proxy_create(void);
348 struct rpc_interface *crypto_proxy_create(void);
349 struct rpc_interface *ps_proxy_create(void);
350 struct rpc_interface *its_proxy_create(void);
351+struct rpc_interface *capsule_update_proxy_create(void);
352
353 #ifdef __cplusplus
354 }
355diff --git a/deployments/se-proxy/se_proxy_interfaces.h b/deployments/se-proxy/se_proxy_interfaces.h
356index 48908f84..3d4a7c20 100644
357--- a/deployments/se-proxy/se_proxy_interfaces.h
358+++ b/deployments/se-proxy/se_proxy_interfaces.h
359@@ -8,9 +8,10 @@
360 #define SE_PROXY_INTERFACES_H
361
362 /* Interface IDs from service endpoints available from an se-proxy deployment */
363-#define SE_PROXY_INTERFACE_ID_ITS (0)
364-#define SE_PROXY_INTERFACE_ID_PS (1)
365-#define SE_PROXY_INTERFACE_ID_CRYPTO (2)
366-#define SE_PROXY_INTERFACE_ID_ATTEST (3)
367+#define SE_PROXY_INTERFACE_ID_ITS (0)
368+#define SE_PROXY_INTERFACE_ID_PS (1)
369+#define SE_PROXY_INTERFACE_ID_CRYPTO (2)
370+#define SE_PROXY_INTERFACE_ID_ATTEST (3)
371+#define SE_PROXY_INTERFACE_ID_CAPSULE_UPDATE (4)
372
373 #endif /* SE_PROXY_INTERFACES_H */
374diff --git a/protocols/service/capsule_update/capsule_update_proto.h b/protocols/service/capsule_update/capsule_update_proto.h
375new file mode 100644
376index 00000000..8f326cd3
377--- /dev/null
378+++ b/protocols/service/capsule_update/capsule_update_proto.h
379@@ -0,0 +1,13 @@
380+/*
381+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
382+ *
383+ * SPDX-License-Identifier: BSD-3-Clause
384+ */
385+
386+#ifndef CAPSULE_UPDATE_PROTO_H
387+#define CAPSULE_UPDATE_PROTO_H
388+
389+#include <protocols/service/capsule_update/opcodes.h>
390+#include <protocols/service/capsule_update/parameters.h>
391+
392+#endif /* CAPSULE_UPDATE_PROTO_H */
393diff --git a/protocols/service/capsule_update/opcodes.h b/protocols/service/capsule_update/opcodes.h
394new file mode 100644
395index 00000000..8185a090
396--- /dev/null
397+++ b/protocols/service/capsule_update/opcodes.h
398@@ -0,0 +1,17 @@
399+/*
400+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
401+ *
402+ * SPDX-License-Identifier: BSD-3-Clause
403+ */
404+
405+#ifndef CAPSULE_UPDATE_OPCODES_H
406+#define CAPSULE_UPDATE_OPCODES_H
407+
408+/**
409+ * Opcode definitions for the capsule update service
410+ */
411+
412+#define CAPSULE_UPDATE_OPCODE_UPDATE_CAPSULE 1
413+#define CAPSULE_UPDATE_OPCODE_BOOT_CONFIRMED 2
414+
415+#endif /* CAPSULE_UPDATE_OPCODES_H */
416diff --git a/protocols/service/capsule_update/parameters.h b/protocols/service/capsule_update/parameters.h
417new file mode 100644
418index 00000000..285d9241
419--- /dev/null
420+++ b/protocols/service/capsule_update/parameters.h
421@@ -0,0 +1,15 @@
422+/*
423+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
424+ *
425+ * SPDX-License-Identifier: BSD-3-Clause
426+ */
427+
428+#ifndef CAPSULE_UPDATE_PARAMETERS_H
429+#define CAPSULE_UPDATE_PARAMETERS_H
430+
431+/**
432+ * Operation parameter definitions for the capsule update service access protocol.
433+ */
434+
435+
436+#endif /* CAPSULE_UPDATE_PARAMETERS_H */