1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /*
8 * CRACEN - Cryptographic accelerator engine
9 *
10 * This file contains the wrapping logic, for the underlying crypto IPs
11 *
12 * That includes the events and interrupt logic and registers
13 *
14 * Note:
15 * * Only the RNG IP is modeled at this point, so:
16 * * SEED is unused at this point and SEEDVALIND & SEEDLOCK ignored
17 * * PROTECTEDRAMLOCK is ignored
18 */
19
20 #include <stdint.h>
21 #include <stdbool.h>
22 #include <string.h>
23 #include "NHW_common_types.h"
24 #include "NHW_config.h"
25 #include "NHW_peri_types.h"
26 #include "NHW_templates.h"
27 #include "NHW_xPPI.h"
28 #include "NHW_CRACEN_RNG.h"
29 #include "NHW_CRACEN_CM.h"
30 #include "irq_ctrl.h"
31 #include "nsi_tasks.h"
32 #include "nsi_hws_models_if.h"
33 #include "bs_utils.h"
34
35 NRF_CRACEN_Type NRF_CRACEN_regs;
36 NRF_CRACENCORE_Type NRF_CRACENCORE_regs;
37
38 static bs_time_t Timer_CRACEN = TIME_NEVER;
39
40 static struct cracen_wrap_status {
41 bool CRYPTOMASTER_int_line;
42 bool RNG_int_line;
43 bool PKEIKG_int_line;
44 } cracen_w_st;
45
46 /**
47 * Initialize the RNG model
48 */
nhw_CRACEN_init(void)49 static void nhw_CRACEN_init(void) {
50 memset(&NRF_CRACEN_regs, 0, sizeof(NRF_CRACEN_regs));
51 memset(&NRF_CRACENCORE_regs, 0, sizeof(NRF_CRACENCORE_regs));
52 memset(&cracen_w_st, 0, sizeof(cracen_w_st));
53
54 nhw_CRACEN_RNG_init();
55 nhw_CRACEN_CM_init();
56 }
57
58 NSI_TASK(nhw_CRACEN_init, HW_INIT, 100);
59
nhw_CRACEN_eval_interrupt(uint inst)60 static void nhw_CRACEN_eval_interrupt(uint inst) {
61 static bool CRACEN_int_line[NHW_CRACEN_TOTAL_INST]; /* Is the CRACEN currently driving its interrupt line high */
62 /* Mapping of peripheral instance to {int controller instance, int number} */
63 static struct nhw_irq_mapping nhw_cracen_irq_map[NHW_CRACEN_TOTAL_INST] = NHW_CRACEN_INT_MAP;
64 bool new_int_line = false;
65
66 NHW_CHECK_INTERRUPT_si(CRACEN, CRYPTOMASTER, NRF_CRACEN_regs.INTEN)
67 NHW_CHECK_INTERRUPT_si(CRACEN, RNG, NRF_CRACEN_regs.INTEN)
68 NHW_CHECK_INTERRUPT_si(CRACEN, PKEIKG, NRF_CRACEN_regs.INTEN)
69
70 hw_irq_ctrl_toggle_level_irq_line_if(&CRACEN_int_line[inst],
71 new_int_line,
72 &nhw_cracen_irq_map[inst]);
73 }
74
75 #define NHW_CRACEN_SIGNAL_EVENT(event) \
76 void nhw_CRACEN_signal_EVENTS_##event(void) \
77 { \
78 NRF_CRACEN_regs.EVENTS_##event = 1; \
79 nhw_CRACEN_eval_interrupt(0); \
80 }
81
82 #define NHW_CRACEN_TOGGLE_INTLINE(event) \
83 void nhw_CRACEN_toggle_##event##_intline(bool level) { \
84 if (level == cracen_w_st. event##_int_line){ \
85 return; \
86 } \
87 cracen_w_st. event##_int_line = level; \
88 if (level) { \
89 nhw_CRACEN_signal_EVENTS_##event(); \
90 } \
91 }
92
93 #define NHW_CRACEN_REGW_SIDEEFFECTS_EVENT(event) \
94 void nhw_CRACEN_regw_sideeffects_EVENTS_##event(void) { \
95 if (cracen_w_st. event##_int_line) { \
96 NRF_CRACEN_regs.EVENTS_##event = 1; \
97 } \
98 nhw_CRACEN_eval_interrupt(0); \
99 }
100
101 #define NHW_CRACEN_EVENT_LOGIC(event) \
102 NHW_CRACEN_SIGNAL_EVENT(event) \
103 NHW_CRACEN_TOGGLE_INTLINE(event) \
104 NHW_CRACEN_REGW_SIDEEFFECTS_EVENT(event) \
105
106 NHW_CRACEN_EVENT_LOGIC(CRYPTOMASTER)
107 NHW_CRACEN_EVENT_LOGIC(RNG)
108 NHW_CRACEN_EVENT_LOGIC(PKEIKG)
109
110 NHW_SIDEEFFECTS_INTEN(CRACEN, NRF_CRACEN_regs., NRF_CRACEN_regs.INTEN)
111 NHW_SIDEEFFECTS_INTSET(CRACEN, NRF_CRACEN_regs., NRF_CRACEN_regs.INTEN)
112 NHW_SIDEEFFECTS_INTCLR(CRACEN, NRF_CRACEN_regs., NRF_CRACEN_regs.INTEN)
113
114 extern bs_time_t Timer_CRACEN_NDRNG;
115 extern bs_time_t Timer_CRACEN_CM;
116
nhw_CRACEN_update_timer(void)117 void nhw_CRACEN_update_timer(void) {
118
119 bs_time_t new_t = BS_MIN(Timer_CRACEN_NDRNG, Timer_CRACEN_CM);
120 if (Timer_CRACEN != new_t) {
121 Timer_CRACEN = new_t;
122 nsi_hws_find_next_event();
123 }
124 }
125
nhw_CRACEN_timer_triggered(void)126 static void nhw_CRACEN_timer_triggered(void) {
127 bs_time_t timer = Timer_CRACEN;
128 if (timer == Timer_CRACEN_NDRNG) {
129 nhw_CRACEN_RNG_timer_triggered();
130 }
131 if (timer == Timer_CRACEN_CM) {
132 nhw_CRACEN_CM_timer_triggered();
133 }
134 }
135
136 NSI_HW_EVENT(Timer_CRACEN, nhw_CRACEN_timer_triggered, 50);
137