mbed-os5 only for TYBLE16
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/ipc/tfm_spm.c@1:9db0e321a9f4, 2019-12-31 (annotated)
- Committer:
- kenjiArai
- Date:
- Tue Dec 31 06:02:27 2019 +0000
- Revision:
- 1:9db0e321a9f4
- Parent:
- 0:5b88d5760320
updated based on mbed-os5.15.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:5b88d5760320 | 1 | /* |
kenjiArai | 0:5b88d5760320 | 2 | * Copyright (c) 2018-2019, Arm Limited. All rights reserved. |
kenjiArai | 0:5b88d5760320 | 3 | * |
kenjiArai | 0:5b88d5760320 | 4 | * SPDX-License-Identifier: BSD-3-Clause |
kenjiArai | 0:5b88d5760320 | 5 | * |
kenjiArai | 0:5b88d5760320 | 6 | */ |
kenjiArai | 0:5b88d5760320 | 7 | #include <inttypes.h> |
kenjiArai | 0:5b88d5760320 | 8 | #include <limits.h> |
kenjiArai | 0:5b88d5760320 | 9 | #include <stdbool.h> |
kenjiArai | 0:5b88d5760320 | 10 | #include <stdio.h> |
kenjiArai | 0:5b88d5760320 | 11 | #include <stdlib.h> |
kenjiArai | 0:5b88d5760320 | 12 | #include "psa_client.h" |
kenjiArai | 0:5b88d5760320 | 13 | #include "psa_service.h" |
kenjiArai | 0:5b88d5760320 | 14 | #include "tfm_utils.h" |
kenjiArai | 0:5b88d5760320 | 15 | #include "platform/include/tfm_spm_hal.h" |
kenjiArai | 0:5b88d5760320 | 16 | #include "spm_api.h" |
kenjiArai | 0:5b88d5760320 | 17 | #include "spm_db.h" |
kenjiArai | 0:5b88d5760320 | 18 | #include "spm_db_setup.h" |
kenjiArai | 0:5b88d5760320 | 19 | #include "tfm_internal_defines.h" |
kenjiArai | 0:5b88d5760320 | 20 | #include "tfm_wait.h" |
kenjiArai | 0:5b88d5760320 | 21 | #include "tfm_message_queue.h" |
kenjiArai | 0:5b88d5760320 | 22 | #include "tfm_list.h" |
kenjiArai | 0:5b88d5760320 | 23 | #include "tfm_pools.h" |
kenjiArai | 0:5b88d5760320 | 24 | #include "tfm_spm.h" |
kenjiArai | 0:5b88d5760320 | 25 | #include "tfm_spm_signal_defs.h" |
kenjiArai | 0:5b88d5760320 | 26 | #include "tfm_thread.h" |
kenjiArai | 0:5b88d5760320 | 27 | #include "region_defs.h" |
kenjiArai | 0:5b88d5760320 | 28 | #include "tfm_nspm.h" |
kenjiArai | 0:5b88d5760320 | 29 | #include "tfm_memory_utils.h" |
kenjiArai | 0:5b88d5760320 | 30 | |
kenjiArai | 0:5b88d5760320 | 31 | /* |
kenjiArai | 0:5b88d5760320 | 32 | * IPC partitions. |
kenjiArai | 0:5b88d5760320 | 33 | * FixMe: Need to get align with spm_partition_db_t. |
kenjiArai | 0:5b88d5760320 | 34 | */ |
kenjiArai | 0:5b88d5760320 | 35 | static struct tfm_spm_ipc_partition_t |
kenjiArai | 0:5b88d5760320 | 36 | g_spm_ipc_partition[SPM_MAX_PARTITIONS] = {}; |
kenjiArai | 0:5b88d5760320 | 37 | |
kenjiArai | 0:5b88d5760320 | 38 | /* Extern SPM variable */ |
kenjiArai | 0:5b88d5760320 | 39 | extern struct spm_partition_db_t g_spm_partition_db; |
kenjiArai | 0:5b88d5760320 | 40 | |
kenjiArai | 0:5b88d5760320 | 41 | /* Extern secure lock variable */ |
kenjiArai | 0:5b88d5760320 | 42 | extern int32_t tfm_secure_lock; |
kenjiArai | 0:5b88d5760320 | 43 | /* Pools */ |
kenjiArai | 0:5b88d5760320 | 44 | TFM_POOL_DECLARE(conn_handle_pool, sizeof(struct tfm_conn_handle_t), |
kenjiArai | 0:5b88d5760320 | 45 | TFM_CONN_HANDLE_MAX_NUM); |
kenjiArai | 0:5b88d5760320 | 46 | TFM_POOL_DECLARE(spm_service_pool, sizeof(struct tfm_spm_service_t), |
kenjiArai | 0:5b88d5760320 | 47 | TFM_SPM_MAX_ROT_SERV_NUM); |
kenjiArai | 0:5b88d5760320 | 48 | TFM_POOL_DECLARE(msg_db_pool, sizeof(struct tfm_msg_body_t), |
kenjiArai | 0:5b88d5760320 | 49 | TFM_MSG_QUEUE_MAX_MSG_NUM); |
kenjiArai | 0:5b88d5760320 | 50 | |
kenjiArai | 0:5b88d5760320 | 51 | static struct tfm_spm_service_db_t g_spm_service_db[] = { |
kenjiArai | 0:5b88d5760320 | 52 | #include "tfm_service_list.inc" |
kenjiArai | 0:5b88d5760320 | 53 | }; |
kenjiArai | 0:5b88d5760320 | 54 | |
kenjiArai | 0:5b88d5760320 | 55 | /********************** SPM functions for handler mode ***********************/ |
kenjiArai | 0:5b88d5760320 | 56 | |
kenjiArai | 0:5b88d5760320 | 57 | /* Service handle management functions */ |
kenjiArai | 0:5b88d5760320 | 58 | psa_handle_t tfm_spm_create_conn_handle(struct tfm_spm_service_t *service) |
kenjiArai | 0:5b88d5760320 | 59 | { |
kenjiArai | 0:5b88d5760320 | 60 | struct tfm_conn_handle_t *node; |
kenjiArai | 0:5b88d5760320 | 61 | |
kenjiArai | 0:5b88d5760320 | 62 | TFM_ASSERT(service); |
kenjiArai | 0:5b88d5760320 | 63 | |
kenjiArai | 0:5b88d5760320 | 64 | /* Get buffer for handle list structure from handle pool */ |
kenjiArai | 0:5b88d5760320 | 65 | node = (struct tfm_conn_handle_t *)tfm_pool_alloc(conn_handle_pool); |
kenjiArai | 0:5b88d5760320 | 66 | if (!node) { |
kenjiArai | 0:5b88d5760320 | 67 | return PSA_NULL_HANDLE; |
kenjiArai | 0:5b88d5760320 | 68 | } |
kenjiArai | 0:5b88d5760320 | 69 | |
kenjiArai | 0:5b88d5760320 | 70 | /* Global unique handle, use handle buffer address directly */ |
kenjiArai | 0:5b88d5760320 | 71 | node->handle = (psa_handle_t)node; |
kenjiArai | 0:5b88d5760320 | 72 | |
kenjiArai | 0:5b88d5760320 | 73 | /* Add handle node to list for next psa functions */ |
kenjiArai | 0:5b88d5760320 | 74 | tfm_list_add_tail(&service->handle_list, &node->list); |
kenjiArai | 0:5b88d5760320 | 75 | |
kenjiArai | 0:5b88d5760320 | 76 | return node->handle; |
kenjiArai | 0:5b88d5760320 | 77 | } |
kenjiArai | 0:5b88d5760320 | 78 | |
kenjiArai | 0:5b88d5760320 | 79 | static struct tfm_conn_handle_t * |
kenjiArai | 0:5b88d5760320 | 80 | tfm_spm_find_conn_handle_node(struct tfm_spm_service_t *service, |
kenjiArai | 0:5b88d5760320 | 81 | psa_handle_t conn_handle) |
kenjiArai | 0:5b88d5760320 | 82 | { |
kenjiArai | 0:5b88d5760320 | 83 | struct tfm_conn_handle_t *handle_node; |
kenjiArai | 0:5b88d5760320 | 84 | struct tfm_list_node_t *node, *head; |
kenjiArai | 0:5b88d5760320 | 85 | |
kenjiArai | 0:5b88d5760320 | 86 | TFM_ASSERT(service); |
kenjiArai | 0:5b88d5760320 | 87 | |
kenjiArai | 0:5b88d5760320 | 88 | head = &service->handle_list; |
kenjiArai | 0:5b88d5760320 | 89 | TFM_LIST_FOR_EACH(node, head) { |
kenjiArai | 0:5b88d5760320 | 90 | handle_node = TFM_GET_CONTAINER_PTR(node, struct tfm_conn_handle_t, |
kenjiArai | 0:5b88d5760320 | 91 | list); |
kenjiArai | 0:5b88d5760320 | 92 | if (handle_node->handle == conn_handle) { |
kenjiArai | 0:5b88d5760320 | 93 | return handle_node; |
kenjiArai | 0:5b88d5760320 | 94 | } |
kenjiArai | 0:5b88d5760320 | 95 | } |
kenjiArai | 0:5b88d5760320 | 96 | return NULL; |
kenjiArai | 0:5b88d5760320 | 97 | } |
kenjiArai | 0:5b88d5760320 | 98 | |
kenjiArai | 0:5b88d5760320 | 99 | int32_t tfm_spm_free_conn_handle(struct tfm_spm_service_t *service, |
kenjiArai | 0:5b88d5760320 | 100 | psa_handle_t conn_handle) |
kenjiArai | 0:5b88d5760320 | 101 | { |
kenjiArai | 0:5b88d5760320 | 102 | struct tfm_conn_handle_t *node; |
kenjiArai | 0:5b88d5760320 | 103 | |
kenjiArai | 0:5b88d5760320 | 104 | TFM_ASSERT(service); |
kenjiArai | 0:5b88d5760320 | 105 | |
kenjiArai | 0:5b88d5760320 | 106 | /* There are many handles for each RoT Service */ |
kenjiArai | 0:5b88d5760320 | 107 | node = tfm_spm_find_conn_handle_node(service, conn_handle); |
kenjiArai | 0:5b88d5760320 | 108 | if (!node) { |
kenjiArai | 0:5b88d5760320 | 109 | tfm_panic(); |
kenjiArai | 0:5b88d5760320 | 110 | } |
kenjiArai | 0:5b88d5760320 | 111 | |
kenjiArai | 0:5b88d5760320 | 112 | /* Remove node from handle list */ |
kenjiArai | 0:5b88d5760320 | 113 | tfm_list_del_node(&node->list); |
kenjiArai | 0:5b88d5760320 | 114 | |
kenjiArai | 0:5b88d5760320 | 115 | node->rhandle = NULL; |
kenjiArai | 0:5b88d5760320 | 116 | |
kenjiArai | 0:5b88d5760320 | 117 | /* Back handle buffer to pool */ |
kenjiArai | 0:5b88d5760320 | 118 | tfm_pool_free(node); |
kenjiArai | 0:5b88d5760320 | 119 | return IPC_SUCCESS; |
kenjiArai | 0:5b88d5760320 | 120 | } |
kenjiArai | 0:5b88d5760320 | 121 | |
kenjiArai | 0:5b88d5760320 | 122 | int32_t tfm_spm_set_rhandle(struct tfm_spm_service_t *service, |
kenjiArai | 0:5b88d5760320 | 123 | psa_handle_t conn_handle, |
kenjiArai | 0:5b88d5760320 | 124 | void *rhandle) |
kenjiArai | 0:5b88d5760320 | 125 | { |
kenjiArai | 0:5b88d5760320 | 126 | struct tfm_conn_handle_t *node; |
kenjiArai | 0:5b88d5760320 | 127 | |
kenjiArai | 0:5b88d5760320 | 128 | TFM_ASSERT(service); |
kenjiArai | 0:5b88d5760320 | 129 | /* Set reverse handle value only be allowed for a connected handle */ |
kenjiArai | 0:5b88d5760320 | 130 | TFM_ASSERT(conn_handle != PSA_NULL_HANDLE); |
kenjiArai | 0:5b88d5760320 | 131 | |
kenjiArai | 0:5b88d5760320 | 132 | /* There are many handles for each RoT Service */ |
kenjiArai | 0:5b88d5760320 | 133 | node = tfm_spm_find_conn_handle_node(service, conn_handle); |
kenjiArai | 0:5b88d5760320 | 134 | if (!node) { |
kenjiArai | 0:5b88d5760320 | 135 | tfm_panic(); |
kenjiArai | 0:5b88d5760320 | 136 | } |
kenjiArai | 0:5b88d5760320 | 137 | |
kenjiArai | 0:5b88d5760320 | 138 | node->rhandle = rhandle; |
kenjiArai | 0:5b88d5760320 | 139 | return IPC_SUCCESS; |
kenjiArai | 0:5b88d5760320 | 140 | } |
kenjiArai | 0:5b88d5760320 | 141 | |
kenjiArai | 0:5b88d5760320 | 142 | void *tfm_spm_get_rhandle(struct tfm_spm_service_t *service, |
kenjiArai | 0:5b88d5760320 | 143 | psa_handle_t conn_handle) |
kenjiArai | 0:5b88d5760320 | 144 | { |
kenjiArai | 0:5b88d5760320 | 145 | struct tfm_conn_handle_t *node; |
kenjiArai | 0:5b88d5760320 | 146 | |
kenjiArai | 0:5b88d5760320 | 147 | TFM_ASSERT(service); |
kenjiArai | 0:5b88d5760320 | 148 | /* Get reverse handle value only be allowed for a connected handle */ |
kenjiArai | 0:5b88d5760320 | 149 | TFM_ASSERT(conn_handle != PSA_NULL_HANDLE); |
kenjiArai | 0:5b88d5760320 | 150 | |
kenjiArai | 0:5b88d5760320 | 151 | /* There are many handles for each RoT Service */ |
kenjiArai | 0:5b88d5760320 | 152 | node = tfm_spm_find_conn_handle_node(service, conn_handle); |
kenjiArai | 0:5b88d5760320 | 153 | if (!node) { |
kenjiArai | 0:5b88d5760320 | 154 | tfm_panic(); |
kenjiArai | 0:5b88d5760320 | 155 | } |
kenjiArai | 0:5b88d5760320 | 156 | |
kenjiArai | 0:5b88d5760320 | 157 | return node->rhandle; |
kenjiArai | 0:5b88d5760320 | 158 | } |
kenjiArai | 0:5b88d5760320 | 159 | |
kenjiArai | 0:5b88d5760320 | 160 | /* Partition management functions */ |
kenjiArai | 0:5b88d5760320 | 161 | struct tfm_spm_service_t * |
kenjiArai | 0:5b88d5760320 | 162 | tfm_spm_get_service_by_signal(struct tfm_spm_ipc_partition_t *partition, |
kenjiArai | 0:5b88d5760320 | 163 | psa_signal_t signal) |
kenjiArai | 0:5b88d5760320 | 164 | { |
kenjiArai | 0:5b88d5760320 | 165 | struct tfm_list_node_t *node, *head; |
kenjiArai | 0:5b88d5760320 | 166 | struct tfm_spm_service_t *service; |
kenjiArai | 0:5b88d5760320 | 167 | |
kenjiArai | 0:5b88d5760320 | 168 | TFM_ASSERT(partition); |
kenjiArai | 0:5b88d5760320 | 169 | |
kenjiArai | 0:5b88d5760320 | 170 | if (tfm_list_is_empty(&partition->service_list)) { |
kenjiArai | 0:5b88d5760320 | 171 | tfm_panic(); |
kenjiArai | 0:5b88d5760320 | 172 | } |
kenjiArai | 0:5b88d5760320 | 173 | |
kenjiArai | 0:5b88d5760320 | 174 | head = &partition->service_list; |
kenjiArai | 0:5b88d5760320 | 175 | TFM_LIST_FOR_EACH(node, head) { |
kenjiArai | 0:5b88d5760320 | 176 | service = TFM_GET_CONTAINER_PTR(node, struct tfm_spm_service_t, list); |
kenjiArai | 0:5b88d5760320 | 177 | if (service->service_db->signal == signal) { |
kenjiArai | 0:5b88d5760320 | 178 | return service; |
kenjiArai | 0:5b88d5760320 | 179 | } |
kenjiArai | 0:5b88d5760320 | 180 | } |
kenjiArai | 0:5b88d5760320 | 181 | return NULL; |
kenjiArai | 0:5b88d5760320 | 182 | } |
kenjiArai | 0:5b88d5760320 | 183 | |
kenjiArai | 0:5b88d5760320 | 184 | struct tfm_spm_service_t *tfm_spm_get_service_by_sid(uint32_t sid) |
kenjiArai | 0:5b88d5760320 | 185 | { |
kenjiArai | 0:5b88d5760320 | 186 | uint32_t i; |
kenjiArai | 0:5b88d5760320 | 187 | struct tfm_list_node_t *node, *head; |
kenjiArai | 0:5b88d5760320 | 188 | struct tfm_spm_service_t *service; |
kenjiArai | 0:5b88d5760320 | 189 | |
kenjiArai | 0:5b88d5760320 | 190 | for (i = 0; i < SPM_MAX_PARTITIONS; i++) { |
kenjiArai | 0:5b88d5760320 | 191 | /* Skip partition without IPC flag */ |
kenjiArai | 0:5b88d5760320 | 192 | if ((tfm_spm_partition_get_flags(g_spm_ipc_partition[i].index) & |
kenjiArai | 0:5b88d5760320 | 193 | SPM_PART_FLAG_IPC) == 0) { |
kenjiArai | 0:5b88d5760320 | 194 | continue; |
kenjiArai | 0:5b88d5760320 | 195 | } |
kenjiArai | 0:5b88d5760320 | 196 | |
kenjiArai | 0:5b88d5760320 | 197 | if (tfm_list_is_empty(&g_spm_ipc_partition[i].service_list)) { |
kenjiArai | 0:5b88d5760320 | 198 | continue; |
kenjiArai | 0:5b88d5760320 | 199 | } |
kenjiArai | 0:5b88d5760320 | 200 | |
kenjiArai | 0:5b88d5760320 | 201 | head = &g_spm_ipc_partition[i].service_list; |
kenjiArai | 0:5b88d5760320 | 202 | TFM_LIST_FOR_EACH(node, head) { |
kenjiArai | 0:5b88d5760320 | 203 | service = TFM_GET_CONTAINER_PTR(node, struct tfm_spm_service_t, |
kenjiArai | 0:5b88d5760320 | 204 | list); |
kenjiArai | 0:5b88d5760320 | 205 | if (service->service_db->sid == sid) { |
kenjiArai | 0:5b88d5760320 | 206 | return service; |
kenjiArai | 0:5b88d5760320 | 207 | } |
kenjiArai | 0:5b88d5760320 | 208 | } |
kenjiArai | 0:5b88d5760320 | 209 | } |
kenjiArai | 0:5b88d5760320 | 210 | return NULL; |
kenjiArai | 0:5b88d5760320 | 211 | } |
kenjiArai | 0:5b88d5760320 | 212 | |
kenjiArai | 0:5b88d5760320 | 213 | struct tfm_spm_service_t * |
kenjiArai | 0:5b88d5760320 | 214 | tfm_spm_get_service_by_handle(psa_handle_t conn_handle) |
kenjiArai | 0:5b88d5760320 | 215 | { |
kenjiArai | 0:5b88d5760320 | 216 | uint32_t i; |
kenjiArai | 0:5b88d5760320 | 217 | struct tfm_conn_handle_t *handle; |
kenjiArai | 0:5b88d5760320 | 218 | struct tfm_list_node_t *service_node, *service_head; |
kenjiArai | 0:5b88d5760320 | 219 | struct tfm_list_node_t *handle_node, *handle_head; |
kenjiArai | 0:5b88d5760320 | 220 | struct tfm_spm_service_t *service; |
kenjiArai | 0:5b88d5760320 | 221 | |
kenjiArai | 0:5b88d5760320 | 222 | for (i = 0; i < SPM_MAX_PARTITIONS; i++) { |
kenjiArai | 0:5b88d5760320 | 223 | /* Skip partition without IPC flag */ |
kenjiArai | 0:5b88d5760320 | 224 | if ((tfm_spm_partition_get_flags(g_spm_ipc_partition[i].index) & |
kenjiArai | 0:5b88d5760320 | 225 | SPM_PART_FLAG_IPC) == 0) { |
kenjiArai | 0:5b88d5760320 | 226 | continue; |
kenjiArai | 0:5b88d5760320 | 227 | } |
kenjiArai | 0:5b88d5760320 | 228 | |
kenjiArai | 0:5b88d5760320 | 229 | if (tfm_list_is_empty(&g_spm_ipc_partition[i].service_list)) { |
kenjiArai | 0:5b88d5760320 | 230 | continue; |
kenjiArai | 0:5b88d5760320 | 231 | } |
kenjiArai | 0:5b88d5760320 | 232 | |
kenjiArai | 0:5b88d5760320 | 233 | service_head = &g_spm_ipc_partition[i].service_list; |
kenjiArai | 0:5b88d5760320 | 234 | TFM_LIST_FOR_EACH(service_node, service_head) { |
kenjiArai | 0:5b88d5760320 | 235 | service = TFM_GET_CONTAINER_PTR(service_node, |
kenjiArai | 0:5b88d5760320 | 236 | struct tfm_spm_service_t, list); |
kenjiArai | 0:5b88d5760320 | 237 | handle_head = &service->handle_list; |
kenjiArai | 0:5b88d5760320 | 238 | TFM_LIST_FOR_EACH(handle_node, handle_head) { |
kenjiArai | 0:5b88d5760320 | 239 | handle = TFM_GET_CONTAINER_PTR(handle_node, |
kenjiArai | 0:5b88d5760320 | 240 | struct tfm_conn_handle_t, list); |
kenjiArai | 0:5b88d5760320 | 241 | if (handle->handle == conn_handle) { |
kenjiArai | 0:5b88d5760320 | 242 | return service; |
kenjiArai | 0:5b88d5760320 | 243 | } |
kenjiArai | 0:5b88d5760320 | 244 | } |
kenjiArai | 0:5b88d5760320 | 245 | } |
kenjiArai | 0:5b88d5760320 | 246 | } |
kenjiArai | 0:5b88d5760320 | 247 | return NULL; |
kenjiArai | 0:5b88d5760320 | 248 | } |
kenjiArai | 0:5b88d5760320 | 249 | |
kenjiArai | 0:5b88d5760320 | 250 | struct tfm_spm_ipc_partition_t * |
kenjiArai | 0:5b88d5760320 | 251 | tfm_spm_get_partition_by_id(int32_t partition_id) |
kenjiArai | 0:5b88d5760320 | 252 | { |
kenjiArai | 0:5b88d5760320 | 253 | uint32_t i; |
kenjiArai | 0:5b88d5760320 | 254 | |
kenjiArai | 0:5b88d5760320 | 255 | for (i = 0; i < SPM_MAX_PARTITIONS; i++) { |
kenjiArai | 0:5b88d5760320 | 256 | if (g_spm_ipc_partition[i].id == partition_id) { |
kenjiArai | 0:5b88d5760320 | 257 | return &g_spm_ipc_partition[i]; |
kenjiArai | 0:5b88d5760320 | 258 | } |
kenjiArai | 0:5b88d5760320 | 259 | } |
kenjiArai | 0:5b88d5760320 | 260 | return NULL; |
kenjiArai | 0:5b88d5760320 | 261 | } |
kenjiArai | 0:5b88d5760320 | 262 | |
kenjiArai | 0:5b88d5760320 | 263 | struct tfm_spm_ipc_partition_t *tfm_spm_get_running_partition(void) |
kenjiArai | 0:5b88d5760320 | 264 | { |
kenjiArai | 0:5b88d5760320 | 265 | uint32_t spid; |
kenjiArai | 0:5b88d5760320 | 266 | |
kenjiArai | 0:5b88d5760320 | 267 | spid = tfm_spm_partition_get_running_partition_id_ext(); |
kenjiArai | 0:5b88d5760320 | 268 | |
kenjiArai | 0:5b88d5760320 | 269 | return tfm_spm_get_partition_by_id(spid); |
kenjiArai | 0:5b88d5760320 | 270 | } |
kenjiArai | 0:5b88d5760320 | 271 | |
kenjiArai | 0:5b88d5760320 | 272 | int32_t tfm_spm_check_client_version(struct tfm_spm_service_t *service, |
kenjiArai | 0:5b88d5760320 | 273 | uint32_t minor_version) |
kenjiArai | 0:5b88d5760320 | 274 | { |
kenjiArai | 0:5b88d5760320 | 275 | TFM_ASSERT(service); |
kenjiArai | 0:5b88d5760320 | 276 | |
kenjiArai | 0:5b88d5760320 | 277 | switch (service->service_db->minor_policy) { |
kenjiArai | 0:5b88d5760320 | 278 | case TFM_VERSION_POLICY_RELAXED: |
kenjiArai | 0:5b88d5760320 | 279 | if (minor_version > service->service_db->minor_version) { |
kenjiArai | 0:5b88d5760320 | 280 | return IPC_ERROR_VERSION; |
kenjiArai | 0:5b88d5760320 | 281 | } |
kenjiArai | 0:5b88d5760320 | 282 | break; |
kenjiArai | 0:5b88d5760320 | 283 | case TFM_VERSION_POLICY_STRICT: |
kenjiArai | 0:5b88d5760320 | 284 | if (minor_version != service->service_db->minor_version) { |
kenjiArai | 0:5b88d5760320 | 285 | return IPC_ERROR_VERSION; |
kenjiArai | 0:5b88d5760320 | 286 | } |
kenjiArai | 0:5b88d5760320 | 287 | break; |
kenjiArai | 0:5b88d5760320 | 288 | default: |
kenjiArai | 0:5b88d5760320 | 289 | return IPC_ERROR_VERSION; |
kenjiArai | 0:5b88d5760320 | 290 | } |
kenjiArai | 0:5b88d5760320 | 291 | return IPC_SUCCESS; |
kenjiArai | 0:5b88d5760320 | 292 | } |
kenjiArai | 0:5b88d5760320 | 293 | |
kenjiArai | 0:5b88d5760320 | 294 | /* Message functions */ |
kenjiArai | 0:5b88d5760320 | 295 | struct tfm_msg_body_t *tfm_spm_get_msg_from_handle(psa_handle_t msg_handle) |
kenjiArai | 0:5b88d5760320 | 296 | { |
kenjiArai | 0:5b88d5760320 | 297 | /* |
kenjiArai | 0:5b88d5760320 | 298 | * There may be one error handle passed by the caller in two conditions: |
kenjiArai | 0:5b88d5760320 | 299 | * 1. Not a valid message handle. |
kenjiArai | 0:5b88d5760320 | 300 | * 2. Handle between different Partitions. Partition A passes one handle |
kenjiArai | 0:5b88d5760320 | 301 | * belong to other Partitions and tries to access other's data. |
kenjiArai | 0:5b88d5760320 | 302 | * So, need do necessary checking to prevent those conditions. |
kenjiArai | 0:5b88d5760320 | 303 | */ |
kenjiArai | 0:5b88d5760320 | 304 | struct tfm_msg_body_t *msg; |
kenjiArai | 0:5b88d5760320 | 305 | uint32_t partition_id; |
kenjiArai | 0:5b88d5760320 | 306 | |
kenjiArai | 0:5b88d5760320 | 307 | msg = (struct tfm_msg_body_t *)msg_handle; |
kenjiArai | 0:5b88d5760320 | 308 | if (!msg) { |
kenjiArai | 0:5b88d5760320 | 309 | return NULL; |
kenjiArai | 0:5b88d5760320 | 310 | } |
kenjiArai | 0:5b88d5760320 | 311 | |
kenjiArai | 0:5b88d5760320 | 312 | /* |
kenjiArai | 0:5b88d5760320 | 313 | * FixMe: For condition 1: using a magic number to define it's a message. |
kenjiArai | 0:5b88d5760320 | 314 | * It needs to be an enhancement to check the handle belong to service. |
kenjiArai | 0:5b88d5760320 | 315 | */ |
kenjiArai | 0:5b88d5760320 | 316 | if (msg->magic != TFM_MSG_MAGIC) { |
kenjiArai | 0:5b88d5760320 | 317 | return NULL; |
kenjiArai | 0:5b88d5760320 | 318 | } |
kenjiArai | 0:5b88d5760320 | 319 | |
kenjiArai | 0:5b88d5760320 | 320 | /* For condition 2: check if the partition ID is same */ |
kenjiArai | 0:5b88d5760320 | 321 | partition_id = tfm_spm_partition_get_running_partition_id_ext(); |
kenjiArai | 0:5b88d5760320 | 322 | if (partition_id != msg->service->partition->id) { |
kenjiArai | 0:5b88d5760320 | 323 | return NULL; |
kenjiArai | 0:5b88d5760320 | 324 | } |
kenjiArai | 0:5b88d5760320 | 325 | |
kenjiArai | 0:5b88d5760320 | 326 | return msg; |
kenjiArai | 0:5b88d5760320 | 327 | } |
kenjiArai | 0:5b88d5760320 | 328 | |
kenjiArai | 0:5b88d5760320 | 329 | struct tfm_msg_body_t *tfm_spm_create_msg(struct tfm_spm_service_t *service, |
kenjiArai | 0:5b88d5760320 | 330 | psa_handle_t handle, |
kenjiArai | 0:5b88d5760320 | 331 | uint32_t type, int32_t ns_caller, |
kenjiArai | 0:5b88d5760320 | 332 | psa_invec *invec, size_t in_len, |
kenjiArai | 0:5b88d5760320 | 333 | psa_outvec *outvec, size_t out_len, |
kenjiArai | 0:5b88d5760320 | 334 | psa_outvec *caller_outvec) |
kenjiArai | 0:5b88d5760320 | 335 | { |
kenjiArai | 0:5b88d5760320 | 336 | struct tfm_msg_body_t *msg = NULL; |
kenjiArai | 0:5b88d5760320 | 337 | uint32_t i; |
kenjiArai | 0:5b88d5760320 | 338 | |
kenjiArai | 0:5b88d5760320 | 339 | TFM_ASSERT(service); |
kenjiArai | 0:5b88d5760320 | 340 | TFM_ASSERT(!(invec == NULL && in_len != 0)); |
kenjiArai | 0:5b88d5760320 | 341 | TFM_ASSERT(!(outvec == NULL && out_len != 0)); |
kenjiArai | 0:5b88d5760320 | 342 | TFM_ASSERT(in_len <= PSA_MAX_IOVEC); |
kenjiArai | 0:5b88d5760320 | 343 | TFM_ASSERT(out_len <= PSA_MAX_IOVEC); |
kenjiArai | 0:5b88d5760320 | 344 | TFM_ASSERT(in_len + out_len <= PSA_MAX_IOVEC); |
kenjiArai | 0:5b88d5760320 | 345 | |
kenjiArai | 0:5b88d5760320 | 346 | /* Get message buffer from message pool */ |
kenjiArai | 0:5b88d5760320 | 347 | msg = (struct tfm_msg_body_t *)tfm_pool_alloc(msg_db_pool); |
kenjiArai | 0:5b88d5760320 | 348 | if (!msg) { |
kenjiArai | 0:5b88d5760320 | 349 | return NULL; |
kenjiArai | 0:5b88d5760320 | 350 | } |
kenjiArai | 0:5b88d5760320 | 351 | |
kenjiArai | 0:5b88d5760320 | 352 | /* Clear message buffer before using it */ |
kenjiArai | 0:5b88d5760320 | 353 | tfm_memset(msg, 0, sizeof(struct tfm_msg_body_t)); |
kenjiArai | 0:5b88d5760320 | 354 | |
kenjiArai | 0:5b88d5760320 | 355 | tfm_event_init(&msg->ack_evnt); |
kenjiArai | 0:5b88d5760320 | 356 | msg->magic = TFM_MSG_MAGIC; |
kenjiArai | 0:5b88d5760320 | 357 | msg->service = service; |
kenjiArai | 0:5b88d5760320 | 358 | msg->handle = handle; |
kenjiArai | 0:5b88d5760320 | 359 | msg->caller_outvec = caller_outvec; |
kenjiArai | 0:5b88d5760320 | 360 | /* Get current partition id */ |
kenjiArai | 0:5b88d5760320 | 361 | if (ns_caller) { |
kenjiArai | 0:5b88d5760320 | 362 | msg->msg.client_id = tfm_nspm_get_current_client_id(); |
kenjiArai | 0:5b88d5760320 | 363 | } else { |
kenjiArai | 0:5b88d5760320 | 364 | msg->msg.client_id = tfm_spm_partition_get_running_partition_id_ext(); |
kenjiArai | 0:5b88d5760320 | 365 | } |
kenjiArai | 0:5b88d5760320 | 366 | |
kenjiArai | 0:5b88d5760320 | 367 | /* Copy contents */ |
kenjiArai | 0:5b88d5760320 | 368 | msg->msg.type = type; |
kenjiArai | 0:5b88d5760320 | 369 | |
kenjiArai | 0:5b88d5760320 | 370 | for (i = 0; i < in_len; i++) { |
kenjiArai | 0:5b88d5760320 | 371 | msg->msg.in_size[i] = invec[i].len; |
kenjiArai | 0:5b88d5760320 | 372 | msg->invec[i].base = invec[i].base; |
kenjiArai | 0:5b88d5760320 | 373 | } |
kenjiArai | 0:5b88d5760320 | 374 | |
kenjiArai | 0:5b88d5760320 | 375 | for (i = 0; i < out_len; i++) { |
kenjiArai | 0:5b88d5760320 | 376 | msg->msg.out_size[i] = outvec[i].len; |
kenjiArai | 0:5b88d5760320 | 377 | msg->outvec[i].base = outvec[i].base; |
kenjiArai | 0:5b88d5760320 | 378 | /* Out len is used to record the writed number, set 0 here again */ |
kenjiArai | 0:5b88d5760320 | 379 | msg->outvec[i].len = 0; |
kenjiArai | 0:5b88d5760320 | 380 | } |
kenjiArai | 0:5b88d5760320 | 381 | |
kenjiArai | 0:5b88d5760320 | 382 | /* Use message address as handle */ |
kenjiArai | 0:5b88d5760320 | 383 | msg->msg.handle = (psa_handle_t)msg; |
kenjiArai | 0:5b88d5760320 | 384 | |
kenjiArai | 0:5b88d5760320 | 385 | /* For connected handle, set rhandle to every message */ |
kenjiArai | 0:5b88d5760320 | 386 | if (handle != PSA_NULL_HANDLE) { |
kenjiArai | 0:5b88d5760320 | 387 | msg->msg.rhandle = tfm_spm_get_rhandle(service, handle); |
kenjiArai | 0:5b88d5760320 | 388 | } |
kenjiArai | 0:5b88d5760320 | 389 | |
kenjiArai | 0:5b88d5760320 | 390 | return msg; |
kenjiArai | 0:5b88d5760320 | 391 | } |
kenjiArai | 0:5b88d5760320 | 392 | |
kenjiArai | 0:5b88d5760320 | 393 | void tfm_spm_free_msg(struct tfm_msg_body_t *msg) |
kenjiArai | 0:5b88d5760320 | 394 | { |
kenjiArai | 0:5b88d5760320 | 395 | tfm_pool_free(msg); |
kenjiArai | 0:5b88d5760320 | 396 | } |
kenjiArai | 0:5b88d5760320 | 397 | |
kenjiArai | 0:5b88d5760320 | 398 | int32_t tfm_spm_send_event(struct tfm_spm_service_t *service, |
kenjiArai | 0:5b88d5760320 | 399 | struct tfm_msg_body_t *msg) |
kenjiArai | 0:5b88d5760320 | 400 | { |
kenjiArai | 0:5b88d5760320 | 401 | TFM_ASSERT(service); |
kenjiArai | 0:5b88d5760320 | 402 | TFM_ASSERT(msg); |
kenjiArai | 0:5b88d5760320 | 403 | |
kenjiArai | 0:5b88d5760320 | 404 | /* Enqueue message to service message queue */ |
kenjiArai | 0:5b88d5760320 | 405 | if (tfm_msg_enqueue(&service->msg_queue, msg) != IPC_SUCCESS) { |
kenjiArai | 0:5b88d5760320 | 406 | return IPC_ERROR_GENERIC; |
kenjiArai | 0:5b88d5760320 | 407 | } |
kenjiArai | 0:5b88d5760320 | 408 | |
kenjiArai | 0:5b88d5760320 | 409 | /* Messages put. Update signals */ |
kenjiArai | 0:5b88d5760320 | 410 | service->partition->signals |= service->service_db->signal; |
kenjiArai | 0:5b88d5760320 | 411 | |
kenjiArai | 0:5b88d5760320 | 412 | tfm_event_wake(&service->partition->signal_evnt, |
kenjiArai | 0:5b88d5760320 | 413 | (service->partition->signals & |
kenjiArai | 0:5b88d5760320 | 414 | service->partition->signal_mask)); |
kenjiArai | 0:5b88d5760320 | 415 | |
kenjiArai | 0:5b88d5760320 | 416 | tfm_event_wait(&msg->ack_evnt); |
kenjiArai | 0:5b88d5760320 | 417 | |
kenjiArai | 0:5b88d5760320 | 418 | return IPC_SUCCESS; |
kenjiArai | 0:5b88d5760320 | 419 | } |
kenjiArai | 0:5b88d5760320 | 420 | |
kenjiArai | 0:5b88d5760320 | 421 | /* SPM extend functions */ |
kenjiArai | 0:5b88d5760320 | 422 | uint32_t tfm_spm_partition_get_running_partition_id_ext(void) |
kenjiArai | 0:5b88d5760320 | 423 | { |
kenjiArai | 0:5b88d5760320 | 424 | struct tfm_thrd_ctx *pth = tfm_thrd_curr_thread(); |
kenjiArai | 0:5b88d5760320 | 425 | struct spm_partition_desc_t *partition; |
kenjiArai | 0:5b88d5760320 | 426 | |
kenjiArai | 0:5b88d5760320 | 427 | partition = TFM_GET_CONTAINER_PTR(pth, struct spm_partition_desc_t, |
kenjiArai | 0:5b88d5760320 | 428 | sp_thrd); |
kenjiArai | 0:5b88d5760320 | 429 | return partition->static_data.partition_id; |
kenjiArai | 0:5b88d5760320 | 430 | } |
kenjiArai | 0:5b88d5760320 | 431 | |
kenjiArai | 0:5b88d5760320 | 432 | static struct tfm_thrd_ctx * |
kenjiArai | 0:5b88d5760320 | 433 | tfm_spm_partition_get_thread_info_ext(uint32_t partition_idx) |
kenjiArai | 0:5b88d5760320 | 434 | { |
kenjiArai | 0:5b88d5760320 | 435 | return &g_spm_partition_db.partitions[partition_idx].sp_thrd; |
kenjiArai | 0:5b88d5760320 | 436 | } |
kenjiArai | 0:5b88d5760320 | 437 | |
kenjiArai | 0:5b88d5760320 | 438 | static tfm_thrd_func_t |
kenjiArai | 0:5b88d5760320 | 439 | tfm_spm_partition_get_init_func_ext(uint32_t partition_idx) |
kenjiArai | 0:5b88d5760320 | 440 | { |
kenjiArai | 0:5b88d5760320 | 441 | return (tfm_thrd_func_t)(g_spm_partition_db.partitions[partition_idx]. |
kenjiArai | 0:5b88d5760320 | 442 | static_data.partition_init); |
kenjiArai | 0:5b88d5760320 | 443 | } |
kenjiArai | 0:5b88d5760320 | 444 | |
kenjiArai | 0:5b88d5760320 | 445 | static uint32_t tfm_spm_partition_get_priority_ext(uint32_t partition_idx) |
kenjiArai | 0:5b88d5760320 | 446 | { |
kenjiArai | 0:5b88d5760320 | 447 | return g_spm_partition_db.partitions[partition_idx].static_data. |
kenjiArai | 0:5b88d5760320 | 448 | partition_priority; |
kenjiArai | 0:5b88d5760320 | 449 | } |
kenjiArai | 0:5b88d5760320 | 450 | |
kenjiArai | 0:5b88d5760320 | 451 | int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller, |
kenjiArai | 0:5b88d5760320 | 452 | enum tfm_memory_access_e access, |
kenjiArai | 0:5b88d5760320 | 453 | uint32_t privileged) |
kenjiArai | 0:5b88d5760320 | 454 | { |
kenjiArai | 0:5b88d5760320 | 455 | int32_t err; |
kenjiArai | 0:5b88d5760320 | 456 | |
kenjiArai | 0:5b88d5760320 | 457 | /* If len is zero, this indicates an empty buffer and base is ignored */ |
kenjiArai | 0:5b88d5760320 | 458 | if (len == 0) { |
kenjiArai | 0:5b88d5760320 | 459 | return IPC_SUCCESS; |
kenjiArai | 0:5b88d5760320 | 460 | } |
kenjiArai | 0:5b88d5760320 | 461 | |
kenjiArai | 0:5b88d5760320 | 462 | if (!buffer) { |
kenjiArai | 0:5b88d5760320 | 463 | return IPC_ERROR_BAD_PARAMETERS; |
kenjiArai | 0:5b88d5760320 | 464 | } |
kenjiArai | 0:5b88d5760320 | 465 | |
kenjiArai | 0:5b88d5760320 | 466 | if ((uintptr_t)buffer > (UINTPTR_MAX - len)) { |
kenjiArai | 0:5b88d5760320 | 467 | return IPC_ERROR_MEMORY_CHECK; |
kenjiArai | 0:5b88d5760320 | 468 | } |
kenjiArai | 0:5b88d5760320 | 469 | |
kenjiArai | 0:5b88d5760320 | 470 | if (access == TFM_MEMORY_ACCESS_RW) { |
kenjiArai | 0:5b88d5760320 | 471 | err = tfm_core_has_write_access_to_region(buffer, len, ns_caller, |
kenjiArai | 0:5b88d5760320 | 472 | privileged); |
kenjiArai | 0:5b88d5760320 | 473 | } else { |
kenjiArai | 0:5b88d5760320 | 474 | err = tfm_core_has_read_access_to_region(buffer, len, ns_caller, |
kenjiArai | 0:5b88d5760320 | 475 | privileged); |
kenjiArai | 0:5b88d5760320 | 476 | } |
kenjiArai | 0:5b88d5760320 | 477 | if (err == TFM_SUCCESS) { |
kenjiArai | 0:5b88d5760320 | 478 | return IPC_SUCCESS; |
kenjiArai | 0:5b88d5760320 | 479 | } |
kenjiArai | 0:5b88d5760320 | 480 | |
kenjiArai | 0:5b88d5760320 | 481 | return IPC_ERROR_MEMORY_CHECK; |
kenjiArai | 0:5b88d5760320 | 482 | } |
kenjiArai | 0:5b88d5760320 | 483 | |
kenjiArai | 0:5b88d5760320 | 484 | uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_idx) |
kenjiArai | 0:5b88d5760320 | 485 | { |
kenjiArai | 0:5b88d5760320 | 486 | if (tfm_spm_partition_get_flags(partition_idx) & SPM_PART_FLAG_PSA_ROT) { |
kenjiArai | 0:5b88d5760320 | 487 | return TFM_PARTITION_PRIVILEGED_MODE; |
kenjiArai | 0:5b88d5760320 | 488 | } else { |
kenjiArai | 0:5b88d5760320 | 489 | return TFM_PARTITION_UNPRIVILEGED_MODE; |
kenjiArai | 0:5b88d5760320 | 490 | } |
kenjiArai | 0:5b88d5760320 | 491 | } |
kenjiArai | 0:5b88d5760320 | 492 | |
kenjiArai | 0:5b88d5760320 | 493 | /********************** SPM functions for thread mode ************************/ |
kenjiArai | 0:5b88d5760320 | 494 | |
kenjiArai | 0:5b88d5760320 | 495 | void tfm_spm_init(void) |
kenjiArai | 0:5b88d5760320 | 496 | { |
kenjiArai | 0:5b88d5760320 | 497 | uint32_t i, num; |
kenjiArai | 0:5b88d5760320 | 498 | struct tfm_spm_ipc_partition_t *partition; |
kenjiArai | 0:5b88d5760320 | 499 | struct tfm_spm_service_t *service; |
kenjiArai | 0:5b88d5760320 | 500 | struct tfm_thrd_ctx *pth, this_thrd; |
kenjiArai | 0:5b88d5760320 | 501 | struct spm_partition_desc_t *part; |
kenjiArai | 0:5b88d5760320 | 502 | |
kenjiArai | 0:5b88d5760320 | 503 | tfm_pool_init(conn_handle_pool, |
kenjiArai | 0:5b88d5760320 | 504 | POOL_BUFFER_SIZE(conn_handle_pool), |
kenjiArai | 0:5b88d5760320 | 505 | sizeof(struct tfm_conn_handle_t), |
kenjiArai | 0:5b88d5760320 | 506 | TFM_CONN_HANDLE_MAX_NUM); |
kenjiArai | 0:5b88d5760320 | 507 | tfm_pool_init(spm_service_pool, POOL_BUFFER_SIZE(spm_service_pool), |
kenjiArai | 0:5b88d5760320 | 508 | sizeof(struct tfm_spm_service_t), |
kenjiArai | 0:5b88d5760320 | 509 | TFM_SPM_MAX_ROT_SERV_NUM); |
kenjiArai | 0:5b88d5760320 | 510 | tfm_pool_init(msg_db_pool, POOL_BUFFER_SIZE(msg_db_pool), |
kenjiArai | 0:5b88d5760320 | 511 | sizeof(struct tfm_msg_body_t), |
kenjiArai | 0:5b88d5760320 | 512 | TFM_MSG_QUEUE_MAX_MSG_NUM); |
kenjiArai | 0:5b88d5760320 | 513 | |
kenjiArai | 0:5b88d5760320 | 514 | /* Init partition first for it will be used when init service */ |
kenjiArai | 0:5b88d5760320 | 515 | for (i = 0; i < SPM_MAX_PARTITIONS; i++) { |
kenjiArai | 0:5b88d5760320 | 516 | part = &g_spm_partition_db.partitions[i]; |
kenjiArai | 0:5b88d5760320 | 517 | tfm_spm_hal_configure_default_isolation(part->platform_data); |
kenjiArai | 0:5b88d5760320 | 518 | g_spm_ipc_partition[i].index = i; |
kenjiArai | 0:5b88d5760320 | 519 | if ((tfm_spm_partition_get_flags(i) & SPM_PART_FLAG_IPC) == 0) { |
kenjiArai | 0:5b88d5760320 | 520 | continue; |
kenjiArai | 0:5b88d5760320 | 521 | } |
kenjiArai | 0:5b88d5760320 | 522 | g_spm_ipc_partition[i].id = tfm_spm_partition_get_partition_id(i); |
kenjiArai | 0:5b88d5760320 | 523 | |
kenjiArai | 0:5b88d5760320 | 524 | tfm_event_init(&g_spm_ipc_partition[i].signal_evnt); |
kenjiArai | 0:5b88d5760320 | 525 | tfm_list_init(&g_spm_ipc_partition[i].service_list); |
kenjiArai | 0:5b88d5760320 | 526 | |
kenjiArai | 0:5b88d5760320 | 527 | pth = tfm_spm_partition_get_thread_info_ext(i); |
kenjiArai | 0:5b88d5760320 | 528 | if (!pth) { |
kenjiArai | 0:5b88d5760320 | 529 | tfm_panic(); |
kenjiArai | 0:5b88d5760320 | 530 | } |
kenjiArai | 0:5b88d5760320 | 531 | |
kenjiArai | 0:5b88d5760320 | 532 | tfm_thrd_init(pth, |
kenjiArai | 0:5b88d5760320 | 533 | tfm_spm_partition_get_init_func_ext(i), |
kenjiArai | 0:5b88d5760320 | 534 | NULL, |
kenjiArai | 0:5b88d5760320 | 535 | (uint8_t *)tfm_spm_partition_get_stack_top(i), |
kenjiArai | 0:5b88d5760320 | 536 | (uint8_t *)tfm_spm_partition_get_stack_bottom(i)); |
kenjiArai | 0:5b88d5760320 | 537 | |
kenjiArai | 0:5b88d5760320 | 538 | pth->prior = tfm_spm_partition_get_priority_ext(i); |
kenjiArai | 0:5b88d5760320 | 539 | |
kenjiArai | 0:5b88d5760320 | 540 | /* Kick off */ |
kenjiArai | 0:5b88d5760320 | 541 | if (tfm_thrd_start(pth) != THRD_SUCCESS) { |
kenjiArai | 0:5b88d5760320 | 542 | tfm_panic(); |
kenjiArai | 0:5b88d5760320 | 543 | } |
kenjiArai | 0:5b88d5760320 | 544 | } |
kenjiArai | 0:5b88d5760320 | 545 | |
kenjiArai | 0:5b88d5760320 | 546 | /* Init Service */ |
kenjiArai | 0:5b88d5760320 | 547 | num = sizeof(g_spm_service_db) / sizeof(struct tfm_spm_service_db_t); |
kenjiArai | 0:5b88d5760320 | 548 | for (i = 0; i < num; i++) { |
kenjiArai | 0:5b88d5760320 | 549 | partition = |
kenjiArai | 0:5b88d5760320 | 550 | tfm_spm_get_partition_by_id(g_spm_service_db[i].partition_id); |
kenjiArai | 0:5b88d5760320 | 551 | if (!partition) { |
kenjiArai | 0:5b88d5760320 | 552 | tfm_panic(); |
kenjiArai | 0:5b88d5760320 | 553 | } |
kenjiArai | 0:5b88d5760320 | 554 | service = (struct tfm_spm_service_t *)tfm_pool_alloc(spm_service_pool); |
kenjiArai | 0:5b88d5760320 | 555 | if (!service) { |
kenjiArai | 0:5b88d5760320 | 556 | tfm_panic(); |
kenjiArai | 0:5b88d5760320 | 557 | } |
kenjiArai | 0:5b88d5760320 | 558 | service->service_db = &g_spm_service_db[i]; |
kenjiArai | 0:5b88d5760320 | 559 | service->partition = partition; |
kenjiArai | 0:5b88d5760320 | 560 | tfm_list_init(&service->handle_list); |
kenjiArai | 0:5b88d5760320 | 561 | tfm_list_add_tail(&partition->service_list, &service->list); |
kenjiArai | 0:5b88d5760320 | 562 | } |
kenjiArai | 0:5b88d5760320 | 563 | |
kenjiArai | 0:5b88d5760320 | 564 | /* |
kenjiArai | 0:5b88d5760320 | 565 | * All threads initialized, start the scheduler. |
kenjiArai | 0:5b88d5760320 | 566 | * |
kenjiArai | 0:5b88d5760320 | 567 | * NOTE: |
kenjiArai | 0:5b88d5760320 | 568 | * Here is the booting privileged thread mode, and will never |
kenjiArai | 0:5b88d5760320 | 569 | * return to this place after scheduler is started. The start |
kenjiArai | 0:5b88d5760320 | 570 | * function has to save current runtime context to act as a |
kenjiArai | 0:5b88d5760320 | 571 | * 'current thread' to avoid repeating NULL 'current thread' |
kenjiArai | 0:5b88d5760320 | 572 | * checking while context switching. This saved context is worthy |
kenjiArai | 0:5b88d5760320 | 573 | * of being saved somewhere if there are potential usage purpose. |
kenjiArai | 0:5b88d5760320 | 574 | * Let's save this context in a local variable 'this_thrd' at |
kenjiArai | 0:5b88d5760320 | 575 | * current since there is no usage for it. |
kenjiArai | 0:5b88d5760320 | 576 | * Also set tfm_nspm_thread_entry as pfn for this thread to |
kenjiArai | 0:5b88d5760320 | 577 | * use in detecting NS/S thread scheduling changes. |
kenjiArai | 0:5b88d5760320 | 578 | */ |
kenjiArai | 0:5b88d5760320 | 579 | this_thrd.pfn = (tfm_thrd_func_t)tfm_nspm_thread_entry; |
kenjiArai | 0:5b88d5760320 | 580 | tfm_thrd_start_scheduler(&this_thrd); |
kenjiArai | 0:5b88d5760320 | 581 | } |
kenjiArai | 0:5b88d5760320 | 582 | |
kenjiArai | 0:5b88d5760320 | 583 | void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb) |
kenjiArai | 0:5b88d5760320 | 584 | { |
kenjiArai | 0:5b88d5760320 | 585 | #if TFM_LVL == 2 |
kenjiArai | 0:5b88d5760320 | 586 | struct spm_partition_desc_t *p_next_partition; |
kenjiArai | 0:5b88d5760320 | 587 | uint32_t is_privileged; |
kenjiArai | 0:5b88d5760320 | 588 | #endif |
kenjiArai | 0:5b88d5760320 | 589 | struct tfm_thrd_ctx *pth_next = tfm_thrd_next_thread(); |
kenjiArai | 0:5b88d5760320 | 590 | struct tfm_thrd_ctx *pth_curr = tfm_thrd_curr_thread(); |
kenjiArai | 0:5b88d5760320 | 591 | |
kenjiArai | 0:5b88d5760320 | 592 | if (pth_curr != pth_next) { |
kenjiArai | 0:5b88d5760320 | 593 | #if TFM_LVL == 2 |
kenjiArai | 0:5b88d5760320 | 594 | p_next_partition = TFM_GET_CONTAINER_PTR(pth_next, |
kenjiArai | 0:5b88d5760320 | 595 | struct spm_partition_desc_t, |
kenjiArai | 0:5b88d5760320 | 596 | sp_thrd); |
kenjiArai | 0:5b88d5760320 | 597 | |
kenjiArai | 0:5b88d5760320 | 598 | if (p_next_partition->static_data.partition_flags & |
kenjiArai | 0:5b88d5760320 | 599 | SPM_PART_FLAG_PSA_ROT) { |
kenjiArai | 0:5b88d5760320 | 600 | is_privileged = TFM_PARTITION_PRIVILEGED_MODE; |
kenjiArai | 0:5b88d5760320 | 601 | } else { |
kenjiArai | 0:5b88d5760320 | 602 | is_privileged = TFM_PARTITION_UNPRIVILEGED_MODE; |
kenjiArai | 0:5b88d5760320 | 603 | } |
kenjiArai | 0:5b88d5760320 | 604 | |
kenjiArai | 0:5b88d5760320 | 605 | tfm_spm_partition_change_privilege(is_privileged); |
kenjiArai | 0:5b88d5760320 | 606 | #endif |
kenjiArai | 0:5b88d5760320 | 607 | /* Increase the secure lock, if we enter secure from non-secure */ |
kenjiArai | 0:5b88d5760320 | 608 | if ((void *)pth_curr->pfn == (void *)tfm_nspm_thread_entry) { |
kenjiArai | 0:5b88d5760320 | 609 | ++tfm_secure_lock; |
kenjiArai | 0:5b88d5760320 | 610 | } |
kenjiArai | 0:5b88d5760320 | 611 | /* Decrease the secure lock, if we return from secure to non-secure */ |
kenjiArai | 0:5b88d5760320 | 612 | if ((void *)pth_next->pfn == (void *)tfm_nspm_thread_entry) { |
kenjiArai | 0:5b88d5760320 | 613 | --tfm_secure_lock; |
kenjiArai | 0:5b88d5760320 | 614 | } |
kenjiArai | 0:5b88d5760320 | 615 | |
kenjiArai | 0:5b88d5760320 | 616 | tfm_thrd_context_switch(ctxb, pth_curr, pth_next); |
kenjiArai | 0:5b88d5760320 | 617 | } |
kenjiArai | 0:5b88d5760320 | 618 | } |