2 * Copyright (c) 2019 Nordic Semiconductor ASA
4 * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
13 #include "nrf_cc310_platform_defines.h"
14 #include "nrf_cc310_platform_mutex.h"
15 #include "nrf_cc310_platform_abort.h"
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.
21 extern nrf_cc310_platform_abort_apis_t platform_abort_apis;
23 /** @brief Definition of mutex for symmetric cryptography
25 K_MUTEX_DEFINE(sym_mutex_int);
27 /** @brief Definition of mutex for asymmetric cryptography
29 K_MUTEX_DEFINE(asym_mutex_int);
31 /** @brief Definition of mutex for random number generation
33 K_MUTEX_DEFINE(rng_mutex_int);
35 /** @brief Definition of mutex for power mode changes
37 K_MUTEX_DEFINE(power_mutex_int);
39 /** @brief Arbritary number of mutexes the system suppors
41 #define NUM_MUTEXES 64
43 /** @brief Structure definition of the mutex slab
45 struct k_mem_slab mutex_slab;
47 /** @brief Definition of buffer used for the mutex slabs
49 char __aligned(4) mutex_slab_buffer[NUM_MUTEXES * sizeof(struct k_mutex)];
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
55 nrf_cc310_platform_mutex_t sym_mutex =
57 .mutex = &sym_mutex_int,
58 .flags = NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID
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
66 nrf_cc310_platform_mutex_t asym_mutex =
68 .mutex = &asym_mutex_int,
69 .flags = NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID
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
77 nrf_cc310_platform_mutex_t rng_mutex =
79 .mutex = &rng_mutex_int,
80 .flags = NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID
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
88 nrf_cc310_platform_mutex_t power_mutex =
90 .mutex = &power_mutex_int,
91 .flags = NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID
95 /**@brief static function to initialize a mutex
97 static void mutex_init(nrf_cc310_platform_mutex_t *mutex) {
99 struct k_mutex * p_mutex;
101 /* Ensure that the mutex is valid (not NULL) */
103 platform_abort_apis.abort_fn(
104 "mutex_init called with NULL parameter");
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)
114 /* Allocation failed. Abort all operations */
115 platform_abort_apis.abort_fn(
116 "Could not allocate mutex before initializing");
119 memset(mutex->mutex, 0, sizeof(struct k_mutex));
121 /** Set a flag to ensure that mutex is deallocated by the freeing
124 mutex->flags |= NRF_CC310_PLATFORM_MUTEX_MASK_IS_ALLOCATED;
127 p_mutex = (struct k_mutex *)mutex->mutex;
128 k_mutex_init(p_mutex);
130 /* Set the mask to indicate that the mutex is valid */
131 mutex->flags |= NRF_CC310_PLATFORM_MUTEX_MASK_IS_VALID;
135 /** @brief Static function to free a mutex
137 static void mutex_free(nrf_cc310_platform_mutex_t *mutex) {
138 /* Ensure that the mutex is valid (not NULL) */
140 platform_abort_apis.abort_fn(
141 "mutex_init called with NULL parameter");
144 /* Check if we are freeing a mutex that isn't initialized */
145 if (mutex->flags == NRF_CC310_PLATFORM_MUTEX_MASK_INVALID) {
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);
156 memset(mutex->mutex, 0, sizeof(struct k_mutex));
159 /* Reset the mutex to invalid state */
160 mutex->flags = NRF_CC310_PLATFORM_MUTEX_MASK_INVALID;
164 /** @brief Static function to lock a mutex
166 static int32_t mutex_lock(nrf_cc310_platform_mutex_t *mutex) {
168 struct k_mutex * p_mutex;
170 /* Ensure that the mutex param is valid (not NULL) */
172 return NRF_CC310_PLATFORM_ERROR_PARAM_NULL;
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;
180 p_mutex = (struct k_mutex *)mutex->mutex;
182 ret = k_mutex_lock(p_mutex, K_FOREVER);
184 return NRF_CC310_PLATFORM_SUCCESS;
187 return NRF_CC310_PLATFORM_ERROR_MUTEX_FAILED;
192 /** @brief Static function to unlock a mutex
194 static int32_t mutex_unlock(nrf_cc310_platform_mutex_t *mutex) {
195 struct k_mutex * p_mutex;
197 /* Ensure that the mutex param is valid (not NULL) */
199 return NRF_CC310_PLATFORM_ERROR_PARAM_NULL;
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;
207 p_mutex = (struct k_mutex *)mutex->mutex;
209 k_mutex_unlock(p_mutex);
210 return NRF_CC310_PLATFORM_SUCCESS;
214 /**@brief Constant definition of mutex APIs to set in nrf_cc310_platform
216 static const nrf_cc310_platform_mutex_apis_t mutex_apis =
218 .mutex_init_fn = mutex_init,
219 .mutex_free_fn = mutex_free,
220 .mutex_lock_fn = mutex_lock,
221 .mutex_unlock_fn = mutex_unlock
225 /** @brief Constant definition of mutexes to set in nrf_cc310_platform
227 static const nrf_cc310_platform_mutexes_t mutexes =
229 .sym_mutex = &sym_mutex,
230 .asym_mutex = &asym_mutex,
231 .rng_mutex = &rng_mutex,
233 .power_mutex = &power_mutex,
236 /** @brief Function to initialize the nrf_cc310_platform mutex APIs
238 void nrf_cc310_platform_mutex_init(void)
240 k_mem_slab_init(&mutex_slab,
242 sizeof(struct k_mutex),
245 nrf_cc310_platform_set_mutexes(&mutex_apis, &mutexes);