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