Subversion Repositories dashGPS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  * @file     tz_context.c
  3.  * @brief    Context Management for Armv8-M TrustZone - Sample implementation
  4.  * @version  V1.1.1
  5.  * @date     10. January 2018
  6.  ******************************************************************************/
  7. /*
  8.  * Copyright (c) 2016-2018 Arm Limited. All rights reserved.
  9.  *
  10.  * SPDX-License-Identifier: Apache-2.0
  11.  *
  12.  * Licensed under the Apache License, Version 2.0 (the License); you may
  13.  * not use this file except in compliance with the License.
  14.  * You may obtain a copy of the License at
  15.  *
  16.  * www.apache.org/licenses/LICENSE-2.0
  17.  *
  18.  * Unless required by applicable law or agreed to in writing, software
  19.  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  20.  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21.  * See the License for the specific language governing permissions and
  22.  * limitations under the License.
  23.  */
  24.  
  25. #include "RTE_Components.h"
  26. #include CMSIS_device_header
  27. #include "tz_context.h"
  28.  
  29. /// Number of process slots (threads may call secure library code)
  30. #ifndef TZ_PROCESS_STACK_SLOTS
  31. #define TZ_PROCESS_STACK_SLOTS     8U
  32. #endif
  33.  
  34. /// Stack size of the secure library code
  35. #ifndef TZ_PROCESS_STACK_SIZE
  36. #define TZ_PROCESS_STACK_SIZE      256U
  37. #endif
  38.  
  39. typedef struct {
  40.   uint32_t sp_top;      // stack space top
  41.   uint32_t sp_limit;    // stack space limit
  42.   uint32_t sp;          // current stack pointer
  43. } stack_info_t;
  44.  
  45. static stack_info_t ProcessStackInfo  [TZ_PROCESS_STACK_SLOTS];
  46. static uint64_t     ProcessStackMemory[TZ_PROCESS_STACK_SLOTS][TZ_PROCESS_STACK_SIZE/8U];
  47. static uint32_t     ProcessStackFreeSlot = 0xFFFFFFFFU;
  48.  
  49.  
  50. /// Initialize secure context memory system
  51. /// \return execution status (1: success, 0: error)
  52. __attribute__((cmse_nonsecure_entry))
  53. uint32_t TZ_InitContextSystem_S (void) {
  54.   uint32_t n;
  55.  
  56.   if (__get_IPSR() == 0U) {
  57.     return 0U;  // Thread Mode
  58.   }
  59.  
  60.   for (n = 0U; n < TZ_PROCESS_STACK_SLOTS; n++) {
  61.     ProcessStackInfo[n].sp = 0U;
  62.     ProcessStackInfo[n].sp_limit = (uint32_t)&ProcessStackMemory[n];
  63.     ProcessStackInfo[n].sp_top   = (uint32_t)&ProcessStackMemory[n] + TZ_PROCESS_STACK_SIZE;
  64.     *((uint32_t *)ProcessStackMemory[n]) = n + 1U;
  65.   }
  66.   *((uint32_t *)ProcessStackMemory[--n]) = 0xFFFFFFFFU;
  67.  
  68.   ProcessStackFreeSlot = 0U;
  69.  
  70.   // Default process stack pointer and stack limit
  71.   __set_PSPLIM((uint32_t)ProcessStackMemory);
  72.   __set_PSP   ((uint32_t)ProcessStackMemory);
  73.  
  74.   // Privileged Thread Mode using PSP
  75.   __set_CONTROL(0x02U);
  76.  
  77.   return 1U;    // Success
  78. }
  79.  
  80.  
  81. /// Allocate context memory for calling secure software modules in TrustZone
  82. /// \param[in]  module   identifies software modules called from non-secure mode
  83. /// \return value != 0 id TrustZone memory slot identifier
  84. /// \return value 0    no memory available or internal error
  85. __attribute__((cmse_nonsecure_entry))
  86. TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module) {
  87.   uint32_t slot;
  88.  
  89.   (void)module; // Ignore (fixed Stack size)
  90.  
  91.   if (__get_IPSR() == 0U) {
  92.     return 0U;  // Thread Mode
  93.   }
  94.  
  95.   if (ProcessStackFreeSlot == 0xFFFFFFFFU) {
  96.     return 0U;  // No slot available
  97.   }
  98.  
  99.   slot = ProcessStackFreeSlot;
  100.   ProcessStackFreeSlot = *((uint32_t *)ProcessStackMemory[slot]);
  101.  
  102.   ProcessStackInfo[slot].sp = ProcessStackInfo[slot].sp_top;
  103.  
  104.   return (slot + 1U);
  105. }
  106.  
  107.  
  108. /// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
  109. /// \param[in]  id  TrustZone memory slot identifier
  110. /// \return execution status (1: success, 0: error)
  111. __attribute__((cmse_nonsecure_entry))
  112. uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id) {
  113.   uint32_t slot;
  114.  
  115.   if (__get_IPSR() == 0U) {
  116.     return 0U;  // Thread Mode
  117.   }
  118.  
  119.   if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) {
  120.     return 0U;  // Invalid ID
  121.   }
  122.  
  123.   slot = id - 1U;
  124.  
  125.   if (ProcessStackInfo[slot].sp == 0U) {
  126.     return 0U;  // Inactive slot
  127.   }
  128.   ProcessStackInfo[slot].sp = 0U;
  129.  
  130.   *((uint32_t *)ProcessStackMemory[slot]) = ProcessStackFreeSlot;
  131.   ProcessStackFreeSlot = slot;
  132.  
  133.   return 1U;    // Success
  134. }
  135.  
  136.  
  137. /// Load secure context (called on RTOS thread context switch)
  138. /// \param[in]  id  TrustZone memory slot identifier
  139. /// \return execution status (1: success, 0: error)
  140. __attribute__((cmse_nonsecure_entry))
  141. uint32_t TZ_LoadContext_S (TZ_MemoryId_t id) {
  142.   uint32_t slot;
  143.  
  144.   if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) {
  145.     return 0U;  // Thread Mode or using Main Stack for threads
  146.   }
  147.  
  148.   if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) {
  149.     return 0U;  // Invalid ID
  150.   }
  151.  
  152.   slot = id - 1U;
  153.  
  154.   if (ProcessStackInfo[slot].sp == 0U) {
  155.     return 0U;  // Inactive slot
  156.   }
  157.  
  158.   // Setup process stack pointer and stack limit
  159.   __set_PSPLIM(ProcessStackInfo[slot].sp_limit);
  160.   __set_PSP   (ProcessStackInfo[slot].sp);
  161.  
  162.   return 1U;    // Success
  163. }
  164.  
  165.  
  166. /// Store secure context (called on RTOS thread context switch)
  167. /// \param[in]  id  TrustZone memory slot identifier
  168. /// \return execution status (1: success, 0: error)
  169. __attribute__((cmse_nonsecure_entry))
  170. uint32_t TZ_StoreContext_S (TZ_MemoryId_t id) {
  171.   uint32_t slot;
  172.   uint32_t sp;
  173.  
  174.   if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) {
  175.     return 0U;  // Thread Mode or using Main Stack for threads
  176.   }
  177.  
  178.   if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) {
  179.     return 0U;  // Invalid ID
  180.   }
  181.  
  182.   slot = id - 1U;
  183.  
  184.   if (ProcessStackInfo[slot].sp == 0U) {
  185.     return 0U;  // Inactive slot
  186.   }
  187.  
  188.   sp = __get_PSP();
  189.   if ((sp < ProcessStackInfo[slot].sp_limit) ||
  190.       (sp > ProcessStackInfo[slot].sp_top)) {
  191.     return 0U;  // SP out of range
  192.   }
  193.   ProcessStackInfo[slot].sp = sp;
  194.  
  195.   // Default process stack pointer and stack limit
  196.   __set_PSPLIM((uint32_t)ProcessStackMemory);
  197.   __set_PSP   ((uint32_t)ProcessStackMemory);
  198.  
  199.   return 1U;    // Success
  200. }
  201.