Mistake on this page?
Report an issue in GitHub or email us
spm_internal.h
1 /* Copyright (c) 2017-2018 ARM Limited
2  *
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef SPM_INTERNAL_H
19 #define SPM_INTERNAL_H
20 
21 #include <stdbool.h>
22 #include "cmsis_os2.h"
23 #include "cmsis.h"
24 #include "psa_defs.h"
25 #include "spm_messages.h"
26 #include "spm_panic.h"
27 #include "handles_manager.h"
28 #include "cmsis_compiler.h"
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 #define SPM_COMPLETION_SEM_MAX_COUNT (1UL) /* Maximum number of available tokens for a completion semaphore. */
35 #define SPM_COMPLETION_SEM_INITIAL_COUNT (0UL) /* Initial number of available tokens for a completion semaphore. */
36 
37 #define PSA_MMIO_PERM_READ_ONLY (0x000000001)
38 #define PSA_MMIO_PERM_READ_WRITE (0x000000003)
39 
40 #define PSA_RESERVED_ERROR_MIN (INT32_MIN + 1)
41 #define PSA_RESERVED_ERROR_MAX (INT32_MIN + 127)
42 
43 #define SPM_CHANNEL_STATE_INVALID (0x01)
44 #define SPM_CHANNEL_STATE_CONNECTING (0x02)
45 #define SPM_CHANNEL_STATE_IDLE (0x03)
46 #define SPM_CHANNEL_STATE_PENDING (0x04)
47 #define SPM_CHANNEL_STATE_ACTIVE (0x05)
48 
49 #define MEM_PARTITIONS_ALL (0) /* A constant to use to retrieve the memory regions for all the partitions at once. */
50 
51 #define SPM_CMSIS_RTOS_ERROR_BIT_MSK (0x80000000)
52 
53 #ifndef TRUE
54 #define TRUE (1)
55 #endif
56 
57 #ifndef FALSE
58 #define FALSE (0)
59 #endif
60 
61 struct spm_partition;
62 struct spm_ipc_channel;
63 
64 /*
65  * Structure to describe MMIO region along with owning partition.
66  */
67 typedef struct mem_region {
68  const uint32_t base;
69  const uint32_t size;
70  const uint32_t permission;
71  const int32_t partition_id;
72 } mem_region_t;
73 
74 typedef union spm_iovec {
75  psa_invec in;
76  psa_outvec out;
77 } spm_iovec_t;
78 
79 /*
80  * IRQ signal mapper definition.
81  * The function will not return on invalid signal.
82  */
83 typedef IRQn_Type(*spm_signal_to_irq_mapper_t)(uint32_t);
84 
85 /*
86  * Structure to aggregate channels queue in a Root of Trust Service.
87  */
88 typedef struct spm_channel_linked_list {
89  struct spm_ipc_channel *head; /* List's first object*/
90  struct spm_ipc_channel *tail; /* List's last object*/
92 
93 /*
94  * Structure containing resources and attributes of a Root of Trust Service.
95  */
96 typedef struct spm_rot_service {
97  const uint32_t sid; /* The Root of Trust Service ID.*/
98  const uint32_t mask; /* The signal for this Root of Trust Service*/
99  struct spm_partition *partition; /* Pointer to the Partition which the Root of Trust Service belongs to.*/
100  const uint32_t min_version; /* Minor version of the Root of Trust Service interface.*/
101  const uint32_t min_version_policy; /* Minor version policy of the Root of Trust Service.*/
102  const bool allow_nspe; /* Whether to allow non-secure clients to connect to the Root of Trust Service.*/
103  spm_channel_linked_list_t queue; /* Queue of channels holding ROT_SRV operations waiting to be served. */
105 
106 /*
107  * Structure containing Partition->RoT-Service channel information.
108  */
109 typedef struct spm_ipc_channel {
110  struct spm_partition *src_partition; /* Pointer to the Partition which connects to the Root of Trust Service.*/
111  spm_rot_service_t *dst_rot_service; /* Pointer to the connected Root of Trust Service.*/
112  void *rhandle; /* Reverse handle to be used for this channel.*/
113  void *msg_ptr; /* Message data sent from user. */
114  struct spm_ipc_channel *next; /* Next channel in the chain.*/
115  uint8_t msg_type; /* The message type.*/
116  uint8_t state; /* The current processing state of the channel.*/
117  uint8_t is_dropped; /* Indicates whether the channel has been dropped by the partition.*/
119 
120 /*
121  * Structure containing the currently active message for a Root of Trust Service.
122  */
123 typedef struct spm_active_msg {
124  spm_ipc_channel_t *channel; /* Pointer to the channel delivering this message.*/
125  spm_iovec_t iovecs[PSA_MAX_IOVEC]; /* IOvecs sent for message and response.*/
126  uint8_t out_index; /* First index of outvecs in iovecs*/
128 
129 /*
130  * Structure containing resources and attributes of a secure partition.
131  */
132 typedef struct spm_partition {
133  const int32_t partition_id; /* The Partition ID.*/
134  osThreadId_t thread_id; /* Thread ID of the Partition thread.*/
135  const uint32_t flags; /* Mask of all the signals the partition supports.*/
136  spm_rot_service_t *rot_services; /* Array of the Partition's Root of Trust Services.*/
137  const uint32_t rot_services_count; /* Number of the Partition's Root of Trust Services.*/
138  const uint32_t *extern_sids; /* Array of Root of Trust Service IDs that the partition can connect to.*/
139  const uint32_t extern_sids_count; /* Number of Root of Trust Services which the partition can connect to.*/
140  osMutexId_t mutex; /* Mutex for all rot_service's queues operations. */
141  spm_signal_to_irq_mapper_t irq_mapper; /* a function which maps signal to irq number*/
143 
144 /*
145  * Structure containing the SPM internal data.
146  */
147 typedef struct spm_db {
148  spm_partition_t *partitions; /* Array of all the Secure Partitions in the system.*/
149  uint32_t partition_count; /* Number of Secure Partitions in the system.*/
150  psa_handle_manager_t channels_handle_mgr;
151  psa_handle_manager_t messages_handle_mgr;
152  osMemoryPoolId_t channel_mem_pool; /* Channel memory pool identifier.*/
153  osMemoryPoolId_t active_messages_mem_pool; /* Channel memory pool identifier.*/
154 } spm_db_t;
155 
156 /*
157  * Returns a pointer to the currently active secure partition or NULL in case called from NSPE.
158  */
159 spm_partition_t *get_active_partition(void);
160 
161 /*
162  * Return an array of memory regions used by a given partition.
163  *
164  * @param[in] partition_id - a partition ID to find memory regions for, if MEM_PARTITIONS_ALL then
165  * memory regions for all the partitions are returned
166  * @param[out] region_count - will be set to the number of memory regions returned
167  */
168 const mem_region_t *get_mem_regions(int32_t partition_id, uint32_t *region_count);
169 
170 // Platform dependent APIs
171 
172 /*
173  * Validates that a memory block accessible from a specific partition
174  *
175  * @param[in] ptr - Pointer to the beggining of the memory block.
176  * @param[in] size - Size of the memory block in bytes.
177  * @param[in] accessing_partition - Which partition is trying to access the memory.
178  * @return `true` if the entire memory block is accessable from given partition.
179  */
180 bool is_buffer_accessible(const void *ptr, size_t size, spm_partition_t *accessing_partition);
181 
182 /**
183  * Alerts NSPE that a proccess (connect or call) has ended.
184  *
185  * @param[in] completion_sem_id - semaphore id in NSPE.
186  */
187 void nspe_done(osSemaphoreId_t completion_sem_id);
188 
189 /*
190  * Validates parameters sent from caller and queues a connect message on the correct ROT_SRV.
191  *
192  * @param[in] sid - desired RoT service ID
193  * @param[in] msg - pointer to connect message struct
194  */
195 void psa_connect_async(uint32_t sid, spm_pending_connect_msg_t *msg);
196 
197 /*
198  * Validates parameters sent from caller and queues a call message on the correct ROT_SRV.
199  *
200  * @param[in] handle - channel handle for the connection
201  * @param[in] msg - pointer to call message struct
202  */
203 void psa_call_async(psa_handle_t handle, spm_pending_call_msg_t *msg);
204 
205 /*
206  * Validates parameters sent from caller and queues a disconnect message on the correct ROT_SRV.
207  *
208  * @param[in] handle - handle of channel to close
209  * @param[in] msg - pointer to close message struct
210  */
211 void psa_close_async(psa_handle_t handle, spm_pending_close_msg_t *msg);
212 
213 
214 /*
215  * Validates IOvecs.
216  *
217  * @param[in] in_vec - psa_invec array
218  * @param[in] in_len - number of elements in in_vec
219  * @param[in] out_vec - psa_outvec array
220  * @param[in] out_len - number of elements in out_vec
221 */
222 void validate_iovec(
223  const void *in_vec,
224  const uint32_t in_len,
225  const void *out_vec,
226  const uint32_t out_len
227 );
228 
229 /*
230  * Assert and modify PSA IPC channel state machine state
231  *
232  * @param[in,out] current_state - current state
233  * @param[in] expected_state - expected state
234  * @param[in] new_state - new state
235 */
236 void channel_state_switch(uint8_t *current_state, uint8_t expected_state, uint8_t new_state);
237 
238 /*
239  * Assert PSA IPC channel state machine state
240  *
241  * @param[in] current_state - current state
242  * @param[in] expected_state - expected state
243 */
244 void channel_state_assert(const uint8_t *current_state, uint8_t expected_state);
245 
246 #ifdef __cplusplus
247 }
248 #endif
249 
250 #endif // SPM_INTERNAL_H
Structure which describes a scatter-gather output buffer.
Definition: client.h:54
Structure that describes a scatter-gather input buffer.
Definition: client.h:48
#define PSA_MAX_IOVEC
Maximum number of psa_invec and psa_outvec structures allowed for psa_call().
Definition: psa_defs.h:54
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.