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/docs/user_guides/services/tfm_platform_integration_guide.rst b/docs/user_guides/services/tfm_platform_integration_guide.rst
index a1733a4..4dffb84 100644
--- a/docs/user_guides/services/tfm_platform_integration_guide.rst
+++ b/docs/user_guides/services/tfm_platform_integration_guide.rst
@@ -27,12 +27,6 @@
*********************
TF-M Platform service
*********************
-The Platform service exposes the following interfaces:
-
-.. code-block:: c
-
- enum tfm_platform_err_t tfm_platform_system_reset(void)
-
The Platform service interfaces and types are defined and documented in
``interface/include/tfm_platform_api.h``
@@ -43,47 +37,49 @@
when the secure partitions request an action to the Platform service
(e.g system reset).
-*************************
-Platform HAL system reset
-*************************
+************
+Platform HAL
+************
-The Platform service service relies on a platform-specific implementation to
-perform some functionalities (e.g. system reset). The platform-specific
-implementation of those APIs will be located in the platform service code
-section (TF-M level 3 isolation) in order to protect it from a direct call from
-other secure partitions.
+The Platform Service relies on a platform-specific implementation to
+perform some functionalities. Mandatory functionality (e.g. system reset)
+that are required to be implemented for a platform to be supported by TF-M have
+their dedicated HAL API functions. Additional platform-specific services can be
+provided using the IOCTL function call.
For API specification, please check: ``platform/include/tfm_platform_system.h``
-An implementation is provided in all the supported platforms. Please,
-check ``platform/ext/target/<SPECIFIC_TARGET_FOLDER>/tfm_platform_system.c``
+An implementation is provided in all the supported platforms. Please, check
+``platform/ext/target/<SPECIFIC_TARGET_FOLDER>/services/src/tfm_platform_system.c``
+for examples.
The API **must** be implemented by the system integrators for their targets.
-The API **must** be implemented by the system integrators for their
-targets.
+IOCTL
+=====
-********************
-Platform pin service
-********************
-This service is designed to perform secure pin services of the platform
-(e.g alternate function setting, pin mode setting, etc).
-The veneer implementation follows IOVEC API implementation, which allows
-the NS application to pack many pin service requests into one service call
-to reduce the overhead of the Secure-Non-Secure context switch.
-Since packing many service requests into one call is application and use-case
-specific, the API implementations in ``tfm_platform_api.c`` and
-```tfm_platform_secure_api.c`` follow the one service in one veneer call design
-but the service implementation in tfm_platform_system.c is prepared to serve
-packed requests.
+A single entry point to platform-specific code across the HAL is provided by the
+IOCTL service and HAL function:
+
+.. code-block:: c
+
+ enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request,
+ psa_invec *in_vec,
+ psa_outvec *out_vec);
+
+A request type is provided by the client, with additional parameters contained
+in the optional ``in_vec`` parameter. An optional output buffer can be passed to
+the service in ``out_vec``.
+An IOCTL request type not supported on a particular platform should return
+``TFM_PLATFORM_ERR_NOT_SUPPORTED``
***************************
Current Service Limitations
***************************
- **system reset** - 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, is
+ isolation level 1. Currently the mechanism by which PSA-RoT services should
+ run in privileged mode in level 3 is not in place due to an ongoing work in
+ TF-M Core. So, the ``NVIC_SystemReset`` call performed by the service is
expected to generate a memory fault when it tries to access the ``SCB->AIRCR``
register in level 3 isolation.
@@ -108,7 +104,7 @@
`DEBUG_AUTHENTICATION` is `DAUTH_CHIP_DEFAULT`.
.. Note::
- `void tfm_spm_hal_init_debug(void)` is called during the TF-M core
+ ``void tfm_spm_hal_init_debug(void)`` is called during the TF-M core
initialisation phase, before initialising secure partition. This means that BL2
runs with the chip default setting.
diff --git a/interface/include/tfm_platform_api.h b/interface/include/tfm_platform_api.h
index 7cc57ab..9c4e023 100644
--- a/interface/include/tfm_platform_api.h
+++ b/interface/include/tfm_platform_api.h
@@ -10,6 +10,7 @@
#include <limits.h>
#include <stdbool.h>
+#include <stdint.h>
#include "tfm_api.h"
#ifdef __cplusplus
@@ -20,7 +21,7 @@
* \brief TFM secure partition platform API version
*/
#define TFM_PLATFORM_API_VERSION_MAJOR (0)
-#define TFM_PLATFORM_API_VERSION_MINOR (2)
+#define TFM_PLATFORM_API_VERSION_MINOR (3)
/* The return value is shared with the TF-M partition status value.
* The Platform return codes shouldn't overlap with predefined TFM status
@@ -38,11 +39,14 @@
TFM_PLATFORM_ERR_SUCCESS = 0,
TFM_PLATFORM_ERR_SYSTEM_ERROR = TFM_PLATFORM_ERR_OFFSET,
TFM_PLATFORM_ERR_INVALID_PARAM,
+ TFM_PLATFORM_ERR_NOT_SUPPORTED,
/* Following entry is only to ensure the error code of int size */
TFM_PLATFORM_ERR_FORCE_INT_SIZE = INT_MAX
};
+typedef int32_t tfm_platform_ioctl_req_t;
+
/*!
* \brief Resets the system.
*
@@ -51,47 +55,18 @@
enum tfm_platform_err_t tfm_platform_system_reset(void);
/*!
- * \brief Sets pin alternate function for the given pins
+ * \brief Performs a platform-specific service
*
- * \param[in] alt_func Alternate function to set (allowed values vary
+ * \param[in] request Request identifier (valid values vary
* based on the platform)
- * \param[in] pin_mask Pin mask of the selected pins
- * \param[out] result Return error value
+ * \param[in] input Input buffer to the requested service (or NULL)
+ * \param[in,out] output Output buffer to the requested service (or NULL)
*
* \return Returns values as specified by the \ref tfm_platform_err_t
*/
-enum tfm_platform_err_t
-tfm_platform_set_pin_alt_func(uint32_t alt_func, uint64_t pin_mask,
- uint32_t *result);
-
-/*!
- * \brief Sets default in value to use when the alternate function is not
- * selected for the pin
- *
- * \param[in] alt_func Alternate function to use (allowed values vary
- * based on the platform)
- * \param[in] pin_value Pin value to use
- * \param[in] default_in_value Default in value to set
- * \param[out] result Return error value
- *
- * \return Returns values as specified by the \ref tfm_platform_err_t
- */
-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);
-
-/*!
- * \brief Sets pin mode for the selected pins
- *
- * \param[in] pin_mask Pin mask of the selected pins
- * \param[in] pin_mode Pin mode to set for the selected pins
- * \param[out] result Return error value
- *
- * \return Returns values as specified by the \ref tfm_platform_err_t
- */
-enum tfm_platform_err_t
-tfm_platform_set_pin_mode(uint64_t pin_mask, uint32_t pin_mode,
- uint32_t *result);
+enum tfm_platform_err_t tfm_platform_ioctl(tfm_platform_ioctl_req_t request,
+ psa_invec *input,
+ psa_outvec *output);
#ifdef __cplusplus
diff --git a/interface/include/tfm_platform_defs.h b/interface/include/tfm_platform_defs.h
deleted file mode 100644
index 23fe4e0..0000000
--- a/interface/include/tfm_platform_defs.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __TFM_PLATFORM_DEFS__
-#define __TFM_PLATFORM_DEFS__
-
-#include <stdint.h>
-#include <limits.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- * \enum tfm_pin_service_type_t
- *
- * \brief Pin service types (supported types may vary based on the platform)
- */
-enum tfm_pin_service_type_t {
- TFM_PIN_SERVICE_TYPE_SET_ALTFUNC = 0, /*!< Set alternate function type */
- TFM_PIN_SERVICE_TYPE_SET_DEFAULT_IN, /*!< Set default in function type */
- TFM_PIN_SERVICE_TYPE_SET_PIN_MODE, /*!< Set pin mode function type */
- TFM_PIN_SERVICE_TYPE_MAX = INT_MAX /*!< Max to force enum max size */
-};
-
-/*!
- * \struct tfm_pin_service_args_t
- *
- * \brief Argument list for each platform pin service
- */
-struct tfm_pin_service_args_t {
- enum tfm_pin_service_type_t type;
- union {
- struct set_altfunc { /*!< TFM_PIN_SERVICE_TYPE_SET_ALTFUNC */
- uint32_t alt_func;
- uint64_t pin_mask;
- } set_altfunc;
- struct set_default_in { /*!< TFM_PIN_SERVICE_TYPE_SET_DEFAULT_IN */
- uint32_t alt_func;
- uint32_t pin_value;
- bool default_in_value;
- } set_default_in;
- struct set_pin_mode { /*!< TFM_PIN_SERVICE_TYPE_SET_PIN_MODE */
- uint64_t pin_mask;
- uint32_t pin_mode;
- } set_pin_mode;
- } u;
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __TFM_PLATFORM_DEFS__ */
diff --git a/interface/include/tfm_platform_veneers.h b/interface/include/tfm_platform_veneers.h
deleted file mode 100644
index 313927e..0000000
--- a/interface/include/tfm_platform_veneers.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __TFM_PLATFORM_VENEERS_H__
-#define __TFM_PLATFORM_VENEERS_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "tfm_platform_api.h"
-
-/*!
- * \brief Resets the system.
- *
- * \return Returns values as specified by the \ref tfm_platform_err_t
- */
-enum tfm_platform_err_t tfm_platform_veneer_system_reset(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __TFM_PLATFORM_VENEERS_H__ */
diff --git a/interface/include/tfm_veneers.h b/interface/include/tfm_veneers.h
index db3de27..71bc9e8 100644
--- a/interface/include/tfm_veneers.h
+++ b/interface/include/tfm_veneers.h
@@ -80,7 +80,7 @@
#ifdef TFM_PARTITION_PLATFORM
/******** TFM_SP_PLATFORM ********/
psa_status_t tfm_platform_sp_system_reset_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
-psa_status_t tfm_platform_sp_pin_service_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_platform_sp_ioctl_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_PLATFORM */
/******** TFM_SP_INITIAL_ATTESTATION ********/
diff --git a/interface/src/tfm_platform_api.c b/interface/src/tfm_platform_api.c
index 9b6f787..b3daa07 100644
--- a/interface/src/tfm_platform_api.c
+++ b/interface/src/tfm_platform_api.c
@@ -7,14 +7,13 @@
#include <stdbool.h>
#include "tfm_platform_api.h"
-#include "tfm_platform_veneers.h"
#include "tfm_ns_lock.h"
-#include "tfm_platform_defs.h"
#include "tfm_veneers.h"
enum tfm_platform_err_t tfm_platform_system_reset(void)
{
- return tfm_ns_lock_dispatch((veneer_fn)tfm_platform_veneer_system_reset,
+ return (enum tfm_platform_err_t) tfm_ns_lock_dispatch(
+ (veneer_fn)tfm_platform_sp_system_reset_veneer,
0,
0,
0,
@@ -22,93 +21,32 @@
}
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)
{
- enum tfm_platform_err_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_ns_lock_dispatch((veneer_fn)tfm_platform_sp_pin_service_veneer,
- (uint32_t)&in_vec, 1,
- (uint32_t)&out_vec, 1);
-
- return ret;
-}
-
-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)
-{
- enum tfm_platform_err_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;
+ if (output != NULL) {
+ outlen = 1;
+ } else {
+ outlen = 0;
}
- 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_ns_lock_dispatch((veneer_fn)tfm_platform_sp_pin_service_veneer,
- (uint32_t)&in_vec, 1,
- (uint32_t)&out_vec, 1);
-
- return ret;
-}
-
-enum tfm_platform_err_t
-tfm_platform_set_pin_mode(uint64_t pin_mask, uint32_t pin_mode,
- uint32_t *result)
-{
- enum tfm_platform_err_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_ns_lock_dispatch((veneer_fn)tfm_platform_sp_pin_service_veneer,
- (uint32_t)&in_vec, 1,
- (uint32_t)&out_vec, 1);
-
- return ret;
+ return (enum tfm_platform_err_t) tfm_ns_lock_dispatch(
+ (veneer_fn)tfm_platform_sp_ioctl_veneer,
+ (uint32_t)in_vec, (uint32_t)inlen,
+ (uint32_t)output, (uint32_t)outlen);
}
diff --git a/platform/ext/Mps2AN519.cmake b/platform/ext/Mps2AN519.cmake
index 53f5833..1268299 100644
--- a/platform/ext/Mps2AN519.cmake
+++ b/platform/ext/Mps2AN519.cmake
@@ -121,7 +121,7 @@
list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an519/attest_hal.c")
list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an519/native_drivers/mpu_armv8m_drv.c")
if (TFM_PARTITION_PLATFORM)
- list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an519/tfm_platform_system.c")
+ list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an519/services/src/tfm_platform_system.c")
endif()
embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
endif()
diff --git a/platform/ext/Mps2AN521.cmake b/platform/ext/Mps2AN521.cmake
index f15b976..339ebf0 100644
--- a/platform/ext/Mps2AN521.cmake
+++ b/platform/ext/Mps2AN521.cmake
@@ -122,7 +122,7 @@
list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an521/attest_hal.c")
list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an521/native_drivers/mpu_armv8m_drv.c")
if (TFM_PARTITION_PLATFORM)
- list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an521/tfm_platform_system.c")
+ list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an521/services/src/tfm_platform_system.c")
endif()
embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
endif()
diff --git a/platform/ext/musca_a.cmake b/platform/ext/musca_a.cmake
index 913061d..950e96b 100644
--- a/platform/ext/musca_a.cmake
+++ b/platform/ext/musca_a.cmake
@@ -122,7 +122,7 @@
list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_a/attest_hal.c")
list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_a/Native_Driver/mpu_armv8m_drv.c")
if (TFM_PARTITION_PLATFORM)
- list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_a/tfm_platform_system.c")
+ list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_a/services/src/tfm_platform_system.c")
endif()
embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
endif()
diff --git a/platform/ext/musca_b1.cmake b/platform/ext/musca_b1.cmake
index 5fbd488..894d731 100644
--- a/platform/ext/musca_b1.cmake
+++ b/platform/ext/musca_b1.cmake
@@ -51,8 +51,13 @@
embedded_include_directories(PATH "${PLATFORM_DIR}/target/musca_b1/Device/Include" ABSOLUTE)
embedded_include_directories(PATH "${PLATFORM_DIR}/target/musca_b1/Native_Driver" ABSOLUTE)
embedded_include_directories(PATH "${PLATFORM_DIR}/target/musca_b1/partition" ABSOLUTE)
+embedded_include_directories(PATH "${PLATFORM_DIR}/target/musca_b1/services/include" ABSOLUTE)
# Gather all source files we need.
+if (TFM_PARTITION_PLATFORM)
+ list(APPEND ALL_SRC_C_NS "${PLATFORM_DIR}/target/musca_b1/services/src/tfm_ioctl_ns_api.c")
+endif()
+
if (NOT DEFINED BUILD_CMSIS_CORE)
message(FATAL_ERROR "Configuration variable BUILD_CMSIS_CORE (true|false) is undefined!")
elseif (BUILD_CMSIS_CORE)
@@ -122,7 +127,8 @@
list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_b1/attest_hal.c")
list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_b1/Native_Driver/mpu_armv8m_drv.c")
if (TFM_PARTITION_PLATFORM)
- list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_b1/tfm_platform_system.c")
+ list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_b1/services/src/tfm_platform_system.c")
+ list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_b1/services/src/tfm_ioctl_s_api.c")
endif()
embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
endif()
diff --git a/platform/ext/target/mps2/an519/services/src/tfm_platform_system.c b/platform/ext/target/mps2/an519/services/src/tfm_platform_system.c
new file mode 100644
index 0000000..93ba614
--- /dev/null
+++ b/platform/ext/target/mps2/an519/services/src/tfm_platform_system.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "platform/include/tfm_platform_system.h"
+#include "cmsis.h"
+
+void tfm_platform_hal_system_reset(void)
+{
+ /* Reset the system */
+ NVIC_SystemReset();
+}
+
+enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request,
+ psa_invec *in_vec,
+ psa_outvec *out_vec)
+{
+ (void)request;
+ (void)in_vec;
+ (void)out_vec;
+
+ /* Not needed for this platform */
+ return TFM_PLATFORM_ERR_NOT_SUPPORTED;
+}
+
diff --git a/platform/ext/target/mps2/an519/tfm_platform_system.c b/platform/ext/target/mps2/an519/tfm_platform_system.c
deleted file mode 100644
index 26c2a73..0000000
--- a/platform/ext/target/mps2/an519/tfm_platform_system.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include "platform/include/tfm_platform_system.h"
-#include "cmsis.h"
-
-void tfm_platform_hal_system_reset(void)
-{
- /* Reset the system */
- NVIC_SystemReset();
-}
-
-enum tfm_plat_err_t
-tfm_platform_hal_pin_service(const psa_invec *in_vec, uint32_t num_invec,
- const psa_outvec *out_vec, uint32_t num_outvec)
-{
- (void)in_vec;
- (void)num_invec;
- (void)out_vec;
- (void)num_outvec;
- /* Not needed for this platform */
- return TFM_PLAT_ERR_SUCCESS;
-}
-
diff --git a/platform/ext/target/mps2/an521/services/src/tfm_platform_system.c b/platform/ext/target/mps2/an521/services/src/tfm_platform_system.c
new file mode 100644
index 0000000..93ba614
--- /dev/null
+++ b/platform/ext/target/mps2/an521/services/src/tfm_platform_system.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "platform/include/tfm_platform_system.h"
+#include "cmsis.h"
+
+void tfm_platform_hal_system_reset(void)
+{
+ /* Reset the system */
+ NVIC_SystemReset();
+}
+
+enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request,
+ psa_invec *in_vec,
+ psa_outvec *out_vec)
+{
+ (void)request;
+ (void)in_vec;
+ (void)out_vec;
+
+ /* Not needed for this platform */
+ return TFM_PLATFORM_ERR_NOT_SUPPORTED;
+}
+
diff --git a/platform/ext/target/mps2/an521/tfm_platform_system.c b/platform/ext/target/mps2/an521/tfm_platform_system.c
deleted file mode 100644
index 26c2a73..0000000
--- a/platform/ext/target/mps2/an521/tfm_platform_system.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include "platform/include/tfm_platform_system.h"
-#include "cmsis.h"
-
-void tfm_platform_hal_system_reset(void)
-{
- /* Reset the system */
- NVIC_SystemReset();
-}
-
-enum tfm_plat_err_t
-tfm_platform_hal_pin_service(const psa_invec *in_vec, uint32_t num_invec,
- const psa_outvec *out_vec, uint32_t num_outvec)
-{
- (void)in_vec;
- (void)num_invec;
- (void)out_vec;
- (void)num_outvec;
- /* Not needed for this platform */
- return TFM_PLAT_ERR_SUCCESS;
-}
-
diff --git a/platform/ext/target/musca_a/services/src/tfm_platform_system.c b/platform/ext/target/musca_a/services/src/tfm_platform_system.c
new file mode 100644
index 0000000..78d8f38
--- /dev/null
+++ b/platform/ext/target/musca_a/services/src/tfm_platform_system.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "platform/include/tfm_platform_system.h"
+#include "platform_description.h"
+
+void tfm_platform_hal_system_reset(void)
+{
+ /* Reset the system */
+ NVIC_SystemReset();
+}
+
+enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request,
+ psa_invec *in_vec,
+ psa_outvec *out_vec)
+{
+ (void)request;
+ (void)in_vec;
+ (void)out_vec;
+
+ /* Not needed for this platform */
+ return TFM_PLATFORM_ERR_NOT_SUPPORTED;
+}
+
diff --git a/platform/ext/target/musca_a/tfm_platform_system.c b/platform/ext/target/musca_a/tfm_platform_system.c
deleted file mode 100644
index cc21804..0000000
--- a/platform/ext/target/musca_a/tfm_platform_system.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include "platform/include/tfm_platform_system.h"
-#include "platform_description.h"
-
-void tfm_platform_hal_system_reset(void)
-{
- /* Reset the system */
- NVIC_SystemReset();
-}
-
-enum tfm_plat_err_t
-tfm_platform_hal_pin_service(const psa_invec *in_vec, uint32_t num_invec,
- const psa_outvec *out_vec, uint32_t num_outvec)
-{
- (void)in_vec;
- (void)num_invec;
- (void)out_vec;
- (void)num_outvec;
- /* SCC is configured as non-secure through PPC,
- * so this function is not needed on this platform
- */
- return TFM_PLAT_ERR_SUCCESS;
-}
-
diff --git a/platform/ext/target/musca_b1/readme.rst b/platform/ext/target/musca_b1/readme.rst
index 159af55..212c28f 100644
--- a/platform/ext/target/musca_b1/readme.rst
+++ b/platform/ext/target/musca_b1/readme.rst
@@ -10,6 +10,16 @@
`Arm Community page <https://community.arm.com/developer/tools-software/oss-platforms/w/docs/425/musca-b1-firmware-update-qspi-boot-recovery>`__
A short description of how to update the DAPLink FW can be found there as well.
+********************
+Platform pin service
+********************
+
+This service is designed to perform secure pin services of the platform
+(e.g alternate function setting, pin mode setting, etc).
+The service uses the IOCTL API of TF-M's Platform Service, which allows the
+non-secure application to make pin service requests on Musca B1 based on a
+generic service request delivery mechanism.
+
--------------
*Copyright (c) 2017-2019, Arm Limited. All rights reserved.*
diff --git a/platform/ext/target/musca_b1/services/include/tfm_ioctl_api.h b/platform/ext/target/musca_b1/services/include/tfm_ioctl_api.h
new file mode 100644
index 0000000..6109a7e
--- /dev/null
+++ b/platform/ext/target/musca_b1/services/include/tfm_ioctl_api.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_IOCTL_API__
+#define __TFM_IOCTL_API__
+
+#include <limits.h>
+#include <stdbool.h>
+#include "tfm_api.h"
+#include "tfm_platform_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum tfm_platform_ioctl_reqest_types_t {
+ TFM_PLATFORM_IOCTL_PIN_SERVICE,
+};
+
+/*!
+ * \enum tfm_pin_service_type_t
+ *
+ * \brief Pin service types
+ */
+enum tfm_pin_service_type_t {
+ TFM_PIN_SERVICE_TYPE_SET_ALTFUNC = 0, /*!< Set alternate function type */
+ TFM_PIN_SERVICE_TYPE_SET_DEFAULT_IN, /*!< Set default in function type */
+ TFM_PIN_SERVICE_TYPE_SET_PIN_MODE, /*!< Set pin mode function type */
+ TFM_PIN_SERVICE_TYPE_MAX = INT_MAX /*!< Max to force enum max size */
+};
+
+/*!
+ * \struct tfm_pin_service_args_t
+ *
+ * \brief Argument list for each platform pin service
+ */
+struct tfm_pin_service_args_t {
+ enum tfm_pin_service_type_t type;
+ union {
+ struct set_altfunc { /*!< TFM_PIN_SERVICE_TYPE_SET_ALTFUNC */
+ uint32_t alt_func;
+ uint64_t pin_mask;
+ } set_altfunc;
+ struct set_default_in { /*!< TFM_PIN_SERVICE_TYPE_SET_DEFAULT_IN */
+ uint32_t alt_func;
+ uint32_t pin_value;
+ bool default_in_value;
+ } set_default_in;
+ struct set_pin_mode { /*!< TFM_PIN_SERVICE_TYPE_SET_PIN_MODE */
+ uint64_t pin_mask;
+ uint32_t pin_mode;
+ } set_pin_mode;
+ } u;
+};
+
+/*!
+ * \brief Sets pin alternate function for the given pins
+ *
+ * \param[in] alt_func Alternate function to set (allowed values vary
+ * based on the platform)
+ * \param[in] pin_mask Pin mask of the selected pins
+ * \param[out] result Return error value
+ *
+ * \return Returns values as specified by the \ref tfm_platform_err_t
+ */
+enum tfm_platform_err_t
+tfm_platform_set_pin_alt_func(uint32_t alt_func, uint64_t pin_mask,
+ uint32_t *result);
+
+/*!
+ * \brief Sets default in value to use when the alternate function is not
+ * selected for the pin
+ *
+ * \param[in] alt_func Alternate function to use (allowed values vary
+ * based on the platform)
+ * \param[in] pin_value Pin value to use
+ * \param[in] default_in_value Default in value to set
+ * \param[out] result Return error value
+ *
+ * \return Returns values as specified by the \ref tfm_platform_err_t
+ */
+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);
+
+/*!
+ * \brief Sets pin mode for the selected pins
+ *
+ * \param[in] pin_mask Pin mask of the selected pins
+ * \param[in] pin_mode Pin mode to set for the selected pins
+ * \param[out] result Return error value
+ *
+ * \return Returns values as specified by the \ref tfm_platform_err_t
+ */
+enum tfm_platform_err_t
+tfm_platform_set_pin_mode(uint64_t pin_mask, uint32_t pin_mode,
+ uint32_t *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_IOCTL_API__ */
diff --git a/platform/ext/target/musca_b1/services/src/tfm_ioctl_ns_api.c b/platform/ext/target/musca_b1/services/src/tfm_ioctl_ns_api.c
new file mode 100644
index 0000000..6c83aeb
--- /dev/null
+++ b/platform/ext/target/musca_b1/services/src/tfm_ioctl_ns_api.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_platform_api.h"
+#include "services/include/tfm_ioctl_api.h"
+
+enum tfm_platform_err_t
+tfm_platform_set_pin_alt_func(uint32_t alt_func, uint64_t pin_mask,
+ uint32_t *result)
+{
+ enum tfm_platform_err_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_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_ioctl(TFM_PLATFORM_IOCTL_PIN_SERVICE,
+ &in_vec,
+ &out_vec);
+
+ return ret;
+}
+
+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)
+{
+ enum tfm_platform_err_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_ioctl(TFM_PLATFORM_IOCTL_PIN_SERVICE,
+ &in_vec,
+ &out_vec);
+
+ return ret;
+}
+
+enum tfm_platform_err_t
+tfm_platform_set_pin_mode(uint64_t pin_mask, uint32_t pin_mode,
+ uint32_t *result)
+{
+ enum tfm_platform_err_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_ioctl(TFM_PLATFORM_IOCTL_PIN_SERVICE,
+ &in_vec,
+ &out_vec);
+
+ return ret;
+}
+
diff --git a/platform/ext/target/musca_b1/services/src/tfm_ioctl_s_api.c b/platform/ext/target/musca_b1/services/src/tfm_ioctl_s_api.c
new file mode 100644
index 0000000..29efe86
--- /dev/null
+++ b/platform/ext/target/musca_b1/services/src/tfm_ioctl_s_api.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_platform_api.h"
+#include "services/include/tfm_ioctl_api.h"
+
+__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)
+{
+ 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_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_ioctl(TFM_PLATFORM_IOCTL_PIN_SERVICE, &in_vec, &out_vec);
+
+ 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_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_ioctl(TFM_PLATFORM_IOCTL_PIN_SERVICE, &in_vec, &out_vec);
+
+ 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_ioctl(TFM_PLATFORM_IOCTL_PIN_SERVICE, &in_vec, &out_vec);
+
+ if (ret != PSA_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ return TFM_PLATFORM_ERR_SUCCESS;
+}
+
diff --git a/platform/ext/target/musca_b1/services/src/tfm_platform_system.c b/platform/ext/target/musca_b1/services/src/tfm_platform_system.c
new file mode 100644
index 0000000..be11acd
--- /dev/null
+++ b/platform/ext/target/musca_b1/services/src/tfm_platform_system.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdbool.h>
+#include "platform/include/tfm_platform_system.h"
+#include "platform_description.h"
+#include "target_cfg.h"
+#include "device_definition.h"
+#include "psa_client.h"
+#include "tfm_secure_api.h"
+#include "services/include/tfm_ioctl_api.h"
+
+/*!
+ * \brief Verify access rights for memory addresses sent in io vectors
+ *
+ * \param[in] in_vec Pointer to in_vec array, which contains pointer
+ * to input arguments for the service
+ * \param[in] out_vec Pointer out_vec array, which contains pointer to
+ * output data of the pin service
+ *
+ * \return Returns true if memory is accessible by the service
+ */
+static bool memory_addr_check(const psa_invec *in_vec,
+ const psa_outvec *out_vec)
+{
+ if ((in_vec->base != NULL) &&
+ (tfm_core_memory_permission_check((void *)in_vec->base, in_vec->len,
+ TFM_MEMORY_ACCESS_RO) == TFM_SUCCESS) &&
+ (out_vec->base != NULL) &&
+ (tfm_core_memory_permission_check((void *)out_vec->base, out_vec->len,
+ TFM_MEMORY_ACCESS_RW) == TFM_SUCCESS)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void tfm_platform_hal_system_reset(void)
+{
+ __disable_irq();
+ mpc_revert_non_secure_to_secure_cfg();
+
+ NVIC->ICPR[0] = UINT32_MAX; /* Clear all pending interrupts */
+ NVIC->ICPR[1] = UINT32_MAX; /* Clear all pending interrupts */
+ NVIC->ICPR[2] = UINT32_MAX; /* Clear all pending interrupts */
+ NVIC->ICPR[3] = UINT32_MAX; /* Clear all pending interrupts */
+ NVIC->ICPR[4] = UINT32_MAX; /* Clear all pending interrupts */
+ NVIC->ICPR[5] = UINT32_MAX; /* Clear all pending interrupts */
+ NVIC->ICPR[6] = UINT32_MAX; /* Clear all pending interrupts */
+ NVIC->ICPR[7] = UINT32_MAX; /* Clear all pending interrupts */
+
+ NVIC_SystemReset();
+}
+
+static enum tfm_platform_err_t
+musca_b1_pin_service(const psa_invec *in_vec,
+ const psa_outvec *out_vec)
+{
+ struct tfm_pin_service_args_t *args;
+ uint32_t *result;
+ enum gpio_altfunc_t altfunc;
+ enum pinmode_select_t pin_mode;
+
+ if (memory_addr_check(in_vec, out_vec) == false) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+ if (in_vec->len != sizeof(struct tfm_pin_service_args_t) ||
+ out_vec->len != sizeof(uint32_t)) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ args = (struct tfm_pin_service_args_t *)in_vec->base;
+ result = (uint32_t *)out_vec->base;
+ switch (args->type) {
+ case TFM_PIN_SERVICE_TYPE_SET_ALTFUNC:
+ altfunc = (enum gpio_altfunc_t)args->u.set_altfunc.alt_func;
+ *result = musca_b1_scc_set_alt_func(&MUSCA_B1_SCC_DEV_S, altfunc,
+ args->u.set_altfunc.pin_mask);
+ break;
+ case TFM_PIN_SERVICE_TYPE_SET_DEFAULT_IN:
+ altfunc = (enum gpio_altfunc_t)args->u.set_altfunc.alt_func;
+ *result = musca_b1_scc_set_default_in(&MUSCA_B1_SCC_DEV_S, altfunc,
+ args->u.set_default_in.pin_value,
+ args->u.set_default_in.default_in_value);
+ break;
+ case TFM_PIN_SERVICE_TYPE_SET_PIN_MODE:
+ pin_mode = (enum pinmode_select_t)args->u.set_pin_mode.pin_mode;
+ *result = musca_b1_scc_set_pinmode(&MUSCA_B1_SCC_DEV_S,
+ args->u.set_pin_mode.pin_mask,
+ pin_mode);
+ break;
+ default:
+ *result = SCC_INVALID_ARG;
+ break;
+ }
+
+ return TFM_PLATFORM_ERR_SUCCESS;
+}
+
+enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request,
+ psa_invec *in_vec,
+ psa_outvec *out_vec)
+{
+ switch (request)
+ {
+ case TFM_PLATFORM_IOCTL_PIN_SERVICE:
+ return musca_b1_pin_service(in_vec, out_vec);
+ default:
+ return TFM_PLATFORM_ERR_NOT_SUPPORTED;
+ }
+}
+
diff --git a/platform/ext/target/musca_b1/tfm_platform_system.c b/platform/ext/target/musca_b1/tfm_platform_system.c
deleted file mode 100644
index 2fb9657..0000000
--- a/platform/ext/target/musca_b1/tfm_platform_system.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include <stdbool.h>
-#include "platform/include/tfm_platform_system.h"
-#include "platform_description.h"
-#include "target_cfg.h"
-#include "device_definition.h"
-#include "psa_client.h"
-#include "tfm_platform_defs.h"
-#include "tfm_secure_api.h"
-
-/*!
- * \brief Verify access rights for memory addresses sent in io vectors
- *
- * \param[in] in_vec Pointer to in_vec array, which contains pointer
- * to input arguments for the service
- * \param[in] out_vec Pointer out_vec array, which contains pointer to
- * output data of the pin service
- *
- * \return Returns true if memory is accessible by the service
- */
-static bool memory_addr_check(const psa_invec *in_vec,
- const psa_outvec *out_vec)
-{
- if ((in_vec->base != NULL) &&
- (tfm_core_memory_permission_check((void *)in_vec->base, in_vec->len,
- TFM_MEMORY_ACCESS_RO) == TFM_SUCCESS) &&
- (out_vec->base != NULL) &&
- (tfm_core_memory_permission_check((void *)out_vec->base, out_vec->len,
- TFM_MEMORY_ACCESS_RW) == TFM_SUCCESS)) {
- return true;
- } else {
- return false;
- }
-}
-
-void tfm_platform_hal_system_reset(void)
-{
- __disable_irq();
- mpc_revert_non_secure_to_secure_cfg();
-
- NVIC->ICPR[0] = UINT32_MAX; /* Clear all pending interrupts */
- NVIC->ICPR[1] = UINT32_MAX; /* Clear all pending interrupts */
- NVIC->ICPR[2] = UINT32_MAX; /* Clear all pending interrupts */
- NVIC->ICPR[3] = UINT32_MAX; /* Clear all pending interrupts */
- NVIC->ICPR[4] = UINT32_MAX; /* Clear all pending interrupts */
- NVIC->ICPR[5] = UINT32_MAX; /* Clear all pending interrupts */
- NVIC->ICPR[6] = UINT32_MAX; /* Clear all pending interrupts */
- NVIC->ICPR[7] = UINT32_MAX; /* Clear all pending interrupts */
-
- NVIC_SystemReset();
-}
-
-enum tfm_plat_err_t
-tfm_platform_hal_pin_service(const psa_invec *in_vec, uint32_t num_invec,
- const psa_outvec *out_vec, uint32_t num_outvec)
-{
- struct tfm_pin_service_args_t *args;
- uint32_t *result;
- enum gpio_altfunc_t altfunc;
- enum pinmode_select_t pin_mode;
-
- while (num_invec && num_outvec) {
- if (memory_addr_check(in_vec, out_vec) == false) {
- return TFM_PLAT_ERR_SYSTEM_ERR;
- }
- if (in_vec->len != sizeof(struct tfm_pin_service_args_t) ||
- out_vec->len != sizeof(uint32_t)) {
- return TFM_PLAT_ERR_SYSTEM_ERR;
- }
-
- args = (struct tfm_pin_service_args_t *)in_vec->base;
- result = (uint32_t *)out_vec->base;
- switch (args->type) {
- case TFM_PIN_SERVICE_TYPE_SET_ALTFUNC:
- altfunc = (enum gpio_altfunc_t)args->u.set_altfunc.alt_func;
- *result = musca_b1_scc_set_alt_func(&MUSCA_B1_SCC_DEV_S, altfunc,
- args->u.set_altfunc.pin_mask);
- break;
- case TFM_PIN_SERVICE_TYPE_SET_DEFAULT_IN:
- altfunc = (enum gpio_altfunc_t)args->u.set_altfunc.alt_func;
- *result = musca_b1_scc_set_default_in(&MUSCA_B1_SCC_DEV_S, altfunc,
- args->u.set_default_in.pin_value,
- args->u.set_default_in.default_in_value);
- break;
- case TFM_PIN_SERVICE_TYPE_SET_PIN_MODE:
- pin_mode = (enum pinmode_select_t)args->u.set_pin_mode.pin_mode;
- *result = musca_b1_scc_set_pinmode(&MUSCA_B1_SCC_DEV_S,
- args->u.set_pin_mode.pin_mask,
- pin_mode);
- break;
- default:
- *result = SCC_INVALID_ARG;
- break;
- }
-
- num_invec--;
- num_outvec--;
- in_vec++;
- out_vec++;
- }
-
- return TFM_PLAT_ERR_SUCCESS;
-}
-
diff --git a/platform/include/tfm_platform_system.h b/platform/include/tfm_platform_system.h
index 411be49..8ad22b1 100644
--- a/platform/include/tfm_platform_system.h
+++ b/platform/include/tfm_platform_system.h
@@ -12,9 +12,9 @@
* target.
*/
-#include "tfm_plat_defs.h"
#include "psa_client.h"
#include "tfm_plat_defs.h"
+#include "tfm_platform_api.h"
#ifdef __cplusplus
extern "C" {
@@ -29,21 +29,19 @@
void tfm_platform_hal_system_reset(void);
/*!
- * \brief Performs pin services of the platform
+ * \brief Performs a platform-specific service
*
- * \param[in] in_vec Pointer to in_vec array, which contains input
- * arguments for the pin service
- * \param[in] num_invec Number of elements in in_vec array
- * \param[in,out] out_vec Pointer out_vec array, which contains output data
- * of the pin service
- * \param[in] num_outvec Number of elements in out_vec array
+ * \param[in] request Request identifier (valid values vary
+ * based on the platform)
+ * \param[in] in_vec Input buffer to the requested service (or NULL)
+ * \param[out] out_vec Output buffer to the requested service (or NULL)
*
- * \return Returns values as specified by the \ref tfm_plat_err_t
+ * \return Returns values as specified by the \ref tfm_platform_err_t
*/
TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION("TFM_SP_PLATFORM")
-enum tfm_plat_err_t
-tfm_platform_hal_pin_service(const psa_invec *in_vec, uint32_t num_invec,
- const psa_outvec *out_vec, uint32_t num_outvec);
+enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request,
+ psa_invec *in_vec,
+ psa_outvec *out_vec);
#ifdef __cplusplus
}
diff --git a/platform/readme.rst b/platform/readme.rst
index 20e5fbc..0dac5e9 100644
--- a/platform/readme.rst
+++ b/platform/readme.rst
@@ -7,9 +7,9 @@
This folder and subfolders, especially the target folder, are likely to be
refactored and updated to improve the overall structure of dependencies.
-**************************
-Interfacing with TF-M core
-**************************
+*********************
+Interfacing with TF-M
+*********************
platformext/target/tfm_peripherals_def.h
========================================
@@ -35,13 +35,19 @@
platform/include/tfm_spm_hal.h
==============================
This file contains the declarations of functions that a platform implementation
-has to provide for TF-M. For details see the comments in the file.
+has to provide for TF-M's SPM. For details see the comments in the file.
secure_fw/core/tfm_platform_core_api.h
======================================
This file contains declarations of functions that can be or have to be called
from platform implementations. For details see the comments in the file.
+platform/include/tfm_platform_system.h
+======================================
+This file contains the declarations of functions that a platform implementation
+has to provide for TF-M's Platform Service. For details see
+``docs/user_guides/services/tfm_platform_integration_guide.rst``
+
***********
Sub-folders
***********
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;
}