0f37e9bdc25df444d7d6c79b5b7705822bb5bea8
[platform/upstream/connectedhomeip.git] / third_party / openthread / repo / third_party / NordicSemiconductor / libraries / nrf_security / nrf_cc310_plat / src / nrf_cc310_platform_mutex_zephyr.c
1 /**
2  * Copyright (c) 2019 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
5  */
6 #include <stdint.h>
7 #include <stddef.h>
8 #include <string.h>
9
10 #include <zephyr.h>
11 #include <kernel.h>
12
13 #include "nrf_cc310_platform_defines.h"
14 #include "nrf_cc310_platform_mutex.h"
15 #include "nrf_cc310_platform_abort.h"
16
17 /** @brief External reference to the platforms abort APIs
18  *         This is used in case the mutex functions don't
19  *                 provide return values in their APIs.
20  */
21 extern nrf_cc310_platform_abort_apis_t platform_abort_apis;
22
23 /** @brief Definition of mutex for symmetric cryptography
24  */
25 K_MUTEX_DEFINE(sym_mutex_int);
26
27 /** @brief Definition of mutex for asymmetric cryptography
28  */
29 K_MUTEX_DEFINE(asym_mutex_int);
30
31 /** @brief Definition of mutex for random number generation
32 */
33 K_MUTEX_DEFINE(rng_mutex_int);
34
35 /** @brief Definition of mutex for power mode changes
36 */
37 K_MUTEX_DEFINE(power_mutex_int);
38
39 /** @brief Arbritary number of mutexes the system suppors
40  */
41 #define NUM_MUTEXES 64
42
43 /** @brief Structure definition of the mutex slab
44  */
45 struct k_mem_slab mutex_slab;
46
47 /** @brief Definition of buffer used for the mutex slabs
48  */
49 char __aligned(4) mutex_slab_buffer[NUM_MUTEXES * sizeof(struct k_mutex)];
50
51 /**@brief Definition of RTOS-independent symmetric cryptography mutex
52  * with NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID set to indicate that
53  * allocation is unneccesary
54 */
55 nrf_cc310_platform_mutex_t sym_mutex =
56 {
57     .mutex = &sym_mutex_int,
58     .flags = NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID
59 };
60
61
62 /**@brief Definition of RTOS-independent asymmetric cryptography mutex
63  * with NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID set to indicate that
64  * allocation is unneccesary
65 */
66 nrf_cc310_platform_mutex_t asym_mutex =
67 {
68     .mutex = &asym_mutex_int,
69     .flags = NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID
70 };
71
72
73 /**@brief Definition of RTOS-independent random number generation mutex
74  * with NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID set to indicate that
75  * allocation is unneccesary
76 */
77 nrf_cc310_platform_mutex_t rng_mutex =
78 {
79     .mutex = &rng_mutex_int,
80     .flags = NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID
81 };
82
83
84 /**@brief Definition of RTOS-independent power management mutex
85  * with NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID set to indicate that
86  * allocation is unneccesary
87 */
88 nrf_cc310_platform_mutex_t power_mutex =
89 {
90     .mutex = &power_mutex_int,
91     .flags = NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID
92 };
93
94
95 /**@brief static function to initialize a mutex
96  */
97 static void mutex_init(nrf_cc310_platform_mutex_t *mutex) {
98     int ret;
99     struct k_mutex * p_mutex;
100
101     /* Ensure that the mutex is valid (not NULL) */
102     if (mutex == NULL) {
103         platform_abort_apis.abort_fn(
104             "mutex_init called with NULL parameter");
105     }
106
107     /* Allocate if this has not been initialized statically */
108     if (mutex->flags == NRF_CC310_PLATFORM_MUTEX_MASK_INVALID &&
109         mutex->mutex == NULL) {
110         /* allocate some memory for the mute*/
111         ret = k_mem_slab_alloc(&mutex_slab, &mutex->mutex, K_FOREVER);
112         if(ret != 0 || mutex->mutex == NULL)
113         {
114             /* Allocation failed. Abort all operations */
115             platform_abort_apis.abort_fn(
116                 "Could not allocate mutex before initializing");
117         }
118
119         memset(mutex->mutex, 0, sizeof(struct k_mutex));
120
121         /** Set a flag to ensure that mutex is deallocated by the freeing
122          * operation
123          */
124         mutex->flags |= NRF_CC310_PLATFORM_MUTEX_MASK_IS_ALLOCATED;
125     }
126
127     p_mutex = (struct k_mutex *)mutex->mutex;
128     k_mutex_init(p_mutex);
129
130     /* Set the mask to indicate that the mutex is valid */
131     mutex->flags |= NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID;
132 }
133
134
135 /** @brief Static function to free a mutex
136  */
137 static void mutex_free(nrf_cc310_platform_mutex_t *mutex) {
138     /* Ensure that the mutex is valid (not NULL) */
139     if (mutex == NULL) {
140         platform_abort_apis.abort_fn(
141             "mutex_init called with NULL parameter");
142     }
143
144     /* Check if we are freeing a mutex that isn't initialized */
145     if (mutex->flags == NRF_CC310_PLATFORM_MUTEX_MASK_INVALID) {
146         /*Nothing to free*/
147         return;
148     }
149
150     /* Check if the mutex was allocated or being statically defined */
151     if ((mutex->flags & NRF_CC310_PLATFORM_MUTEX_MASK_IS_ALLOCATED) == 0) {
152         k_mem_slab_free(&mutex_slab, mutex->mutex);
153         mutex->mutex = NULL;
154     }
155     else {
156         memset(mutex->mutex, 0, sizeof(struct k_mutex));
157     }
158
159     /* Reset the mutex to invalid state */
160     mutex->flags = NRF_CC310_PLATFORM_MUTEX_MASK_INVALID;
161 }
162
163
164 /** @brief Static function to lock a mutex
165  */
166 static int32_t mutex_lock(nrf_cc310_platform_mutex_t *mutex) {
167     int ret;
168     struct k_mutex * p_mutex;
169
170     /* Ensure that the mutex param is valid (not NULL) */
171     if(mutex == NULL) {
172         return NRF_CC310_PLATFORM_ERROR_PARAM_NULL;
173     }
174
175     /* Ensure that the mutex has been initialized */
176     if (mutex->flags == NRF_CC310_PLATFORM_MUTEX_MASK_INVALID) {
177         return NRF_CC310_PLATFORM_ERROR_MUTEX_NOT_INITIALIZED;
178     }
179
180     p_mutex = (struct k_mutex *)mutex->mutex;
181
182     ret = k_mutex_lock(p_mutex, K_FOREVER);
183     if (ret == 0) {
184         return NRF_CC310_PLATFORM_SUCCESS;
185     }
186     else {
187         return NRF_CC310_PLATFORM_ERROR_MUTEX_FAILED;
188     }
189 }
190
191
192 /** @brief Static function to unlock a mutex
193  */
194 static int32_t mutex_unlock(nrf_cc310_platform_mutex_t *mutex) {
195     struct k_mutex * p_mutex;
196
197     /* Ensure that the mutex param is valid (not NULL) */
198     if(mutex == NULL) {
199         return NRF_CC310_PLATFORM_ERROR_PARAM_NULL;
200     }
201
202     /* Ensure that the mutex has been initialized */
203     if (mutex->flags == NRF_CC310_PLATFORM_MUTEX_MASK_INVALID) {
204         return NRF_CC310_PLATFORM_ERROR_MUTEX_NOT_INITIALIZED;
205     }
206
207     p_mutex = (struct k_mutex *)mutex->mutex;
208
209     k_mutex_unlock(p_mutex);
210     return NRF_CC310_PLATFORM_SUCCESS;
211 }
212
213
214 /**@brief Constant definition of mutex APIs to set in nrf_cc310_platform
215  */
216 static const nrf_cc310_platform_mutex_apis_t mutex_apis =
217 {
218     .mutex_init_fn = mutex_init,
219     .mutex_free_fn = mutex_free,
220     .mutex_lock_fn = mutex_lock,
221     .mutex_unlock_fn = mutex_unlock
222 };
223
224
225 /** @brief Constant definition of mutexes to set in nrf_cc310_platform
226  */
227 static const nrf_cc310_platform_mutexes_t mutexes =
228 {
229     .sym_mutex = &sym_mutex,
230     .asym_mutex = &asym_mutex,
231     .rng_mutex = &rng_mutex,
232     .reserved  = NULL,
233     .power_mutex = &power_mutex,
234 };
235
236 /** @brief Function to initialize the nrf_cc310_platform mutex APIs
237  */
238 void nrf_cc310_platform_mutex_init(void)
239 {
240     k_mem_slab_init(&mutex_slab,
241             mutex_slab_buffer,
242             sizeof(struct k_mutex),
243             NUM_MUTEXES);
244
245     nrf_cc310_platform_set_mutexes(&mutex_apis, &mutexes);
246 }