Core: Update parameter packing mechanism

The existing parameter packing mechanism wrappers the vectors and
length into the new defined structure, and marks the 'out_vec' as
input is confusing. Move the type and length into a new defined
'control' parameter to clear the confusion. And this could be expanded
easily to welcome more extra parameters.

Change-Id: Id63f4c48af90231480a3238570b0c1956a2918d8
Signed-off-by: Summer Qin <summer.qin@arm.com>
diff --git a/interface/include/tfm_api.h b/interface/include/tfm_api.h
index af2b492..5e2aacb 100644
--- a/interface/include/tfm_api.h
+++ b/interface/include/tfm_api.h
@@ -58,6 +58,16 @@
     TFM_ERROR_GENERIC = 0x1F,
 };
 
+/*
+ * Structure to package type, in_len and out_len, it is mainly used for
+ * psa_call.
+ */
+struct tfm_control_parameter_t {
+   int32_t type;
+   size_t in_len;
+   size_t out_len;
+};
+
 /********************* Secure function declarations ***************************/
 
 /**
@@ -102,16 +112,17 @@
  * \brief Call a secure function referenced by a connection handle.
  *
  * \param[in] handle            Handle to connection.
- * \param[in] type              The reuqest type. Must be zero(PSA_IPC_CALL) or
- *                              positive.
+ * \param[in] ctrl_param        Parameter structure, includes reuqest type,
+ *                              in_num and out_num.
  * \param[in] in_vec            Array of input \ref psa_invec structures.
- * \param[in] out_vec           Array of output \ref psa_invec structures.
+ * \param[in/out] out_vec       Array of output \ref psa_outvec structures.
  *
  * \return Returns \ref psa_status_t status code.
  */
-psa_status_t tfm_psa_call_veneer(psa_handle_t handle, int32_t type,
-                                 const psa_invec *in_vec,
-                                 const psa_invec *out_vec);
+psa_status_t tfm_psa_call_veneer(psa_handle_t handle,
+                               const struct tfm_control_parameter_t *ctrl_param,
+                               const psa_invec *in_vec,
+                               psa_outvec *out_vec);
 
 /**
  * \brief Close connection to secure function referenced by a connection handle.
diff --git a/interface/src/tfm_psa_ns_api.c b/interface/src/tfm_psa_ns_api.c
index 5fb5de3..9a677a2 100644
--- a/interface/src/tfm_psa_ns_api.c
+++ b/interface/src/tfm_psa_ns_api.c
@@ -54,18 +54,18 @@
     /* Due to v8M restrictions, TF-M NS API needs to add another layer of
      * serialization in order for NS to pass arguments to S
      */
-    psa_invec in_vecs, out_vecs;
+    const struct tfm_control_parameter_t ctrl_param = {
+        .type = type,
+        .in_len = in_len,
+        .out_len = out_len,
+    };
 
-    in_vecs.base = in_vec;
-    in_vecs.len = in_len;
-    out_vecs.base = out_vec;
-    out_vecs.len = out_len;
     return tfm_ns_interface_dispatch(
                                 (veneer_fn)tfm_psa_call_veneer,
                                 (uint32_t)handle,
-                                (uint32_t)type,
-                                (uint32_t)&in_vecs,
-                                (uint32_t)&out_vecs);
+                                (uint32_t)&ctrl_param,
+                                (uint32_t)in_vec,
+                                (uint32_t)out_vec);
 }
 
 void psa_close(psa_handle_t handle)
diff --git a/secure_fw/core/ipc/tfm_svcalls.c b/secure_fw/core/ipc/tfm_svcalls.c
index 3b71e17..039b4b4 100644
--- a/secure_fw/core/ipc/tfm_svcalls.c
+++ b/secure_fw/core/ipc/tfm_svcalls.c
@@ -80,11 +80,7 @@
 
     TFM_ASSERT(args != NULL);
     handle = (psa_handle_t)args[0];
-    type = (int32_t)args[1];
 
-    if (type < 0) {
-        tfm_panic();
-    }
     partition = tfm_spm_get_running_partition();
     if (!partition) {
         tfm_panic();
@@ -93,6 +89,7 @@
         partition->static_data->partition_flags);
 
     if (!ns_caller) {
+        type = (int32_t)args[1];
         inptr = (psa_invec *)args[2];
         in_num = (size_t)args[3];
         /*
@@ -120,26 +117,28 @@
         }
     } else {
         /*
-         * FixMe: From non-secure caller, vec and len are composed into a new
-         * struct parameter. Need to extract them.
+         * FixMe: From non-secure caller, type, in_len and out_len are composed
+         * into a new struct parameter. Need to extract them.
          */
         /*
          * Read parameters from the arguments. It is a fatal error if the
          * memory reference for buffer is invalid or not readable.
          */
-        if (tfm_memory_check((const void *)args[2], sizeof(uint32_t),
-            ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
+        if (tfm_memory_check((const void *)args[1],
+            sizeof(struct tfm_control_parameter_t), ns_caller,
+            TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
             tfm_panic();
         }
-        if (tfm_memory_check((const void *)args[3], sizeof(uint32_t),
-            ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
-            tfm_panic();
-        }
+        type = ((struct tfm_control_parameter_t *)args[1])->type;
+        in_num = ((struct tfm_control_parameter_t *)args[1])->in_len;
+        out_num = ((struct tfm_control_parameter_t *)args[1])->out_len;
+        inptr = (psa_invec *)args[2];
+        outptr = (psa_outvec *)args[3];
+    }
 
-        inptr = (psa_invec *)((psa_invec *)args[2])->base;
-        in_num = ((psa_invec *)args[2])->len;
-        outptr = (psa_outvec *)((psa_invec *)args[3])->base;
-        out_num = ((psa_invec *)args[3])->len;
+    /* The request type must be zero or positive. */
+    if (type < 0) {
+        tfm_panic();
     }
 
     return tfm_psa_call(handle, type, inptr, in_num, outptr, out_num, ns_caller,
diff --git a/secure_fw/ns_callable/tfm_psa_api_veneers.c b/secure_fw/ns_callable/tfm_psa_api_veneers.c
index a052c8d..4c45e7e 100644
--- a/secure_fw/ns_callable/tfm_psa_api_veneers.c
+++ b/secure_fw/ns_callable/tfm_psa_api_veneers.c
@@ -97,12 +97,13 @@
 }
 
 __tfm_secure_gateway_attributes__
-psa_status_t tfm_psa_call_veneer(psa_handle_t handle, int32_t type,
-                                 const psa_invec *in_vec,
-                                 const psa_invec *out_vec)
+psa_status_t tfm_psa_call_veneer(psa_handle_t handle,
+                               const struct tfm_control_parameter_t *ctrl_param,
+                               const psa_invec *in_vec,
+                               psa_outvec *out_vec)
 {
-    TFM_CORE_NS_IPC_REQUEST_VENEER(tfm_svcall_psa_call, handle, type, in_vec,
-                                   out_vec);
+    TFM_CORE_NS_IPC_REQUEST_VENEER(tfm_svcall_psa_call, handle, ctrl_param,
+                                   in_vec, out_vec);
 }
 
 __tfm_secure_gateway_attributes__