1 /*
2 * Copyright (c) 2018 - 2024, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef NRF_KMU_H__
35 #define NRF_KMU_H__
36
37 #include <nrfx.h>
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /**
44 * @defgroup nrf_kmu_hal KMU HAL
45 * @{
46 * @ingroup nrf_kmu
47 * @brief Hardware access layer for managing the Key Management Unit (KMU) peripheral.
48 */
49
50 #if defined(KMU_INTEN_KEYSLOT_ERROR_Msk) || defined(__NRFX_DOXYGEN__)
51 /** @brief Symbol indicating whether INTEN register is available. */
52 #define NRF_KMU_HAS_INTEN 1
53 #else
54 #define NRF_KMU_HAS_INTEN 0
55 #endif
56
57 #if defined(KMU_TASKS_PROVISION_TASKS_PROVISION_Msk) || defined(__NRFX_DOXYGEN__)
58 /** @brief Symbol indicating whether KMU has PROVISION registers. */
59 #define NRF_KMU_HAS_PROVISION 1
60 #else
61 #define NRF_KMU_HAS_PROVISION 0
62 #endif
63
64 #if defined(KMU_TASKS_REVOKE_TASKS_REVOKE_Msk) || defined(__NRFX_DOXYGEN__)
65 /** @brief Symbol indicating whether KMU has REVOKE registers. */
66 #define NRF_KMU_HAS_REVOKE 1
67 #else
68 #define NRF_KMU_HAS_REVOKE 0
69 #endif
70
71 #if defined(KMU_TASKS_READMETADATA_TASKS_READMETADATA_Msk) || defined(__NRFX_DOXYGEN__)
72 /** @brief Symbol indicating whether KMU has READMETADATA registers. */
73 #define NRF_KMU_HAS_READ_METADATA 1
74 #else
75 #define NRF_KMU_HAS_READ_METADATA 0
76 #endif
77
78 #if defined(KMU_TASKS_PUSHBLOCK_TASKS_PUSHBLOCK_Msk) || defined(__NRFX_DOXYGEN__)
79 /** @brief Symbol indicating whether KMU has PUSHBLOCK registers. */
80 #define NRF_KMU_HAS_PUSH_BLOCK 1
81 #else
82 #define NRF_KMU_HAS_PUSH_BLOCK 0
83 #endif
84
85 #if defined(KMU_SRC_SRC_Msk) || defined(__NRFX_DOXYGEN__)
86 /** @brief Symbol indicating whether KMU has SRC registers. */
87 #define NRF_KMU_HAS_SRC 1
88 #else
89 #define NRF_KMU_HAS_SRC 0
90 #endif
91
92 #if defined(KMU_METADATA_METADATA_Msk) || defined(__NRFX_DOXYGEN__)
93 /** @brief Symbol indicating whether KMU has METADATA registers. */
94 #define NRF_KMU_HAS_METADATA 1
95 #else
96 #define NRF_KMU_HAS_METADATA 0
97 #endif
98
99 /** @brief KMU tasks. */
100 typedef enum
101 {
102 #if NRF_KMU_HAS_PROVISION
103 NRF_KMU_TASK_PROVISION_KEYSLOT = offsetof(NRF_KMU_Type, TASKS_PROVISION), ///< Provision key slot.
104 #endif
105 #if defined(KMU_TASKS_PUSH_KEYSLOT_TASKS_PUSH_KEYSLOT_Msk) || defined(__NRFX_DOXYGEN__)
106 NRF_KMU_TASK_PUSH_KEYSLOT = offsetof(NRF_KMU_Type, TASKS_PUSH_KEYSLOT), ///< Push a key slot over secure APB.
107 #else
108 NRF_KMU_TASK_PUSH_KEYSLOT = offsetof(NRF_KMU_Type, TASKS_PUSH), ///< Push key slot.
109 #endif
110 #if NRF_KMU_HAS_REVOKE
111 NRF_KMU_TASK_REVOKE_KEYSLOT = offsetof(NRF_KMU_Type, TASKS_REVOKE), ///< Revoke key slot.
112 #endif
113 #if NRF_KMU_HAS_READ_METADATA
114 NRF_KMU_TASK_READ_METADATA = offsetof(NRF_KMU_Type, TASKS_READMETADATA), ///< Read key slot metedata into METADATA register.
115 #endif
116 #if NRF_KMU_HAS_PUSH_BLOCK
117 NRF_KMU_TASK_PUSH_BLOCK = offsetof(NRF_KMU_Type, TASKS_PUSHBLOCK), ///< Block the PUSH operation of key slot, preventing the key slot being PUSH until next reset.
118 #endif
119 } nrf_kmu_task_t;
120
121 /** @brief KMU events. */
122 typedef enum
123 {
124 #if NRF_KMU_HAS_PROVISION
125 NRF_KMU_EVENT_EVENTS_PROVISIONED = offsetof(NRF_KMU_Type, EVENTS_PROVISIONED), ///< Key slot successfully provisioned.
126 #endif
127
128 #if defined(KMU_EVENTS_KEYSLOT_PUSHED_EVENTS_KEYSLOT_PUSHED_Msk) || defined(__NRFX_DOXYGEN__)
129 NRF_KMU_EVENT_KEYSLOT_PUSHED = offsetof(NRF_KMU_Type, EVENTS_KEYSLOT_PUSHED), ///< Key successfully pushed over secure APB.
130 #else
131 NRF_KMU_EVENT_KEYSLOT_PUSHED = offsetof(NRF_KMU_Type, EVENTS_PUSHED), ///< Key successfully pushed over secure APB.
132 #endif
133
134 #if defined(KMU_EVENTS_KEYSLOT_REVOKED_EVENTS_KEYSLOT_REVOKED_Msk) || defined(__NRFX_DOXYGEN__)
135 NRF_KMU_EVENT_KEYSLOT_REVOKED = offsetof(NRF_KMU_Type, EVENTS_KEYSLOT_REVOKED), ///< Key has been revoked and cannot be tasked for selection.
136 #else
137 NRF_KMU_EVENT_KEYSLOT_REVOKED = offsetof(NRF_KMU_Type, EVENTS_REVOKED), ///< Key has been revoked and cannot be tasked for selection.
138 #endif
139
140 #if defined(KMU_EVENTS_KEYSLOT_ERROR_EVENTS_KEYSLOT_ERROR_Msk) || defined(__NRFX_DOXYGEN__)
141 NRF_KMU_EVENT_KEYSLOT_ERROR = offsetof(NRF_KMU_Type, EVENTS_KEYSLOT_ERROR), ///< No key slot selected or no destination address defined or error during push mechanism.
142 #else
143 NRF_KMU_EVENT_KEYSLOT_ERROR = offsetof(NRF_KMU_Type, EVENTS_ERROR), ///< No key slot selected or no destination address defined or error during push mechanism.
144 #endif
145
146 #if NRF_KMU_HAS_READ_METADATA
147 NRF_KMU_EVENT_EVENTS_EVENTS_METADATA_READ = offsetof(NRF_KMU_Type, EVENTS_METADATAREAD), ///< Key slot metedata has been read into METADATA register.
148 #endif
149
150 #if NRF_KMU_HAS_PUSH_BLOCK
151 NRF_KMU_EVENT_EVENTS_EVENTS_PUSHBLOCKED = offsetof(NRF_KMU_Type, EVENTS_PUSHBLOCKED), ///< The PUSHBLOCK operation was succesful.
152 #endif
153 } nrf_kmu_event_t;
154
155 #if NRF_KMU_HAS_INTEN
156 /** @brief KMU interrupts. */
157 typedef enum
158 {
159 NRF_KMU_INT_PUSHED_MASK = KMU_INTEN_KEYSLOT_PUSHED_Msk, ///< Interrupt on KEYSLOT_PUSHED event.
160 NRF_KMU_INT_REVOKED_MASK = KMU_INTEN_KEYSLOT_REVOKED_Msk, ///< Interrupt on KEYSLOT_REVOKED event.
161 NRF_KMU_INT_ERROR_MASK = KMU_INTEN_KEYSLOT_ERROR_Msk ///< Interrupt on KEYSLOT_ERROR event.
162 } nrf_kmu_int_mask_t;
163 #endif
164
165 /** @brief KMU operation status. */
166 typedef enum
167 {
168 #if defined(KMU_STATUS_BLOCKED_Msk) || defined(__NRFX_DOXYGEN__)
169 NRF_KMU_STATUS_BLOCKED_MASK = KMU_STATUS_BLOCKED_Msk, ///< Access violation detected and blocked.
170 #endif
171 #if defined(KMU_STATUS_SELECTED_Msk) || defined(__NRFX_DOXYGEN__)
172 NRF_KMU_STATUS_SELECTED_MASK = KMU_STATUS_SELECTED_Msk, ///< Key slot ID successfully selected by KMU.
173 #endif
174 #if defined(KMU_STATUS_STATUS_Msk) || defined(__NRFX_DOXYGEN__)
175 NRF_KMU_STATUS_READY = KMU_STATUS_STATUS_Ready, ///< KMU is ready for a new operation.
176 NRF_KMU_STATUS_BUSY = KMU_STATUS_STATUS_Busy, ///< KMU is busy, an operation is in progress.
177 #endif
178 } nrf_kmu_status_t;
179
180 /**
181 * @brief Function for activating a specific KMU task.
182 *
183 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
184 * @param[in] task Task to be activated.
185 */
186 NRF_STATIC_INLINE void nrf_kmu_task_trigger(NRF_KMU_Type * p_reg, nrf_kmu_task_t task);
187
188 /**
189 * @brief Function for getting the address of a specific KMU task register.
190 *
191 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
192 * @param[in] task Requested task.
193 *
194 * @return Address of the specified task register.
195 */
196 NRF_STATIC_INLINE uint32_t nrf_kmu_task_address_get(NRF_KMU_Type const * p_reg,
197 nrf_kmu_task_t task);
198
199 /**
200 * @brief Function for clearing a specific KMU event.
201 *
202 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
203 * @param[in] event Event to clear.
204 */
205 NRF_STATIC_INLINE void nrf_kmu_event_clear(NRF_KMU_Type * p_reg, nrf_kmu_event_t event);
206
207 /**
208 * @brief Function for retrieving the state of the KMU event.
209 *
210 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
211 * @param[in] event Event to be checked.
212 *
213 * @retval true The event has been generated.
214 * @retval false The event has not been generated.
215 */
216 NRF_STATIC_INLINE bool nrf_kmu_event_check(NRF_KMU_Type const * p_reg, nrf_kmu_event_t event);
217
218 /**
219 * @brief Function for getting the address of a specific KMU event register.
220 *
221 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
222 * @param[in] event Requested event.
223 *
224 * @return Address of the specified event register.
225 */
226 NRF_STATIC_INLINE uint32_t nrf_kmu_event_address_get(NRF_KMU_Type const * p_reg,
227 nrf_kmu_event_t event);
228
229 #if NRF_KMU_HAS_INTEN
230 /**
231 * @brief Function for enabling specified interrupts.
232 *
233 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
234 * @param[in] mask Mask of interrupts to be enabled.
235 * Use @ref nrf_kmu_int_mask_t values for bit masking.
236 */
237 NRF_STATIC_INLINE void nrf_kmu_int_enable(NRF_KMU_Type * p_reg, uint32_t mask);
238
239 /**
240 * @brief Function for disabling specified interrupts.
241 *
242 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
243 * @param[in] mask Mask of interrupts to be disabled.
244 * Use @ref nrf_kmu_int_mask_t values for bit masking.
245 */
246 NRF_STATIC_INLINE void nrf_kmu_int_disable(NRF_KMU_Type * p_reg, uint32_t mask);
247
248 /**
249 * @brief Function for checking if the specified interrupts are enabled.
250 *
251 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
252 * @param[in] mask Mask of interrupts to be checked.
253 * Use @ref nrf_kmu_int_mask_t values for bit masking.
254 *
255 * @return Mask of enabled interrupts.
256 */
257 NRF_STATIC_INLINE uint32_t nrf_kmu_int_enable_check(NRF_KMU_Type const * p_reg, uint32_t mask);
258
259 /**
260 * @brief Function for retrieving the state of pending interrupts.
261 *
262 * @note States of pending interrupt are saved as a bitmask.
263 * One set at particular position means that interrupt for event is pending.
264 *
265 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
266 *
267 * @return Bitmask with information about pending interrupts.
268 * Use @ref nrf_kmu_int_mask_t values for bit masking.
269 */
270 NRF_STATIC_INLINE uint32_t nrf_kmu_intpend_get(NRF_KMU_Type const * p_reg);
271 #endif // NRF_KMU_HAS_INTEN
272
273 /**
274 * @brief Function for getting status bits of the KMU operation.
275 *
276 * Please use @ref nrf_kmu_status_t to check operations status.
277 *
278 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
279 *
280 * @return Operation status.
281 */
282 NRF_STATIC_INLINE uint32_t nrf_kmu_status_get(NRF_KMU_Type const * p_reg);
283
284 /**
285 * @brief Function for selecting the key slot ID.
286 *
287 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
288 * @param[in] keyslot_id Key slot ID to be read over AHB or pushed over
289 * secure APB when TASKS_PUSH_KEYSLOT is started.
290 */
291 NRF_STATIC_INLINE void nrf_kmu_keyslot_set(NRF_KMU_Type * p_reg, uint8_t keyslot_id);
292
293 /**
294 * @brief Function for getting the key slot ID.
295 *
296 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
297 *
298 * @return Key slot ID.
299 */
300 NRF_STATIC_INLINE uint8_t nrf_kmu_keyslot_get(NRF_KMU_Type const * p_reg);
301
302 #if NRF_KMU_HAS_SRC
303 /**
304 * @brief Function for setting the source address for provisioning.
305 *
306 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
307 * @param[in] src Source address to be set.
308 */
309 NRF_STATIC_INLINE void nrf_kmu_src_set(NRF_KMU_Type * p_reg, uint32_t src);
310
311 /**
312 * @brief Function for getting the source address for provisioning.
313 *
314 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
315 *
316 * @return Source address.
317 */
318 NRF_STATIC_INLINE uint32_t nrf_kmu_src_get(NRF_KMU_Type const * p_reg);
319 #endif // NRF_KMU_HAS_SRC
320
321 #if NRF_KMU_HAS_METADATA
322 /**
323 * @brief Function for setting the key slot metadata.
324 *
325 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
326 * @param[in] metdata Key slot metadata.
327 */
328 NRF_STATIC_INLINE void nrf_kmu_metadata_set(NRF_KMU_Type * p_reg, uint32_t metdata);
329
330 /**
331 * @brief Function for getting the key slot metadata.
332 *
333 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
334 *
335 * @return Key slot metadata.
336 */
337 NRF_STATIC_INLINE uint32_t nrf_kmu_metadata_get(NRF_KMU_Type const * p_reg);
338 #endif // NRF_KMU_HAS_METADATA
339
340 #ifndef NRF_DECLARE_ONLY
341
nrf_kmu_task_trigger(NRF_KMU_Type * p_reg,nrf_kmu_task_t task)342 NRF_STATIC_INLINE void nrf_kmu_task_trigger(NRF_KMU_Type * p_reg, nrf_kmu_task_t task)
343 {
344 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
345 }
346
nrf_kmu_task_address_get(NRF_KMU_Type const * p_reg,nrf_kmu_task_t task)347 NRF_STATIC_INLINE uint32_t nrf_kmu_task_address_get(NRF_KMU_Type const * p_reg,
348 nrf_kmu_task_t task)
349 {
350 return ((uint32_t)p_reg + (uint32_t)task);
351 }
352
nrf_kmu_event_clear(NRF_KMU_Type * p_reg,nrf_kmu_event_t event)353 NRF_STATIC_INLINE void nrf_kmu_event_clear(NRF_KMU_Type * p_reg, nrf_kmu_event_t event)
354 {
355 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
356 nrf_event_readback((uint8_t *)p_reg + (uint32_t)event);
357 }
358
nrf_kmu_event_check(NRF_KMU_Type const * p_reg,nrf_kmu_event_t event)359 NRF_STATIC_INLINE bool nrf_kmu_event_check(NRF_KMU_Type const * p_reg, nrf_kmu_event_t event)
360 {
361 return nrf_event_check(p_reg, event);
362 }
363
nrf_kmu_event_address_get(NRF_KMU_Type const * p_reg,nrf_kmu_event_t event)364 NRF_STATIC_INLINE uint32_t nrf_kmu_event_address_get(NRF_KMU_Type const * p_reg,
365 nrf_kmu_event_t event)
366 {
367 return ((uint32_t)p_reg + (uint32_t)event);
368 }
369
370 #if NRF_KMU_HAS_INTEN
nrf_kmu_int_enable(NRF_KMU_Type * p_reg,uint32_t mask)371 NRF_STATIC_INLINE void nrf_kmu_int_enable(NRF_KMU_Type * p_reg, uint32_t mask)
372 {
373 p_reg->INTENSET = mask;
374 }
375
nrf_kmu_int_disable(NRF_KMU_Type * p_reg,uint32_t mask)376 NRF_STATIC_INLINE void nrf_kmu_int_disable(NRF_KMU_Type * p_reg, uint32_t mask)
377 {
378 p_reg->INTENCLR = mask;
379 }
380
nrf_kmu_int_enable_check(NRF_KMU_Type const * p_reg,uint32_t mask)381 NRF_STATIC_INLINE uint32_t nrf_kmu_int_enable_check(NRF_KMU_Type const * p_reg, uint32_t mask)
382 {
383 return p_reg->INTENSET & mask;
384 }
385
nrf_kmu_intpend_get(NRF_KMU_Type const * p_reg)386 NRF_STATIC_INLINE uint32_t nrf_kmu_intpend_get(NRF_KMU_Type const * p_reg)
387 {
388 return p_reg->INTPEND;
389 }
390 #endif // NRF_KMU_HAS_INTEN
391
nrf_kmu_status_get(NRF_KMU_Type const * p_reg)392 NRF_STATIC_INLINE uint32_t nrf_kmu_status_get(NRF_KMU_Type const * p_reg)
393 {
394 return p_reg->STATUS;
395 }
396
nrf_kmu_keyslot_set(NRF_KMU_Type * p_reg,uint8_t keyslot_id)397 NRF_STATIC_INLINE void nrf_kmu_keyslot_set(NRF_KMU_Type * p_reg, uint8_t keyslot_id)
398 {
399 #if defined(KMU_SELECTKEYSLOT_ID_Msk)
400 p_reg->SELECTKEYSLOT = (uint32_t)keyslot_id;
401 #elif defined(KMU_KEYSLOT_ID_Msk)
402 p_reg->KEYSLOT = (uint32_t)keyslot_id;
403 #else
404 #error "Unsupported"
405 #endif
406 }
407
nrf_kmu_keyslot_get(NRF_KMU_Type const * p_reg)408 NRF_STATIC_INLINE uint8_t nrf_kmu_keyslot_get(NRF_KMU_Type const * p_reg)
409 {
410 #if defined(KMU_SELECTKEYSLOT_ID_Msk)
411 return (uint8_t)p_reg->SELECTKEYSLOT;
412 #elif defined(KMU_KEYSLOT_ID_Msk)
413 return (uint8_t)p_reg->KEYSLOT;
414 #else
415 #error "Unsupported"
416 #endif
417 }
418
419 #if NRF_KMU_HAS_SRC
nrf_kmu_src_set(NRF_KMU_Type * p_reg,uint32_t src)420 NRF_STATIC_INLINE void nrf_kmu_src_set(NRF_KMU_Type * p_reg, uint32_t src)
421 {
422 p_reg->SRC = src;
423 }
424
nrf_kmu_src_get(NRF_KMU_Type const * p_reg)425 NRF_STATIC_INLINE uint32_t nrf_kmu_src_get(NRF_KMU_Type const * p_reg)
426 {
427 return p_reg->SRC;
428 }
429 #endif // NRF_KMU_HAS_SRC
430
431 #if NRF_KMU_HAS_METADATA
nrf_kmu_metadata_set(NRF_KMU_Type * p_reg,uint32_t metdata)432 NRF_STATIC_INLINE void nrf_kmu_metadata_set(NRF_KMU_Type * p_reg, uint32_t metdata)
433 {
434 p_reg->METADATA = metdata;
435 }
436
nrf_kmu_metadata_get(NRF_KMU_Type const * p_reg)437 NRF_STATIC_INLINE uint32_t nrf_kmu_metadata_get(NRF_KMU_Type const * p_reg)
438 {
439 return p_reg->METADATA;
440 }
441 #endif // NRF_KMU_HAS_METADATA
442
443 #endif // NRF_DECLARE_ONLY
444
445 /** @} */
446
447 #ifdef __cplusplus
448 }
449 #endif
450
451 #endif // NRF_KMU_H__
452