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 dif_rv_plic_t plic;
37 static dif_alert_handler_t alert_handler;
38 static dif_aon_timer_t aon_timer;
39 static dif_pwrmgr_t pwrmgr;
40 static dif_rstmgr_t rstmgr;
41 static dif_rv_core_ibex_t ibex;
44 static volatile const uint8_t kExpectedAlertNumber = 0;
49 static void init_peripherals(
void) {
52 CHECK_DIF_OK(dif_rv_plic_init(base_addr, &plic));
55 CHECK_DIF_OK(dif_alert_handler_init(base_addr, &alert_handler));
58 CHECK_DIF_OK(dif_pwrmgr_init(
62 CHECK_DIF_OK(dif_aon_timer_init(
65 CHECK_DIF_OK(dif_rstmgr_init(
70 CHECK_DIF_OK(dif_rv_core_ibex_init(ibex_addr, &ibex));
76 kCounterTestSteps = 0,
79 kCounterMaxWakeups = 1,
87 static void alert_handler_config(uint32_t ping_timeout) {
95 alert_classes[i] = kDifAlertHandlerClassA;
101 kDifAlertHandlerLocalAlertAlertPingFail,
102 kDifAlertHandlerLocalAlertAlertIntegrityFail,
103 kDifAlertHandlerLocalAlertBusIntegrityFail,
104 kDifAlertHandlerLocalAlertEscalationIntegrityFail,
105 kDifAlertHandlerLocalAlertEscalationPingFail,
106 kDifAlertHandlerLocalAlertShadowedStorageError,
107 kDifAlertHandlerLocalAlertShadowedUpdateError};
109 kDifAlertHandlerClassB, kDifAlertHandlerClassA, kDifAlertHandlerClassA,
110 kDifAlertHandlerClassA, kDifAlertHandlerClassA, kDifAlertHandlerClassA,
111 kDifAlertHandlerClassA};
114 CHECK_STATUS_OK(alert_handler_testutils_get_cycles_from_us(200, &cycles));
118 .duration_cycles = cycles,
123 .accumulator_threshold = 0,
124 .irq_deadline_cycles = cycles,
125 .escalation_phases = esc_phases,
126 .escalation_phases_len =
ARRAYSIZE(esc_phases),
134 kDifAlertHandlerClassB};
137 .alert_classes = alert_classes,
139 .local_alerts = loc_alerts,
140 .local_alert_classes = loc_alert_classes,
141 .local_alerts_len =
ARRAYSIZE(loc_alerts),
143 .class_configs = class_configs,
145 .ping_timeout = ping_timeout,
148 CHECK_STATUS_OK(alert_handler_testutils_configure_all(&alert_handler, config,
151 CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
154 CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
161 static void alert_handler_clear_cause_regs(
void) {
169 i < ALERT_HANDLER_PARAM_N_LOC_ALERT; i++) {
178 static uint16_t alert_handler_num_fired_alerts(
void) {
181 uint16_t accumulator = 0;
189 accumulator += is_cause;
198 static uint16_t alert_handler_num_fired_loc_alerts(
void) {
201 uint16_t accumulator = 0;
204 i < ALERT_HANDLER_PARAM_N_LOC_ALERT; i++) {
207 accumulator += is_cause;
216 static void enter_low_power(
bool deep_sleep) {
220 kDifPwrmgrDomainOptionUsbClockInLowPower |
221 kDifPwrmgrDomainOptionUsbClockInActivePower)) |
222 (!deep_sleep ? kDifPwrmgrDomainOptionMainPowerInLowPower : 0);
226 CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(
227 &pwrmgr, kDifPwrmgrWakeupRequestSourceFive,
235 void cleanup_wakeup_src(
void) {
244 static plic_isr_ctx_t plic_ctx = {.rv_plic = &plic,
247 static pwrmgr_isr_ctx_t pwrmgr_isr_ctx = {
250 .expected_irq = kDifPwrmgrIrqWakeup,
251 .is_only_irq =
true};
254 static uint32_t num_total_wakeups;
256 static size_t test_step_cnt;
262 void init_test_components(
void) {
264 irq_global_ctrl(
true);
265 irq_external_ctrl(
true);
269 ret_sram_testutils_init();
280 ret_sram_testutils_counter_get(kCounterTestSteps, &test_step_cnt));
283 ret_sram_testutils_counter_get(kCounterMaxWakeups, &num_total_wakeups));
285 CHECK(test_step_cnt < INT_MAX,
"test_step_cnt too large");
289 if (num_total_wakeups == 0) {
291 num_total_wakeups = 2;
293 ret_sram_testutils_counter_set(kCounterMaxWakeups, num_total_wakeups));
300 static void execute_test_phases(uint8_t test_phase, uint32_t ping_timeout_cyc) {
304 uint16_t num_fired_alerts;
305 uint16_t num_fired_loc_alerts;
312 alert_handler_config(ping_timeout_cyc);
316 if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) ==
true) {
320 CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterTestSteps));
322 ret_sram_testutils_counter_get(kCounterTestSteps, &test_step_cnt));
325 CHECK_STATUS_OK(aon_timer_testutils_wakeup_config(
326 &aon_timer, (uint32_t)rand_testutils_gen32_range(2, 10)));
330 LOG_INFO(
"Ready for fault injection");
333 enter_low_power(
false);
334 }
else if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(
335 &pwrmgr, kDifPwrmgrWakeupRequestSourceFive)) ==
338 cleanup_wakeup_src();
345 "The alert handler should be locked after waking up from normal sleep");
348 alert_handler_clear_cause_regs();
354 LOG_INFO(
"Phase #1 step %d", test_step_cnt);
355 LOG_INFO(
"Expected alert number = %d", kExpectedAlertNumber);
357 num_fired_alerts = alert_handler_num_fired_alerts();
358 num_fired_loc_alerts = alert_handler_num_fired_loc_alerts();
359 LOG_INFO(
"num_fired alerts = %d, num_fired_loc_alerts = %d",
360 num_fired_alerts, num_fired_loc_alerts);
363 CHECK(num_fired_alerts == 1,
364 "Phase #1: Only a single alert must be fired after wakeup!");
365 CHECK(num_fired_loc_alerts == 0,
366 "Phase #1: No local alerts must be fired!");
370 &alert_handler, kExpectedAlertNumber, &is_cause));
371 CHECK(is_cause,
"Phase #1: Expected alert has NOT been fired!!");
374 CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterTestSteps));
376 ret_sram_testutils_counter_get(kCounterTestSteps, &test_step_cnt));
379 CHECK_STATUS_OK(aon_timer_testutils_wakeup_config(
380 &aon_timer, (uint32_t)rand_testutils_gen32_range(2, 10)));
382 enter_low_power(
false);
386 LOG_ERROR(
"Unexpected wakeup_reason=%x", wakeup_reason);
387 CHECK(
false,
"Unexpected wakeup reason");
394 void ottf_external_isr(uint32_t *exc_info) {
395 dif_pwrmgr_irq_t irq_id;
398 isr_testutils_pwrmgr_isr(plic_ctx, pwrmgr_isr_ctx, &peripheral, &irq_id);
402 "IRQ peripheral: %d is incorrect", peripheral);
403 CHECK(irq_id == kDifPwrmgrIrqWakeup,
"IRQ ID: %d is incorrect", irq_id);
409 rst_info = rstmgr_testutils_reason_get();
410 rstmgr_testutils_reason_clear();
414 "Wrong reset reason %02X", rst_info);
417 CHECK_STATUS_OK(ret_sram_testutils_counter_clear(kCounterTestSteps));
418 CHECK_STATUS_OK(ret_sram_testutils_counter_clear(kCounterMaxWakeups));
420 init_test_components();
426 while (test_step_cnt < num_total_wakeups) {
433 execute_test_phases(1, 256);
437 cleanup_wakeup_src();