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;
}