interface.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright (c) 2019,2020 Linaro Limited
  3. * Copyright (c) 2021 Nordic Semiconductor ASA
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. */
  7. #include <device.h>
  8. #include <init.h>
  9. #include <kernel.h>
  10. #include <arch/arm/aarch32/cortex_m/cmsis.h>
  11. #include <arch/arm/aarch32/cortex_m/fpu.h>
  12. #include <tfm_ns_interface.h>
  13. /**
  14. * @file @brief Zephyr's TF-M NS interface implementation
  15. *
  16. */
  17. /* Global mutex to be used by the TF-M NS dispatcher, preventing
  18. * the Non-Secure application from initiating multiple parallel
  19. * TF-M secure calls.
  20. */
  21. K_MUTEX_DEFINE(tfm_mutex);
  22. int32_t tfm_ns_interface_dispatch(veneer_fn fn,
  23. uint32_t arg0, uint32_t arg1,
  24. uint32_t arg2, uint32_t arg3)
  25. {
  26. int32_t result;
  27. /* TF-M request protected by NS lock */
  28. if (k_mutex_lock(&tfm_mutex, K_FOREVER) != 0) {
  29. return (int32_t)TFM_ERROR_GENERIC;
  30. }
  31. #if !defined(CONFIG_ARM_NONSECURE_PREEMPTIBLE_SECURE_CALLS)
  32. /*
  33. * Prevent the thread from being preempted, while executing a Secure
  34. * function. This is required to prevent system crashes that could
  35. * occur, if a thead context switch is triggered in the middle of a
  36. * Secure call.
  37. */
  38. k_sched_lock();
  39. #endif
  40. #if defined(CONFIG_ARM_NONSECURE_PREEMPTIBLE_SECURE_CALLS)
  41. struct fpu_ctx_full context_buffer;
  42. z_arm_save_fp_context(&context_buffer);
  43. #endif
  44. result = fn(arg0, arg1, arg2, arg3);
  45. #if defined(CONFIG_ARM_NONSECURE_PREEMPTIBLE_SECURE_CALLS)
  46. z_arm_restore_fp_context(&context_buffer);
  47. #endif
  48. #if !defined(CONFIG_ARM_NONSECURE_PREEMPTIBLE_SECURE_CALLS)
  49. /* Unlock the scheduler, to allow the thread to be preempted. */
  50. k_sched_unlock();
  51. #endif
  52. k_mutex_unlock(&tfm_mutex);
  53. return result;
  54. }
  55. enum tfm_status_e tfm_ns_interface_init(void)
  56. {
  57. /*
  58. * The static K_MUTEX_DEFINE handles mutex initialization,
  59. * so this function may be implemented as no-op.
  60. */
  61. return TFM_SUCCESS;
  62. }
  63. #if defined(TFM_PSA_API)
  64. #include "psa_manifest/sid.h"
  65. #endif /* TFM_PSA_API */
  66. static int ns_interface_init(const struct device *arg)
  67. {
  68. ARG_UNUSED(arg);
  69. __ASSERT(tfm_ns_interface_init() == TFM_SUCCESS,
  70. "TF-M NS interface init failed");
  71. return 0;
  72. }
  73. /* Initialize the TFM NS interface */
  74. SYS_INIT(ns_interface_init, POST_KERNEL,
  75. CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);