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_RTC.h"
16 #include "NRF_AES_ECB.h"
17 #include "NRF_AES_CCM.h"
18 #include "NRF_CLOCK.h"
19 #include "NRF_RADIO.h"
20 #include "NRF_FICR.h"
21 #include "NRF_PPI.h"
22 #include "NRF_TIMER.h"
23 #include "irq_ctrl.h"
24 #include "BLECrypt_if.h"
25 #include "fake_timer.h"
26
nrf_hw_models_free_all()27 void nrf_hw_models_free_all(){
28 nrf_clock_clean_up();
29 nrf_rng_clean_up();
30 nrf_rtc_clean_up();
31 nrf_aes_ecb_clean_up();
32 nrf_aes_ccm_clean_up();
33 nrf_aar_clean_up();
34 nrf_radio_clean_up();
35 nrf_ficr_clean_up();
36 nrf_ppi_clean_up();
37 nrf_timer_clean_up();
38 }
39
40 /*
41 * Run any pre-initialization tasks which needs to be done very early
42 * Like registering command line arguments or dump files
43 */
nrf_hw_pre_init()44 void nrf_hw_pre_init() {
45
46 }
47
48 /*
49 * Initialize all HW models and set registers to defaults
50 */
nrf_hw_initialize(nrf_hw_sub_args_t * args)51 void nrf_hw_initialize(nrf_hw_sub_args_t *args){
52
53 BLECrypt_if_enable_real_encryption(args->useRealAES);
54 hw_irq_ctrl_init();
55 nrf_clock_init();
56 nrg_rng_init();
57 nrf_rtc_init();
58 nrf_aes_ecb_init();
59 nrf_aes_ccm_init();
60 nrf_aar_init();
61 nrf_radio_init();
62 nrf_ficr_init();
63 nrf_ppi_init();
64 nrf_timer_init();
65 nrf_hw_find_next_timer_to_trigger();
66 }
67
68 extern bs_time_t Timer_event_fw_test_ticker;
69 extern bs_time_t Timer_irq_ctrl;
70 extern bs_time_t Timer_RNG;
71 extern bs_time_t Timer_CLOCK_LF;
72 extern bs_time_t Timer_CLOCK_HF;
73 extern bs_time_t Timer_RTC;
74 extern bs_time_t Timer_TIMERs;
75 extern bs_time_t Timer_RADIO;
76 extern bs_time_t Timer_RADIO_abort_reeval; //This timer should have the lowest priority
77 extern bs_time_t Timer_ECB;
78 extern bs_time_t Timer_AAR;
79 extern bs_time_t Timer_fake_timer;
80 extern bs_time_t Timer_RADIO_bitcounter;
81
82 //The events priorities are as in this enum from top to bottom
83 // (priority == which executes if they have the same timing)
84 typedef enum {
85 fake_timer,
86 fw_test_ticker,
87 irq_ctrl_timer,
88 RNG_timer,
89 ECB_timer,
90 AAR_timer,
91 CLOCK_LF_timer,
92 CLOCK_HF_timer,
93 RTC_timer,
94 TIMER_timer,
95 RADIO_timer,
96 RADIO_bitcounter,
97 RADIO_abort_reeval_timer,
98 NumberOfNRFHWTimers,
99 None
100 } NRF_HW_next_timer_to_trigger_t;
101 static bs_time_t *Timers[NumberOfNRFHWTimers] = { //Indexed with NRF_HW_next_timer_to_trigger_t
102 &Timer_fake_timer,
103 &Timer_event_fw_test_ticker,
104 &Timer_irq_ctrl,
105 &Timer_RNG,
106 &Timer_ECB,
107 &Timer_AAR,
108 &Timer_CLOCK_LF,
109 &Timer_CLOCK_HF,
110 &Timer_RTC,
111 &Timer_TIMERs,
112 &Timer_RADIO,
113 &Timer_RADIO_bitcounter,
114 &Timer_RADIO_abort_reeval //This timer should always be the latest in this list (lowest priority)
115 };
116
117 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
118 static NRF_HW_next_timer_to_trigger_t nrf_hw_next_timer_to_trigger = None;
119
120 /**
121 * Look into all timers and update next_timer_to_trigger* accordingly
122 * To be called each time a "timed process" updates its timer
123 */
nrf_hw_find_next_timer_to_trigger()124 void nrf_hw_find_next_timer_to_trigger(){
125 bs_time_t new_timer = *Timers[0];
126 nrf_hw_next_timer_to_trigger = 0;
127
128 for (uint i = 1; i < NumberOfNRFHWTimers ; i++){
129 if ( new_timer > *Timers[i] ) {
130 new_timer = *Timers[i];
131 nrf_hw_next_timer_to_trigger = i;
132 }
133 }
134 if ( new_timer != timer_nrf_main_timer ){
135 timer_nrf_main_timer = new_timer;
136 tm_find_next_timer_to_trigger();
137 }
138 }
139
nrf_hw_some_timer_reached()140 void nrf_hw_some_timer_reached() {
141
142 switch ( nrf_hw_next_timer_to_trigger ) {
143 case fake_timer:
144 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: fake timer\n");
145 fake_timer_triggered();
146 break;
147 case fw_test_ticker:
148 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: FW test ticker\n");
149 bst_ticker_triggered(timer_nrf_main_timer);
150 break;
151 case irq_ctrl_timer:
152 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: IRQ ctrl timer\n");
153 hw_irq_ctrl_timer_triggered();
154 break;
155 case RNG_timer:
156 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: RNG timer\n");
157 nrf_rng_timer_triggered();
158 break;
159 case ECB_timer:
160 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: ECB timer\n");
161 nrf_ecb_timer_triggered();
162 break;
163 case AAR_timer:
164 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: AAR timer\n");
165 nrf_aar_timer_triggered();
166 break;
167 case CLOCK_LF_timer:
168 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: CLOCK LF timer\n");
169 nrf_clock_LFTimer_triggered();
170 break;
171 case CLOCK_HF_timer:
172 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: CLOCK HF timer\n");
173 nrf_clock_HFTimer_triggered();
174 break;
175 case RTC_timer:
176 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: RTC timer\n");
177 nrf_rtc_timer_triggered();
178 break;
179 case TIMER_timer:
180 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: TIMERx timer\n");
181 nrf_timer_timer_triggered();
182 break;
183 case RADIO_timer:
184 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: RADIO timer\n");
185 nrf_radio_timer_triggered();
186 break;
187 case RADIO_bitcounter:
188 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: RADIO bitcounter timer\n");
189 nrf_radio_bitcounter_timer_triggered();
190 break;
191 case RADIO_abort_reeval_timer:
192 bs_trace_raw_manual_time(8, tm_get_abs_time(),"NRF HW: RADIO abort reeval timer\n");
193 nrf_radio_timer_abort_reeval_triggered();
194 break;
195 default:
196 bs_trace_error_line("nrf_hw_next_timer_to_trigger corrupted\n");
197 break;
198 }
199 }
200