16
16
17
17
#include "pico/binary_info.h"
18
18
19
+ #include "hardware/clocks.h"
20
+ #include "hardware/xosc.h"
21
+ #include "hardware/structs/rosc.h"
22
+
19
23
#include "config.h"
20
24
21
25
extern uint32_t rstate_sha [4 ];
@@ -145,6 +149,125 @@ void init_rstate() {
145
149
// No need to wait for SHA, as we polled the EHR one extra time, which
146
150
// takes longer than the SHA.
147
151
for (i = 0 ;i < 4 ;i ++ ) rstate_sha [i ]= sha256 -> sum [i ];
152
+
153
+ rosc_hw -> random = rstate_sha [0 ];
154
+ }
155
+
156
+ // These just have to be higher than the actual frequency, to prevent overclocking unused peripherals
157
+ #define ROSC_HZ 300*MHZ
158
+ #define OTHER_CLK_DIV 30
159
+
160
+ void runtime_init_clocks (void ) {
161
+ // Disable resus that may be enabled from previous software
162
+ clocks_hw -> resus .ctrl = 0 ;
163
+
164
+ bi_decl (bi_ptr_int32 (0 , 0 , rosc_div , 2 )); // default divider 2
165
+ bi_decl (bi_ptr_int32 (0 , 0 , rosc_drive , 0x0000 )); // default drives of 0
166
+ bi_decl (bi_ptr_int32 (0 , 0 , xosc_mhz , 12 )); // xosc freq in MHz
167
+ bi_decl (bi_ptr_int32 (0 , 0 , clk_mhz , 150 )); // xosc freq in MHz
168
+
169
+ // Bump up ROSC speed to ~90MHz
170
+ rosc_hw -> freqa = 0 ; // reset the drive strengths
171
+ rosc_hw -> div = rosc_div | ROSC_DIV_VALUE_PASS ; // set divider
172
+ // Increment the freqency range one step at a time - this is safe provided the current config is not TOOHIGH
173
+ // because ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM | ROSC_CTRL_FREQ_RANGE_VALUE_HIGH == ROSC_CTRL_FREQ_RANGE_VALUE_HIGH
174
+ static_assert (ROSC_CTRL_FREQ_RANGE_VALUE_LOW | ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM == ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM );
175
+ static_assert (ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM | ROSC_CTRL_FREQ_RANGE_VALUE_HIGH == ROSC_CTRL_FREQ_RANGE_VALUE_HIGH );
176
+ hw_set_bits (& rosc_hw -> ctrl , ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM );
177
+ hw_set_bits (& rosc_hw -> ctrl , ROSC_CTRL_FREQ_RANGE_VALUE_HIGH );
178
+
179
+ // Enable rosc randomisation
180
+ rosc_hw -> freqa = (ROSC_FREQA_PASSWD_VALUE_PASS << ROSC_FREQA_PASSWD_LSB ) |
181
+ rosc_drive | ROSC_FREQA_DS1_RANDOM_BITS | ROSC_FREQA_DS0_RANDOM_BITS ; // enable randomisation
182
+
183
+ // Not used with FREQ_RANGE_VALUE_HIGH, but should still be set
184
+ rosc_hw -> freqb = (ROSC_FREQB_PASSWD_VALUE_PASS << ROSC_FREQB_PASSWD_LSB ) |
185
+ rosc_drive ;
186
+
187
+ // Calibrate ROSC frequency if XOSC present - otherwise just configure
188
+ uint32_t rosc_freq_mhz = 0 ;
189
+ if (xosc_mhz ) {
190
+ xosc_init ();
191
+ // CLK_REF = XOSC
192
+ clock_configure_int_divider (clk_ref ,
193
+ CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC ,
194
+ 0 ,
195
+ xosc_mhz * MHZ ,
196
+ 1 );
197
+ // CLK_SYS = CLK_REF
198
+ clock_configure_int_divider (clk_sys ,
199
+ CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF ,
200
+ CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC , // leave the aux source on ROSC
201
+ xosc_mhz * MHZ ,
202
+ 1 );
203
+
204
+ // Max out rosc
205
+ rosc_hw -> div = 1 | ROSC_DIV_VALUE_PASS ;
206
+ rosc_hw -> freqa = (ROSC_FREQA_PASSWD_VALUE_PASS << ROSC_FREQA_PASSWD_LSB ) |
207
+ ROSC_FREQA_DS3_BITS | ROSC_FREQA_DS2_BITS |
208
+ ROSC_FREQA_DS1_RANDOM_BITS | ROSC_FREQA_DS0_RANDOM_BITS ; // enable randomisation
209
+ rosc_hw -> freqb = (ROSC_FREQB_PASSWD_VALUE_PASS << ROSC_FREQB_PASSWD_LSB ) |
210
+ ROSC_FREQB_DS7_LSB | ROSC_FREQB_DS6_LSB | ROSC_FREQB_DS5_LSB | ROSC_FREQB_DS4_LSB ;
211
+
212
+ // Wait for ROSC to be stable
213
+ while (!(rosc_hw -> status & ROSC_STATUS_STABLE_BITS )) {
214
+ tight_loop_contents ();
215
+ }
216
+
217
+ rosc_freq_mhz = frequency_count_khz (CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC_PH ) / KHZ ;
218
+ }
219
+ if (rosc_freq_mhz > clk_mhz ) {
220
+ // CLK SYS = ROSC divided down to clk_mhz, according to XOSC calibration
221
+ clock_configure_mhz (clk_sys ,
222
+ CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX ,
223
+ CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC ,
224
+ rosc_freq_mhz ,
225
+ clk_mhz );
226
+ } else { // Either ROSC is running too slowly, or there was no XOSC to calibrate it against
227
+ // CLK SYS = ROSC directly, as it's running slowly enough
228
+ clock_configure_int_divider (clk_sys ,
229
+ CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX ,
230
+ CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC ,
231
+ ROSC_HZ , // this doesn't have to be accurate
232
+ 1 );
233
+ }
234
+
235
+ // Configure other clocks - none of these need to be accurate
236
+
237
+ // CLK_REF = ROSC / OTHER_CLK_DIV - this and other clocks aren't really used, so just need to be set to a low enough frequency
238
+ clock_configure_int_divider (clk_ref ,
239
+ CLOCKS_CLK_REF_CTRL_SRC_VALUE_ROSC_CLKSRC_PH ,
240
+ 0 ,
241
+ ROSC_HZ ,
242
+ OTHER_CLK_DIV );
243
+
244
+ // CLK USB (not used)
245
+ clock_configure_int_divider (clk_usb ,
246
+ 0 , // No GLMUX
247
+ CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH ,
248
+ ROSC_HZ ,
249
+ OTHER_CLK_DIV );
250
+
251
+ // CLK ADC (not used)
252
+ clock_configure_int_divider (clk_adc ,
253
+ 0 , // No GLMUX
254
+ CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH ,
255
+ ROSC_HZ ,
256
+ OTHER_CLK_DIV );
257
+
258
+ // CLK PERI Used as reference clock for UART and SPI serial. (not used)
259
+ clock_configure_int_divider (clk_peri ,
260
+ 0 ,
261
+ CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS ,
262
+ ROSC_HZ ,
263
+ OTHER_CLK_DIV );
264
+
265
+ // CLK_HSTX Transmit bit clock for the HSTX peripheral. (not used)
266
+ clock_configure_int_divider (clk_hstx ,
267
+ 0 ,
268
+ CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_CLK_SYS ,
269
+ ROSC_HZ ,
270
+ OTHER_CLK_DIV );
148
271
}
149
272
150
273
@@ -158,14 +281,13 @@ int main() {
158
281
otp_hw -> crt_key_w [i ] = key_i ;
159
282
}
160
283
161
- bi_decl (bi_program_feature_group (0x1111 , 0x2222 , "encryption_config" ));
162
- bi_decl (bi_ptr_int32 (0x1111 , 0x2222 , data_start_addr , 0x20000000 ));
163
- bi_decl (bi_ptr_int32 (0x1111 , 0x2222 , data_size , 0x78000 ));
164
- bi_decl (bi_ptr_int32 (0x1111 , 0x2222 , iv0 , 0 ));
165
- bi_decl (bi_ptr_int32 (0x1111 , 0x2222 , iv1 , 1 ));
166
- bi_decl (bi_ptr_int32 (0x1111 , 0x2222 , iv2 , 2 ));
167
- bi_decl (bi_ptr_int32 (0x1111 , 0x2222 , iv3 , 3 ));
168
- bi_decl (bi_ptr_int32 (0x1111 , 0x2222 , otp_key_page , 30 ));
284
+ bi_decl (bi_ptr_int32 (0 , 0 , data_start_addr , 0x20000000 ));
285
+ bi_decl (bi_ptr_int32 (0 , 0 , data_size , 0x78000 ));
286
+ bi_decl (bi_ptr_int32 (0 , 0 , iv0 , 0 ));
287
+ bi_decl (bi_ptr_int32 (0 , 0 , iv1 , 1 ));
288
+ bi_decl (bi_ptr_int32 (0 , 0 , iv2 , 2 ));
289
+ bi_decl (bi_ptr_int32 (0 , 0 , iv3 , 3 ));
290
+ bi_decl (bi_ptr_int32 (0 , 0 , otp_key_page , 30 ));
169
291
170
292
// Initialise IV from binary info words
171
293
uint8_t iv [16 ];
0 commit comments