Platform: IOCTL for platform-specific services

Introduce new API function in HAL and a new generic platform
service to provide the means for platforms to implement proprietary
functions using a uniform framework and a single secure entry point.

Change-Id: I72ddbb3342ae851fe9851ccb27a54c8f4322b01f
Signed-off-by: Miklos Balint <miklos.balint@arm.com>
diff --git a/secure_fw/ns_callable/CMakeLists.inc b/secure_fw/ns_callable/CMakeLists.inc
index 3abee33..b8fcf5f 100644
--- a/secure_fw/ns_callable/CMakeLists.inc
+++ b/secure_fw/ns_callable/CMakeLists.inc
@@ -29,10 +29,6 @@
 	set (SS_NS_CALLABLE_C_SRC "${CMAKE_CURRENT_LIST_DIR}/tfm_veneers.c")
 endif()
 
-if (TFM_PARTITION_PLATFORM)
-    list(APPEND SS_NS_CALLABLE_C_SRC "${CMAKE_CURRENT_LIST_DIR}/tfm_platform_veneers.c")
-endif()
-
 if (TFM_PARTITION_AUDIT_LOG)
 	list(APPEND SS_NS_CALLABLE_C_SRC "${CMAKE_CURRENT_LIST_DIR}/tfm_audit_veneers.c")
 endif()
diff --git a/secure_fw/ns_callable/tfm_platform_veneers.c b/secure_fw/ns_callable/tfm_platform_veneers.c
deleted file mode 100644
index c2515fe..0000000
--- a/secure_fw/ns_callable/tfm_platform_veneers.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include "tfm_platform_veneers.h"
-#include "secure_fw/services/platform/platform_sp.h"
-#include "tfm_secure_api.h"
-#include "tfm_api.h"
-#include "spm_partition_defs.h"
-
-__tfm_secure_gateway_attributes__
-enum tfm_platform_err_t tfm_platform_veneer_system_reset(void)
-{
-    TFM_CORE_SFN_REQUEST(TFM_SP_PLATFORM_ID,
-                         platform_sp_system_reset,
-                         0, 0, 0, 0);
-}
diff --git a/secure_fw/ns_callable/tfm_veneers.c b/secure_fw/ns_callable/tfm_veneers.c
index aff38e8..3effa95 100644
--- a/secure_fw/ns_callable/tfm_veneers.c
+++ b/secure_fw/ns_callable/tfm_veneers.c
@@ -74,7 +74,7 @@
 #ifdef TFM_PARTITION_PLATFORM
 /******** TFM_SP_PLATFORM ********/
 psa_status_t platform_sp_system_reset(psa_invec *, size_t, psa_outvec *, size_t);
