78 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
81 #include "sw/device/lib/runtime/irq.h"
83 #include "sw/device/lib/testing/alert_handler_testutils.h"
84 #include "sw/device/lib/testing/aon_timer_testutils.h"
85 #include "sw/device/lib/testing/flash_ctrl_testutils.h"
86 #include "sw/device/lib/testing/rand_testutils.h"
87 #include "sw/device/lib/testing/ret_sram_testutils.h"
88 #include "sw/device/lib/testing/rstmgr_testutils.h"
89 #include "sw/device/lib/testing/rv_plic_testutils.h"
90 #include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h"
91 #include "sw/device/lib/testing/test_framework/check.h"
96 OTTF_DEFINE_TEST_CONFIG();
100 static volatile const uint32_t kErrorRamAddress = 0;
105 static volatile const uint32_t kFaultTarget = 0;
107 static const uint32_t kExpectedAlertNumber =
128 kFaultTargetMainSramData,
129 kFaultTargetRetSramData,
130 kFaultTargetMainSramInstr
146 kEscalationPhase0Micros = 400,
148 kEscalationPhase1Micros = 400,
150 kEscalationPhase2Micros = 200,
152 kEscalationPhase3Micros = 200,
157 kWdogBarkMicros = 850,
158 kWdogBiteMicros = 900,
164 kWdogBarkMicros < kWdogBiteMicros &&
165 kWdogBarkMicros > (kEscalationPhase0Micros + kEscalationPhase1Micros),
166 "The wdog bite shall after the NMI phase when lc_escalate_en is asserted.");
186 static
void sram_function_test(
void) {
188 asm(
"auipc %[pc], 0;" : [pc]
"=r"(pc));
189 LOG_INFO(
"PC: %p, SRAM: [%p, %p)", pc, kSramStart, kSramEnd);
190 CHECK(pc >= kSramStart && pc < kSramEnd,
"PC is outside the main SRAM");
194 volatile static const uint32_t kSramFunctionTestAddress =
195 (uint32_t)sram_function_test;
201 static dif_alert_handler_t alert_handler;
202 static dif_aon_timer_t aon_timer;
204 static dif_rstmgr_t rstmgr;
205 static dif_rv_core_ibex_t rv_core_ibex;
206 static dif_rv_plic_t plic;
208 static void rv_core_ibex_fault_checker(
bool enable) {
209 dif_rv_core_ibex_error_status_t codes;
210 CHECK_DIF_OK(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));
212 CHECK(codes == (enable ? kDifRvCoreIbexErrorStatusFatalResponseIntegrity : 0),
213 "Unexpected ibex error status");
223 void ottf_external_isr(uint32_t *exc_info) {
226 LOG_INFO(
"At regular external ISR");
230 CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterInterrupt));
243 CHECK(
false,
"Unexpected aon timer interrupt %d", irq);
247 "Unexpected irq_id, expected %d, got %d",
255 CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(&alert_handler, irq,
267 LOG_INFO(
"Regular external ISR exiting");
275 void ottf_load_integrity_error_handler(uint32_t *exc_info) {
276 LOG_INFO(
"At load integrity error handler");
278 CHECK(kFaultTarget != kFaultTargetMainSramInstr,
279 "Expected fault target 0 or 1, got %d", kFaultTarget);
282 CHECK(mtval == kErrorRamAddress,
"Unexpected mtval: expected 0x%x, got 0x%x",
283 kErrorRamAddress, mtval);
285 CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterException));
287 rv_core_ibex_fault_checker(
true);
288 LOG_INFO(
"Load integrity error handler exiting");
296 void ottf_instr_access_fault_handler(uint32_t *exc_info) {
297 LOG_INFO(
"At instr access fault handler");
299 CHECK(kFaultTargetMainSramInstr == 2,
"Expected fault target 2, got %d",
301 CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterException));
303 rv_core_ibex_fault_checker(
true);
304 LOG_INFO(
"Instr access fault handler exiting");
312 void ottf_external_nmi_handler(uint32_t *exc_info) {
316 CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterNmi));
320 CHECK_DIF_OK(dif_rv_core_ibex_get_nmi_state(
323 "Alert handler NMI state not expected:\n\t"
324 "alert_enable:%x\n\talert_raised:%x\n",
327 "Watchdog NMI state not expected:\n\t"
328 "wdog_enabled:%x\n\twdog_barked:%x\n",
334 alert_class_to_use, &state));
338 bool is_cause =
false;
340 &alert_handler, kExpectedAlertNumber, &is_cause));
345 kExpectedAlertNumber));
352 static void init_peripherals(
void) {
353 CHECK_DIF_OK(dif_alert_handler_init(
357 CHECK_DIF_OK(dif_aon_timer_init(
364 CHECK_DIF_OK(dif_rstmgr_init(
367 CHECK_DIF_OK(dif_rv_core_ibex_init(
371 CHECK_DIF_OK(dif_rv_plic_init(
379 static void alert_handler_config(
void) {
381 kDifAlertHandlerClassA, kDifAlertHandlerClassD);
385 uint32_t cycles[4] = {0};
386 CHECK_STATUS_OK(alert_handler_testutils_get_cycles_from_us(
387 kEscalationPhase0Micros, &cycles[0]));
388 CHECK_STATUS_OK(alert_handler_testutils_get_cycles_from_us(
389 kEscalationPhase1Micros, &cycles[1]));
390 CHECK_STATUS_OK(alert_handler_testutils_get_cycles_from_us(
391 kEscalationPhase2Micros, &cycles[2]));
392 CHECK_STATUS_OK(alert_handler_testutils_get_cycles_from_us(
393 kEscalationPhase3Micros, &cycles[3]));
397 .signal = 0xFFFFFFFF,
398 .duration_cycles = cycles[0]},
401 .duration_cycles = cycles[1]},
404 .duration_cycles = cycles[2]},
407 .duration_cycles = cycles[3]}};
412 uint32_t deadline_cycles = 0;
413 uint16_t threshold = 0;
414 LOG_INFO(
"Configuring class %d with %d cycles and %d occurrences",
415 alert_class_to_use, deadline_cycles, threshold);
418 .accumulator_threshold = threshold,
419 .irq_deadline_cycles = deadline_cycles,
420 .escalation_phases = esc_phases,
421 .escalation_phases_len =
ARRAYSIZE(esc_phases),
428 .alert_classes = alert_classes,
431 .class_configs = class_config,
433 .ping_timeout = kAlertHandlerTestutilsDefaultPingTimeout,
436 CHECK_STATUS_OK(alert_handler_testutils_configure_all(&alert_handler, config,
441 CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
443 CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
445 CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
447 CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
451 static void set_aon_timers(
void) {
452 uint32_t bark_cycles = 0;
453 CHECK_STATUS_OK(aon_timer_testutils_get_aon_cycles_32_from_us(kWdogBarkMicros,
455 uint32_t bite_cycles = 0;
456 CHECK_STATUS_OK(aon_timer_testutils_get_aon_cycles_32_from_us(kWdogBiteMicros,
460 "Wdog will bark after %u us (%u cycles) and bite after %u us (%u cycles)",
461 (uint32_t)kWdogBarkMicros, bark_cycles, (uint32_t)kWdogBiteMicros,
466 aon_timer_testutils_watchdog_config(&aon_timer, bark_cycles, bite_cycles,
476 static void execute_test(
void) {
477 alert_handler_config();
481 dif_rv_core_ibex_enable_nmi(&rv_core_ibex, kDifRvCoreIbexNmiSourceAlert));
483 dif_rv_core_ibex_enable_nmi(&rv_core_ibex, kDifRvCoreIbexNmiSourceWdog));
488 if (kFaultTarget == kFaultTargetMainSramInstr) {
489 LOG_INFO(
"Jump to corrupted SRAM test function at %x",
490 kSramFunctionTestAddress);
491 sram_function_test();
493 "Since the SRAM test function is corrupted, this should not be "
499 LOG_INFO(
"Jump to SRAM test function at %x", kSramFunctionTestAddress);
500 sram_function_test();
501 LOG_INFO(
"Returned from the SRAM test function");
503 LOG_INFO(
"Reading corrupted address 0x%x, expecting alert %d",
504 kErrorRamAddress, kExpectedAlertNumber);
507 uint32_t data = *((uint32_t *)kErrorRamAddress);
510 LOG_INFO(
"Read from address 0x%0x with expected error gets 0x%x",
511 kErrorRamAddress, data);
515 CHECK(
false,
"This should not be reached");
522 irq_global_ctrl(
true);
523 irq_external_ctrl(
true);
527 ret_sram_testutils_init();
530 rv_plic_testutils_irq_range_enable(
533 rv_plic_testutils_irq_range_enable(&plic, kPlicTarget,
537 LOG_INFO(
"Setting default region accesses");
539 flash_ctrl_testutils_default_region_access(&flash_ctrl_state,
549 rst_info = rstmgr_testutils_reason_get();
550 rstmgr_testutils_reason_clear();
554 "Wrong reset reason %02X", rst_info);
557 LOG_INFO(
"Booting for the first time, starting test");
558 CHECK_STATUS_OK(ret_sram_testutils_counter_clear(kCounterException));
559 CHECK_STATUS_OK(ret_sram_testutils_counter_clear(kCounterInterrupt));
560 CHECK_STATUS_OK(ret_sram_testutils_counter_clear(kCounterNmi));
561 CHECK_STATUS_OK(ret_sram_testutils_counter_clear(kCounterReset));
564 uint32_t reset_count;
565 LOG_INFO(
"Booting for the second time due to escalation reset");
566 CHECK_STATUS_OK(ret_sram_testutils_counter_get(kCounterReset,
567 (uint32_t *)&reset_count));
568 LOG_INFO(
"Reset counter value: %u", reset_count);
569 if (reset_count > kMaxResets) {
570 CHECK(
false,
"Got too many resets (%d)", reset_count);
574 CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterReset));
577 uint32_t interrupt_count = 0;
579 ret_sram_testutils_counter_get(kCounterInterrupt, &interrupt_count));
580 uint32_t nmi_count = 0;
581 CHECK_STATUS_OK(ret_sram_testutils_counter_get(kCounterNmi, &nmi_count));
582 uint32_t exception_count = 0;
584 ret_sram_testutils_counter_get(kCounterException, &exception_count));
586 LOG_INFO(
"Interrupt count %d", interrupt_count);
587 LOG_INFO(
"NMI count %d", nmi_count);
588 LOG_INFO(
"Exception count %d", exception_count);
590 CHECK(interrupt_count > 0,
"Expected at least one regular interrupt");
593 CHECK(nmi_count > 0,
"Expected at least one nmi");
594 CHECK(exception_count > 0,
"Expected at least one exception");
597 bool is_cause =
true;
599 &alert_handler, kExpectedAlertNumber, &is_cause));
603 rv_core_ibex_fault_checker(
false);
606 LOG_ERROR(
"Unexpected rst_info=0x%x", rst_info);