From eeae3d73dd5bed868207d1022edbc3326968a2c0 Mon Sep 17 00:00:00 2001 From: Lingkai Dong Date: Mon, 8 Mar 2021 17:22:39 +0000 Subject: [PATCH] Import OS wrapper from the vanilla TF-M Previous, we patched TF-M to replace its OS wrapper with CMSIS RTOS to resolve manage management issue when integrated with Mbed OS. But as of TF-M v1.2, the OS wrapper has been reworked in the vanilla TF-M, and now it makes identical calls to its underlying CMSIS RTOS as our patches do. So, we remove our patches and use vanilla TF-M's OS wrapper instead to avoid extra maintenance overhead. This commit re-imports TF-M files associated with the OS wrapper. --- .../TARGET_TFM_LATEST/CMakeLists.txt | 1 + .../TARGET_TFM_V8M/src/tfm_ns_interface.c | 30 +-- .../include/os_wrapper/common.h | 26 +++ .../include/os_wrapper/mutex.h | 62 +++++ .../include/os_wrapper/semaphore.h | 64 ++++++ .../include/os_wrapper/thread.h | 103 +++++++++ .../include/os_wrapper/tick.h | 28 +++ .../src/os_wrapper_cmsis_rtos_v2.c | 217 ++++++++++++++++++ 8 files changed, 511 insertions(+), 20 deletions(-) create mode 100644 platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/common.h create mode 100644 platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/mutex.h create mode 100644 platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/semaphore.h create mode 100644 platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/thread.h create mode 100644 platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/tick.h create mode 100644 platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/os_wrapper_cmsis_rtos_v2.c diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt index 2fdfea56b7..121c8e211f 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt @@ -32,6 +32,7 @@ target_include_directories(mbed-psa target_sources(mbed-psa INTERFACE + src/os_wrapper_cmsis_rtos_v2.c src/tfm_crypto_ipc_api.c src/tfm_initial_attestation_ipc_api.c src/tfm_its_ipc_api.c diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/TARGET_TFM_V8M/src/tfm_ns_interface.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/TARGET_TFM_V8M/src/tfm_ns_interface.c index 9759145590..7b016950cd 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/TARGET_TFM_V8M/src/tfm_ns_interface.c +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/TARGET_TFM_V8M/src/tfm_ns_interface.c @@ -7,14 +7,15 @@ #include #include +#include "os_wrapper/mutex.h" + #include "tfm_api.h" #include "tfm_ns_interface.h" -#include "cmsis_os2.h" /** * \brief the ns_lock ID */ -static osMutexId_t ns_lock_handle = NULL; +static void *ns_lock_handle = NULL; __attribute__((weak)) int32_t tfm_ns_interface_dispatch(veneer_fn fn, @@ -22,18 +23,16 @@ int32_t tfm_ns_interface_dispatch(veneer_fn fn, uint32_t arg2, uint32_t arg3) { int32_t result; - osStatus_t status; /* TFM request protected by NS lock */ - status = osMutexAcquire(ns_lock_handle, osWaitForever); - if (status != osOK) { + if (os_wrapper_mutex_acquire(ns_lock_handle, OS_WRAPPER_WAIT_FOREVER) + != OS_WRAPPER_SUCCESS) { return (int32_t)TFM_ERROR_GENERIC; } result = fn(arg0, arg1, arg2, arg3); - status = osMutexRelease(ns_lock_handle); - if (status != osOK) { + if (os_wrapper_mutex_release(ns_lock_handle) != OS_WRAPPER_SUCCESS) { return (int32_t)TFM_ERROR_GENERIC; } @@ -43,22 +42,13 @@ int32_t tfm_ns_interface_dispatch(veneer_fn fn, __attribute__((weak)) enum tfm_status_e tfm_ns_interface_init(void) { - const osMutexAttr_t attr = { - .name = NULL, - .attr_bits = osMutexPrioInherit, /* Priority inheritance is recommended - * to enable if it is supported. - * For recursive mutex and the ability - * of auto release when owner being - * terminated is not required. - */ - .cb_mem = NULL, - .cb_size = 0U - }; + void *handle; - ns_lock_handle = osMutexNew(&attr); - if (!ns_lock_handle) { + handle = os_wrapper_mutex_create(); + if (!handle) { return TFM_ERROR_GENERIC; } + ns_lock_handle = handle; return TFM_SUCCESS; } diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/common.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/common.h new file mode 100644 index 0000000000..6494723030 --- /dev/null +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/common.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017-2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __OS_WRAPPER_COMMON_H__ +#define __OS_WRAPPER_COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define OS_WRAPPER_SUCCESS (0x0) +#define OS_WRAPPER_ERROR (0xFFFFFFFFU) +#define OS_WRAPPER_WAIT_FOREVER (0xFFFFFFFFU) +#define OS_WRAPPER_DEFAULT_STACK_SIZE (-1) + +#ifdef __cplusplus +} +#endif + +#endif /* __OS_WRAPPER_COMMON_H__ */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/mutex.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/mutex.h new file mode 100644 index 0000000000..e55ef706e2 --- /dev/null +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/mutex.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017-2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __OS_WRAPPER_MUTEX_H__ +#define __OS_WRAPPER_MUTEX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "common.h" + +/** + * \brief Creates a mutex for mutual exclusion of resources + * + * \return The handle of the created mutex on success or NULL on error + */ +void *os_wrapper_mutex_create(void); + +/** + * \brief Acquires a mutex that is created by \ref os_wrapper_mutex_create() + * + * \param[in] handle The handle of the mutex to acquire. Should be one of the + * handles returned by \ref os_wrapper_mutex_create() + * \param[in] timeout The maximum amount of time(in tick periods) for the + * thread to wait for the mutex to be available. + * If timeout is zero, the function will return immediately. + * Setting timeout to \ref OS_WRAPPER_WAIT_FOREVER will + * cause the thread to wait indefinitely + * + * \return \ref OS_WRAPPER_SUCCESS on success or \ref OS_WRAPPER_ERROR on error + */ +uint32_t os_wrapper_mutex_acquire(void *handle, uint32_t timeout); + +/** + * \brief Releases the mutex acquired previously + * + + * \param[in] handle The handle of the mutex that has been acquired + * + * \return \ref OS_WRAPPER_SUCCESS on success or \ref OS_WRAPPER_ERROR on error + */ +uint32_t os_wrapper_mutex_release(void *handle); + +/** + * \brief Deletes a mutex that is created by \ref os_wrapper_mutex_create() + * + * \param[in] handle The handle of the mutex to be deleted + * + * \return \ref OS_WRAPPER_SUCCESS on success or \ref OS_WRAPPER_ERROR on error + */ +uint32_t os_wrapper_mutex_delete(void *handle); + +#ifdef __cplusplus +} +#endif + +#endif /* __OS_WRAPPER_MUTEX_H__ */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/semaphore.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/semaphore.h new file mode 100644 index 0000000000..83d88cac65 --- /dev/null +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/semaphore.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __OS_WRAPPER_SEMAPHORE_H__ +#define __OS_WRAPPER_SEMAPHORE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "common.h" + +/** + * \brief Creates a new semaphore + * + * \param[in] max_count Highest count of the semaphore + * \param[in] initial_count Starting count of the available semaphore + * \param[in] name Name of the semaphore + * + * \return Returns handle of the semaphore created, or NULL in case of error + */ +void *os_wrapper_semaphore_create(uint32_t max_count, uint32_t initial_count, + const char *name); + +/** + * \brief Acquires the semaphore + * + * \param[in] hanlde Semaphore handle + * \param[in] timeout Timeout value + * + * \return \ref OS_WRAPPER_SUCCESS in case of successful acquision, or + * \ref OS_WRAPPER_ERROR in case of error + */ +uint32_t os_wrapper_semaphore_acquire(void *handle, uint32_t timeout); + +/** + * \brief Releases the semaphore + * + * \param[in] hanlde Semaphore handle + * + * \return \ref OS_WRAPPER_SUCCESS in case of successful release, or + * \ref OS_WRAPPER_ERROR in case of error + */ +uint32_t os_wrapper_semaphore_release(void *handle); + +/** + * \brief Deletes the semaphore + * + * \param[in] handle Semaphore handle + * + * \return \ref OS_WRAPPER_SUCCESS in case of successful release, or + * \ref OS_WRAPPER_ERROR in case of error + */ +uint32_t os_wrapper_semaphore_delete(void *handle); + +#ifdef __cplusplus +} +#endif + +#endif /* __OS_WRAPPER_SEMAPHORE_H__ */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/thread.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/thread.h new file mode 100644 index 0000000000..a493593a61 --- /dev/null +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/thread.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2017-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __OS_WRAPPER_THREAD_H__ +#define __OS_WRAPPER_THREAD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "common.h" + +/* prototype for the thread entry function */ +typedef void (*os_wrapper_thread_func) (void *argument); + +/** + * \brief Creates a new thread + * + * \param[in] name Name of the thread + * \param[in] stack_size Size of stack to be allocated for this thread. It can + * be \ref OS_WRAPPER_DEFAULT_STACK_SIZE to use the + * default value provided by the underlying RTOS + * \param[in] func Pointer to the function invoked by thread + * \param[in] arg Argument to pass to the function invoked by thread + * \param[in] priority Initial thread priority + * + * \return Returns the thread handle created, or NULL in case of error + */ +void *os_wrapper_thread_new(const char *name, int32_t stack_size, + os_wrapper_thread_func func, void *arg, + uint32_t priority); +/** + * \brief Gets current thread handle + * + * \return Returns the thread handle, or NULL in case of error + */ +void *os_wrapper_thread_get_handle(void); + +/** + * \brief Gets thread priority + * + * \param[in] handle Thread handle + * \param[out] priority The priority of the thread + * + * \return Returns \ref OS_WRAPPER_SUCCESS on success, or \ref OS_WRAPPER_ERROR + * in case of error + */ +uint32_t os_wrapper_thread_get_priority(void *handle, uint32_t *priority); + +/** + * \brief Exits the calling thread + */ +void os_wrapper_thread_exit(void); + +/** + * \brief Set the event flags for synchronizing a thread specified by handle. + * + * \note This function may not be allowed to be called from Interrupt Service + * Routines. + * + * \param[in] handle Thread handle to be notified + * \param[in] flags Event flags value + * + * \return Returns \ref OS_WRAPPER_SUCCESS on success, or \ref OS_WRAPPER_ERROR + * in case of error + */ +uint32_t os_wrapper_thread_set_flag(void *handle, uint32_t flags); + +/** + * \brief Set the event flags in an interrupt handler for synchronizing a thread + * specified by handle. + * + * \param[in] handle Thread handle to be notified + * \param[in] flags Event flags value + * + * \return Returns \ref OS_WRAPPER_SUCCESS on success, or \ref OS_WRAPPER_ERROR + * in case of error + */ +uint32_t os_wrapper_thread_set_flag_isr(void *handle, uint32_t flags); + +/** + * \brief Wait for the event flags for synchronizing threads. + * + * \note This function may not be allowed to be called from Interrupt Service + * Routines. + * + * \param[in] flags Specify the flags to wait for + * \param[in] timeout Timeout value + * + * \return Returns \ref OS_WRAPPER_SUCCESS on success, or \ref OS_WRAPPER_ERROR + * in case of error + */ +uint32_t os_wrapper_thread_wait_flag(uint32_t flags, uint32_t timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* __OS_WRAPPER_THREAD_H__ */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/tick.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/tick.h new file mode 100644 index 0000000000..b377b0e5fb --- /dev/null +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/include/os_wrapper/tick.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __OS_WRAPPER_TICK_H__ +#define __OS_WRAPPER_TICK_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "common.h" + +/** + * \brief Return RTOS current tick count + * + * \return The current tick count + */ +uint32_t os_wrapper_get_tick(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __OS_WRAPPER_TICK_H__ */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/os_wrapper_cmsis_rtos_v2.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/os_wrapper_cmsis_rtos_v2.c new file mode 100644 index 0000000000..9892290c73 --- /dev/null +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/os_wrapper_cmsis_rtos_v2.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2017-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "os_wrapper/thread.h" +#include "os_wrapper/mutex.h" +#include "os_wrapper/semaphore.h" + +#include +#include "cmsis_os2.h" + +/* This is an example OS abstraction layer for CMSIS-RTOSv2 */ + +void *os_wrapper_thread_new(const char *name, int32_t stack_size, + os_wrapper_thread_func func, void *arg, + uint32_t priority) +{ + osThreadAttr_t task_attribs = {.tz_module = 1}; + + /* By default, the thread starts as osThreadDetached */ + if (stack_size != OS_WRAPPER_DEFAULT_STACK_SIZE) { + task_attribs.stack_size = stack_size; + } + task_attribs.name = name; + task_attribs.priority = (osPriority_t) priority; + + return (void *)osThreadNew(func, arg, &task_attribs); +} + +void *os_wrapper_semaphore_create(uint32_t max_count, uint32_t initial_count, + const char *name) +{ + osSemaphoreAttr_t sema_attrib = {0}; + + sema_attrib.name = name; + + return (void *)osSemaphoreNew(max_count, initial_count, &sema_attrib); +} + +uint32_t os_wrapper_semaphore_acquire(void *handle, uint32_t timeout) +{ + osStatus_t status; + + status = osSemaphoreAcquire((osSemaphoreId_t)handle, + (timeout == OS_WRAPPER_WAIT_FOREVER) ? + osWaitForever : timeout); + if (status != osOK) { + return OS_WRAPPER_ERROR; + } + + return OS_WRAPPER_SUCCESS; +} + +uint32_t os_wrapper_semaphore_release(void *handle) +{ + osStatus_t status; + + status = osSemaphoreRelease((osSemaphoreId_t)handle); + if (status != osOK) { + return OS_WRAPPER_ERROR; + } + + return OS_WRAPPER_SUCCESS; +} + +uint32_t os_wrapper_semaphore_delete(void *handle) +{ + osStatus_t status; + + status = osSemaphoreDelete((osSemaphoreId_t)handle); + if (status != osOK) { + return OS_WRAPPER_ERROR; + } + + return OS_WRAPPER_SUCCESS; +} + +void *os_wrapper_mutex_create(void) +{ + const osMutexAttr_t attr = { + .name = NULL, + .attr_bits = osMutexPrioInherit, /* Priority inheritance is recommended + * to enable if it is supported. + * For recursive mutex and the ability + * of auto release when owner being + * terminated is not required. + */ + .cb_mem = NULL, + .cb_size = 0U + }; + + return (void *)osMutexNew(&attr); +} + +uint32_t os_wrapper_mutex_acquire(void *handle, uint32_t timeout) +{ + osStatus_t status = osOK; + + if (!handle) { + return OS_WRAPPER_ERROR; + } + + status = osMutexAcquire((osMutexId_t)handle, + (timeout == OS_WRAPPER_WAIT_FOREVER) ? + osWaitForever : timeout); + if (status != osOK) { + return OS_WRAPPER_ERROR; + } + + return OS_WRAPPER_SUCCESS; +} + +uint32_t os_wrapper_mutex_release(void *handle) +{ + osStatus_t status = osOK; + + if (!handle) { + return OS_WRAPPER_ERROR; + } + + status = osMutexRelease((osMutexId_t)handle); + if (status != osOK) { + return OS_WRAPPER_ERROR; + } + + return OS_WRAPPER_SUCCESS; +} + +uint32_t os_wrapper_mutex_delete(void *handle) +{ + osStatus_t status = osOK; + + if (!handle) { + return OS_WRAPPER_ERROR; + } + + status = osMutexDelete((osMutexId_t)handle); + if (status != osOK) { + return OS_WRAPPER_ERROR; + } + + return OS_WRAPPER_SUCCESS; +} + +void *os_wrapper_thread_get_handle(void) +{ + return (void *)osThreadGetId(); +} + +uint32_t os_wrapper_thread_get_priority(void *handle, uint32_t *priority) +{ + osPriority_t prio; + + prio = osThreadGetPriority((osThreadId_t)handle); + if (prio == osPriorityError) { + return OS_WRAPPER_ERROR; + } + + *priority = (uint32_t)prio; + + return OS_WRAPPER_SUCCESS; +} + +void os_wrapper_thread_exit(void) +{ + osThreadExit(); +} + +uint32_t os_wrapper_thread_set_flag(void *handle, uint32_t flags) +{ + uint32_t ret; + + ret = osThreadFlagsSet((osThreadId_t)handle, flags); + if (ret & osFlagsError) { + return OS_WRAPPER_ERROR; + } + + return OS_WRAPPER_SUCCESS; +} + +/* + * According to the description of CMSIS-RTOS v2 Thread Flags, + * osThreadFlagsSet() can be called inside Interrupt Service Routine. + */ +uint32_t os_wrapper_thread_set_flag_isr(void *handle, uint32_t flags) +{ + uint32_t ret; + + ret = osThreadFlagsSet((osThreadId_t)handle, flags); + if (ret & osFlagsError) { + return OS_WRAPPER_ERROR; + } + + return OS_WRAPPER_SUCCESS; +} + +uint32_t os_wrapper_thread_wait_flag(uint32_t flags, uint32_t timeout) +{ + uint32_t ret; + + ret = osThreadFlagsWait(flags, osFlagsWaitAll, + (timeout == OS_WRAPPER_WAIT_FOREVER) ? + osWaitForever : timeout); + if (ret & osFlagsError) { + return OS_WRAPPER_ERROR; + } + + return OS_WRAPPER_SUCCESS; +} + +uint32_t os_wrapper_get_tick(void) +{ + return osKernelGetTickCount(); +}