SPM: Redirect PSA API runtimely instead of statically
The previous PSA API redirecting is statically performed in header
files, based on C preprocessors exported by the configuration system.
The C preprocessors make the configuration maintenance harder, and
users could not find the exact PSA API name in debug symbols, which
is confusing.
Now the redirecting turns into a runtime behavior. SPRTL calls
corresponded ABI for PSA API. The ABI is set in the Secure Partition
local storage by SPM when booting, based on Secure Partition types.
Check 'prv_process_metadata' and 'psa_api_ipc.c' for details.
Co-authored-by: Ken Liu <ken.liu@arm.com>
Signed-off-by: Sherry Zhang <sherry.zhang2@arm.com>
Change-Id: Ifc974941ddb6653389d9deca9f18f754b8f25b27
diff --git a/interface/include/psa_interface_redirect.h b/interface/include/psa_interface_redirect.h
index f8d24bd..70d9f02 100644
--- a/interface/include/psa_interface_redirect.h
+++ b/interface/include/psa_interface_redirect.h
@@ -12,9 +12,6 @@
#if CONFIG_TFM_PSA_API_SUPERVISOR_CALL == 1
-#define psa_framework_version psa_framework_version_svc
-#define psa_version psa_version_svc
-#define tfm_psa_call_pack tfm_psa_call_pack_svc
#define psa_wait psa_wait_svc
#define psa_get psa_get_svc
#define psa_read psa_read_svc
@@ -31,8 +28,6 @@
/* 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 */
@@ -51,9 +46,6 @@
#elif CONFIG_TFM_PSA_API_CROSS_CALL == 1
-#define psa_framework_version psa_framework_version_cross
-#define psa_version psa_version_cross
-#define tfm_psa_call_pack tfm_psa_call_pack_cross
#define psa_wait psa_wait_cross
#define psa_get psa_get_cross
#define psa_read psa_read_cross
@@ -70,8 +62,6 @@
/* 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 */
@@ -97,17 +87,12 @@
#elif CONFIG_TFM_PSA_API_SFN_CALL == 1
-#define psa_framework_version psa_framework_version_sfn
-#define psa_version psa_version_sfn
-#define tfm_psa_call_pack psa_call_pack_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 CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
#define psa_wait psa_wait_sfn
diff --git a/secure_fw/partitions/lib/runtime/CMakeLists.txt b/secure_fw/partitions/lib/runtime/CMakeLists.txt
index a83a80f..cf34b93 100644
--- a/secure_fw/partitions/lib/runtime/CMakeLists.txt
+++ b/secure_fw/partitions/lib/runtime/CMakeLists.txt
@@ -26,6 +26,7 @@
$<$<BOOL:${CONFIG_TFM_PARTITION_META}>:./sprt_partition_metadata_indicator.c>
$<$<BOOL:${CONFIG_TFM_PARTITION_META}>:./rt_main.c>
$<$<BOOL:${CONFIG_TFM_SPM_BACKEND_IPC}>:./sfn_common_thread.c>
+ $<$<BOOL:${CONFIG_TFM_SPM_BACKEND_IPC}>:./psa_api_ipc.c>
$<$<BOOL:${TFM_SP_LOG_RAW_ENABLED}>:./tfm_sp_log_raw.c>
$<$<BOOL:${TFM_SP_LOG_RAW_ENABLED}>:${CMAKE_SOURCE_DIR}/platform/ext/common/tfm_hal_sp_logdev_periph.c>
)
@@ -44,7 +45,7 @@
$<$<BOOL:${TFM_SP_LOG_RAW_ENABLED}>:TFM_SP_LOG_RAW_ENABLED>
)
-target_include_directories(tfm_partitions
+target_include_directories(tfm_sprt
INTERFACE
$<BUILD_INTERFACE:$<$<BOOL:${CONFIG_TFM_PARTITION_META}>:${CMAKE_CURRENT_SOURCE_DIR}/include>>
)
diff --git a/secure_fw/partitions/lib/runtime/psa_api_ipc.c b/secure_fw/partitions/lib/runtime/psa_api_ipc.c
new file mode 100644
index 0000000..3b12232
--- /dev/null
+++ b/secure_fw/partitions/lib/runtime/psa_api_ipc.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+#include "psa/client.h"
+#include "tfm_psa_call_pack.h"
+#include "sprt_partition_metadata_indicator.h"
+#include "runtime_defs.h"
+
+psa_status_t tfm_psa_call_pack(psa_handle_t handle,
+ uint32_t ctrl_param,
+ const psa_invec *in_vec,
+ psa_outvec *out_vec)
+{
+ return PART_METADATA()->psa_fns->psa_call(handle, ctrl_param,
+ in_vec, out_vec);
+}
+
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+psa_handle_t psa_connect(uint32_t sid, uint32_t version)
+{
+ return PART_METADATA()->psa_fns->psa_connect(sid, version);
+}
+
+void psa_close(psa_handle_t handle)
+{
+ return PART_METADATA()->psa_fns->psa_close(handle);
+}
+#endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
+
+uint32_t psa_version(uint32_t sid)
+{
+ return PART_METADATA()->psa_fns->psa_version(sid);
+}
+
+uint32_t psa_framework_version(void)
+{
+ return PART_METADATA()->psa_fns->psa_framework_version();
+}
diff --git a/secure_fw/spm/cmsis_psa/psa_interface_cross.c b/secure_fw/spm/cmsis_psa/psa_interface_cross.c
index 5638acb..ef57226 100644
--- a/secure_fw/spm/cmsis_psa/psa_interface_cross.c
+++ b/secure_fw/spm/cmsis_psa/psa_interface_cross.c
@@ -15,6 +15,7 @@
#include "psa/client.h"
#include "psa/lifecycle.h"
#include "psa/service.h"
+#include "runtime_defs.h"
#if defined(__ICCARM__)
@@ -422,3 +423,13 @@
}
#endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
+
+const struct psa_api_tbl_t psa_api_cross = {
+ tfm_psa_call_pack_cross,
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+ psa_connect_cross,
+ psa_close_cross,
+#endif
+ psa_version_cross,
+ psa_framework_version_cross
+ };
diff --git a/secure_fw/spm/cmsis_psa/psa_interface_sfn.c b/secure_fw/spm/cmsis_psa/psa_interface_sfn.c
index eb584f6..0980c11 100644
--- a/secure_fw/spm/cmsis_psa/psa_interface_sfn.c
+++ b/secure_fw/spm/cmsis_psa/psa_interface_sfn.c
@@ -12,7 +12,7 @@
#include "ffm/psa_api.h"
#include "psa/client.h"
-uint32_t psa_framework_version_sfn(void)
+uint32_t psa_framework_version(void)
{
if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
/* PSA APIs must be called from Thread mode */
@@ -22,7 +22,7 @@
return tfm_spm_client_psa_framework_version();
}
-uint32_t psa_version_sfn(uint32_t sid)
+uint32_t psa_version(uint32_t sid)
{
if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
/* PSA APIs must be called from Thread mode */
@@ -32,7 +32,7 @@
return tfm_spm_client_psa_version(sid);
}
-psa_status_t psa_call_pack_sfn(psa_handle_t handle, uint32_t ctrl_param,
+psa_status_t tfm_psa_call_pack(psa_handle_t handle, uint32_t ctrl_param,
const psa_invec *in_vec, psa_outvec *out_vec)
{
struct partition_t *p_client, *p_target;
@@ -107,7 +107,7 @@
/* 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)
+psa_handle_t psa_connect(uint32_t sid, uint32_t version)
{
struct partition_t *p_client, *p_target;
psa_status_t stat;
@@ -134,7 +134,7 @@
return (psa_handle_t)stat;
}
-void psa_close_sfn(psa_handle_t handle)
+void psa_close(psa_handle_t handle)
{
struct partition_t *p_client, *p_target;
psa_status_t stat;
diff --git a/secure_fw/spm/cmsis_psa/psa_interface_svc.c b/secure_fw/spm/cmsis_psa/psa_interface_svc.c
index 28e27bd..a250210 100644
--- a/secure_fw/spm/cmsis_psa/psa_interface_svc.c
+++ b/secure_fw/spm/cmsis_psa/psa_interface_svc.c
@@ -8,6 +8,7 @@
#include <stdint.h>
#include "compiler_ext_defs.h"
#include "config_spm.h"
+#include "runtime_defs.h"
#include "svc_num.h"
#include "tfm_psa_call_pack.h"
#include "utilities.h"
@@ -157,3 +158,14 @@
#endif
#endif /* CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 */
+
+
+const struct psa_api_tbl_t psa_api_svc = {
+ tfm_psa_call_pack_svc,
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+ psa_connect_svc,
+ psa_close_svc,
+#endif
+ psa_version_svc,
+ psa_framework_version_svc
+ };
diff --git a/secure_fw/spm/ffm/backend_ipc.c b/secure_fw/spm/ffm/backend_ipc.c
index 07b01f5..8950e54 100644
--- a/secure_fw/spm/ffm/backend_ipc.c
+++ b/secure_fw/spm/ffm/backend_ipc.c
@@ -102,6 +102,9 @@
return state;
}
+extern struct psa_api_tbl_t psa_api_cross;
+extern struct psa_api_tbl_t psa_api_svc;
+
static void prv_process_metadata(struct partition_t *p_pt)
{
const struct partition_load_info_t *p_pt_ldi;
@@ -128,6 +131,12 @@
ARCH_CTXCTRL_ALLOCATED_PTR(ctx_ctrl);
p_rt_meta->entry = p_pt_ldi->entry;
+#if TFM_LVL == 1
+ p_rt_meta->psa_fns = &psa_api_cross;
+#else
+ /* TODO: ABI for PRoT partitions needs to be updated based on implementations. */
+ p_rt_meta->psa_fns = &psa_api_svc;
+#endif
p_rt_meta->n_sfn = 0;
p_sfn_table = p_rt_meta->sfn_table;
diff --git a/secure_fw/spm/include/interface/runtime_defs.h b/secure_fw/spm/include/interface/runtime_defs.h
index 60fee8c..8b57f81 100644
--- a/secure_fw/spm/include/interface/runtime_defs.h
+++ b/secure_fw/spm/include/interface/runtime_defs.h
@@ -10,6 +10,7 @@
#include <stdint.h>
+#include "psa/client.h"
#include "psa/error.h"
#include "psa/service.h"
@@ -17,10 +18,33 @@
typedef psa_status_t (*service_fn_t)(psa_msg_t *msg);
typedef psa_status_t (*sfn_init_fn_t)(void);
-struct runtime_metadata_t {
- uintptr_t entry; /* Entry function invoked by sprt_main */
- uint32_t n_sfn; /* Number of Secure FuNctions */
- service_fn_t sfn_table[]; /* Secure FuNctions Table */
+/* PSA API dispatcher for IPC model. */
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
+
+typedef psa_status_t (*psa_call_fn_t)(psa_handle_t, uint32_t,
+ const psa_invec *in_vec,
+ psa_outvec *out_vec);
+typedef psa_handle_t (*psa_connect_fn_t)(uint32_t, uint32_t);
+typedef void (*psa_close_fn_t)(psa_handle_t);
+typedef uint32_t (*psa_version_fn_t)(uint32_t);
+typedef uint32_t (*psa_framework_version_fn_t)(void);
+
+struct psa_api_tbl_t {
+ psa_call_fn_t psa_call;
+#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
+ psa_connect_fn_t psa_connect;
+ psa_close_fn_t psa_close;
+#endif
+ psa_version_fn_t psa_version;
+ psa_framework_version_fn_t psa_framework_version;
};
+struct runtime_metadata_t {
+ uintptr_t entry; /* Entry function invoked by sprt_main */
+ struct psa_api_tbl_t *psa_fns; /* PSA API entry table */
+ uint32_t n_sfn; /* Number of Secure FuNctions */
+ service_fn_t sfn_table[];/* Secure FuNctions Table */
+};
+#endif /* CONFIG_TFM_SPM_BACKEND_IPC == 1 */
+
#endif /* __RUNTIME_DEFS_H__ */