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