15 #include "sw/device/lib/runtime/irq.h"
17 #include "sw/device/lib/testing/alert_handler_testutils.h"
18 #include "sw/device/lib/testing/aon_timer_testutils.h"
19 #include "sw/device/lib/testing/clkmgr_testutils.h"
20 #include "sw/device/lib/testing/entropy_src_testutils.h"
21 #include "sw/device/lib/testing/entropy_testutils.h"
22 #include "sw/device/lib/testing/pwrmgr_testutils.h"
23 #include "sw/device/lib/testing/rstmgr_testutils.h"
24 #include "sw/device/lib/testing/rv_plic_testutils.h"
25 #include "sw/device/lib/testing/test_framework/check.h"
29 #include "sensor_ctrl_regs.h"
30 #include "sw/device/lib/testing/autogen/isr_testutils.h"
32 #define kAlertSet true
33 #define kAlertClear false
36 #define kDifNoWakeup 0
38 OTTF_DEFINE_TEST_CONFIG();
40 static volatile const uint8_t kNumLowPowerSamples;
41 static volatile const uint8_t kNumNormalPowerSamples;
42 static volatile const uint8_t kWakeUpTimeInUs;
44 static volatile const uint8_t kChannel0MaxLowByte;
45 static volatile const uint8_t kChannel0MaxHighByte;
46 static volatile const uint8_t kChannel0MinLowByte;
47 static volatile const uint8_t kChannel0MinHighByte;
49 static volatile const uint8_t kChannel1MaxLowByte;
50 static volatile const uint8_t kChannel1MaxHighByte;
51 static volatile const uint8_t kChannel1MinLowByte;
52 static volatile const uint8_t kChannel1MinHighByte;
54 static dif_sensor_ctrl_t sensor_ctrl;
55 static dif_alert_handler_t alert_handler;
56 static dif_aon_timer_t aon_timer;
57 static dif_rv_plic_t rv_plic;
58 static dif_pwrmgr_t pwrmgr;
59 static dif_rstmgr_t rstmgr;
60 static dif_entropy_src_t entropy_src;
62 static dif_clkmgr_t clkmgr;
63 static dif_adc_ctrl_t adc_ctrl;
65 static const dt_adc_ctrl_t kAdcCtrlDt = 0;
66 static_assert(kDtAdcCtrlCount == 1,
"this test expects a adc_ctrl");
67 static const dt_clkmgr_t kClkmgrDt = 0;
68 static_assert(kDtClkmgrCount == 1,
"this test expects a clkmgr");
69 static const dt_rstmgr_t kRstmgrDt = 0;
70 static_assert(kDtRstmgrCount == 1,
"this test expects a rstmgr");
71 static const dt_pwrmgr_t kPwrmgrDt = 0;
72 static_assert(kDtPwrmgrCount == 1,
"this test expects a pwrmgr");
73 static_assert(kDtAonTimerCount == 1,
"this test expects an aon_timer");
74 static const dt_aon_timer_t kAonTimerDt = 0;
75 static_assert(kDtEntropySrcCount == 1,
"this test expects an entropy_src");
76 static const dt_entropy_src_t kEntropySrcDt = 0;
77 static const dt_alert_handler_t kAlertHandlerDt = 0;
78 static_assert(kDtAlertHandlerCount == 1,
79 "this library expects exactly one alert_handler");
80 static const dt_rv_plic_t kRvPlicDt = 0;
81 static_assert(kDtRvPlicCount == 1,
"this test expects exactly one rv_plic");
82 static const dt_sensor_ctrl_t kSensorCtrlDt = 0;
83 static_assert(kDtSensorCtrlCount >= 1,
"this test expects a sensor_ctrl");
85 static volatile bool interrupt_serviced =
false;
86 static bool first_adc_setup =
true;
93 kEntropyFifoBufferSize = 16,
97 kPowerUpTimeInUs = 30,
100 static uint32_t read_fifo_depth(dif_entropy_src_t *entropy) {
101 uint32_t fifo_depth = 0;
119 static void clear_event(uint32_t idx,
dif_toggle_t fatal) {
131 bool fatal_cause =
false;
132 bool recov_cause =
false;
143 CHECK(fatal_cause & !recov_cause,
144 "Fatal alert not correctly observed in alert handler");
146 CHECK(recov_cause & !fatal_cause,
147 "Recov alert not correctly observed in alert handler");
164 static void test_event(uint32_t idx,
dif_toggle_t fatal,
bool set_event) {
181 CHECK(((get_events(fatal) >> idx) & 0x1) == 1,
182 "Event %d not observed in AST", idx);
185 CHECK(((get_events(!fatal) >> idx) & 0x1) == 0,
186 "Event %d observed in AST when it should not be", idx);
189 clear_event(idx, fatal);
192 check_alert_state(fatal);
200 void init_units(
void) {
201 CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kPwrmgrDt, &pwrmgr));
202 CHECK_DIF_OK(dif_rstmgr_init_from_dt(kRstmgrDt, &rstmgr));
203 CHECK_DIF_OK(dif_entropy_src_init_from_dt(kEntropySrcDt, &entropy_src));
204 CHECK_DIF_OK(dif_aon_timer_init_from_dt(kAonTimerDt, &aon_timer));
205 CHECK_DIF_OK(dif_rv_plic_init_from_dt(kRvPlicDt, &rv_plic));
206 CHECK_DIF_OK(dif_sensor_ctrl_init_from_dt(kSensorCtrlDt, &sensor_ctrl));
207 CHECK_DIF_OK(dif_alert_handler_init_from_dt(kAlertHandlerDt, &alert_handler));
208 CHECK_DIF_OK(dif_clkmgr_init_from_dt(kClkmgrDt, &clkmgr));
209 CHECK_DIF_OK(dif_adc_ctrl_init_from_dt(kAdcCtrlDt, &adc_ctrl));
215 static void configure_adc_ctrl(
const dif_adc_ctrl_t *adc_ctrl) {
216 uint32_t wake_up_time_aon_cycles = 0;
217 uint32_t power_up_time_aon_cycles = 0;
219 CHECK_STATUS_OK(aon_timer_testutils_get_aon_cycles_32_from_us(
220 kPowerUpTimeInUs, &power_up_time_aon_cycles));
221 CHECK_STATUS_OK(aon_timer_testutils_get_aon_cycles_32_from_us(
222 kWakeUpTimeInUs, &wake_up_time_aon_cycles));
229 .num_low_power_samples = kNumLowPowerSamples,
230 .num_normal_power_samples = kNumNormalPowerSamples,
231 .power_up_time_aon_cycles = (uint8_t)power_up_time_aon_cycles + 1,
232 .wake_up_time_aon_cycles = wake_up_time_aon_cycles}));
235 static void en_plic_irqs(dif_rv_plic_t *plic) {
239 for (uint32_t i = 0; i <
ARRAYSIZE(plic_irqs); ++i) {
248 irq_global_ctrl(
true);
249 irq_external_ctrl(
true);
252 void adc_setup(
bool first_adc_setup) {
254 CHECK_DIF_OK(dif_adc_ctrl_irq_set_enabled(
257 uint16_t channel0_filter0_max =
258 ((uint16_t)(kChannel0MaxHighByte << 8)) | kChannel0MaxLowByte;
259 uint16_t channel0_filter0_min =
260 ((uint16_t)(kChannel0MinHighByte << 8)) | kChannel0MinLowByte;
261 uint16_t channel1_filter0_max =
262 ((uint16_t)(kChannel1MaxHighByte << 8)) | kChannel1MaxLowByte;
263 uint16_t channel1_filter0_min =
264 ((uint16_t)(kChannel1MinHighByte << 8)) | kChannel1MinLowByte;
266 if (first_adc_setup) {
268 configure_adc_ctrl(&adc_ctrl);
273 en_plic_irqs(&rv_plic);
276 &adc_ctrl, kDifAdcCtrlChannel0,
278 .generate_irq_on_match =
true,
279 .generate_wakeup_on_match =
true,
281 .max_voltage = channel0_filter0_max,
282 .min_voltage = channel0_filter0_min},
285 &adc_ctrl, kDifAdcCtrlChannel1,
287 .generate_irq_on_match =
true,
288 .generate_wakeup_on_match =
true,
290 .max_voltage = channel1_filter0_max,
291 .min_voltage = channel1_filter0_min},
300 if (first_adc_setup) {
305 void ast_enter_sleep_states_and_check_functionality(
308 uint32_t read_fifo_depth_val = 0;
309 uint32_t unhealthy_fifos, errors, alerts;
311 const dif_edn_t edn0 = {
313 const dif_edn_t edn1 = {
316 if ((pwrmgr_config & (~kDifPwrmgrDomainOptionUsbClockInActivePower)) == 0) {
325 kDtAdcCtrlWakeupWkupReq, &adc_ctrl_wakeup_sources));
327 if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, kDifNoWakeup)) ==
333 CHECK_STATUS_OK(entropy_src_testutils_drain_observe_fifo(&entropy_src));
343 rv_plic_testutils_irq_range_enable(
350 CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
354 read_fifo_depth_val = read_fifo_depth(&entropy_src);
358 adc_setup(first_adc_setup);
361 CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(
362 &pwrmgr, adc_ctrl_wakeup_sources, pwrmgr_config));
365 LOG_INFO(
"Issued WFI to enter sleep.");
370 CHECK(interrupt_serviced);
372 interrupt_serviced =
false;
374 }
else if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(
375 &pwrmgr, adc_ctrl_wakeup_sources))) {
377 first_adc_setup =
false;
379 adc_setup(first_adc_setup);
386 CHECK_STATUS_OK(entropy_src_testutils_drain_observe_fifo(&entropy_src));
392 if (read_fifo_depth_val >= read_fifo_depth(&entropy_src))
394 "read_fifo_depth after exit from idle=%0d should be equal/greater "
395 "than previous read value (%0d)",
396 read_fifo_depth(&entropy_src), read_fifo_depth_val);
412 if (unhealthy_fifos != 0 || errors != 0 || alerts != 0)
413 LOG_ERROR(
"edn0: error=0x%x, unhealthy_fifos=0x%x, alerts=0x%x", errors,
414 unhealthy_fifos, alerts);
418 if (unhealthy_fifos != 0 || errors != 0 || alerts != 0)
419 LOG_ERROR(
"edn1: error=0x%x, unhealthy_fifos=0x%x, alerts=0x%x", errors,
420 unhealthy_fifos, alerts);
426 void set_edn_auto_mode(
void) {
427 const dif_csrng_t csrng = {
429 const dif_edn_t edn0 = {
431 const dif_edn_t edn1 = {
435 CHECK_STATUS_OK(entropy_testutils_stop_all());
443 .buffer_threshold = kEntropyFifoBufferSize,
447 CHECK_STATUS_OK(entropy_testutils_entropy_src_init());
460 kMultiBitBool4False << 8,
470 kMultiBitBool4False << 8,
484 .reseed_interval = 32,
495 kMultiBitBool4False << 8,
505 kMultiBitBool4False << 8,
519 .reseed_interval = 4,
525 CHECK_STATUS_OK(entropy_src_testutils_drain_observe_fifo(&entropy_src));
528 void ottf_external_isr(uint32_t *exc_info) {
529 plic_isr_ctx_t plic_ctx = {.rv_plic = &rv_plic,
532 adc_ctrl_isr_ctx_t adc_ctrl_ctx = {
533 .adc_ctrl = &adc_ctrl,
536 .is_only_irq =
true};
539 dif_adc_ctrl_irq_t adc_ctrl_irq;
540 isr_testutils_adc_ctrl_isr(plic_ctx, adc_ctrl_ctx,
false, &peripheral,
544 CHECK(adc_ctrl_irq == kDifAdcCtrlIrqMatchPending);
545 interrupt_serviced =
true;
564 LOG_INFO(
"1 test alert/rng after Deep sleep 1");
565 pwrmgr_config = kDifPwrmgrDomainOptionUsbClockInActivePower;
566 ast_enter_sleep_states_and_check_functionality(pwrmgr_config, kAlertVal7);
568 LOG_INFO(
"2 test alert/rng after regular sleep (usb clk enabled)");
570 pwrmgr_config = kDifPwrmgrDomainOptionUsbClockInActivePower |
571 kDifPwrmgrDomainOptionUsbClockInLowPower |
572 kDifPwrmgrDomainOptionMainPowerInLowPower;
573 ast_enter_sleep_states_and_check_functionality(pwrmgr_config, kAlertVal8);
575 LOG_INFO(
"3 test alert/rng after regular sleep (all clk disabled in lp)");
577 pwrmgr_config = kDifPwrmgrDomainOptionMainPowerInLowPower |
578 kDifPwrmgrDomainOptionUsbClockInActivePower;
579 ast_enter_sleep_states_and_check_functionality(pwrmgr_config, kAlertVal7);