-psa_status_t platform_sp_pin_service(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t platform_sp_ioctl(psa_invec *, size_t, psa_outvec *, size_t);
 #endif /* TFM_PARTITION_PLATFORM */
 
 /******** TFM_SP_INITIAL_ATTESTATION ********/
@@ -186,7 +186,7 @@
 #ifdef TFM_PARTITION_PLATFORM
 /******** TFM_SP_PLATFORM ********/
 TFM_VENEER_FUNCTION(TFM_SP_PLATFORM, platform_sp_system_reset)
-TFM_VENEER_FUNCTION(TFM_SP_PLATFORM, platform_sp_pin_service)
+TFM_VENEER_FUNCTION(TFM_SP_PLATFORM, platform_sp_ioctl)
 #endif /* TFM_PARTITION_PLATFORM */
 
 /******** TFM_SP_INITIAL_ATTESTATION ********/
diff --git a/secure_fw/services/platform/manifest.yaml b/secure_fw/services/platform/manifest.yaml
index 283802e..9a5c7b1 100644
--- a/secure_fw/services/platform/manifest.yaml
+++ b/secure_fw/services/platform/manifest.yaml
@@ -23,9 +23,9 @@
       "minor_policy": "strict"
     },
     {
-      "sfid": "TFM_SP_PLATFORM_PIN_SERVICE_SFID",
-      "signal": "TFM_SP_PLATFORM_PIN_SERVICE",
-      "tfm_symbol": "platform_sp_pin_service",
+      "sfid": "TFM_SP_PLATFORM_IOCTL_SFID",
+      "signal": "TFM_SP_PLATFORM_IOCTL",
+      "tfm_symbol": "platform_sp_ioctl",
       "non_secure_clients": true,
       "minor_version": 1,
       "minor_policy": "strict"
diff --git a/secure_fw/services/platform/platform_sp.c b/secure_fw/services/platform/platform_sp.c
index 59fa186..13aed6a 100644
--- a/secure_fw/services/platform/platform_sp.c
+++ b/secure_fw/services/platform/platform_sp.c
@@ -28,11 +28,6 @@
 
     /* FIXME: The system reset functionality is only supported in isolation
      *        level 1.
-     *        Currently, the mechanism by which PRoT services should run in
-     *        privileged mode in level 3, it is not in place due to an ongoing
-     *        work in TF-M Core. So, the NVIC_SystemReset call performed by the
-     *        service, it is expected to generate a memory fault when it tries
-     *        to access the SCB->AIRCR register in level 3 isolation.
      */
 
     tfm_platform_hal_system_reset();
@@ -41,13 +36,23 @@
 }
 
 enum tfm_platform_err_t
-platform_sp_pin_service(const psa_invec  *in_vec,  uint32_t num_invec,
-                        const psa_outvec *out_vec, uint32_t num_outvec)
+platform_sp_ioctl(psa_invec  *in_vec,  uint32_t num_invec,
+                  psa_outvec *out_vec, uint32_t num_outvec)
 {
-    enum tfm_plat_err_t ret = tfm_platform_hal_pin_service(in_vec, num_invec,
-                                                           out_vec, num_outvec);
+    void *input, *output;
+    tfm_platform_ioctl_req_t request;
 
-    return ((ret == TFM_PLAT_ERR_SUCCESS) ? TFM_PLATFORM_ERR_SUCCESS :
-                                                 TFM_PLATFORM_ERR_SYSTEM_ERROR);
+    if ((num_invec < 1) || (num_invec > 2) ||
+        (num_outvec > 1) ||
+        (in_vec[0].base == NULL) ||
+        (in_vec[0].len != sizeof(tfm_platform_ioctl_req_t))) {
+        return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+    }
+
+    input = (num_invec == 1) ? NULL : &in_vec[1];
+    output = out_vec;
+    request = *((tfm_platform_ioctl_req_t *)in_vec[0].base);
+
+    return tfm_platform_hal_ioctl(request, input, output);
 }
 
diff --git a/secure_fw/services/platform/tfm_platform_secure_api.c b/secure_fw/services/platform/tfm_platform_secure_api.c
index dccd3ce..9103ab4 100644
--- a/secure_fw/services/platform/tfm_platform_secure_api.c
+++ b/secure_fw/services/platform/tfm_platform_secure_api.c
@@ -6,113 +6,42 @@
  */
 
 #include "tfm_platform_api.h"
-#include "tfm_platform_veneers.h"
-#include "tfm_platform_defs.h"
 #include "tfm_veneers.h"
 
 __attribute__((section("SFN")))
 enum tfm_platform_err_t tfm_platform_system_reset(void)
 {
-    return tfm_platform_veneer_system_reset();
+    return (enum tfm_platform_err_t) tfm_platform_sp_system_reset_veneer(
+                                                              NULL, 0, NULL, 0);
 }
 
 __attribute__((section("SFN")))
 enum tfm_platform_err_t
