Core: Improve secure function entry point in Library model

In current Library model implementation, each secure function
includes the same inline entry point tfm_core_partition_request().
However, it is only required to make NS client check as inline.
The remaining steps in tfm_core_partition_request() increase the
memory footprint when they are also inlined in secure functions.

Extract checking NS client from tfm_core_partition_request() and
add an inline function tfm_core_is_ns_client().
Change tfm_core_partition_request() to a normal function called
by each secure function.

It can save several KB in code size in Library model.

Change-Id: I2b8d58d8daff22068cddbfa1145203ca92f305a4
Signed-off-by: David Hu <david.hu@arm.com>
diff --git a/secure_fw/core/include/tfm_secure_api.h b/secure_fw/core/include/tfm_secure_api.h
index b85bdd8..250dc0a 100644
--- a/secure_fw/core/include/tfm_secure_api.h
+++ b/secure_fw/core/include/tfm_secure_api.h
@@ -127,20 +127,16 @@
             return (int32_t)TFM_ERROR_GENERIC;                       \
         } while (0)
 #else
-#define TFM_CORE_IOVEC_SFN_REQUEST(id, fn, a, b, c, d)               \
-        return tfm_core_partition_request(id, fn,                    \
+#define TFM_CORE_IOVEC_SFN_REQUEST(id, is_ns, fn, a, b, c, d)        \
+        return tfm_core_partition_request(id, is_ns, fn,             \
                 (int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d)
 
-__attribute__ ((always_inline)) __STATIC_INLINE
-int32_t tfm_core_partition_request(uint32_t id, void *fn,
-            int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4)
-{
-    int32_t args[4] = {arg1, arg2, arg3, arg4};
-    struct tfm_sfn_req_s desc, *desc_ptr = &desc;
+int32_t tfm_core_partition_request(uint32_t id, bool is_ns, void *fn,
+            int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4);
 
-    desc.sp_id = id;
-    desc.sfn = (sfn_t) fn;
-    desc.args = args;
+__attribute__ ((always_inline)) __STATIC_INLINE
+bool tfm_core_is_ns_client(void)
+{
     /*
      * This preprocessor condition checks if a version of GCC smaller than
      * 7.3.1 is being used to compile the code.
@@ -156,30 +152,16 @@
      * Use the fact that, if called from Non-Secure, the LSB of the return
      * address is set to 0.
      */
-    desc.ns_caller = !(
-           (intptr_t)__builtin_extract_return_addr(__builtin_return_address(0U))
-           & 1);
+    return !(
+          (uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0U))
+          & 0x1);
 #else
     /*
      * Convert the result of cmse_nonsecure_caller from an int to a bool
      * to prevent using an int in the tfm_sfn_req_s structure.
      */
-    desc.ns_caller = (cmse_nonsecure_caller() != 0) ? true : false;
+    return (cmse_nonsecure_caller() != 0) ? true : false;
 #endif /* Check for GCC compiler version smaller than 7.3.1 */
-    if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
-        /* The veneer of a secure service had been called from Handler mode.
-         * This violates TF-M's programming model, and is considered an
-         * unrecoverable error.
-         */
-        tfm_core_panic();
-    } else {
-        if (desc.ns_caller) {
-            return tfm_core_sfn_request(desc_ptr);
-        } else {
-            return tfm_spm_sfn_request_thread_mode(desc_ptr);
-        }
-    }
-    return TFM_ERROR_GENERIC;
 }
 #endif
 
diff --git a/secure_fw/core/tfm_secure_api.c b/secure_fw/core/tfm_secure_api.c
index 53b3499..2c49717 100644
--- a/secure_fw/core/tfm_secure_api.c
+++ b/secure_fw/core/tfm_secure_api.c
@@ -57,3 +57,32 @@
     ERROR_MSG("Security violation when calling secure API");
     tfm_core_panic();
 }
+
+#ifndef TFM_PSA_API
+int32_t tfm_core_partition_request(uint32_t id, bool is_ns, void *fn,
+            int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4)
+{
+    int32_t args[4] = {arg1, arg2, arg3, arg4};
+    struct tfm_sfn_req_s desc, *desc_ptr = &desc;
+
+    desc.sp_id = id;
+    desc.sfn = (sfn_t) fn;
+    desc.args = args;
+    desc.ns_caller = is_ns;
+
+    if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
+        /* The veneer of a secure service had been called from Handler mode.
+         * This violates TF-M's programming model, and is considered an
+         * unrecoverable error.
+         */
+        tfm_core_panic();
+    } else {
+        if (desc.ns_caller) {
+            return tfm_core_sfn_request(desc_ptr);
+        } else {
+            return tfm_spm_sfn_request_thread_mode(desc_ptr);
+        }
+    }
+    return TFM_ERROR_GENERIC;
+}
+#endif
diff --git a/secure_fw/ns_callable/tfm_veneers.c b/secure_fw/ns_callable/tfm_veneers.c
index 02b0ca4..0ec4da5 100644
--- a/secure_fw/ns_callable/tfm_veneers.c
+++ b/secure_fw/ns_callable/tfm_veneers.c
@@ -175,7 +175,10 @@
                                          psa_outvec *out_vec, \
                                          size_t out_len) \
     { \
+        bool is_ns = tfm_core_is_ns_client(); \
+      \
         TFM_CORE_IOVEC_SFN_REQUEST(partition_name, \
+                                   is_ns, \
                                    (void *) sfn_name, \
                                    in_vec, in_len, out_vec, out_len); \
     }
diff --git a/secure_fw/ns_callable/tfm_veneers.c.template b/secure_fw/ns_callable/tfm_veneers.c.template
index a5035aa..258f5bd 100644
--- a/secure_fw/ns_callable/tfm_veneers.c.template
+++ b/secure_fw/ns_callable/tfm_veneers.c.template
@@ -31,7 +31,10 @@
                                          psa_outvec *out_vec, \
                                          size_t out_len) \
     { \
+        bool is_ns = tfm_core_is_ns_client(); \
+      \
         TFM_CORE_IOVEC_SFN_REQUEST(partition_name, \
+                                   is_ns, \
                                    (void *) sfn_name, \
                                    in_vec, in_len, out_vec, out_len); \
     }