5 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
7 #include "gtest/gtest.h"
9 #include "sw/device/lib/base/mock_mmio.h"
13 #include "rv_core_ibex_regs.h"
23 std::ostream &operator<<(
28 <<
" .remap_addr = " << mapping.
remap_addr <<
",\n"
29 <<
" .size = " << mapping.
size <<
",\n"
40 std::ostream &operator<<(std::ostream &os,
51 std::ostream &operator<<(std::ostream &os,
54 <<
"fault_state = {\n"
61 <<
"previous_fault_state = {\n"
73 namespace dif_rv_core_ibex_test {
85 dif_rv_core_ibex_t ibex_;
94 public testing::WithParamInterface<
95 std::tuple<dif_rv_core_ibex_addr_translation_slot_t,
96 dif_rv_core_ibex_addr_translation_bus_t, uint32_t,
97 uint32_t, uint32_t, uint32_t>> {
101 .remap_addr = 0x2000000,
105 uint32_t Napot(uint32_t addr,
size_t size) {
return addr | (size - 1) >> 1; }
108 AddressTranslationTest::kMapping;
110 INSTANTIATE_TEST_SUITE_P(
112 testing::ValuesIn(std::vector<
113 std::tuple<dif_rv_core_ibex_addr_translation_slot_t,
114 dif_rv_core_ibex_addr_translation_bus_t,
115 uint32_t, uint32_t, uint32_t, uint32_t>>{{
116 {kDifRvCoreIbexAddrTranslationSlot_0, kDifRvCoreIbexAddrTranslationDBus,
117 RV_CORE_IBEX_DBUS_ADDR_MATCHING_0_REG_OFFSET,
118 RV_CORE_IBEX_DBUS_REMAP_ADDR_0_REG_OFFSET,
119 RV_CORE_IBEX_DBUS_ADDR_EN_0_REG_OFFSET,
120 RV_CORE_IBEX_DBUS_REGWEN_0_REG_OFFSET},
122 {kDifRvCoreIbexAddrTranslationSlot_0, kDifRvCoreIbexAddrTranslationIBus,
123 RV_CORE_IBEX_IBUS_ADDR_MATCHING_0_REG_OFFSET,
124 RV_CORE_IBEX_IBUS_REMAP_ADDR_0_REG_OFFSET,
125 RV_CORE_IBEX_IBUS_ADDR_EN_0_REG_OFFSET,
126 RV_CORE_IBEX_IBUS_REGWEN_0_REG_OFFSET},
128 {kDifRvCoreIbexAddrTranslationSlot_1, kDifRvCoreIbexAddrTranslationDBus,
129 RV_CORE_IBEX_DBUS_ADDR_MATCHING_1_REG_OFFSET,
130 RV_CORE_IBEX_DBUS_REMAP_ADDR_1_REG_OFFSET,
131 RV_CORE_IBEX_DBUS_ADDR_EN_1_REG_OFFSET,
132 RV_CORE_IBEX_DBUS_REGWEN_1_REG_OFFSET},
134 {kDifRvCoreIbexAddrTranslationSlot_1, kDifRvCoreIbexAddrTranslationIBus,
135 RV_CORE_IBEX_IBUS_ADDR_MATCHING_1_REG_OFFSET,
136 RV_CORE_IBEX_IBUS_REMAP_ADDR_1_REG_OFFSET,
137 RV_CORE_IBEX_IBUS_ADDR_EN_1_REG_OFFSET,
138 RV_CORE_IBEX_IBUS_REGWEN_1_REG_OFFSET},
140 [](const ::testing::TestParamInfo<AddressTranslationTest::ParamType>
142 const auto slot = std::get<0>(info.param);
143 const auto bus = std::get<1>(info.param);
144 std::string name =
"";
145 name += bus == kDifRvCoreIbexAddrTranslationDBus ?
"DBus" :
"IBus";
146 name += slot == kDifRvCoreIbexAddrTranslationSlot_0 ?
"Slot0" :
"Slot1";
150 TEST_P(AddressTranslationTest, DisableSuccess) {
151 const auto slot = std::get<0>(GetParam());
152 const auto bus = std::get<1>(GetParam());
153 const auto en_reg = std::get<4>(GetParam());
154 const auto r_regwen = std::get<5>(GetParam());
156 EXPECT_READ32(r_regwen, 1);
157 EXPECT_WRITE32(en_reg, 0);
158 EXPECT_DIF_OK(dif_rv_core_ibex_disable_addr_translation(&ibex_, slot, bus));
161 TEST_P(AddressTranslationTest, EnableSuccess) {
162 const auto slot = std::get<0>(GetParam());
163 const auto bus = std::get<1>(GetParam());
164 const auto en_reg = std::get<4>(GetParam());
165 const auto r_regwen = std::get<5>(GetParam());
167 EXPECT_READ32(r_regwen, 1);
168 EXPECT_WRITE32(en_reg, 1);
169 EXPECT_DIF_OK(dif_rv_core_ibex_enable_addr_translation(&ibex_, slot, bus));
172 TEST_P(AddressTranslationTest, ConfigureSuccess) {
173 const auto slot = std::get<0>(GetParam());
174 const auto bus = std::get<1>(GetParam());
175 const auto r_matching = std::get<2>(GetParam());
176 const auto r_remap = std::get<3>(GetParam());
177 const auto r_regwen = std::get<5>(GetParam());
179 EXPECT_READ32(r_regwen, 1);
181 EXPECT_WRITE32(r_matching, 0x9003fff);
182 EXPECT_WRITE32(r_remap, kMapping.remap_addr);
185 dif_rv_core_ibex_configure_addr_translation(&ibex_, slot, bus, kMapping));
188 TEST_P(AddressTranslationTest, PowerOfTwoAlignmentSuccess) {
189 const auto slot = std::get<0>(GetParam());
190 const auto bus = std::get<1>(GetParam());
191 const auto r_matching = std::get<2>(GetParam());
192 const auto r_remap = std::get<3>(GetParam());
193 const auto r_regwen = std::get<5>(GetParam());
198 for (
size_t i = 0; i < (
sizeof(uint32_t) * 8) - 1; ++i) {
199 mapping.
size = 1u << i;
201 EXPECT_READ32(r_regwen, 1);
206 EXPECT_DIF_OK(dif_rv_core_ibex_configure_addr_translation(&ibex_, slot, bus,
211 TEST_P(AddressTranslationTest, NotPowerOfTwo) {
212 const auto slot = std::get<0>(GetParam());
213 const auto bus = std::get<1>(GetParam());
216 mapping.
size += 0x20;
218 dif_rv_core_ibex_configure_addr_translation(&ibex_, slot, bus, mapping));
221 TEST_P(AddressTranslationTest, ReadSuccess) {
222 const auto slot = std::get<0>(GetParam());
223 const auto bus = std::get<1>(GetParam());
224 const auto r_matching = std::get<2>(GetParam());
225 const auto r_remap = std::get<3>(GetParam());
227 EXPECT_READ32(r_matching, 0x9003fff);
228 EXPECT_READ32(r_remap, kMapping.remap_addr);
232 dif_rv_core_ibex_read_addr_translation(&ibex_, slot, bus, &mapping));
234 EXPECT_EQ(mapping, kMapping);
237 TEST_P(AddressTranslationTest, LockSuccess) {
238 const auto slot = std::get<0>(GetParam());
239 const auto bus = std::get<1>(GetParam());
240 const auto r_regwen = std::get<5>(GetParam());
242 EXPECT_READ32(r_regwen, 1);
243 EXPECT_WRITE32(r_regwen, 0);
245 EXPECT_DIF_OK(dif_rv_core_ibex_lock_addr_translation(&ibex_, slot, bus));
248 TEST_P(AddressTranslationTest, Locked) {
249 const auto slot = std::get<0>(GetParam());
250 const auto bus = std::get<1>(GetParam());
251 const auto r_regwen = std::get<5>(GetParam());
253 EXPECT_READ32(r_regwen, 0);
255 dif_rv_core_ibex_configure_addr_translation(&ibex_, slot, bus, kMapping),
258 EXPECT_READ32(r_regwen, 0);
259 EXPECT_EQ(dif_rv_core_ibex_enable_addr_translation(&ibex_, slot, bus),
262 EXPECT_READ32(r_regwen, 0);
263 EXPECT_EQ(dif_rv_core_ibex_disable_addr_translation(&ibex_, slot, bus),
268 EXPECT_READ32(r_regwen, 0);
269 EXPECT_DIF_OK(dif_rv_core_ibex_lock_addr_translation(&ibex_, slot, bus));
272 TEST_F(AddressTranslationTest, BadArg) {
273 const auto slot = kDifRvCoreIbexAddrTranslationSlot_0;
274 const auto bus = kDifRvCoreIbexAddrTranslationDBus;
275 const auto bad_slot = kDifRvCoreIbexAddrTranslationSlotCount;
276 const auto bad_bus = kDifRvCoreIbexAddrTranslationBusCount;
280 dif_rv_core_ibex_configure_addr_translation(
nullptr, slot, bus, mapping));
282 &ibex_, slot, bad_bus, mapping));
284 &ibex_, bad_slot, bus, mapping));
287 dif_rv_core_ibex_read_addr_translation(
nullptr, slot, bus, &mapping));
289 dif_rv_core_ibex_read_addr_translation(&ibex_, bad_slot, bus, &mapping));
291 dif_rv_core_ibex_read_addr_translation(&ibex_, slot, bad_bus, &mapping));
293 dif_rv_core_ibex_read_addr_translation(&ibex_, slot, bus,
nullptr));
297 dif_rv_core_ibex_lock_addr_translation(&ibex_, bad_slot, bus));
299 dif_rv_core_ibex_lock_addr_translation(&ibex_, slot, bad_bus));
302 dif_rv_core_ibex_enable_addr_translation(
nullptr, slot, bus));
304 dif_rv_core_ibex_enable_addr_translation(&ibex_, bad_slot, bus));
306 dif_rv_core_ibex_enable_addr_translation(&ibex_, slot, bad_bus));
309 dif_rv_core_ibex_disable_addr_translation(
nullptr, slot, bus));
311 dif_rv_core_ibex_disable_addr_translation(&ibex_, bad_slot, bus));
313 dif_rv_core_ibex_disable_addr_translation(&ibex_, slot, bad_bus));
318 public testing::WithParamInterface<
319 std::tuple<uint32_t, dif_rv_core_ibex_error_status_t>> {};
322 auto reg = std::get<0>(GetParam());
323 auto status = std::get<1>(GetParam());
325 EXPECT_READ32(RV_CORE_IBEX_ERR_STATUS_REG_OFFSET, {{reg, 1}});
326 dif_rv_core_ibex_error_status_t error_status;
327 EXPECT_DIF_OK(dif_rv_core_ibex_get_error_status(&ibex_, &error_status));
328 EXPECT_EQ(
status, error_status);
331 TEST_P(ErrorStatusTest, ClearSuccess) {
332 auto reg = std::get<0>(GetParam());
333 auto status = std::get<1>(GetParam());
334 EXPECT_WRITE32(RV_CORE_IBEX_ERR_STATUS_REG_OFFSET, {{reg, 1}});
338 INSTANTIATE_TEST_SUITE_P(
339 ErrorStatusTest, ErrorStatusTest,
341 std::vector<std::tuple<uint32_t, dif_rv_core_ibex_error_status_t>>{{
342 {RV_CORE_IBEX_ERR_STATUS_REG_INTG_ERR_BIT,
343 kDifRvCoreIbexErrorStatusRegisterTransmissionIntegrity},
344 {RV_CORE_IBEX_ERR_STATUS_FATAL_INTG_ERR_BIT,
345 kDifRvCoreIbexErrorStatusFatalResponseIntegrity},
346 {RV_CORE_IBEX_ERR_STATUS_FATAL_CORE_ERR_BIT,
347 kDifRvCoreIbexErrorStatusFatalInternalError},
348 {RV_CORE_IBEX_ERR_STATUS_RECOV_CORE_ERR_BIT,
349 kDifRvCoreIbexErrorStatusRecoverableInternal},
352 TEST_F(ErrorStatusTest, ReadBadArg) {
353 dif_rv_core_ibex_error_status_t error_status;
358 TEST_F(ErrorStatusTest, ClearBadArg) {
360 nullptr, kDifRvCoreIbexErrorStatusRegisterTransmissionIntegrity));
362 &ibex_,
static_cast<dif_rv_core_ibex_error_status_t
>(-1)));
367 public testing::WithParamInterface<dif_rv_core_ibex_nmi_state_t> {};
369 TEST_F(
NMITest, EnableAlertSuccess) {
370 EXPECT_WRITE32(RV_CORE_IBEX_NMI_ENABLE_REG_OFFSET,
371 {{RV_CORE_IBEX_NMI_ENABLE_ALERT_EN_BIT, 1}});
373 dif_rv_core_ibex_enable_nmi(&ibex_, kDifRvCoreIbexNmiSourceAlert));
376 TEST_F(NMITest, EnableWdogSuccess) {
377 EXPECT_WRITE32(RV_CORE_IBEX_NMI_ENABLE_REG_OFFSET,
378 {{RV_CORE_IBEX_NMI_ENABLE_WDOG_EN_BIT, 1}});
380 dif_rv_core_ibex_enable_nmi(&ibex_, kDifRvCoreIbexNmiSourceWdog));
383 TEST_F(NMITest, EnableAllSuccess) {
384 EXPECT_WRITE32(RV_CORE_IBEX_NMI_ENABLE_REG_OFFSET,
385 {{RV_CORE_IBEX_NMI_ENABLE_WDOG_EN_BIT, 1},
386 {RV_CORE_IBEX_NMI_ENABLE_ALERT_EN_BIT, 1}});
388 dif_rv_core_ibex_enable_nmi(&ibex_, kDifRvCoreIbexNmiSourceAll));
391 TEST_F(NMITest, EnableBadArg) {
393 dif_rv_core_ibex_enable_nmi(
nullptr, kDifRvCoreIbexNmiSourceWdog));
395 &ibex_,
static_cast<dif_rv_core_ibex_nmi_source_t
>(-1)));
398 TEST_P(NMITest, GetStateSuccess) {
402 RV_CORE_IBEX_NMI_ENABLE_REG_OFFSET,
404 {RV_CORE_IBEX_NMI_ENABLE_ALERT_EN_BIT, expected_state.
alert_enabled},
405 {RV_CORE_IBEX_NMI_ENABLE_WDOG_EN_BIT, expected_state.
wdog_enabled},
409 RV_CORE_IBEX_NMI_STATE_REG_OFFSET,
411 {RV_CORE_IBEX_NMI_STATE_ALERT_BIT, expected_state.
alert_raised},
412 {RV_CORE_IBEX_NMI_STATE_WDOG_BIT, expected_state.
wdog_barked},
416 EXPECT_DIF_OK(dif_rv_core_ibex_get_nmi_state(&ibex_, &state));
417 EXPECT_EQ(expected_state, state);
420 INSTANTIATE_TEST_SUITE_P(
422 testing::ValuesIn(std::vector<dif_rv_core_ibex_nmi_state_t>{{
423 {
true,
false,
false,
false},
424 {
false,
true,
false,
false},
425 {
false,
false,
true,
false},
426 {
false,
false,
false,
true},
429 TEST_F(NMITest, GetStateBadArg) {
435 TEST_F(NMITest, ClearAlertSuccess) {
436 EXPECT_WRITE32(RV_CORE_IBEX_NMI_STATE_REG_OFFSET,
437 {{RV_CORE_IBEX_NMI_STATE_ALERT_BIT, 1}});
439 dif_rv_core_ibex_clear_nmi_state(&ibex_, kDifRvCoreIbexNmiSourceAlert));
442 TEST_F(NMITest, ClearWdogSuccess) {
443 EXPECT_WRITE32(RV_CORE_IBEX_NMI_STATE_REG_OFFSET,
444 {{RV_CORE_IBEX_NMI_STATE_WDOG_BIT, 1}});
446 dif_rv_core_ibex_clear_nmi_state(&ibex_, kDifRvCoreIbexNmiSourceWdog));
449 TEST_F(NMITest, ClearAllSuccess) {
450 EXPECT_WRITE32(RV_CORE_IBEX_NMI_STATE_REG_OFFSET,
451 {{RV_CORE_IBEX_NMI_STATE_WDOG_BIT, 1},
452 {RV_CORE_IBEX_NMI_ENABLE_ALERT_EN_BIT, 1}});
454 dif_rv_core_ibex_clear_nmi_state(&ibex_, kDifRvCoreIbexNmiSourceAll));
457 TEST_F(NMITest, ClearBadArg) {
459 dif_rv_core_ibex_clear_nmi_state(
nullptr, kDifRvCoreIbexNmiSourceWdog));
461 &ibex_,
static_cast<dif_rv_core_ibex_nmi_source_t
>(-1)));
467 EXPECT_READ32(RV_CORE_IBEX_RND_DATA_REG_OFFSET, 0xf55ef65e);
470 EXPECT_DIF_OK(dif_rv_core_ibex_read_rnd_data(&ibex_, &data));
471 EXPECT_EQ(data, 0xf55ef65e);
474 TEST_F(RndTest, ReadBadArg) {
480 TEST_F(RndTest, StatusValid) {
481 EXPECT_READ32(RV_CORE_IBEX_RND_STATUS_REG_OFFSET,
482 {{RV_CORE_IBEX_RND_STATUS_RND_DATA_VALID_BIT,
true}});
484 dif_rv_core_ibex_rnd_status_t
status;
486 EXPECT_EQ(
status, kDifRvCoreIbexRndStatusValid);
489 TEST_F(RndTest, StatusFipsCompliant) {
490 EXPECT_READ32(RV_CORE_IBEX_RND_STATUS_REG_OFFSET,
491 {{RV_CORE_IBEX_RND_STATUS_RND_DATA_FIPS_BIT,
true}});
493 dif_rv_core_ibex_rnd_status_t
status;
495 EXPECT_EQ(
status, kDifRvCoreIbexRndStatusFipsCompliant);
498 TEST_F(RndTest, StatusBadArg) {
499 dif_rv_core_ibex_rnd_status_t
status;
507 EXPECT_READ32(RV_CORE_IBEX_FPGA_INFO_REG_OFFSET, 0xf55ef65e);
508 dif_rv_core_ibex_fpga_info_t info;
509 EXPECT_DIF_OK(dif_rv_core_ibex_read_fpga_info(&ibex_, &info));
510 EXPECT_EQ(info, 0xf55ef65e);
513 TEST_F(FpgaInfoTest, ReadZero) {
514 EXPECT_READ32(RV_CORE_IBEX_FPGA_INFO_REG_OFFSET, 0);
515 dif_rv_core_ibex_fpga_info_t info;
516 EXPECT_DIF_OK(dif_rv_core_ibex_read_fpga_info(&ibex_, &info));
520 TEST_F(FpgaInfoTest, ReadBadArg) {
521 dif_rv_core_ibex_fpga_info_t info;
531 EXPECT_READ32(RV_CORE_IBEX_SW_FATAL_ERR_REG_OFFSET, 0x01);
532 EXPECT_DIF_OK(dif_rv_core_ibex_get_sw_fatal_err_alert(&ibex_, &enabled));
533 EXPECT_TRUE(enabled);
535 EXPECT_READ32(RV_CORE_IBEX_SW_FATAL_ERR_REG_OFFSET, kMultiBitBool4True);
536 EXPECT_DIF_OK(dif_rv_core_ibex_get_sw_fatal_err_alert(&ibex_, &enabled));
537 EXPECT_TRUE(enabled);
540 TEST_F(FatalErrorAlertTest, ReadAlertDisabled) {
543 EXPECT_READ32(RV_CORE_IBEX_SW_FATAL_ERR_REG_OFFSET, kMultiBitBool4False);
544 EXPECT_DIF_OK(dif_rv_core_ibex_get_sw_fatal_err_alert(&ibex_, &enabled));
545 EXPECT_FALSE(enabled);
548 TEST_F(FatalErrorAlertTest, TriggerSuccess) {
549 EXPECT_WRITE32(RV_CORE_IBEX_SW_FATAL_ERR_REG_OFFSET, kMultiBitBool4True);
550 EXPECT_DIF_OK(dif_rv_core_ibex_trigger_sw_fatal_err_alert(&ibex_));
553 TEST_F(FatalErrorAlertTest, ReadBadArg) {
559 TEST_F(FatalErrorAlertTest, TriggerBadArg) {
568 EXPECT_READ32(RV_CORE_IBEX_SW_RECOV_ERR_REG_OFFSET, 0x01);
569 EXPECT_DIF_OK(dif_rv_core_ibex_get_sw_recov_err_alert(&ibex_, &enabled));
570 EXPECT_TRUE(enabled);
572 EXPECT_READ32(RV_CORE_IBEX_SW_RECOV_ERR_REG_OFFSET, kMultiBitBool4True);
573 EXPECT_DIF_OK(dif_rv_core_ibex_get_sw_recov_err_alert(&ibex_, &enabled));
574 EXPECT_TRUE(enabled);
577 TEST_F(RecoverableErrorAlertTest, ReadAlertDisabled) {
580 EXPECT_READ32(RV_CORE_IBEX_SW_RECOV_ERR_REG_OFFSET, kMultiBitBool4False);
581 EXPECT_DIF_OK(dif_rv_core_ibex_get_sw_recov_err_alert(&ibex_, &enabled));
582 EXPECT_FALSE(enabled);
585 TEST_F(RecoverableErrorAlertTest, TriggerSuccess) {
586 EXPECT_WRITE32(RV_CORE_IBEX_SW_RECOV_ERR_REG_OFFSET, kMultiBitBool4True);
587 EXPECT_DIF_OK(dif_rv_core_ibex_trigger_sw_recov_err_alert(&ibex_));
590 TEST_F(RecoverableErrorAlertTest, ReadBadArg) {
596 TEST_F(RecoverableErrorAlertTest, TriggerBadArg) {
609 .previous_fault_state = {.mtval = 0x15555555, .mpec = 0x25555555},
616 memcpy(cpu_info, &ref,
sizeof(cpu_info));
618 dif_rv_core_ibex_parse_crash_dump(&ibex_, cpu_info,
sizeof(ref), &dump));
619 EXPECT_EQ(dump, ref);
622 TEST_F(ParseCrashDumpTest, SingleFault) {
629 .previous_fault_state = {.mtval = 0x15555555, .mpec = 0x25555555},
636 memcpy(cpu_info, &ref,
sizeof(cpu_info));
638 dif_rv_core_ibex_parse_crash_dump(&ibex_, cpu_info,
sizeof(ref), &dump));
639 EXPECT_EQ(dump, ref);
642 TEST_F(ParseCrashDumpTest, ReadBadArg) {
647 dif_rv_core_ibex_parse_crash_dump(&ibex_,
nullptr, 9, &out));
650 dif_rv_core_ibex_parse_crash_dump(&ibex_, info, 9,
nullptr));