5 #include "dt/dt_pwrmgr.h"
6 #include "dt/dt_rstmgr.h"
7 #include "dt/dt_rv_core_ibex.h"
13 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
15 #include "sw/device/lib/testing/aon_timer_testutils.h"
16 #include "sw/device/lib/testing/rstmgr_testutils.h"
17 #include "sw/device/lib/testing/rv_core_ibex_testutils.h"
18 #include "sw/device/lib/testing/test_framework/check.h"
19 #include "sw/device/lib/testing/test_framework/ottf_isrs.h"
22 OTTF_DEFINE_TEST_CONFIG();
46 kIllegalAddr0 = 0xF0000000,
47 kIllegalAddr1 = 0xF0000004,
48 kIllegalAddr2 = 0x00000008,
53 extern const uint32_t _ottf_interrupt_vector;
56 extern const char kSingleFaultAddr[];
57 extern const char kSingleFaultAddrCurrentPc[];
58 extern const char kSingleFaultAddrNextPc[];
59 extern const char kDoubleFaultFirstAddr[];
60 extern const char kDoubleFaultSecondAddr[];
63 static dif_rstmgr_t rstmgr;
66 volatile static uint32_t addr_val;
73 volatile static bool double_fault;
78 void ottf_exception_handler(uint32_t *exc_info) {
93 "This point should be unreachable; "
94 "a reset or another fault should have occured.");
104 const dif_rv_core_ibex_t *ibex) {
110 CHECK(size_read == kCpuDumpSize,
111 "The observed cpu info dump's size was %d, "
112 "but it was expected to be %d",
113 size_read, kCpuDumpSize);
117 dif_rv_core_ibex_parse_crash_dump(ibex, dump, size_read, &output));
135 RV_CORE_IBEX_TESTUTILS_PRINT_CRASH_DUMP(obs_state);
136 RV_CORE_IBEX_TESTUTILS_PRINT_CRASH_DUMP(exp_state);
139 "Last Exception Access Addr: Expected 0x%x != Observed 0x%x",
143 CHECK(exp_state.
mcpc == obs_state.
mcpc ||
145 exp_state.
mcpc - 4 == obs_state.
mcpc),
146 "Current PC: Observed 0x%x not within 4 bytes of Expected 0x%x",
148 CHECK(exp_state.
mnpc == obs_state.
mnpc,
149 "Next PC: Expected 0x%x != Observed 0x%x", exp_state.
mnpc,
151 CHECK(exp_state.
mdaa == obs_state.
mdaa,
152 "Last Data Access Addr: Expected 0x%x != Observed 0x%x", exp_state.
mdaa,
154 CHECK(exp_state.
mpec == obs_state.
mpec,
155 "The Observed MPEC, 0x%x, was not in the expected 0x%x", obs_state.
mpec,
166 static void check_prev_state(
169 RV_CORE_IBEX_TESTUTILS_PRINT_CRASH_PREVIOUS_DUMP(obs_prev_state);
170 RV_CORE_IBEX_TESTUTILS_PRINT_CRASH_PREVIOUS_DUMP(exp_prev_state);
171 CHECK(exp_prev_state.
mtval == obs_prev_state.
mtval,
172 "Last Exception Access Addr: Expected 0x%x != Observed 0x%x",
174 CHECK(exp_prev_state.
mpec == obs_prev_state.
mpec,
175 "The Observed Previous MPEC, 0x%x, "
176 "was not in the expected 0x%x",
177 obs_prev_state.
mpec, exp_prev_state.
mpec);
183 dif_aon_timer_t aon_timer;
185 dif_rv_core_ibex_t ibex;
186 dt_rv_core_ibex_t ibex_dt = (dt_rv_core_ibex_t)0;
187 static_assert(kDtRvCoreIbexCount >= 1,
188 "This test requires at least 1 Ibex core.");
191 CHECK_DIF_OK(dif_rstmgr_init_from_dt(kDtRstmgrAon, &rstmgr));
192 CHECK_DIF_OK(dif_aon_timer_init_from_dt(kDtAonTimerAon, &aon_timer));
193 CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kDtPwrmgrAon, &pwrmgr));
194 CHECK_DIF_OK(dif_rv_core_ibex_init_from_dt(ibex_dt, &ibex));
196 switch (rstmgr_testutils_reason_get()) {
198 LOG_INFO(
"Triggering single fault.");
203 double_fault =
false;
207 "This should be unreachable; a single fault should have occurred.");
211 LOG_INFO(
"Checking CPU info dump after single fault.");
213 dump = get_dump(&ibex);
217 "CPU Info dump shows a double fault after experiencing only a single "
222 .mtval = (uint32_t)kIllegalAddr0,
223 .mpec = (uint32_t)kSingleFaultAddr + 4,
224 .mdaa = (uint32_t)&addr_val,
225 .mcpc = (uint32_t)kSingleFaultAddrCurrentPc,
226 .mnpc = (uint32_t)kSingleFaultAddrNextPc,
230 LOG_INFO(
"Setting up watch dog and triggering a double fault.");
234 uint32_t bark_cycles = 0;
236 aon_timer_testutils_get_aon_cycles_32_from_us(1, &bark_cycles));
237 uint32_t bite_cycles = 0;
239 aon_timer_testutils_get_aon_cycles_32_from_us(100, &bite_cycles));
246 CHECK_STATUS_OK(aon_timer_testutils_watchdog_config(
247 &aon_timer, bark_cycles, bite_cycles,
false));
255 "This should be unreachable; a double fault should have occured.");
258 case kDifRstmgrResetInfoWatchdog:
259 LOG_INFO(
"Checking CPU info dump after double fault.");
261 dump = get_dump(&ibex);
264 "CPU Info dump doesn't show a double fault has happened.");
275 .mtval = (uint32_t)kIllegalAddr2,
276 .mpec = (uint32_t)kDoubleFaultSecondAddr,
277 .mdaa = (uint32_t)kIllegalAddr2,
278 .mcpc = (uint32_t)kDoubleFaultSecondAddr + 4,
279 .mnpc = (uint32_t)&_ottf_interrupt_vector,
285 .mtval = (uint32_t)kIllegalAddr1,
286 .mpec = (uint32_t)kDoubleFaultFirstAddr + 4,
292 CHECK(
false,
"Device was reset by an unexpected source.");