1 /*
2 * Copyright (c) 2017 Oticon A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "bs_tracing.h"
7 #include "bs_types.h"
8 #include "bs_utils.h"
9 #include "NRF_HW_model_top.h"
10 #include "bstest_ticker.h"
11 #include "time_machine_if.h"
12 #include "NRF_hw_args.h"
13 #include "NRF_AAR.h"
14 #include "NRF_RNG.h"
15 #include "NRF_TEMP.h"
16 #include "NRF_RTC.h"
17 #include "NRF_AES_ECB.h"
18 #include "NRF_AES_CCM.h"
19 #include "NRF_CLOCK.h"
20 #include "NRF_RADIO.h"
21 #include "NRF_FICR.h"
22 #include "NRF_PPI.h"
23 #include "NRF_TIMER.h"
24 #include "NRF_EGU.h"
25 #include "NRF_NVMC.h"
26 #include "irq_ctrl.h"
27 #include "BLECrypt_if.h"
28 #include "fake_timer.h"
29
nrf_hw_models_free_all()30 void nrf_hw_models_free_all(){
31 BLECrypt_if_free();
32 fake_timer_cleanup();
33 hw_irq_ctrl_cleanup();
34 nrf_clock_clean_up();
35 nrf_rng_clean_up();
36 nrf_temp_clean_up();
37 nrf_rtc_clean_up();
38 nrf_aes_ecb_clean_up();
39 nrf_aes_ccm_clean_up();
40 nrf_aar_clean_up();
41 nrf_radio_clean_up();
42 nrf_ficr_clean_up();
43 nrf_ppi_clean_up();
44 nrf_egu_clean_up();
45 nrfhw_nvmc_uicr_clean_up();
46 nrf_hw_model_timer_clean_up();
47 }
48
49 /*
50 * Run any pre-initialization tasks which needs to be done very early
51 * Like registering command line arguments or dump files
52 */
nrf_hw_pre_init()53 void nrf_hw_pre_init() {
54 nrfhw_nvmc_uicr_pre_init();
55 }
56
57 /*
58 * Initialize all HW models and set registers to defaults
59 */
nrf_hw_initialize(nrf_hw_sub_args_t * args)60 void nrf_hw_initialize(nrf_hw_sub_args_t *args){
61
62 BLECrypt_if_enable_real_encryption(args->useRealAES);
63 fake_timer_init();
64 hw_irq_ctrl_init();
65 nrf_clock_init();
66 nrf_rng_init();
67 nrf_temp_init();
68 nrf_rtc_init();
69 nrf_aes_ecb_init();
70 nrf_aes_ccm_init();
71 nrf_aar_init();
72 nrf_radio_init();
73 nrf_ficr_init();
74 nrf_ppi_init();
75 nrf_egu_init();
76 nrfhw_nvmc_uicr_init();
77 nrf_hw_model_timer_init();
78 nrf_hw_find_next_timer_to_trigger();
79 }
80
81 extern bs_time_t Timer_event_fw_test_ticker;
82 extern bs_time_t Timer_irq_ctrl;
83 extern bs_time_t Timer_RNG;
84 extern bs_time_t Timer_TEMP;
85 extern bs_time_t Timer_NVMC;
86 extern bs_time_t Timer_CLOCK_LF;
87 extern bs_time_t Timer_CLOCK_HF;
88 extern bs_time_t Timer_RTC;
89 extern bs_time_t Timer_TIMERs;
90 extern bs_time_t Timer_RADIO;
91 extern bs_time_t Timer_RADIO_abort_reeval; //This timer should have the lowest priority
92 extern bs_time_t Timer_ECB;
93 extern bs_time_t Timer_AAR;
94 extern bs_time_t Timer_fake_timer;
95 extern bs_time_t Timer_RADIO_bitcounter;
96
97 //The events priorities are as in this enum from top to bottom
98 // (priority == which executes if they have the same timing)
99 typedef enum {
100 fake_timer,
101 fw_test_ticker,
102 irq_ctrl_timer,
103 RNG_timer,
104 TEMP_timer,
105 NVMC_timer,
106 ECB_timer,
107 AAR_timer,
108 CLOCK_LF_timer,
109 CLOCK_HF_timer,
110 RTC_timer,
111 TIMER_timer,
112 RADIO_timer,
113 RADIO_bitcounter,
114 RADIO_abort_reeval_timer,
115 NumberOfNRFHWTimers,
116 None
117 } NRF_HW_next_timer_to_trigger_t;
118 static bs_time_t *Timers[NumberOfNRFHWTimers] = { //Indexed with NRF_HW_next_timer_to_trigger_t
119 &Timer_fake_timer,
120 &Timer_event_fw_test_ticker,
121 &Timer_irq_ctrl,
122 &Timer_RNG,
123 &Timer_TEMP,
124 &Timer_NVMC,
125 &Timer_ECB,
126 &Timer_AAR,
127 &Timer_CLOCK_LF,
128 &Timer_CLOCK_HF,
129 &Timer_RTC,
130 &Timer_TIMERs,
131 &Timer_RADIO,
132 &Timer_RADIO_bitcounter,
133 &Timer_RADIO_abort_reeval //This timer should always be the latest in this list (lowest priority)
134 };
135
136 bs_time_t timer_nrf_main_timer = TIME_NEVER; //This timer is exposed to the top level time_machine which will call us when it is reached
137 static NRF_HW_next_timer_to_trigger_t nrf_hw_next_timer_to_trigger = None;
138
139 /**
140 * Look into all timers and update next_timer_to_trigger* accordingly
141 * To be called each time a "timed process" updates its timer
142 */
nrf_hw_find_next_timer_to_trigger()143 void nrf_hw_find_next_timer_to_trigger(){
144 bs_time_t new_timer = *Timers[0];
145 nrf_hw_next_timer_to_trigger = 0;
146
147 for (uint i = 1; i < NumberOfNRFHWTimers ; i++){
148 if ( new_timer > *Timers[i] ) {
149 new_timer = *Timers[i];
150 nrf_hw_next_timer_to_trigger = i;
151 }
152 }
153 if ( new_timer != timer_nrf_main_timer ){
154 timer_nrf_main_timer = new_timer;
155 tm_find_next_timer_to_trigger();
156 }
157 }
158
nrf_hw_some_timer_reached()159 void nrf_hw_some_timer_reached() {
160
161 switch ( nrf_hw_next_timer_to_trigger ) {
162 case fake_timer:
163 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: fake timer\n");
164 fake_timer_triggered();
165 break;
166 case fw_test_ticker:
167 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: FW test ticker\n");
168 bst_ticker_triggered(timer_nrf_main_timer);
169 break;
170 case irq_ctrl_timer:
171 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: IRQ ctrl timer\n");
172 hw_irq_ctrl_timer_triggered();
173 break;
174 case RNG_timer:
175 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: RNG timer\n");
176 nrf_rng_timer_triggered();
177 break;
178 case TEMP_timer:
179 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: TEMP timer\n");
180 nrf_temp_timer_triggered();
181 break;
182 case NVMC_timer:
183 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: NVMC timer\n");
184 nrfhw_nvmc_timer_triggered();
185 break;
186 case ECB_timer:
187 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: ECB timer\n");
188 nrf_ecb_timer_triggered();
189 break;
190 case AAR_timer:
191 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: AAR timer\n");
192 nrf_aar_timer_triggered();
193 break;
194 case CLOCK_LF_timer:
195 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: CLOCK LF timer\n");
196 nrf_clock_LFTimer_triggered();
197 break;
198 case CLOCK_HF_timer:
199 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: CLOCK HF timer\n");
200 nrf_clock_HFTimer_triggered();
201 break;
202 case RTC_timer:
203 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: RTC timer\n");
204 nrf_rtc_timer_triggered();
205 break;
206 case TIMER_timer:
207 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: TIMERx timer\n");
208 nrf_hw_model_timer_timer_triggered();
209 break;
210 case RADIO_timer:
211 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: RADIO timer\n");
212 nrf_radio_timer_triggered();
213 break;
214 case RADIO_bitcounter:
215 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: RADIO bitcounter timer\n");
216 nrf_radio_bitcounter_timer_triggered();
217 break;
218 case RADIO_abort_reeval_timer:
219 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: RADIO abort reeval timer\n");
220 nrf_radio_timer_abort_reeval_triggered();
221 break;
222 default:
223 bs_trace_error_line("nrf_hw_next_timer_to_trigger corrupted\n");
224 break;
225 }
226 }
227