SPM: tfm_get_caller_client_id() optimisation

Optimise tfm_get_caller_client_id() secure API for Library model
in LEVEL 1. This reduces the number of SVC calls in a workload
like the Regression test.

Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: If0ce614de2a1e37b4da0369661ab2e4c4c179b7c
diff --git a/secure_fw/spm/cmsis_func/arch.c b/secure_fw/spm/cmsis_func/arch.c
index 6fe40db..9d45336 100644
--- a/secure_fw/spm/cmsis_func/arch.c
+++ b/secure_fw/spm/cmsis_func/arch.c
@@ -27,15 +27,6 @@
 }
 
 __attribute__((naked))
-int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id)
-{
-    __ASM volatile(
-        "SVC %0\n"
-        "BX LR\n"
-        : : "I" (TFM_SVC_GET_CALLER_CLIENT_ID));
-}
-
-__attribute__((naked))
 static int32_t tfm_spm_request(int32_t request_type)
 {
     __ASM volatile(
diff --git a/secure_fw/spm/cmsis_func/include/spm_func.h b/secure_fw/spm/cmsis_func/include/spm_func.h
index ac0bc7b..2fbaa25 100644
--- a/secure_fw/spm/cmsis_func/include/spm_func.h
+++ b/secure_fw/spm/cmsis_func/include/spm_func.h
@@ -382,5 +382,15 @@
  */
 void tfm_spm_seal_psp_stacks(void);
 
+/**
+ * \brief Get the flags associated with a partition
+ *
+ * \param[in] partition_idx     Partition index
+ *
+ * \return Flags associated with the partition
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ */
+uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx);
 
 #endif /* __SPM_FUNC_H__ */
diff --git a/secure_fw/spm/cmsis_func/include/tfm_core_svc.h b/secure_fw/spm/cmsis_func/include/tfm_core_svc.h
index accf1b8..1c06a33 100644
--- a/secure_fw/spm/cmsis_func/include/tfm_core_svc.h
+++ b/secure_fw/spm/cmsis_func/include/tfm_core_svc.h
@@ -15,7 +15,6 @@
 #define TFM_SVC_PSA_EOI                 (0x1)
 #define TFM_SVC_SFN_REQUEST             (0x2)
 #define TFM_SVC_SFN_RETURN              (0x3)
-#define TFM_SVC_GET_CALLER_CLIENT_ID    (0x4)
 #define TFM_SVC_SPM_REQUEST             (0x5)
 #define TFM_SVC_GET_BOOT_DATA           (0x6)
 #define TFM_SVC_DEPRIV_REQ              (0x7)
diff --git a/secure_fw/spm/cmsis_func/spm_func.c b/secure_fw/spm/cmsis_func/spm_func.c
index 1c8edbc..443ea02 100644
--- a/secure_fw/spm/cmsis_func/spm_func.c
+++ b/secure_fw/spm/cmsis_func/spm_func.c
@@ -454,21 +454,6 @@
     return SPM_ERR_OK;
 }
 
-/**
- * \brief Get the flags associated with a partition
- *
- * \param[in] partition_idx     Partition index
- *
- * \return Flags associated with the partition
- *
- * \note This function doesn't check if partition_idx is valid.
- */
-static uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx)
-{
-    return g_spm_partition_db.partitions[partition_idx].static_data->
-           partition_flags;
-}
-
 static enum tfm_status_e tfm_start_partition(
                                          const struct tfm_sfn_req_s *desc_ptr,
                                          const struct iovec_params_t *iovec_ptr,
@@ -770,6 +755,12 @@
     return TFM_SUCCESS;
 }
 
+uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx)
+{
+    return g_spm_partition_db.partitions[partition_idx].static_data->
+           partition_flags;
+}
+
 uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx)
 {
     return g_spm_partition_db.partitions[partition_idx].static_data->
@@ -909,48 +900,6 @@
     return TFM_ERROR_INVALID_PARAMETER;
 }
 
