12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- /*
- * Copyright (c) 2019,2020 Linaro Limited
- * Copyright (c) 2021 Nordic Semiconductor ASA
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <device.h>
- #include <init.h>
- #include <kernel.h>
- #include <arch/arm/aarch32/cortex_m/cmsis.h>
- #include <arch/arm/aarch32/cortex_m/fpu.h>
- #include <tfm_ns_interface.h>
- /**
- * @file @brief Zephyr's TF-M NS interface implementation
- *
- */
- /* Global mutex to be used by the TF-M NS dispatcher, preventing
- * the Non-Secure application from initiating multiple parallel
- * TF-M secure calls.
- */
- K_MUTEX_DEFINE(tfm_mutex);
- int32_t tfm_ns_interface_dispatch(veneer_fn fn,
- uint32_t arg0, uint32_t arg1,
- uint32_t arg2, uint32_t arg3)
- {
- int32_t result;
- /* TF-M request protected by NS lock */
- if (k_mutex_lock(&tfm_mutex, K_FOREVER) != 0) {
- return (int32_t)TFM_ERROR_GENERIC;
- }
- #if !defined(CONFIG_ARM_NONSECURE_PREEMPTIBLE_SECURE_CALLS)
- /*
- * Prevent the thread from being preempted, while executing a Secure
- * function. This is required to prevent system crashes that could
- * occur, if a thead context switch is triggered in the middle of a
- * Secure call.
- */
- k_sched_lock();
- #endif
- #if defined(CONFIG_ARM_NONSECURE_PREEMPTIBLE_SECURE_CALLS)
- struct fpu_ctx_full context_buffer;
- z_arm_save_fp_context(&context_buffer);
- #endif
- result = fn(arg0, arg1, arg2, arg3);
- #if defined(CONFIG_ARM_NONSECURE_PREEMPTIBLE_SECURE_CALLS)
- z_arm_restore_fp_context(&context_buffer);
- #endif
- #if !defined(CONFIG_ARM_NONSECURE_PREEMPTIBLE_SECURE_CALLS)
- /* Unlock the scheduler, to allow the thread to be preempted. */
- k_sched_unlock();
- #endif
- k_mutex_unlock(&tfm_mutex);
- return result;
- }
- enum tfm_status_e tfm_ns_interface_init(void)
- {
- /*
- * The static K_MUTEX_DEFINE handles mutex initialization,
- * so this function may be implemented as no-op.
- */
- return TFM_SUCCESS;
- }
- #if defined(TFM_PSA_API)
- #include "psa_manifest/sid.h"
- #endif /* TFM_PSA_API */
- static int ns_interface_init(const struct device *arg)
- {
- ARG_UNUSED(arg);
- __ASSERT(tfm_ns_interface_init() == TFM_SUCCESS,
- "TF-M NS interface init failed");
- return 0;
- }
- /* Initialize the TFM NS interface */
- SYS_INIT(ns_interface_init, POST_KERNEL,
- CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|