-tfm_platform_set_pin_alt_func(uint32_t alt_func, uint64_t pin_mask,
-                              uint32_t *result)
+tfm_platform_ioctl(tfm_platform_ioctl_req_t request,
+                   psa_invec *input, psa_outvec *output)
 {
-    psa_status_t ret;
-    psa_invec in_vec;
-    psa_outvec out_vec;
-    struct tfm_pin_service_args_t args;
+    tfm_platform_ioctl_req_t req = request;
+    struct psa_invec in_vec[2];
+    size_t inlen, outlen;
 
-    if (result == NULL) {
-        return TFM_PLATFORM_ERR_INVALID_PARAM;
+    in_vec[0].base = &req;
+    in_vec[0].len = sizeof(req);
+    if (input != NULL) {
+        in_vec[1].base = input->base;
+        in_vec[1].len = input->len;
+        inlen = 2;
+    } else {
+        inlen = 1;
     }
 
-    args.type = TFM_PIN_SERVICE_TYPE_SET_ALTFUNC;
-    args.u.set_altfunc.alt_func = alt_func;
-    args.u.set_altfunc.pin_mask = pin_mask;
-
-    in_vec.base = (const void *)&args;
-    in_vec.len = sizeof(args);
-
-    out_vec.base = (void *)result;
-    out_vec.len = sizeof(*result);
-
-    ret = tfm_platform_sp_pin_service_veneer(&in_vec,  1, &out_vec, 1);
-
-    if (ret != PSA_SUCCESS) {
-        return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+    if (output != NULL) {
+        outlen = 1;
+    } else {
+        outlen = 0;
     }
 
-    return TFM_PLATFORM_ERR_SUCCESS;
-}
+    return (enum tfm_platform_err_t) tfm_platform_sp_ioctl_veneer(
+                                                in_vec, inlen, output, outlen);
 
-__attribute__((section("SFN")))
-enum tfm_platform_err_t
-tfm_platform_set_pin_default_in(uint32_t alt_func, uint32_t pin_value,
-                              bool default_in_value, uint32_t *result)
-{
-    psa_status_t ret;
-    psa_invec in_vec;
-    psa_outvec out_vec;
-    struct tfm_pin_service_args_t args;
-
-    if (result == NULL) {
-        return TFM_PLATFORM_ERR_INVALID_PARAM;
-    }
-
-    args.type = TFM_PIN_SERVICE_TYPE_SET_DEFAULT_IN;
-    args.u.set_default_in.alt_func = alt_func;
-    args.u.set_default_in.pin_value = pin_value;
-    args.u.set_default_in.default_in_value = default_in_value;
-
-    in_vec.base = (const void *)&args;
-    in_vec.len = sizeof(args);
-
-    out_vec.base = (void *)result;
-    out_vec.len = sizeof(*result);
-
-    ret = tfm_platform_sp_pin_service_veneer(&in_vec,  1, &out_vec, 1);
-
-    if (ret != PSA_SUCCESS) {
-        return TFM_PLATFORM_ERR_SYSTEM_ERROR;
-    }
-
-    return TFM_PLATFORM_ERR_SUCCESS;
-}
-
-__attribute__((section("SFN")))
-enum tfm_platform_err_t
-tfm_platform_set_pin_mode(uint64_t pin_mask, uint32_t pin_mode,
-                          uint32_t *result)
-{
-    psa_status_t ret;
-    psa_invec in_vec;
-    psa_outvec out_vec;
-    struct tfm_pin_service_args_t args;
-
-    if (result == NULL) {
-        return TFM_PLATFORM_ERR_INVALID_PARAM;
-    }
-
-    args.type = TFM_PIN_SERVICE_TYPE_SET_PIN_MODE;
-    args.u.set_pin_mode.pin_mask = pin_mask;
-    args.u.set_pin_mode.pin_mode = pin_mode;
-
-    in_vec.base = (const void *)&args;
-    in_vec.len = sizeof(args);
-
-    out_vec.base = (void *)result;
-    out_vec.len = sizeof(*result);
-
-    ret = tfm_platform_sp_pin_service_veneer(&in_vec,  1, &out_vec, 1);
-
-    if (ret != PSA_SUCCESS) {
-        return TFM_PLATFORM_ERR_SYSTEM_ERROR;
-    }
-
-    return TFM_PLATFORM_ERR_SUCCESS;
 }