SPM: Add build-time config for optional PSA APIs
When there is no connection-based service,
the following PSA APIs are optional:
- psa_connect
- psa_close
- psa_set_rhandle
Currently, they are always built, linked and not removed
because the SVC handler references them.
This patch adds a config CONFIG_TFM_CONNECTION_BASED_SERVICE_API
so that they can be excluded and save memory footprints.
Signed-off-by: Xinyu Zhang <xinyu.zhang@arm.com>
Change-Id: I0205ca6a569d375fb1879ab673470a4b2a7a7c01
diff --git a/interface/include/config_impl.h.template b/interface/include/config_impl.h.template
index 2a220ab..0696b91 100644
--- a/interface/include/config_impl.h.template
+++ b/interface/include/config_impl.h.template
@@ -59,4 +59,9 @@
#error "FP is not supported for SFN model."
#endif
+{% if partition_statistics['connection_based_srv_num'] > 0 %}
+/* Connection-based services exist, include the connection-specific API set. */
+#define {{"%-56s"|format("CONFIG_TFM_CONNECTION_BASED_SERVICE_API")}} 1
+{% endif %}
+
#endif /* __CONFIG_IMPL_H__ */
diff --git a/interface/include/psa_interface_redirect.h b/interface/include/psa_interface_redirect.h
index 1514f93..3c16cdf 100644
--- a/interface/include/psa_interface_redirect.h
+++ b/interface/include/psa_interface_redirect.h
@@ -13,12 +13,9 @@
#define psa_framework_version psa_framework_version_svc
#define psa_version psa_version_svc
-#define psa_connect psa_connect_svc
#define tfm_psa_call_pack tfm_psa_call_pack_svc
-#define psa_close psa_close_svc
#define psa_wait psa_wait_svc
#define psa_get psa_get_svc
-#define psa_set_rhandle psa_set_rhandle_svc
#define psa_read psa_read_svc
#define psa_skip psa_skip_svc
#define psa_write psa_write_svc
@@ -31,17 +28,20 @@
#define psa_irq_disable psa_irq_disable_svc
#define psa_reset_signal psa_reset_signal_svc
#define psa_rot_lifecycle_state psa_rot_lifecycle_state_svc
+/* Following PSA APIs are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+#define psa_connect psa_connect_svc
+#define psa_close psa_close_svc
+#define psa_set_rhandle psa_set_rhandle_svc
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
#elif defined(CONFIG_TFM_PSA_API_CROSS_CALL)
#define psa_framework_version psa_framework_version_cross
#define psa_version psa_version_cross
-#define psa_connect psa_connect_cross
#define tfm_psa_call_pack tfm_psa_call_pack_cross
-#define psa_close psa_close_cross
#define psa_wait psa_wait_cross
#define psa_get psa_get_cross
-#define psa_set_rhandle psa_set_rhandle_cross
#define psa_read psa_read_cross
#define psa_skip psa_skip_cross
#define psa_write psa_write_cross
@@ -54,6 +54,12 @@
#define psa_irq_disable psa_irq_disable_cross
#define psa_reset_signal psa_reset_signal_cross
#define psa_rot_lifecycle_state psa_rot_lifecycle_state_cross
+/* Following PSA APIs are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+#define psa_connect psa_connect_cross
+#define psa_close psa_close_cross
+#define psa_set_rhandle psa_set_rhandle_cross
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
#if PSA_FRAMEWORK_HAS_MM_IOVEC
#define psa_map_invec psa_map_invec_cross
@@ -66,14 +72,17 @@
#define psa_framework_version psa_framework_version_sfn
#define psa_version psa_version_sfn
-#define psa_connect psa_connect_sfn
#define tfm_psa_call_pack psa_call_pack_sfn
-#define psa_close psa_close_sfn
#define psa_wait psa_wait_sfn
#define psa_read psa_read_sfn
#define psa_skip psa_skip_sfn
#define psa_write psa_write_sfn
#define psa_panic psa_panic_sfn
+/* Following PSA APIs are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+#define psa_connect psa_connect_sfn
+#define psa_close psa_close_sfn
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
#if PSA_FRAMEWORK_HAS_MM_IOVEC
#define psa_map_invec psa_map_invec_sfn
diff --git a/secure_fw/partitions/ns_agent_tz/tfm_psa_api_veneers.c b/secure_fw/partitions/ns_agent_tz/tfm_psa_api_veneers.c
index 6b4c824..69273d0 100644
--- a/secure_fw/partitions/ns_agent_tz/tfm_psa_api_veneers.c
+++ b/secure_fw/partitions/ns_agent_tz/tfm_psa_api_veneers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -42,10 +42,13 @@
#pragma required = tfm_spm_client_psa_framework_version
#pragma required = tfm_spm_client_psa_version
-#pragma required = tfm_spm_client_psa_connect
#pragma required = tfm_spm_client_psa_call
-#pragma required = tfm_spm_client_psa_close
#pragma required = spm_interface_cross_dispatcher
+/* Following PSA APIs are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+#pragma required = tfm_spm_client_psa_connect
+#pragma required = tfm_spm_client_psa_close
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
#endif /* CONFIG_TFM_PSA_API_CROSS_CALL */
@@ -140,50 +143,6 @@
}
__tfm_psa_secure_gateway_attributes__
-psa_handle_t tfm_psa_connect_veneer(uint32_t sid, uint32_t version)
-{
- __ASM volatile(
-#if !defined(__ICCARM__)
- ".syntax unified \n"
-#endif
-
-#if !defined(__ARM_ARCH_8_1M_MAIN__)
- " ldr r2, [sp] \n"
- " ldr r3, ="M2S(STACK_SEAL_PATTERN)" \n"
- " cmp r2, r3 \n"
- " bne reent_panic3 \n"
-#endif
- " mrs r3, control \n"
- " push {r2, r3} \n"
-#ifdef CONFIG_TFM_PSA_API_CROSS_CALL
- " push {r0-r4, lr} \n"
- " ldr r0, =tfm_spm_client_psa_connect \n"
- " mov r1, sp \n"
- " movs r2, #0 \n"
- " bl spm_interface_cross_dispatcher \n"
- " pop {r0-r3} \n"
- " pop {r2, r3} \n"
- " mov lr, r3 \n"
-#elif defined(CONFIG_TFM_PSA_API_SFN_CALL)
- " push {r4, lr} \n"
- " bl psa_connect_sfn \n"
- " pop {r2, r3} \n"
- " mov lr, r3 \n"
-#else
- " svc "M2S(TFM_SVC_PSA_CONNECT)" \n"
-#endif
- " pop {r2, r3} \n"
- " msr control, r3 \n"
- " bxns lr \n"
-#if !defined(__ARM_ARCH_8_1M_MAIN__)
- "reent_panic3: \n"
- " svc "M2S(TFM_SVC_PSA_PANIC)" \n"
- " b . \n"
-#endif
- );
-}
-
-__tfm_psa_secure_gateway_attributes__
psa_status_t tfm_psa_call_veneer(psa_handle_t handle,
uint32_t ctrl_param,
const psa_invec *in_vec,
@@ -234,6 +193,54 @@
);
}
+/* Following veneers are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+
+__tfm_psa_secure_gateway_attributes__
+psa_handle_t tfm_psa_connect_veneer(uint32_t sid, uint32_t version)
+{
+ __ASM volatile(
+#if !defined(__ICCARM__)
+ ".syntax unified \n"
+#endif
+
+#if !defined(__ARM_ARCH_8_1M_MAIN__)
+ " ldr r2, [sp] \n"
+ " ldr r3, ="M2S(STACK_SEAL_PATTERN)" \n"
+ " cmp r2, r3 \n"
+ " bne reent_panic3 \n"
+#endif
+ " mrs r3, control \n"
+ " push {r2, r3} \n"
+ " mov r3, r12 \n"
+#ifdef CONFIG_TFM_PSA_API_CROSS_CALL
+ " push {r0-r4, lr} \n"
+ " ldr r0, =tfm_spm_client_psa_connect \n"
+ " mov r1, sp \n"
+ " movs r2, #0 \n"
+ " bl spm_interface_cross_dispatcher \n"
+ " pop {r0-r3} \n"
+ " pop {r2, r3} \n"
+ " mov lr, r3 \n"
+#elif defined(CONFIG_TFM_PSA_API_SFN_CALL)
+ " push {r4, lr} \n"
+ " bl psa_connect_sfn \n"
+ " pop {r2, r3} \n"
+ " mov lr, r3 \n"
+#else
+ " svc "M2S(TFM_SVC_PSA_CONNECT)" \n"
+#endif
+ " pop {r2, r3} \n"
+ " msr control, r3 \n"
+ " bxns lr \n"
+#if !defined(__ARM_ARCH_8_1M_MAIN__)
+ "reent_panic3: \n"
+ " svc "M2S(TFM_SVC_PSA_PANIC)" \n"
+ " b . \n"
+#endif
+ );
+}
+
__tfm_psa_secure_gateway_attributes__
void tfm_psa_close_veneer(psa_handle_t handle)
{
@@ -277,3 +284,5 @@
#endif
);
}
+
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
diff --git a/secure_fw/spm/cmsis_psa/psa_interface_cross.c b/secure_fw/spm/cmsis_psa/psa_interface_cross.c
index 1d3a7c2..1f9de89 100644
--- a/secure_fw/spm/cmsis_psa/psa_interface_cross.c
+++ b/secure_fw/spm/cmsis_psa/psa_interface_cross.c
@@ -69,21 +69,6 @@
__naked
__section(".psa_interface_cross_call")
-psa_handle_t psa_connect_cross(uint32_t sid, uint32_t version)
-{
- __asm volatile(
-#if !defined(__ICCARM__)
- ".syntax unified \n"
-#endif
- "push {r0-r4, lr} \n"
- "ldr r0, =tfm_spm_client_psa_connect \n"
- "mov r1, sp \n"
- "b psa_interface_cross_unified_entry \n"
- );
-}
-
-__naked
-__section(".psa_interface_cross_call")
psa_status_t tfm_psa_call_pack_cross(psa_handle_t handle,
uint32_t ctrl_param,
const psa_invec *in_vec,
@@ -102,21 +87,6 @@
__naked
__section(".psa_interface_cross_call")
-void psa_close_cross(psa_handle_t handle)
-{
- __asm volatile(
-#if !defined(__ICCARM__)
- ".syntax unified \n"
-#endif
- "push {r0-r4, lr} \n"
- "ldr r0, =tfm_spm_client_psa_close \n"
- "mov r1, sp \n"
- "b psa_interface_cross_unified_entry \n"
- );
-}
-
-__naked
-__section(".psa_interface_cross_call")
psa_signal_t psa_wait_cross(psa_signal_t signal_mask, uint32_t timeout)
{
__asm volatile(
@@ -147,21 +117,6 @@
__naked
__section(".psa_interface_cross_call")
-void psa_set_rhandle_cross(psa_handle_t msg_handle, void *rhandle)
-{
- __asm volatile(
-#if !defined(__ICCARM__)
- ".syntax unified \n"
-#endif
- "push {r0-r4, lr} \n"
- "ldr r0, =tfm_spm_partition_psa_set_rhandle \n"
- "mov r1, sp \n"
- "b psa_interface_cross_unified_entry \n"
- );
-}
-
-__naked
-__section(".psa_interface_cross_call")
size_t psa_read_cross(psa_handle_t msg_handle, uint32_t invec_idx,
void *buffer, size_t num_bytes)
{
@@ -343,6 +298,56 @@
);
}
+/* Following PSA APIs are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+
+__naked
+__section(".psa_interface_cross_call")
+psa_handle_t psa_connect_cross(uint32_t sid, uint32_t version)
+{
+ __asm volatile(
+#if !defined(__ICCARM__)
+ ".syntax unified \n"
+#endif
+ "push {r0-r4, lr} \n"
+ "ldr r0, =tfm_spm_client_psa_connect \n"
+ "mov r1, sp \n"
+ "b psa_interface_cross_unified_entry \n"
+ );
+}
+
+__naked
+__section(".psa_interface_cross_call")
+void psa_close_cross(psa_handle_t handle)
+{
+ __asm volatile(
+#if !defined(__ICCARM__)
+ ".syntax unified \n"
+#endif
+ "push {r0-r4, lr} \n"
+ "ldr r0, =tfm_spm_client_psa_close \n"
+ "mov r1, sp \n"
+ "b psa_interface_cross_unified_entry \n"
+ );
+}
+
+__naked
+__section(".psa_interface_cross_call")
+void psa_set_rhandle_cross(psa_handle_t msg_handle, void *rhandle)
+{
+ __asm volatile(
+#if !defined(__ICCARM__)
+ ".syntax unified \n"
+#endif
+ "push {r0-r4, lr} \n"
+ "ldr r0, =tfm_spm_partition_psa_set_rhandle \n"
+ "mov r1, sp \n"
+ "b psa_interface_cross_unified_entry \n"
+ );
+}
+
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
+
#if PSA_FRAMEWORK_HAS_MM_IOVEC
__naked
diff --git a/secure_fw/spm/cmsis_psa/psa_interface_sfn.c b/secure_fw/spm/cmsis_psa/psa_interface_sfn.c
index e4eb05a..07d5d80 100644
--- a/secure_fw/spm/cmsis_psa/psa_interface_sfn.c
+++ b/secure_fw/spm/cmsis_psa/psa_interface_sfn.c
@@ -22,24 +22,6 @@
return tfm_spm_client_psa_version(sid);
}
-psa_handle_t psa_connect_sfn(uint32_t sid, uint32_t version)
-{
- struct partition_t *p_client, *p_target;
- psa_status_t stat;
-
- p_client = GET_CURRENT_COMPONENT();
-
- stat = tfm_spm_client_psa_connect(sid, version);
-
- p_target = GET_CURRENT_COMPONENT();
- if (p_client != p_target) {
- stat = tfm_spm_partition_psa_reply(p_target->p_msg->msg.handle, stat);
- }
-
- spm_handle_programmer_errors(stat);
- return (psa_handle_t)stat;
-}
-
psa_status_t psa_call_pack_sfn(psa_handle_t handle, uint32_t ctrl_param,
const psa_invec *in_vec, psa_outvec *out_vec)
{
@@ -59,24 +41,6 @@
return (psa_status_t)stat;
}
-void psa_close_sfn(psa_handle_t handle)
-{
- struct partition_t *p_client, *p_target;
- psa_status_t stat;
-
- p_client = GET_CURRENT_COMPONENT();
-
- stat = tfm_spm_client_psa_close(handle);
-
- p_target = GET_CURRENT_COMPONENT();
- if (p_client != p_target) {
- stat = tfm_spm_partition_psa_reply(p_target->p_msg->msg.handle,
- PSA_SUCCESS);
- }
-
- spm_handle_programmer_errors(stat);
-}
-
psa_signal_t psa_wait_sfn(psa_signal_t signal_mask, uint32_t timeout)
{
/*
@@ -106,6 +70,47 @@
tfm_spm_partition_psa_write(msg_handle, outvec_idx, buffer, num_bytes);
}
+/* Following PSA APIs are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+
+psa_handle_t psa_connect_sfn(uint32_t sid, uint32_t version)
+{
+ struct partition_t *p_client, *p_target;
+ psa_status_t stat;
+
+ p_client = GET_CURRENT_COMPONENT();
+
+ stat = tfm_spm_client_psa_connect(sid, version);
+
+ p_target = GET_CURRENT_COMPONENT();
+ if (p_client != p_target) {
+ stat = tfm_spm_partition_psa_reply(p_target->p_msg->msg.handle, stat);
+ }
+
+ spm_handle_programmer_errors(stat);
+ return (psa_handle_t)stat;
+}
+
+void psa_close_sfn(psa_handle_t handle)
+{
+ struct partition_t *p_client, *p_target;
+ psa_status_t stat;
+
+ p_client = GET_CURRENT_COMPONENT();
+
+ stat = tfm_spm_client_psa_close(handle);
+
+ p_target = GET_CURRENT_COMPONENT();
+ if (p_client != p_target) {
+ stat = tfm_spm_partition_psa_reply(p_target->p_msg->msg.handle,
+ PSA_SUCCESS);
+ }
+
+ spm_handle_programmer_errors(stat);
+}
+
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
+
#if PSA_FRAMEWORK_HAS_MM_IOVEC
const void *psa_map_invec_sfn(psa_handle_t msg_handle, uint32_t invec_idx)
diff --git a/secure_fw/spm/cmsis_psa/psa_interface_svc.c b/secure_fw/spm/cmsis_psa/psa_interface_svc.c
index 129db54..ef34b84 100644
--- a/secure_fw/spm/cmsis_psa/psa_interface_svc.c
+++ b/secure_fw/spm/cmsis_psa/psa_interface_svc.c
@@ -26,12 +26,6 @@
"bx lr \n");
}
-__naked psa_handle_t psa_connect_svc(uint32_t sid, uint32_t version)
-{
- __asm volatile("svc "M2S(TFM_SVC_PSA_CONNECT)" \n"
- "bx lr \n");
-}
-
__naked psa_status_t tfm_psa_call_pack_svc(psa_handle_t handle,
uint32_t ctrl_param,
const psa_invec *in_vec,
@@ -41,12 +35,6 @@
"bx lr \n");
}
-__naked void psa_close_svc(psa_handle_t handle)
-{
- __asm volatile("svc "M2S(TFM_SVC_PSA_CLOSE)" \n"
- "bx lr \n");
-}
-
__naked psa_signal_t psa_wait_svc(psa_signal_t signal_mask, uint32_t timeout)
{
__asm volatile("svc "M2S(TFM_SVC_PSA_WAIT)" \n"
@@ -59,12 +47,6 @@
"bx lr \n");
}
-__naked void psa_set_rhandle_svc(psa_handle_t msg_handle, void *rhandle)
-{
- __asm volatile("svc "M2S(TFM_SVC_PSA_SET_RHANDLE)" \n"
- "bx lr \n");
-}
-
__naked size_t psa_read_svc(psa_handle_t msg_handle, uint32_t invec_idx,
void *buffer, size_t num_bytes)
{
@@ -139,3 +121,26 @@
__asm volatile("svc "M2S(TFM_SVC_PSA_LIFECYCLE)" \n"
"bx lr \n");
}
+
+/* Following PSA APIs are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+
+__naked psa_handle_t psa_connect_svc(uint32_t sid, uint32_t version)
+{
+ __asm volatile("svc "M2S(TFM_SVC_PSA_CONNECT)" \n"
+ "bx lr \n");
+}
+
+__naked void psa_close_svc(psa_handle_t handle)
+{
+ __asm volatile("svc "M2S(TFM_SVC_PSA_CLOSE)" \n"
+ "bx lr \n");
+}
+
+__naked void psa_set_rhandle_svc(psa_handle_t msg_handle, void *rhandle)
+{
+ __asm volatile("svc "M2S(TFM_SVC_PSA_SET_RHANDLE)" \n"
+ "bx lr \n");
+}
+
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
diff --git a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
index e0d92f3..1c41851 100644
--- a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
+++ b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -42,25 +42,16 @@
return tfm_spm_client_psa_framework_version();
case TFM_SVC_PSA_VERSION:
return tfm_spm_client_psa_version(ctx[0]);
- case TFM_SVC_PSA_CONNECT:
- status = tfm_spm_client_psa_connect(ctx[0], ctx[1]);
- break;
case TFM_SVC_PSA_CALL:
status = tfm_spm_client_psa_call((psa_handle_t)ctx[0], ctx[1],
(const psa_invec *)ctx[2],
(psa_outvec *)ctx[3]);
break;
- case TFM_SVC_PSA_CLOSE:
- status = tfm_spm_client_psa_close((psa_handle_t)ctx[0]);
- break;
case TFM_SVC_PSA_WAIT:
return tfm_spm_partition_psa_wait((psa_signal_t)ctx[0], ctx[1]);
case TFM_SVC_PSA_GET:
return tfm_spm_partition_psa_get((psa_signal_t)ctx[0],
(psa_msg_t *)ctx[1]);
- case TFM_SVC_PSA_SET_RHANDLE:
- tfm_spm_partition_psa_set_rhandle((psa_handle_t)ctx[0], (void *)ctx[1]);
- break;
case TFM_SVC_PSA_READ:
return tfm_spm_partition_psa_read((psa_handle_t)ctx[0], ctx[1],
(void *)ctx[2], (size_t)ctx[3]);
@@ -88,6 +79,18 @@
break;
case TFM_SVC_PSA_LIFECYCLE:
return tfm_spm_get_lifecycle_state();
+/* Following svc handlers are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+ case TFM_SVC_PSA_CONNECT:
+ status = tfm_spm_client_psa_connect(ctx[0], ctx[1]);
+ break;
+ case TFM_SVC_PSA_CLOSE:
+ status = tfm_spm_client_psa_close((psa_handle_t)ctx[0]);
+ break;
+ case TFM_SVC_PSA_SET_RHANDLE:
+ tfm_spm_partition_psa_set_rhandle((psa_handle_t)ctx[0], (void *)ctx[1]);
+ break;
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
#if TFM_SP_LOG_RAW_ENABLED
case TFM_SVC_OUTPUT_UNPRIV_STRING:
return tfm_hal_output_spm_log((const char *)ctx[0], ctx[1]);
diff --git a/secure_fw/spm/cmsis_psa/tfm_rpc.c b/secure_fw/spm/cmsis_psa/tfm_rpc.c
index 5fcd85f..88e7bdd 100644
--- a/secure_fw/spm/cmsis_psa/tfm_rpc.c
+++ b/secure_fw/spm/cmsis_psa/tfm_rpc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -47,13 +47,6 @@
return tfm_spm_client_psa_version(params->sid);
}
-psa_status_t tfm_rpc_psa_connect(const struct client_call_params_t *params)
-{
- TFM_CORE_ASSERT(params != NULL);
-
- return tfm_spm_client_psa_connect(params->sid, params->version);
-}
-
psa_status_t tfm_rpc_psa_call(const struct client_call_params_t *params)
{
TFM_CORE_ASSERT(params != NULL);
@@ -65,6 +58,16 @@
params->in_vec, params->out_vec);
}
+/* Following PSA APIs are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+
+psa_status_t tfm_rpc_psa_connect(const struct client_call_params_t *params)
+{
+ TFM_CORE_ASSERT(params != NULL);
+
+ return tfm_spm_client_psa_connect(params->sid, params->version);
+}
+
void tfm_rpc_psa_close(const struct client_call_params_t *params)
{
TFM_CORE_ASSERT(params != NULL);
@@ -72,6 +75,8 @@
tfm_spm_client_psa_close(params->handle);
}
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
+
int32_t tfm_rpc_register_ops(const struct tfm_rpc_ops_t *ops_ptr)
{
if (!ops_ptr) {
diff --git a/secure_fw/spm/cmsis_psa/tfm_spe_mailbox.c b/secure_fw/spm/cmsis_psa/tfm_spe_mailbox.c
index 7c01dc5..ef19c80 100644
--- a/secure_fw/spm/cmsis_psa/tfm_spe_mailbox.c
+++ b/secure_fw/spm/cmsis_psa/tfm_spe_mailbox.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
* Copyright (c) 2021, Cypress Semiconductor Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -39,11 +39,6 @@
spm_params.sid = params->psa_version_params.sid;
*psa_ret = tfm_rpc_psa_version(&spm_params);
return MAILBOX_SUCCESS;
- case MAILBOX_PSA_CONNECT:
- spm_params.sid = params->psa_connect_params.sid;
- spm_params.version = params->psa_connect_params.version;
- *psa_ret = tfm_rpc_psa_connect(&spm_params);
- return MAILBOX_SUCCESS;
case MAILBOX_PSA_CALL:
spm_params.handle = params->psa_call_params.handle;
spm_params.type = params->psa_call_params.type;
@@ -53,10 +48,18 @@
spm_params.out_len = params->psa_call_params.out_len;
*psa_ret = tfm_rpc_psa_call(&spm_params);
return MAILBOX_SUCCESS;
+/* Following cases are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+ case MAILBOX_PSA_CONNECT:
+ spm_params.sid = params->psa_connect_params.sid;
+ spm_params.version = params->psa_connect_params.version;
+ *psa_ret = tfm_rpc_psa_connect(&spm_params);
+ return MAILBOX_SUCCESS;
case MAILBOX_PSA_CLOSE:
spm_params.handle = params->psa_close_params.handle;
tfm_rpc_psa_close(&spm_params);
return MAILBOX_SUCCESS;
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
default:
return MAILBOX_INVAL_PARAMS;
}
diff --git a/secure_fw/spm/ffm/psa_api.c b/secure_fw/spm/ffm/psa_api.c
index 5d5d2d8..7b8342b 100644
--- a/secure_fw/spm/ffm/psa_api.c
+++ b/secure_fw/spm/ffm/psa_api.c
@@ -139,69 +139,6 @@
return service->p_ldinf->version;
}
-psa_status_t tfm_spm_client_psa_connect(uint32_t sid, uint32_t version)
-{
- struct service_t *service;
- struct tfm_msg_body_t *msg;
- struct tfm_conn_handle_t *connect_handle;
- int32_t client_id;
- psa_handle_t handle;
- bool ns_caller = tfm_spm_is_ns_caller();
- struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
-
- /*
- * It is a PROGRAMMER ERROR if the RoT Service does not exist on the
- * platform.
- */
- service = tfm_spm_get_service_by_sid(sid);
- if (!service) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
-
- /* It is a PROGRAMMER ERROR if connecting to a stateless service. */
- if (SERVICE_IS_STATELESS(service->p_ldinf->flags)) {
- return PSA_ERROR_PROGRAMMER_ERROR;
- }
-
- /*
- * It is a PROGRAMMER ERROR if the caller is not authorized to access the
- * RoT Service.
- */
- if (tfm_spm_check_authorization(sid, service, ns_caller) != SPM_SUCCESS) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
-
- /*
- * It is a PROGRAMMER ERROR if the version of the RoT Service requested is
- * not supported on the platform.
- */
- if (tfm_spm_check_client_version(service, version) != SPM_SUCCESS) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
-
- client_id = tfm_spm_get_client_id(ns_caller);
-
- /*
- * Create connection handle here since it is possible to return the error
- * code to client when creation fails.
- */
- CRITICAL_SECTION_ENTER(cs_assert);
- connect_handle = tfm_spm_create_conn_handle(service, client_id);
- CRITICAL_SECTION_LEAVE(cs_assert);
- if (!connect_handle) {
- return PSA_ERROR_CONNECTION_BUSY;
- }
-
- msg = tfm_spm_get_msg_buffer_from_conn_handle(connect_handle);
-
- handle = tfm_spm_to_user_handle(connect_handle);
- /* No input or output needed for connect message */
- tfm_spm_fill_msg(msg, service, handle, PSA_IPC_CONNECT,
- client_id, NULL, 0, NULL, 0, NULL);
-
- return backend_instance.messaging(service, msg);
-}
-
psa_status_t tfm_spm_client_psa_call(psa_handle_t handle,
uint32_t ctrl_param,
const psa_invec *inptr,
@@ -388,6 +325,72 @@
return backend_instance.messaging(service, msg);
}
+/* Following PSA APIs are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+
+psa_status_t tfm_spm_client_psa_connect(uint32_t sid, uint32_t version)
+{
+ struct service_t *service;
+ struct tfm_msg_body_t *msg;
+ struct tfm_conn_handle_t *connect_handle;
+ int32_t client_id;
+ psa_handle_t handle;
+ bool ns_caller = tfm_spm_is_ns_caller();
+ struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
+
+ /*
+ * It is a PROGRAMMER ERROR if the RoT Service does not exist on the
+ * platform.
+ */
+ service = tfm_spm_get_service_by_sid(sid);
+ if (!service) {
+ return PSA_ERROR_CONNECTION_REFUSED;
+ }
+
+ /* It is a PROGRAMMER ERROR if connecting to a stateless service. */
+ if (SERVICE_IS_STATELESS(service->p_ldinf->flags)) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+
+ /*
+ * It is a PROGRAMMER ERROR if the caller is not authorized to access the
+ * RoT Service.
+ */
+ if (tfm_spm_check_authorization(sid, service, ns_caller) != SPM_SUCCESS) {
+ return PSA_ERROR_CONNECTION_REFUSED;
+ }
+
+ /*
+ * It is a PROGRAMMER ERROR if the version of the RoT Service requested is
+ * not supported on the platform.
+ */
+ if (tfm_spm_check_client_version(service, version) != SPM_SUCCESS) {
+ return PSA_ERROR_CONNECTION_REFUSED;
+ }
+
+ client_id = tfm_spm_get_client_id(ns_caller);
+
+ /*
+ * Create connection handle here since it is possible to return the error
+ * code to client when creation fails.
+ */
+ CRITICAL_SECTION_ENTER(cs_assert);
+ connect_handle = tfm_spm_create_conn_handle(service, client_id);
+ CRITICAL_SECTION_LEAVE(cs_assert);
+ if (!connect_handle) {
+ return PSA_ERROR_CONNECTION_BUSY;
+ }
+
+ msg = tfm_spm_get_msg_buffer_from_conn_handle(connect_handle);
+
+ handle = tfm_spm_to_user_handle(connect_handle);
+ /* No input or output needed for connect message */
+ tfm_spm_fill_msg(msg, service, handle, PSA_IPC_CONNECT,
+ client_id, NULL, 0, NULL, 0, NULL);
+
+ return backend_instance.messaging(service, msg);
+}
+
psa_status_t tfm_spm_client_psa_close(psa_handle_t handle)
{
struct service_t *service;
@@ -440,6 +443,8 @@
return backend_instance.messaging(service, msg);
}
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
+
/* PSA Partition API function body */
psa_signal_t tfm_spm_partition_psa_wait(psa_signal_t signal_mask,
@@ -545,29 +550,6 @@
return PSA_SUCCESS;
}
-void tfm_spm_partition_psa_set_rhandle(psa_handle_t msg_handle, void *rhandle)
-{
- struct tfm_msg_body_t *msg = NULL;
- struct tfm_conn_handle_t *conn_handle;
-
- /* It is a fatal error if message handle is invalid */
- msg = tfm_spm_get_msg_from_handle(msg_handle);
- if (!msg) {
- tfm_core_panic();
- }
-
- /* It is a PROGRAMMER ERROR if a stateless service sets rhandle. */
- if (SERVICE_IS_STATELESS(msg->service->p_ldinf->flags)) {
- tfm_core_panic();
- }
-
- msg->msg.rhandle = rhandle;
- conn_handle = tfm_spm_to_handle_instance(msg_handle);
-
- /* Store reverse handle for following client calls. */
- tfm_spm_set_rhandle(msg->service, conn_handle, rhandle);
-}
-
size_t tfm_spm_partition_psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
void *buffer, size_t num_bytes)
{
@@ -1040,6 +1022,34 @@
CRITICAL_SECTION_LEAVE(cs_assert);
}
+/* psa_set_rhandle is only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+
+void tfm_spm_partition_psa_set_rhandle(psa_handle_t msg_handle, void *rhandle)
+{
+ struct tfm_msg_body_t *msg = NULL;
+ struct tfm_conn_handle_t *conn_handle;
+
+ /* It is a fatal error if message handle is invalid */
+ msg = tfm_spm_get_msg_from_handle(msg_handle);
+ if (!msg) {
+ tfm_core_panic();
+ }
+
+ /* It is a PROGRAMMER ERROR if a stateless service sets rhandle. */
+ if (SERVICE_IS_STATELESS(msg->service->p_ldinf->flags)) {
+ tfm_core_panic();
+ }
+
+ msg->msg.rhandle = rhandle;
+ conn_handle = tfm_spm_to_handle_instance(msg_handle);
+
+ /* Store reverse handle for following client calls. */
+ tfm_spm_set_rhandle(msg->service, conn_handle, rhandle);
+}
+
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
+
#if PSA_FRAMEWORK_HAS_MM_IOVEC
const void *tfm_spm_partition_psa_map_invec(psa_handle_t msg_handle,
diff --git a/secure_fw/spm/include/ffm/psa_api.h b/secure_fw/spm/include/ffm/psa_api.h
index 1258c76..97ab352 100644
--- a/secure_fw/spm/include/ffm/psa_api.h
+++ b/secure_fw/spm/include/ffm/psa_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -59,23 +59,6 @@
uint32_t tfm_spm_client_psa_version(uint32_t sid);
/**
- * \brief handler for \ref psa_connect.
- *
- * \param[in] sid RoT Service identity.
- * \param[in] version The version of the RoT Service.
- *
- * \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_status_t tfm_spm_client_psa_connect(uint32_t sid, uint32_t version);
-
-/**
* \brief handler for \ref psa_call.
*
* \param[in] handle Service handle to the established connection,
@@ -102,6 +85,26 @@
const psa_invec *inptr,
psa_outvec *outptr);
+/* Following PSA APIs are only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+
+/**
+ * \brief handler for \ref psa_connect.
+ *
+ * \param[in] sid RoT Service identity.
+ * \param[in] version The version of the RoT Service.
+ *
+ * \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_status_t tfm_spm_client_psa_connect(uint32_t sid, uint32_t version);
+
/**
* \brief handler for \ref psa_close.
*
@@ -118,6 +121,8 @@
*/
psa_status_t tfm_spm_client_psa_close(psa_handle_t handle);
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
+
/* PSA Partition API function body, for privileged use only. */
/**
@@ -157,19 +162,6 @@
psa_status_t tfm_spm_partition_psa_get(psa_signal_t signal, psa_msg_t *msg);
/**
- * \brief Function body of \ref psa_set_rhandle.
- *
- * \param[in] msg_handle Handle for the client's message.
- * \param[in] rhandle Reverse handle allocated by the RoT Service.
- *
- * \retval void Success, rhandle will be provided with all
- * subsequent messages delivered on this
- * connection.
- * \retval "PROGRAMMER ERROR" msg_handle is invalid.
- */
-void tfm_spm_partition_psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
-
-/**
* \brief Function body of \ref psa_read.
*
* \param[in] msg_handle Handle for the client's message.
@@ -355,6 +347,24 @@
*/
void tfm_spm_partition_psa_reset_signal(psa_signal_t irq_signal);
+/* psa_set_rhandle is only needed by connection-based services */
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+
+/**
+ * \brief Function body of \ref psa_set_rhandle.
+ *
+ * \param[in] msg_handle Handle for the client's message.
+ * \param[in] rhandle Reverse handle allocated by the RoT Service.
+ *
+ * \retval void Success, rhandle will be provided with all
+ * subsequent messages delivered on this
+ * connection.
+ * \retval "PROGRAMMER ERROR" msg_handle is invalid.
+ */
+void tfm_spm_partition_psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
+
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
+
#if PSA_FRAMEWORK_HAS_MM_IOVEC
/**
diff --git a/tools/tfm_parse_manifest_list.py b/tools/tfm_parse_manifest_list.py
index 3a6bd71..b359f15 100644
--- a/tools/tfm_parse_manifest_list.py
+++ b/tools/tfm_parse_manifest_list.py
@@ -142,6 +142,7 @@
pid_list = []
no_pid_manifest_idx = []
partition_statistics = {
+ 'connection_based_srv_num': 0,
'ipc_partition_num': 0,
'sfn_partition_num': 0
}
@@ -218,6 +219,12 @@
else:
partition_statistics['ipc_partition_num'] += 1
+ for service in manifest.get('services', []):
+ if 'connection_based' not in service.keys():
+ partition_statistics['connection_based_srv_num'] += 1
+ elif service['connection_based']:
+ partition_statistics['connection_based_srv_num'] += 1
+
manifest_out_basename = os.path.splitext(os.path.basename(manifest_path))[0]
if 'output_path' in manifest_item:
@@ -250,7 +257,6 @@
context['partitions'] = partition_list
context['partition_statistics'] = partition_statistics
-
context['stateless_services'] = process_stateless_services(partition_list)
return context