SPM: Introduce new agent API
Initially, just wrap the existing SPM PSA API.
This mostly just helps to identify the callers and to nail down the
types needed.
Some fairly minor changes to the design documentation to match this
implementation.
No behavioural change.
Signed-off-by: Chris Brand <chris.brand@cypress.com>
Change-Id: Id2f36d10156e8ace55f9f50355e6e8ebe1d762b8
diff --git a/docs/design_docs/dual-cpu/mailbox_ns_agent_update.rst b/docs/design_docs/dual-cpu/mailbox_ns_agent_update.rst
index f6760d1..ae84e6e 100644
--- a/docs/design_docs/dual-cpu/mailbox_ns_agent_update.rst
+++ b/docs/design_docs/dual-cpu/mailbox_ns_agent_update.rst
@@ -131,7 +131,7 @@
.. code-block:: c
psa_handle_t agent_psa_connect(uint32_t sid, uint32_t version,
- int32_t ns_client_id, void *client_data);
+ int32_t ns_client_id, const void *client_data);
One extra parameter ``ns_client_id`` added to tell SPM which NS client the
agent is representing when API gets called. It is recorded in the handle
@@ -151,18 +151,19 @@
.. code-block:: c
- typedef struct {
- psa_invec in_vecs[PSA_MAX_IOVEC];
- psa_outvec out_vecs[PSA_MAX_IOVEC];
- } client_vectors_t;
+ struct client_vectors {
+ psa_invec * in_vec;
+ psa_outvec * out_vec;
+ };
- typedef struct {
- int32_t ns_client_id;
- void *client_data;
- } client_param_t;
+ struct client_params {
+ int32_t ns_client_id;
+ const void *client_data;
+ };
- psa_status_t agent_psa_call(psa_handle_t handle, int32_t type,
- client_vectors_t *vecs, client_param_t *params);
+ psa_status_t agent_psa_call(psa_handle_t handle, int32_t ctrl_param,
+ const struct client_vectors *vecs,
+ const struct client_params *params);
Compared to the standard ``psa_call``, this API:
@@ -223,7 +224,7 @@
psa_signal_t signals;
psa_status_t status;
psa_msg_t msg;
- client_param_t client_param;
+ struct client_params client_param;
struct __customized_t ns_msg;
while (1) {
@@ -234,9 +235,10 @@
__customized_platform_get_mail(&ns_msg);
/*
- * MACRO 'SID', 'VER', 'NSID' and 'VECTORS' represents necessary
- * information extraction from 'ns_msg', put MACRO names here
- * and leave the details to the implementation.
+ * MACRO 'SID', 'VER', 'NSID', 'INVEC_LEN', 'OUTVEC_LEN', and
+ * 'VECTORS' represent necessary information extraction from
+ * 'ns_msg', put MACRO names here and leave the details to the
+ * implementation.
*/
if (ns_msg.type == PSA_IPC_CONNECT) {
ns_msg.handle = agent_psa_connect(SID(ns_msg), VER(ns_msg),
@@ -249,7 +251,9 @@
client_param.client_data = &ns_msg;
ns_msg.status = agent_psa_call(ns_msg.handle,
- ns_msg.type,
+ PARAM_PACK(ns_msg.type,
+ INVEC_LEN(ns_msg),
+ OUTVEC_LEN(ns_msg)),
VECTORS(ns_msg),
&client_param);
/* Handle the stateless service case. */
@@ -291,7 +295,8 @@
.. code-block:: c
psa_status_t agent_psa_call(psa_handle_t handle, int32_t ctrl_param,
- client_vectors_t *vecs, client_param_t *params);
+ const struct client_vectors *vecs,
+ const struct client_params *params);
``agent_psa_call`` reuses the existing ``tfm_spm_client_psa_call`` as the
@@ -441,3 +446,5 @@
--------------
*Copyright (c) 2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
+or an affiliate of Cypress Semiconductor Corporation. All rights reserved.*
diff --git a/platform/ext/target/arm/corstone1000/openamp/tfm_spe_dual_core_psa_client_secure_lib.c b/platform/ext/target/arm/corstone1000/openamp/tfm_spe_dual_core_psa_client_secure_lib.c
index fe49835..0d3a6ac 100644
--- a/platform/ext/target/arm/corstone1000/openamp/tfm_spe_dual_core_psa_client_secure_lib.c
+++ b/platform/ext/target/arm/corstone1000/openamp/tfm_spe_dual_core_psa_client_secure_lib.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- * Copyright (c) 2021, Cypress Semiconductor Corporation. All rights reserved.
+ * Copyright (c) 2021-2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -177,6 +178,8 @@
spm_params->type = s_map_entry->msg.params.psa_call_params.type;
spm_params->in_len = s_map_entry->msg.params.psa_call_params.in_len;
spm_params->out_len = s_map_entry->msg.params.psa_call_params.out_len;
+ spm_params->ns_client_id = s_map_entry->msg.client_id;
+ spm_params->client_data = NULL;
spm_params->out_vec = NULL;
ret = alloc_and_prepare_out_vecs(&spm_params->out_vec, s_map_entry);
@@ -279,6 +282,8 @@
case OPENAMP_PSA_CONNECT:
spm_params.sid = s_map_entry->msg.params.psa_connect_params.sid;
spm_params.version = s_map_entry->msg.params.psa_connect_params.version;
+ spm_params->ns_client_id = s_map_entry->msg.client_id;
+ spm_params.client_data = NULL;
psa_ret = tfm_rpc_psa_connect(&spm_params);
if (psa_ret != PSA_SUCCESS) {
send_service_reply_to_non_secure(psa_ret, s_map_entry);
diff --git a/platform/ext/target/arm/rss/common/rss_comms/rss_comms.c b/platform/ext/target/arm/rss/common/rss_comms/rss_comms.c
index d51e8d8..b28cda4 100644
--- a/platform/ext/target/arm/rss/common/rss_comms/rss_comms.c
+++ b/platform/ext/target/arm/rss/common/rss_comms/rss_comms.c
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -32,6 +34,8 @@
.in_len = req->in_len,
.out_vec = req->out_vec,
.out_len = req->out_len,
+ .ns_client_id = req->client_id,
+ .client_data = NULL,
};
SPMLOG_DBGMSG("[RSS-COMMS] Dispatching message\r\n");
diff --git a/secure_fw/spm/CMakeLists.txt b/secure_fw/spm/CMakeLists.txt
index 9c69791..63c9d9d 100755
--- a/secure_fw/spm/CMakeLists.txt
+++ b/secure_fw/spm/CMakeLists.txt
@@ -1,6 +1,6 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2020-2023, Arm Limited. All rights reserved.
-# Copyright (c) 2021-2022 Cypress Semiconductor Corporation (an Infineon
+# Copyright (c) 2021-2023 Cypress Semiconductor Corporation (an Infineon
# company) or an affiliate of Cypress Semiconductor Corporation. All rights
# reserved.
#
@@ -34,6 +34,7 @@
target_sources(tfm_spm
PRIVATE
+ $<$<BOOL:${TFM_MULTI_CORE_TOPOLOGY}>:core/agent_api.c>
core/tfm_boot_data.c
core/utilities.c
$<$<NOT:$<STREQUAL:${TFM_SPM_LOG_LEVEL},TFM_SPM_LOG_LEVEL_SILENCE>>:core/spm_log.c>
diff --git a/secure_fw/spm/core/agent_api.c b/secure_fw/spm/core/agent_api.c
new file mode 100644
index 0000000..b7944bc
--- /dev/null
+++ b/secure_fw/spm/core/agent_api.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "ffm/agent_api.h"
+
+#include "ffm/psa_api.h"
+
+psa_status_t agent_psa_call(psa_handle_t handle, int32_t ctrl_param,
+ const struct client_vectors *vecs,
+ const struct client_params *params)
+{
+ (void)params;
+
+ /* For now, just call the non-agent API */
+ return tfm_spm_client_psa_call(handle, ctrl_param,
+ vecs->in_vec, vecs->out_vec);
+}
+
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+
+psa_handle_t agent_psa_connect(uint32_t sid, uint32_t version,
+ int32_t ns_client_id, const void *client_data)
+{
+ (void)ns_client_id;
+ (void)client_data;
+
+ return tfm_spm_client_psa_connect(sid, version);
+}
+
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
diff --git a/secure_fw/spm/core/tfm_rpc.c b/secure_fw/spm/core/tfm_rpc.c
index 71efcf0..f178499 100644
--- a/secure_fw/spm/core/tfm_rpc.c
+++ b/secure_fw/spm/core/tfm_rpc.c
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -7,6 +9,7 @@
#include "config_impl.h"
#include "spm.h"
+#include "ffm/agent_api.h"
#include "ffm/psa_api.h"
#include "tfm_rpc.h"
#include "utilities.h"
@@ -51,12 +54,22 @@
psa_status_t tfm_rpc_psa_call(const struct client_call_params_t *params)
{
SPM_ASSERT(params != NULL);
+ /* TODO: Is the lifetime of this variable appropriate ? */
+ const struct client_vectors vecs = {
+ .in_vec = params->in_vec,
+ .out_vec = params->out_vec,
+ };
+ const struct client_params client_params = {
+ .ns_client_id = params->ns_client_id,
+ .client_data = params->client_data,
+ };
- return tfm_spm_client_psa_call(params->handle,
- PARAM_PACK(params->type,
- params->in_len,
- params->out_len),
- params->in_vec, params->out_vec);
+ return agent_psa_call(params->handle,
+ PARAM_PACK(params->type,
+ params->in_len,
+ params->out_len),
+ &vecs,
+ &client_params);
}
/* Following PSA APIs are only needed by connection-based services */
@@ -66,7 +79,10 @@
{
SPM_ASSERT(params != NULL);
- return tfm_spm_client_psa_connect(params->sid, params->version);
+ return agent_psa_connect(params->sid,
+ params->version,
+ params->ns_client_id,
+ params->client_data);
}
void tfm_rpc_psa_close(const struct client_call_params_t *params)
diff --git a/secure_fw/spm/core/tfm_rpc.h b/secure_fw/spm/core/tfm_rpc.h
index 40de90b..ae0524f 100644
--- a/secure_fw/spm/core/tfm_rpc.h
+++ b/secure_fw/spm/core/tfm_rpc.h
@@ -42,6 +42,8 @@
psa_outvec *out_vec;
size_t out_len;
uint32_t version;
+ int32_t ns_client_id;
+ void *client_data;
};
/*
diff --git a/secure_fw/spm/core/tfm_spe_mailbox.c b/secure_fw/spm/core/tfm_spe_mailbox.c
index b8d4fb2..adb01af 100644
--- a/secure_fw/spm/core/tfm_spe_mailbox.c
+++ b/secure_fw/spm/core/tfm_spe_mailbox.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2019-2022, Arm Limited. All rights reserved.
- * Copyright (c) 2021, Cypress Semiconductor Corporation. All rights reserved.
+ * Copyright (c) 2021-2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -29,8 +30,6 @@
SPM_ASSERT(params != NULL);
SPM_ASSERT(psa_ret != NULL);
- (void)client_id;
-
switch (call_type) {
case MAILBOX_PSA_FRAMEWORK_VERSION:
*psa_ret = tfm_rpc_psa_framework_version();
@@ -46,6 +45,8 @@
spm_params.in_len = params->psa_call_params.in_len;
spm_params.out_vec = params->psa_call_params.out_vec;
spm_params.out_len = params->psa_call_params.out_len;
+ spm_params.ns_client_id = client_id;
+ spm_params.client_data = NULL;
*psa_ret = tfm_rpc_psa_call(&spm_params);
return MAILBOX_SUCCESS;
/* Following cases are only needed by connection-based services */
@@ -53,6 +54,8 @@
case MAILBOX_PSA_CONNECT:
spm_params.sid = params->psa_connect_params.sid;
spm_params.version = params->psa_connect_params.version;
+ spm_params.ns_client_id = client_id;
+ spm_params.client_data = NULL;
*psa_ret = tfm_rpc_psa_connect(&spm_params);
return MAILBOX_SUCCESS;
case MAILBOX_PSA_CLOSE:
diff --git a/secure_fw/spm/include/ffm/agent_api.h b/secure_fw/spm/include/ffm/agent_api.h
new file mode 100644
index 0000000..f76b61d
--- /dev/null
+++ b/secure_fw/spm/include/ffm/agent_api.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __AGENT_API_H__
+#define __AGENT_API_H__
+
+#include <stdint.h>
+
+#include "config_impl.h"
+#include "psa/client.h"
+
+
+struct client_vectors {
+ const psa_invec *in_vec;
+ psa_outvec *out_vec;
+};
+
+
+struct client_params {
+ int32_t ns_client_id;
+ const void *client_data;
+};
+
+
+/**
+ * \brief psa_call() interface for NS agents
+ *
+ * \param[in] handle Service handle to the established connection,
+ * \ref psa_handle_t
+ * \param[in] ctrl_param Parameters combined in uint32_t,
+ * includes request type, in_num and out_num.
+ * \param[in] vecs Combines the psa_invec and psa_outvec params
+ * for the psa_call() to be made.
+ * \param[in] params NS agent's client identifier.
+ * Ignored for connection-based services.
+ * ns_client_id identifies the NS client.
+ * Zero or positive values are ignored and SPM
+ * uses the agent's ID instead.
+ * client_data is treated as opaque by SPM.
+ *
+ * \retval PSA_SUCCESS Success.
+ * \retval "Does not return" The call is invalid, one or more of the
+ * following are true:
+ * \arg An invalid handle was passed.
+ * \arg The connection is already handling a request.
+ * \arg An invalid memory reference was provided.
+ * \arg in_num + out_num > PSA_MAX_IOVEC.
+ * \arg The message is unrecognized by the RoT
+ * Service or incorrectly formatted.
+ */
+psa_status_t agent_psa_call(psa_handle_t handle, int32_t ctrl_param,
+ const struct client_vectors *vecs,
+ const struct client_params *params);
+
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+
+/**
+ * \brief psa_connect() interface for NS agents
+ *
+ * \param[in] sid RoT Service identity.
+ * \param[in] version The version of the RoT Service.
+ * \param[in] ns_client_id Which NS client is being represented.
+ * Negative value identifies the NS client.
+ * Zero or positive values are ignored
+ * and SPM uses the agent's ID instead.
+ * \param[in] client_data Caller identifier, treated as opaque
+ * by SPM.
+ *
+ * \retval PSA_SUCCESS Success.
+ * \retval PSA_ERROR_CONNECTION_REFUSED The SPM or RoT Service has refused the
+ * connection.
+ * \retval PSA_ERROR_CONNECTION_BUSY The SPM or RoT Service cannot make the
+ * connection at the moment.
+ * \retval "Does not return" The RoT Service ID and version are not
+ * supported, or the caller is not
+ * permitted to access the service.
+ */
+psa_handle_t agent_psa_connect(uint32_t sid, uint32_t version,
+ int32_t ns_client_id, const void *client_data);
+
+#else
+#define agent_psa_connect NULL
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
+
+#endif /* __AGENT_API_H__ */