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_rv_plic_t plic;
59 static dif_pwrmgr_t pwrmgr;
60 static dif_rstmgr_t rstmgr;
61 static dif_entropy_src_t entropy_src;
63 static dif_clkmgr_t clkmgr;
64 static dif_adc_ctrl_t adc_ctrl;
66 static volatile bool interrupt_serviced =
false;
67 static bool first_adc_setup =
true;
74 kEntropyFifoBufferSize = 16,
78 kPowerUpTimeInUs = 30,
81 static uint32_t read_fifo_depth(dif_entropy_src_t *entropy) {
82 uint32_t fifo_depth = 0;
100 static void clear_event(uint32_t idx,
dif_toggle_t fatal) {
112 bool fatal_cause =
false;
113 bool recov_cause =
false;
124 CHECK(fatal_cause & !recov_cause,
125 "Fatal alert not correctly observed in alert handler");
127 CHECK(recov_cause & !fatal_cause,
128 "Recov alert not correctly observed in alert handler");
145 static void test_event(uint32_t idx,
dif_toggle_t fatal,
bool set_event) {
162 CHECK(((get_events(fatal) >> idx) & 0x1) == 1,
163 "Event %d not observed in AST", idx);
166 CHECK(((get_events(!fatal) >> idx) & 0x1) == 0,
167 "Event %d observed in AST when it should not be", idx);
170 clear_event(idx, fatal);
173 check_alert_state(fatal);
181 void init_units(
void) {
182 CHECK_DIF_OK(dif_pwrmgr_init(
184 CHECK_DIF_OK(dif_rstmgr_init(
186 CHECK_DIF_OK(dif_entropy_src_init(
188 CHECK_DIF_OK(dif_aon_timer_init(
190 CHECK_DIF_OK(dif_rv_plic_init(
192 CHECK_DIF_OK(dif_sensor_ctrl_init(
195 CHECK_DIF_OK(dif_alert_handler_init(
198 CHECK_DIF_OK(dif_rv_plic_init(
200 CHECK_DIF_OK(dif_clkmgr_init(
202 CHECK_DIF_OK(dif_adc_ctrl_init(
209 static void configure_adc_ctrl(
const dif_adc_ctrl_t *adc_ctrl) {
210 uint32_t wake_up_time_aon_cycles = 0;
211 uint32_t power_up_time_aon_cycles = 0;
213 CHECK_STATUS_OK(aon_timer_testutils_get_aon_cycles_32_from_us(
214 kPowerUpTimeInUs, &power_up_time_aon_cycles));
215 CHECK_STATUS_OK(aon_timer_testutils_get_aon_cycles_32_from_us(
216 kWakeUpTimeInUs, &wake_up_time_aon_cycles));
223 .num_low_power_samples = kNumLowPowerSamples,
224 .num_normal_power_samples = kNumNormalPowerSamples,
225 .power_up_time_aon_cycles = (uint8_t)power_up_time_aon_cycles + 1,
226 .wake_up_time_aon_cycles = wake_up_time_aon_cycles}));
229 static void en_plic_irqs(dif_rv_plic_t *plic) {
233 for (uint32_t i = 0; i <
ARRAYSIZE(plic_irqs); ++i) {
242 irq_global_ctrl(
true);
243 irq_external_ctrl(
true);
246 void adc_setup(
bool first_adc_setup) {
248 CHECK_DIF_OK(dif_adc_ctrl_irq_set_enabled(
251 uint16_t channel0_filter0_max =
252 ((uint16_t)(kChannel0MaxHighByte << 8)) | kChannel0MaxLowByte;
253 uint16_t channel0_filter0_min =
254 ((uint16_t)(kChannel0MinHighByte << 8)) | kChannel0MinLowByte;
255 uint16_t channel1_filter0_max =
256 ((uint16_t)(kChannel1MaxHighByte << 8)) | kChannel1MaxLowByte;
257 uint16_t channel1_filter0_min =
258 ((uint16_t)(kChannel1MinHighByte << 8)) | kChannel1MinLowByte;
260 if (first_adc_setup) {
262 configure_adc_ctrl(&adc_ctrl);
270 &adc_ctrl, kDifAdcCtrlChannel0,
272 .generate_irq_on_match =
true,
273 .generate_wakeup_on_match =
true,
275 .max_voltage = channel0_filter0_max,
276 .min_voltage = channel0_filter0_min},
279 &adc_ctrl, kDifAdcCtrlChannel1,
281 .generate_irq_on_match =
true,
282 .generate_wakeup_on_match =
true,
284 .max_voltage = channel1_filter0_max,
285 .min_voltage = channel1_filter0_min},
294 if (first_adc_setup) {
299 void ast_enter_sleep_states_and_check_functionality(
302 uint32_t read_fifo_depth_val = 0;
303 uint32_t unhealthy_fifos, errors, alerts;
305 const dif_edn_t edn0 = {
307 const dif_edn_t edn1 = {
310 if ((pwrmgr_config & (~kDifPwrmgrDomainOptionUsbClockInActivePower)) == 0) {
316 if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, kDifNoWakeup)) ==
322 CHECK_STATUS_OK(entropy_src_testutils_drain_observe_fifo(&entropy_src));
332 rv_plic_testutils_irq_range_enable(
339 CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
343 read_fifo_depth_val = read_fifo_depth(&entropy_src);
347 adc_setup(first_adc_setup);
350 CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(
351 &pwrmgr, kDifPwrmgrWakeupRequestSourceTwo, pwrmgr_config));
354 LOG_INFO(
"Issued WFI to enter sleep.");
359 CHECK(interrupt_serviced);
361 interrupt_serviced =
false;
363 }
else if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(
364 &pwrmgr, kDifPwrmgrWakeupRequestSourceTwo)) ==
true) {
366 first_adc_setup =
false;
368 adc_setup(first_adc_setup);
375 CHECK_STATUS_OK(entropy_src_testutils_drain_observe_fifo(&entropy_src));
381 if (read_fifo_depth_val >= read_fifo_depth(&entropy_src))
383 "read_fifo_depth after exit from idle=%0d should be equal/greater "
384 "than previous read value (%0d)",
385 read_fifo_depth(&entropy_src), read_fifo_depth_val);
401 if (unhealthy_fifos != 0 || errors != 0 || alerts != 0)
402 LOG_ERROR(
"edn0: error=0x%x, unhealthy_fifos=0x%x, alerts=0x%x", errors,
403 unhealthy_fifos, alerts);
407 if (unhealthy_fifos != 0 || errors != 0 || alerts != 0)
408 LOG_ERROR(
"edn1: error=0x%x, unhealthy_fifos=0x%x, alerts=0x%x", errors,
409 unhealthy_fifos, alerts);
415 void set_edn_auto_mode(
void) {
416 const dif_csrng_t csrng = {
418 const dif_edn_t edn0 = {
420 const dif_edn_t edn1 = {
424 CHECK_STATUS_OK(entropy_testutils_stop_all());
432 .buffer_threshold = kEntropyFifoBufferSize,
436 CHECK_STATUS_OK(entropy_testutils_entropy_src_init());
449 kMultiBitBool4False << 8,
459 kMultiBitBool4False << 8,
473 .reseed_interval = 32,
484 kMultiBitBool4False << 8,
494 kMultiBitBool4False << 8,
508 .reseed_interval = 4,
514 CHECK_STATUS_OK(entropy_src_testutils_drain_observe_fifo(&entropy_src));
517 void ottf_external_isr(uint32_t *exc_info) {
518 plic_isr_ctx_t plic_ctx = {.rv_plic = &plic,
521 adc_ctrl_isr_ctx_t adc_ctrl_ctx = {
522 .adc_ctrl = &adc_ctrl,
525 .is_only_irq =
true};
528 dif_adc_ctrl_irq_t adc_ctrl_irq;
529 isr_testutils_adc_ctrl_isr(plic_ctx, adc_ctrl_ctx,
false, &peripheral,
533 CHECK(adc_ctrl_irq == kDifAdcCtrlIrqMatchPending);
534 interrupt_serviced =
true;
553 LOG_INFO(
"1 test alert/rng after Deep sleep 1");
554 pwrmgr_config = kDifPwrmgrDomainOptionUsbClockInActivePower;
555 ast_enter_sleep_states_and_check_functionality(pwrmgr_config, kAlertVal7);
557 LOG_INFO(
"2 test alert/rng after regular sleep (usb clk enabled)");
559 pwrmgr_config = kDifPwrmgrDomainOptionUsbClockInActivePower |
560 kDifPwrmgrDomainOptionUsbClockInLowPower |
561 kDifPwrmgrDomainOptionMainPowerInLowPower;
562 ast_enter_sleep_states_and_check_functionality(pwrmgr_config, kAlertVal8);
564 LOG_INFO(
"3 test alert/rng after regular sleep (all clk disabled in lp)");
566 pwrmgr_config = kDifPwrmgrDomainOptionMainPowerInLowPower |
567 kDifPwrmgrDomainOptionUsbClockInActivePower;
568 ast_enter_sleep_states_and_check_functionality(pwrmgr_config, kAlertVal7);