14 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
16 #include "sw/device/lib/runtime/irq.h"
18 #include "sw/device/lib/testing/alert_handler_testutils.h"
19 #include "sw/device/lib/testing/aon_timer_testutils.h"
20 #include "sw/device/lib/testing/pwrmgr_testutils.h"
21 #include "sw/device/lib/testing/rand_testutils.h"
22 #include "sw/device/lib/testing/ret_sram_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/FreeRTOSConfig.h"
26 #include "sw/device/lib/testing/test_framework/check.h"
29 #include "alert_handler_regs.h"
31 #include "pwrmgr_regs.h"
32 #include "sw/device/lib/testing/autogen/isr_testutils.h"
34 OTTF_DEFINE_TEST_CONFIG();
36 static const dt_rstmgr_t kRstmgrDt = 0;
37 static_assert(kDtRstmgrCount == 1,
"this test expects a rstmgr");
38 static const dt_pwrmgr_t kPwrmgrDt = 0;
39 static_assert(kDtPwrmgrCount == 1,
"this test expects a pwrmgr");
40 static const dt_aon_timer_t kAonTimerDt = 0;
41 static_assert(kDtAonTimerCount == 1,
"this test expects an aon_timer");
42 static const dt_rv_plic_t kRvPlicDt = 0;
43 static_assert(kDtRvPlicCount == 1,
"this test expects exactly one rv_plic");
44 static const dt_rv_core_ibex_t kRvCoreIbexDt = 0;
45 static_assert(kDtRvCoreIbexCount == 1,
46 "this test expects exactly one rv_core_ibex");
47 static const dt_alert_handler_t kAlertHandlerDt = 0;
48 static_assert(kDtAlertHandlerCount == 1,
49 "this library expects exactly one alert_handler");
51 static dif_rv_plic_t plic;
52 static dif_alert_handler_t alert_handler;
53 static dif_aon_timer_t aon_timer;
54 static dif_pwrmgr_t pwrmgr;
55 static dif_rstmgr_t rstmgr;
56 static dif_rv_core_ibex_t ibex;
59 static volatile const uint8_t kExpectedAlertNumber = 0;
66 static void init_peripherals(
void) {
67 CHECK_DIF_OK(dif_rv_plic_init_from_dt(kRvPlicDt, &plic));
69 CHECK_DIF_OK(dif_alert_handler_init_from_dt(kAlertHandlerDt, &alert_handler));
72 CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kPwrmgrDt, &pwrmgr));
75 CHECK_DIF_OK(dif_aon_timer_init_from_dt(kAonTimerDt, &aon_timer));
78 kDtAonTimerWakeupWkupReq, &pwrmgr_aon_timer_wakeups));
80 CHECK_DIF_OK(dif_rstmgr_init_from_dt(kRstmgrDt, &rstmgr));
82 CHECK_DIF_OK(dif_rv_core_ibex_init_from_dt(kRvCoreIbexDt, &ibex));
88 kCounterTestSteps = 0,
91 kCounterMaxWakeups = 1,
99 static void alert_handler_config(uint32_t ping_timeout) {
107 alert_classes[i] = kDifAlertHandlerClassA;
113 kDifAlertHandlerLocalAlertAlertPingFail,
114 kDifAlertHandlerLocalAlertAlertIntegrityFail,
115 kDifAlertHandlerLocalAlertBusIntegrityFail,
116 kDifAlertHandlerLocalAlertEscalationIntegrityFail,
117 kDifAlertHandlerLocalAlertEscalationPingFail,
118 kDifAlertHandlerLocalAlertShadowedStorageError,
119 kDifAlertHandlerLocalAlertShadowedUpdateError};
121 kDifAlertHandlerClassB, kDifAlertHandlerClassA, kDifAlertHandlerClassA,
122 kDifAlertHandlerClassA, kDifAlertHandlerClassA, kDifAlertHandlerClassA,
123 kDifAlertHandlerClassA};
126 CHECK_STATUS_OK(alert_handler_testutils_get_cycles_from_us(200, &cycles));
130 .duration_cycles = cycles,
135 .accumulator_threshold = 0,
136 .irq_deadline_cycles = cycles,
137 .escalation_phases = esc_phases,
138 .escalation_phases_len =
ARRAYSIZE(esc_phases),
146 kDifAlertHandlerClassB};
149 .alert_classes = alert_classes,
151 .local_alerts = loc_alerts,
152 .local_alert_classes = loc_alert_classes,
153 .local_alerts_len =
ARRAYSIZE(loc_alerts),
155 .class_configs = class_configs,
157 .ping_timeout = ping_timeout,
160 CHECK_STATUS_OK(alert_handler_testutils_configure_all(&alert_handler, config,
163 CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
166 CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
173 static void alert_handler_clear_cause_regs(
void) {
181 i < ALERT_HANDLER_PARAM_N_LOC_ALERT; i++) {
190 static uint16_t alert_handler_num_fired_alerts(
void) {
193 uint16_t accumulator = 0;
201 accumulator += is_cause;
210 static uint16_t alert_handler_num_fired_loc_alerts(
void) {
213 uint16_t accumulator = 0;
216 i < ALERT_HANDLER_PARAM_N_LOC_ALERT; i++) {
219 accumulator += is_cause;
228 static void enter_low_power(
bool deep_sleep) {
232 kDifPwrmgrDomainOptionUsbClockInLowPower |
233 kDifPwrmgrDomainOptionUsbClockInActivePower)) |
234 (!deep_sleep ? kDifPwrmgrDomainOptionMainPowerInLowPower : 0);
237 CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(
238 &pwrmgr, pwrmgr_aon_timer_wakeups, cfg));
245 void cleanup_wakeup_src(
void) {
254 static plic_isr_ctx_t plic_ctx = {.rv_plic = &plic,
257 static pwrmgr_isr_ctx_t pwrmgr_isr_ctx = {
260 .expected_irq = kDifPwrmgrIrqWakeup,
261 .is_only_irq =
true};
264 static uint32_t num_total_wakeups;
266 static size_t test_step_cnt;
272 void init_test_components(
void) {
274 irq_global_ctrl(
true);
275 irq_external_ctrl(
true);
279 ret_sram_testutils_init();
290 ret_sram_testutils_counter_get(kCounterTestSteps, &test_step_cnt));
293 ret_sram_testutils_counter_get(kCounterMaxWakeups, &num_total_wakeups));
295 CHECK(test_step_cnt < INT_MAX,
"test_step_cnt too large");
299 if (num_total_wakeups == 0) {
301 num_total_wakeups = 2;
303 ret_sram_testutils_counter_set(kCounterMaxWakeups, num_total_wakeups));
310 static void execute_test_phases(uint8_t test_phase, uint32_t ping_timeout_cyc) {
314 uint16_t num_fired_alerts;
315 uint16_t num_fired_loc_alerts;
322 alert_handler_config(ping_timeout_cyc);
326 if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) ==
true) {
330 CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterTestSteps));
332 ret_sram_testutils_counter_get(kCounterTestSteps, &test_step_cnt));
335 CHECK_STATUS_OK(aon_timer_testutils_wakeup_config(
336 &aon_timer, (uint32_t)rand_testutils_gen32_range(2, 10)));
340 LOG_INFO(
"Ready for fault injection");
343 enter_low_power(
false);
344 }
else if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(
345 &pwrmgr, pwrmgr_aon_timer_wakeups))) {
347 cleanup_wakeup_src();
354 "The alert handler should be locked after waking up from normal sleep");
357 alert_handler_clear_cause_regs();
363 LOG_INFO(
"Phase #1 step %d", test_step_cnt);
364 LOG_INFO(
"Expected alert number = %d", kExpectedAlertNumber);
366 num_fired_alerts = alert_handler_num_fired_alerts();
367 num_fired_loc_alerts = alert_handler_num_fired_loc_alerts();
368 LOG_INFO(
"num_fired alerts = %d, num_fired_loc_alerts = %d",
369 num_fired_alerts, num_fired_loc_alerts);
372 CHECK(num_fired_alerts == 1,
373 "Phase #1: Only a single alert must be fired after wakeup!");
374 CHECK(num_fired_loc_alerts == 0,
375 "Phase #1: No local alerts must be fired!");
379 &alert_handler, kExpectedAlertNumber, &is_cause));
380 CHECK(is_cause,
"Phase #1: Expected alert has NOT been fired!!");
383 CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterTestSteps));
385 ret_sram_testutils_counter_get(kCounterTestSteps, &test_step_cnt));
388 CHECK_STATUS_OK(aon_timer_testutils_wakeup_config(
389 &aon_timer, (uint32_t)rand_testutils_gen32_range(2, 10)));
391 enter_low_power(
false);
395 LOG_ERROR(
"Unexpected wakeup_reason=%x", wakeup_reason);
396 CHECK(
false,
"Unexpected wakeup reason");
403 void ottf_external_isr(uint32_t *exc_info) {
404 dif_pwrmgr_irq_t irq_id;
407 isr_testutils_pwrmgr_isr(plic_ctx, pwrmgr_isr_ctx, &peripheral, &irq_id);
411 "IRQ peripheral: %d is incorrect", peripheral);
412 CHECK(irq_id == kDifPwrmgrIrqWakeup,
"IRQ ID: %d is incorrect", irq_id);
418 rst_info = rstmgr_testutils_reason_get();
419 rstmgr_testutils_reason_clear();
423 "Wrong reset reason %02X", rst_info);
426 CHECK_STATUS_OK(ret_sram_testutils_counter_clear(kCounterTestSteps));
427 CHECK_STATUS_OK(ret_sram_testutils_counter_clear(kCounterMaxWakeups));
429 init_test_components();
435 while (test_step_cnt < num_total_wakeups) {
442 execute_test_phases(1, 256);
446 cleanup_wakeup_src();