-void tfm_spm_get_caller_client_id_handler(uint32_t *svc_args)
-{
-    uintptr_t result_ptr_value = svc_args[0];
-    uint32_t running_partition_idx =
-            tfm_spm_partition_get_running_partition_idx();
-    const uint32_t running_partition_flags =
-            tfm_spm_partition_get_flags(running_partition_idx);
-    const struct spm_partition_runtime_data_t *curr_part_data =
-            tfm_spm_partition_get_runtime_data(running_partition_idx);
-    int res = 0;
-
-    if (!(running_partition_flags & SPM_PART_FLAG_APP_ROT) ||
-        curr_part_data->partition_state == SPM_PARTITION_STATE_HANDLING_IRQ ||
-        curr_part_data->partition_state == SPM_PARTITION_STATE_SUSPENDED) {
-        /* This handler shouldn't be called from outside partition context.
-         * Also if the current partition is handling IRQ, the caller partition
-         * index might not be valid;
-         * Partitions are only allowed to run while S domain is locked.
-         */
-        svc_args[0] = (uint32_t)TFM_ERROR_INVALID_PARAMETER;
-        return;
-    }
-
-    /* Make sure that the output pointer points to a memory area that is owned
-     * by the partition
-     */
-    res = tfm_spm_check_buffer_access(running_partition_idx,
-                                      (void *)result_ptr_value,
-                                      sizeof(curr_part_data->caller_client_id),
-                                      2);
-    if (res != TFM_SUCCESS) {
-        /* Not in accessible range, return error */
-        svc_args[0] = (uint32_t)res;
-        return;
-    }
-
-    *((int32_t *)result_ptr_value) = curr_part_data->caller_client_id;
-
-    /* Store return value in r0 */
-    svc_args[0] = (uint32_t)TFM_SUCCESS;
-}
-
 /* This SVC handler is called if veneer is running in thread mode */
 uint32_t tfm_spm_partition_request_svc_handler(
         const uint32_t *svc_ctx, uint32_t excReturn)
diff --git a/secure_fw/spm/cmsis_func/tfm_core_svcalls_func.c b/secure_fw/spm/cmsis_func/tfm_core_svcalls_func.c
index aeec327..a06edc1 100644
--- a/secure_fw/spm/cmsis_func/tfm_core_svcalls_func.c
+++ b/secure_fw/spm/cmsis_func/tfm_core_svcalls_func.c
@@ -66,9 +66,6 @@
     case TFM_SVC_SFN_RETURN:
         retval = tfm_spm_partition_return_handler(exc_return);
         break;
-    case TFM_SVC_GET_CALLER_CLIENT_ID:
-        tfm_spm_get_caller_client_id_handler(svc_args);
-        break;
     case TFM_SVC_SPM_REQUEST:
         tfm_spm_request_handler((struct tfm_state_context_t *)svc_args);
         break;
diff --git a/secure_fw/spm/cmsis_func/tfm_secure_api.c b/secure_fw/spm/cmsis_func/tfm_secure_api.c
index cede704..7696c3e 100644
--- a/secure_fw/spm/cmsis_func/tfm_secure_api.c
+++ b/secure_fw/spm/cmsis_func/tfm_secure_api.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -41,3 +41,44 @@
     }
     return TFM_ERROR_GENERIC;
 }
+
+enum tfm_status_e tfm_core_get_caller_client_id(int32_t *caller_client_id)
+{
+    if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
+        /* This API is available only in Thread mode and when called
+         * from Handler mode is considered a violation of the
+         * programming model.
+         */
+        tfm_core_panic();
+    }
+
+    const uint32_t running_partition_idx =
+            tfm_spm_partition_get_running_partition_idx();
+    const uint32_t running_partition_flags =
+            tfm_spm_partition_get_flags(running_partition_idx);
+    const struct spm_partition_runtime_data_t *curr_part_data =
+            tfm_spm_partition_get_runtime_data(running_partition_idx);
+
+    if (!(running_partition_flags & SPM_PART_FLAG_APP_ROT) ||
+        curr_part_data->partition_state == SPM_PARTITION_STATE_HANDLING_IRQ ||
+        curr_part_data->partition_state == SPM_PARTITION_STATE_SUSPENDED) {
+        /* This API shouldn't be called from outside partition context.
+         * Also if the current partition is handling IRQ, the caller partition
+         * index might not be valid;
+         * Partitions are only allowed to run while S domain is locked.
+         */
+        return TFM_ERROR_INVALID_PARAMETER;
+    }
+
+    int32_t res = tfm_spm_check_buffer_access(running_partition_idx,
+                                      (void *)caller_client_id,
+                                      sizeof(int32_t),
+                                      2);
+    if (res != TFM_SUCCESS) {
+        return res;
+    }
+
+    *caller_client_id = curr_part_data->caller_client_id;
+
+    return TFM_SUCCESS;
+}