SPM: Add mailbox agent support in SFN model
Currently, the mailbox agent only supports IPC model.
This patch enables mailbox agent in SFN model. Unlike
IPC model, the reply request is handled as a sync one.
This patch covers the default dual-core routine and the
RSS routine.
Signed-off-by: Sherry Zhang <sherry.zhang2@arm.com>
Change-Id: I1035d81aa2427d2e58acaa187b44bbcef275426c
diff --git a/config/check_config.cmake b/config/check_config.cmake
index 5e38818..91a0145 100644
--- a/config/check_config.cmake
+++ b/config/check_config.cmake
@@ -29,9 +29,6 @@
tfm_invalid_config(TFM_MULTI_CORE_TOPOLOGY AND TFM_NS_MANAGE_NSID)
tfm_invalid_config(TFM_PLAT_SPECIFIC_MULTI_CORE_COMM AND NOT TFM_MULTI_CORE_TOPOLOGY)
-# Multi-core platform with mailbox partition cannot fully work with SFN backend yet.
-tfm_invalid_config(TFM_MULTI_CORE_TOPOLOGY AND (CONFIG_TFM_SPM_BACKEND STREQUAL "SFN"))
-
tfm_invalid_config(TFM_ISOLATION_LEVEL EQUAL 3 AND CONFIG_TFM_STACK_WATERMARKS)
tfm_invalid_config((TFM_S_REG_TEST OR TFM_NS_REG_TEST) AND TEST_PSA_API)
diff --git a/config/config_base.h b/config/config_base.h
index 811a42d..62f25b1 100644
--- a/config/config_base.h
+++ b/config/config_base.h
@@ -239,6 +239,11 @@
#define PS_STACK_SIZE 0x700
#endif
+/* The stack size of the NS Agent Mailbox Secure Partition */
+#ifndef NS_AGENT_MAILBOX_STACK_SIZE
+#define NS_AGENT_MAILBOX_STACK_SIZE 0x800
+#endif
+
/* SPM Partition Configs */
#ifdef CONFIG_TFM_CONNECTION_POOL_ENABLE
diff --git a/config/profile/config_profile_large.h b/config/profile/config_profile_large.h
index cc7fc4c..933514d 100644
--- a/config/profile/config_profile_large.h
+++ b/config/profile/config_profile_large.h
@@ -223,6 +223,11 @@
#define PS_STACK_SIZE 0x700
#endif
+/* The stack size of the NS Agent Mailbox Secure Partition */
+#ifndef NS_AGENT_MAILBOX_STACK_SIZE
+#define NS_AGENT_MAILBOX_STACK_SIZE 0x800
+#endif
+
/* SPM Partition Configs */
/* The maximal number of secure services that are connected or requested at the same time */
diff --git a/config/profile/config_profile_medium.h b/config/profile/config_profile_medium.h
index 97ac059..89f8eeb 100644
--- a/config/profile/config_profile_medium.h
+++ b/config/profile/config_profile_medium.h
@@ -221,6 +221,11 @@
#define PS_STACK_SIZE 0x700
#endif
+/* The stack size of the NS Agent Mailbox Secure Partition */
+#ifndef NS_AGENT_MAILBOX_STACK_SIZE
+#define NS_AGENT_MAILBOX_STACK_SIZE 0x800
+#endif
+
/* SPM Partition Configs */
/* The maximal number of secure services that are connected or requested at the same time */
diff --git a/config/profile/config_profile_medium_arotless.h b/config/profile/config_profile_medium_arotless.h
index 2569793..5c7cdd0 100644
--- a/config/profile/config_profile_medium_arotless.h
+++ b/config/profile/config_profile_medium_arotless.h
@@ -221,6 +221,11 @@
#define PS_STACK_SIZE 0x700
#endif
+/* The stack size of the NS Agent Mailbox Secure Partition */
+#ifndef NS_AGENT_MAILBOX_STACK_SIZE
+#define NS_AGENT_MAILBOX_STACK_SIZE 0x800
+#endif
+
/* SPM Partition Configs */
/* The maximal number of secure services that are connected or requested at the same time */
diff --git a/config/profile/config_profile_small.h b/config/profile/config_profile_small.h
index e37ffe2..fc5cbd8 100644
--- a/config/profile/config_profile_small.h
+++ b/config/profile/config_profile_small.h
@@ -218,6 +218,11 @@
#define PS_STACK_SIZE 0x700
#endif
+/* The stack size of the NS Agent Mailbox Secure Partition */
+#ifndef NS_AGENT_MAILBOX_STACK_SIZE
+#define NS_AGENT_MAILBOX_STACK_SIZE 0x800
+#endif
+
/* SPM Partition Configs */
/* Disable the doorbell APIs */
diff --git a/config/set_config.cmake b/config/set_config.cmake
index 87f276a..97eeb81 100644
--- a/config/set_config.cmake
+++ b/config/set_config.cmake
@@ -49,8 +49,7 @@
# check.
# Also select IPC model by default for multi-core platform unless it has already selected SFN model
if((DEFINED TFM_ISOLATION_LEVEL AND TFM_ISOLATION_LEVEL GREATER 1) OR
- CONFIG_TFM_SPM_BACKEND STREQUAL "IPC" OR
- TFM_MULTI_CORE_TOPOLOGY)
+ CONFIG_TFM_SPM_BACKEND STREQUAL "IPC")
include(config/tfm_ipc_config_default.cmake)
else()
#The default backend is SFN
diff --git a/config/tests/config_test_psa_api.h b/config/tests/config_test_psa_api.h
index 9127a33..c0a322c 100644
--- a/config/tests/config_test_psa_api.h
+++ b/config/tests/config_test_psa_api.h
@@ -232,6 +232,11 @@
#define PS_STACK_SIZE 0x700
#endif
+/* The stack size of the NS Agent Mailbox Secure Partition */
+#ifndef NS_AGENT_MAILBOX_STACK_SIZE
+#define NS_AGENT_MAILBOX_STACK_SIZE 0x800
+#endif
+
/* SPM Partition Configs */
/* The maximal number of secure services that are connected or requested at the same time */
diff --git a/docs/configuration/index.rst b/docs/configuration/index.rst
index b8a87b4..28ed681 100644
--- a/docs/configuration/index.rst
+++ b/docs/configuration/index.rst
@@ -257,6 +257,15 @@
|PLATFORM_NV_COUNTER_MODULE_DISABLED | Component | 0 |
+-------------------------------------+-----------+------------+
+NS Agent Mailbox Secure Partition
+=================================
++-------------------------------------+-----------+------------+
+| Options | Type | Base Value |
++=====================================+===========+============+
+|NS_AGENT_MAILBOX_STACK_SIZE | Component | 0x800 |
++-------------------------------------+-----------+------------+
+
+
Secure Partition Manager
========================
+----------------------------------------+-----------+-------------+
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 2a5a380..0205f3a 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
@@ -113,10 +113,22 @@
/* Deliver PSA Client call request to handler in SPM. */
req_to_process = queue_entry;
status = message_dispatch(req_to_process);
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
+ /*
+ * If status == PSA_SUCCESS, peer will be replied when mailbox agent
+ * partition receives a 'ASYNC_MSG_REPLY' signal from the requested
+ * service partition.
+ * If status != PSA_SUCCESS, the service call has been finished.
+ * Reply to the peer directly.
+ */
if (status != PSA_SUCCESS) {
SPMLOG_DBGMSGVAL("[RSS-COMMS] Message dispatch failed: ", status);
rss_comms_reply(req_to_process, status);
}
+#else
+ /* In SFN model, the service call has been finished. Reply to the peer directly. */
+ rss_comms_reply(req_to_process, status);
+#endif
}
}
diff --git a/platform/ext/target/arm/rss/tc/config_tfm_target.h b/platform/ext/target/arm/rss/tc/config_tfm_target.h
index fd4f9e8..73f8d6c 100644
--- a/platform/ext/target/arm/rss/tc/config_tfm_target.h
+++ b/platform/ext/target/arm/rss/tc/config_tfm_target.h
@@ -17,4 +17,6 @@
#define ATTEST_TOKEN_PROFILE_ARM_CCA 1
+#define NS_AGENT_MAILBOX_STACK_SIZE 0xC00
+
#endif /* __CONFIG_TFM_TARGET_H__ */
diff --git a/platform/ext/target/cypress/psoc64/Device/Source/system_psoc6_cm0plus.c b/platform/ext/target/cypress/psoc64/Device/Source/system_psoc6_cm0plus.c
index babda47..8da2c57 100644
--- a/platform/ext/target/cypress/psoc64/Device/Source/system_psoc6_cm0plus.c
+++ b/platform/ext/target/cypress/psoc64/Device/Source/system_psoc6_cm0plus.c
@@ -532,5 +532,9 @@
}
#endif /* defined (__ARMCC_VERSION) && (__ARMCC_VERSION < 6010050) */
+void __WEAK PendSV_Handler(void) __NO_RETURN;
+void PendSV_Handler(void) {
+ while(1);
+}
/* [] END OF FILE */
diff --git a/secure_fw/partitions/ns_agent_mailbox/ns_agent_mailbox.c b/secure_fw/partitions/ns_agent_mailbox/ns_agent_mailbox.c
index cde1b8b..459b3d7 100644
--- a/secure_fw/partitions/ns_agent_mailbox/ns_agent_mailbox.c
+++ b/secure_fw/partitions/ns_agent_mailbox/ns_agent_mailbox.c
@@ -43,8 +43,10 @@
if (signals & MAILBOX_SIGNAL) {
psa_eoi(MAILBOX_SIGNAL);
tfm_rpc_client_call_handler();
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
} else if (signals & ASYNC_MSG_REPLY) {
tfm_rpc_client_call_reply();
+#endif
} else {
psa_panic();
}
diff --git a/secure_fw/partitions/ns_agent_mailbox/ns_agent_mailbox.yaml b/secure_fw/partitions/ns_agent_mailbox/ns_agent_mailbox.yaml
index a9ffd63..a2d402d 100644
--- a/secure_fw/partitions/ns_agent_mailbox/ns_agent_mailbox.yaml
+++ b/secure_fw/partitions/ns_agent_mailbox/ns_agent_mailbox.yaml
@@ -15,7 +15,7 @@
"priority": "LOW",
"model": "IPC",
"entry_point": "ns_agent_mailbox_entry",
- "stack_size": "0x800",
+ "stack_size": "NS_AGENT_MAILBOX_STACK_SIZE",
"irqs": [
{
"source": "MAILBOX_IRQ",
diff --git a/secure_fw/spm/core/psa_api.c b/secure_fw/spm/core/psa_api.c
index 4342482..fcd0f40 100644
--- a/secure_fw/spm/core/psa_api.c
+++ b/secure_fw/spm/core/psa_api.c
@@ -287,15 +287,23 @@
CRITICAL_SECTION_LEAVE(cs_assert);
/*
- * When using the asynchronous agent API, retain the handle
- * until the response has been collected by the agent
+ * When IPC model is using the asynchronous agent API, retain the handle
+ * until the response has been collected by the agent.
*/
- if (!is_tfm_rpc_msg(handle)) {
- if (handle->status == TFM_HANDLE_STATUS_TO_FREE) {
- spm_free_connection(handle);
- } else {
- handle->status = TFM_HANDLE_STATUS_IDLE;
- }
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
+ if (is_tfm_rpc_msg(handle)) {
+ return ret;
+ }
+#endif
+
+ /*
+ * When the asynchronous agent API is not used or when in SFN model, free
+ * the connection handle immediately.
+ */
+ if (handle->status == TFM_HANDLE_STATUS_TO_FREE) {
+ spm_free_connection(handle);
+ } else {
+ handle->status = TFM_HANDLE_STATUS_IDLE;
}
return ret;
diff --git a/secure_fw/spm/core/psa_interface_sfn.c b/secure_fw/spm/core/psa_interface_sfn.c
index c896134..e4752a9 100644
--- a/secure_fw/spm/core/psa_interface_sfn.c
+++ b/secure_fw/spm/core/psa_interface_sfn.c
@@ -260,5 +260,67 @@
tfm_spm_partition_psa_unmap_outvec(msg_handle, outvec_idx, len);
}
-
#endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
+
+#ifdef TFM_PARTITION_NS_AGENT_MAILBOX
+psa_status_t agent_psa_call(psa_handle_t handle,
+ uint32_t control,
+ const struct client_params_t *params,
+ const void *client_data_stateless)
+{
+ struct partition_t *p_client, *p_target;
+ psa_status_t stat;
+
+ if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
+ /* PSA APIs must be called from Thread mode */
+ tfm_core_panic();
+ }
+
+ p_client = GET_CURRENT_COMPONENT();
+
+ stat = tfm_spm_agent_psa_call(handle, control, params, client_data_stateless);
+
+ p_target = GET_CURRENT_COMPONENT();
+ if (p_client != p_target) {
+ /* Execution is returned from RoT Service */
+ stat = tfm_spm_partition_psa_reply(p_target->p_handles->msg.handle,
+ stat);
+ } else {
+ /* Execution is returned from SPM */
+ spm_handle_programmer_errors(stat);
+ }
+
+ return (psa_status_t)stat;
+}
+
+#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)
+{
+ struct partition_t *p_client, *p_target;
+ psa_status_t stat;
+
+ if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
+ /* PSA APIs must be called from Thread mode */
+ tfm_core_panic();
+ }
+
+ p_client = GET_CURRENT_COMPONENT();
+
+ stat = tfm_spm_agent_psa_connect(sid, version, ns_client_id, client_data);
+
+ p_target = GET_CURRENT_COMPONENT();
+ if (p_client != p_target) {
+ /* Execution is returned from RoT Service */
+ stat = tfm_spm_partition_psa_reply(p_target->p_handles->msg.handle,
+ stat);
+ } else {
+ /* Execution is returned from SPM */
+ spm_handle_programmer_errors(stat);
+ }
+
+ return (psa_handle_t)stat;
+}
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
+#endif /* TFM_PARTITION_NS_AGENT_MAILBOX */
+
diff --git a/secure_fw/spm/core/tfm_spe_mailbox.c b/secure_fw/spm/core/tfm_spe_mailbox.c
index 3fe2f46..910ba2e 100644
--- a/secure_fw/spm/core/tfm_spe_mailbox.c
+++ b/secure_fw/spm/core/tfm_spe_mailbox.c
@@ -183,8 +183,14 @@
params->psa_call_params.in_len,
params->psa_call_params.out_len);
psa_status_t psa_ret = PSA_ERROR_GENERIC_ERROR;
- /* assume asynchronous */
+
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
+ /* Assume asynchronous. Set to synchronous when an error happens. */
bool sync = false;
+#else
+ /* Assume synchronous. */
+ bool sync = true;
+#endif
SPM_ASSERT(params != NULL);
SPM_ASSERT(psa_ret != NULL);