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