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