1 /*
2  * Copyright (c) 2017-2022, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "os_wrapper/thread.h"
9 #include "os_wrapper/mutex.h"
10 #include "os_wrapper/semaphore.h"
11 #include "os_wrapper/delay.h"
12 
13 #include "cmsis_os2.h"
14 
15 #include "tfm_nsid_manager.h"
16 #ifdef TFM_NS_MANAGE_NSID
17 #include "tfm_nsid_map_table.h"
18 #endif
19 
20 /* This is an example OS abstraction layer for CMSIS-RTOSv2 */
21 
os_wrapper_thread_new(const char * name,int32_t stack_size,os_wrapper_thread_func func,void * arg,uint32_t priority)22 void *os_wrapper_thread_new(const char *name, int32_t stack_size,
23                             os_wrapper_thread_func func, void *arg,
24                             uint32_t priority)
25 {
26     osThreadAttr_t task_attribs = {
27         .tz_module = ((TZ_ModuleId_t)TFM_DEFAULT_NSID)
28     };
29 
30     /* By default, the thread starts as osThreadDetached */
31     if (stack_size != OS_WRAPPER_DEFAULT_STACK_SIZE) {
32         task_attribs.stack_size = stack_size;
33     }
34     task_attribs.name = name;
35     task_attribs.priority = (osPriority_t) priority;
36 
37 #ifdef TFM_NS_MANAGE_NSID
38     task_attribs.tz_module = (TZ_ModuleId_t)nsid_mgr_get_thread_nsid(name);
39 #endif
40 
41     return (void *)osThreadNew(func, arg, &task_attribs);
42 }
43 
os_wrapper_semaphore_create(uint32_t max_count,uint32_t initial_count,const char * name)44 void *os_wrapper_semaphore_create(uint32_t max_count, uint32_t initial_count,
45                                   const char *name)
46 {
47     osSemaphoreAttr_t sema_attrib = {0};
48 
49     sema_attrib.name = name;
50 
51     return (void *)osSemaphoreNew(max_count, initial_count, &sema_attrib);
52 }
53 
os_wrapper_semaphore_acquire(void * handle,uint32_t timeout)54 uint32_t os_wrapper_semaphore_acquire(void *handle, uint32_t timeout)
55 {
56     osStatus_t status;
57 
58     status = osSemaphoreAcquire((osSemaphoreId_t)handle,
59                                 (timeout == OS_WRAPPER_WAIT_FOREVER) ?
60                                 osWaitForever : timeout);
61     if (status != osOK) {
62         return OS_WRAPPER_ERROR;
63     }
64 
65     return OS_WRAPPER_SUCCESS;
66 }
67 
os_wrapper_semaphore_release(void * handle)68 uint32_t os_wrapper_semaphore_release(void *handle)
69 {
70     osStatus_t status;
71 
72     status = osSemaphoreRelease((osSemaphoreId_t)handle);
73     if (status != osOK) {
74         return OS_WRAPPER_ERROR;
75     }
76 
77     return OS_WRAPPER_SUCCESS;
78 }
79 
os_wrapper_semaphore_delete(void * handle)80 uint32_t os_wrapper_semaphore_delete(void *handle)
81 {
82     osStatus_t status;
83 
84     status = osSemaphoreDelete((osSemaphoreId_t)handle);
85     if (status != osOK) {
86         return OS_WRAPPER_ERROR;
87     }
88 
89     return OS_WRAPPER_SUCCESS;
90 }
91 
os_wrapper_mutex_create(void)92 void *os_wrapper_mutex_create(void)
93 {
94     const osMutexAttr_t attr = {
95         .name = NULL,
96         .attr_bits = osMutexPrioInherit, /* Priority inheritance is recommended
97                                           * to enable if it is supported.
98                                           * For recursive mutex and the ability
99                                           * of auto release when owner being
100                                           * terminated is not required.
101                                           */
102         .cb_mem = NULL,
103         .cb_size = 0U
104     };
105 
106     return (void *)osMutexNew(&attr);
107 }
108 
os_wrapper_mutex_acquire(void * handle,uint32_t timeout)109 uint32_t os_wrapper_mutex_acquire(void *handle, uint32_t timeout)
110 {
111     osStatus_t status = osOK;
112 
113     if (!handle) {
114         return OS_WRAPPER_ERROR;
115     }
116 
117     status = osMutexAcquire((osMutexId_t)handle,
118                             (timeout == OS_WRAPPER_WAIT_FOREVER) ?
119                              osWaitForever : timeout);
120     if (status != osOK) {
121         return OS_WRAPPER_ERROR;
122     }
123 
124     return OS_WRAPPER_SUCCESS;
125 }
126 
os_wrapper_mutex_release(void * handle)127 uint32_t os_wrapper_mutex_release(void *handle)
128 {
129     osStatus_t status = osOK;
130 
131     if (!handle) {
132         return OS_WRAPPER_ERROR;
133     }
134 
135     status = osMutexRelease((osMutexId_t)handle);
136     if (status != osOK) {
137         return OS_WRAPPER_ERROR;
138     }
139 
140     return OS_WRAPPER_SUCCESS;
141 }
142 
os_wrapper_mutex_delete(void * handle)143 uint32_t os_wrapper_mutex_delete(void *handle)
144 {
145     osStatus_t status = osOK;
146 
147     if (!handle) {
148         return OS_WRAPPER_ERROR;
149     }
150 
151     status = osMutexDelete((osMutexId_t)handle);
152     if (status != osOK) {
153         return OS_WRAPPER_ERROR;
154     }
155 
156     return OS_WRAPPER_SUCCESS;
157 }
158 
os_wrapper_thread_get_handle(void)159 void *os_wrapper_thread_get_handle(void)
160 {
161     return (void *)osThreadGetId();
162 }
163 
os_wrapper_thread_get_priority(void * handle,uint32_t * priority)164 uint32_t os_wrapper_thread_get_priority(void *handle, uint32_t *priority)
165 {
166     osPriority_t prio;
167 
168     prio = osThreadGetPriority((osThreadId_t)handle);
169     if (prio == osPriorityError) {
170         return OS_WRAPPER_ERROR;
171     }
172 
173     *priority = (uint32_t)prio;
174 
175     return OS_WRAPPER_SUCCESS;
176 }
177 
os_wrapper_thread_exit(void)178 void os_wrapper_thread_exit(void)
179 {
180     osThreadExit();
181 }
182 
os_wrapper_thread_set_flag(void * handle,uint32_t flags)183 uint32_t os_wrapper_thread_set_flag(void *handle, uint32_t flags)
184 {
185     uint32_t ret;
186 
187     ret = osThreadFlagsSet((osThreadId_t)handle, flags);
188     if (ret & osFlagsError) {
189         return OS_WRAPPER_ERROR;
190     }
191 
192     return OS_WRAPPER_SUCCESS;
193 }
194 
195 /*
196  * According to the description of CMSIS-RTOS v2 Thread Flags,
197  * osThreadFlagsSet() can be called inside Interrupt Service Routine.
198  */
os_wrapper_thread_set_flag_isr(void * handle,uint32_t flags)199 uint32_t os_wrapper_thread_set_flag_isr(void *handle, uint32_t flags)
200 {
201     uint32_t ret;
202 
203     ret = osThreadFlagsSet((osThreadId_t)handle, flags);
204     if (ret & osFlagsError) {
205         return OS_WRAPPER_ERROR;
206     }
207 
208     return OS_WRAPPER_SUCCESS;
209 }
210 
os_wrapper_thread_wait_flag(uint32_t flags,uint32_t timeout)211 uint32_t os_wrapper_thread_wait_flag(uint32_t flags, uint32_t timeout)
212 {
213     uint32_t ret;
214 
215     ret = osThreadFlagsWait(flags, osFlagsWaitAll,
216                             (timeout == OS_WRAPPER_WAIT_FOREVER) ?
217                             osWaitForever : timeout);
218     if (ret & osFlagsError) {
219         return OS_WRAPPER_ERROR;
220     }
221 
222     return OS_WRAPPER_SUCCESS;
223 }
224 
os_wrapper_get_tick(void)225 uint32_t os_wrapper_get_tick(void)
226 {
227     return osKernelGetTickCount();
228 }
229 
os_wrapper_msg_queue_create(size_t msg_size,uint8_t msg_count)230 void *os_wrapper_msg_queue_create(size_t msg_size, uint8_t msg_count)
231 {
232     osMessageQueueId_t mq_id;
233 
234     mq_id = osMessageQueueNew(msg_count, msg_size, NULL);
235 
236     return (void *)mq_id;
237 }
238 
os_wrapper_msg_queue_send(void * mq_handle,const void * msg_ptr)239 int32_t os_wrapper_msg_queue_send(void *mq_handle,
240                                   const void *msg_ptr)
241 {
242     osStatus_t status;
243 
244     status = osMessageQueuePut(mq_handle, msg_ptr, 0, 0);
245     if (status == osOK) {
246         return OS_WRAPPER_SUCCESS;
247     }
248 
249     return OS_WRAPPER_ERROR;
250 }
251 
os_wrapper_msg_queue_receive(void * mq_handle,void * msg_ptr)252 int32_t os_wrapper_msg_queue_receive(void *mq_handle,
253                                      void *msg_ptr)
254 {
255     osStatus_t status;
256 
257     status = osMessageQueueGet(mq_handle, msg_ptr, NULL, osWaitForever);
258     if (status == osOK) {
259         return OS_WRAPPER_SUCCESS;
260     }
261 
262     return OS_WRAPPER_ERROR;
263 }
264 
os_wrapper_delay(uint32_t ticks)265 int32_t os_wrapper_delay(uint32_t ticks)
266 {
267     osStatus_t status;
268 
269     status = osDelay(ticks);
270     if (status == osOK) {
271         return OS_WRAPPER_SUCCESS;
272     }
273 
274     return OS_WRAPPER_ERROR;
275 }
276