7 #include "sw/device/lib/dif/dif_rv_core_ibex.h"
10 #include "sw/device/lib/testing/test_framework/check.h"
13 static_assert(kDtOtbnCount >= 1,
14 "This test requires at least one OTBN instance");
16 static_assert(kDtRvCoreIbexCount >= 1,
17 "This test requires at least one rv_core_ibex instance");
19 static dt_otbn_t kTestOtbn = (dt_otbn_t)0;
20 static dt_rv_core_ibex_t kTestRvCoreIbex = (dt_rv_core_ibex_t)0;
22 OTTF_DEFINE_TEST_CONFIG();
24 typedef dif_result_t (*otbn_read_t)(
const dif_otbn_t *otbn,
25 uint32_t offset_bytes,
void *dest,
28 typedef dif_result_t (*otbn_write_t)(
const dif_otbn_t *otbn,
29 uint32_t offset_bytes,
const void *src,
80 kNumIntgErrorsThreshold = kNumAddrs - 2,
82 static_assert(kNumAddrs == 50,
83 "kNumAddrs changed, so kEccErrorProbability should be "
86 static volatile bool has_irq_fired;
91 void ottf_load_integrity_error_handler(uint32_t *exc_info) {
104 static void get_rand_words(dif_rv_core_ibex_t *ibex,
int num, uint32_t *rnd_buf,
107 for (
int i = 0; i < num; ++i) {
109 while (found ==
false) {
111 CHECK_DIF_OK(dif_rv_core_ibex_read_rnd_data(ibex, &rnd_word));
112 rnd_word = rnd_word % max;
115 for (
int j = 0; j < i; ++j) {
116 if (rnd_buf[j] == rnd_word) {
124 rnd_buf[i] = rnd_word;
137 static void otbn_write_mem_words(
const dif_otbn_t *otbn,
const int num,
138 const uint32_t *word_addrs,
139 otbn_write_t otbn_write) {
140 for (
int i = 0; i < num; ++i) {
141 otbn_write(otbn, word_addrs[i] *
sizeof(uint32_t), (
void *)&word_addrs[i],
159 static void otbn_check_mem_words(
const dif_otbn_t *otbn,
const int num,
160 const uint32_t *word_addrs,
161 otbn_read_t otbn_read,
int *num_matches,
162 int *num_intg_errors) {
164 *num_intg_errors = 0;
168 for (
int i = 0; i < num; ++i) {
171 has_irq_fired =
false;
172 otbn_read(otbn, word_addrs[i] *
sizeof(uint32_t), (
void *)&word,
174 match = (word_addrs[i] == word);
179 *num_intg_errors += 1;
183 if ((match ==
false) && (has_irq_fired ==
false)) {
185 "Mismatch without integrity error: Entry %i, address 0x%x, "
187 i, word_addrs[i], word);
195 CHECK_DIF_OK(dif_otbn_init_from_dt(kTestOtbn, &otbn));
198 dif_rv_core_ibex_t ibex;
199 CHECK_DIF_OK(dif_rv_core_ibex_init_from_dt(kTestRvCoreIbex, &ibex));
201 uint32_t imem_offsets[kNumAddrs];
202 uint32_t dmem_offsets[kNumAddrs];
204 int num_matches_imem, num_intg_errors_imem;
205 int num_matches_dmem, num_intg_errors_dmem;
209 get_rand_words(&ibex, kNumAddrs, imem_offsets, max);
211 get_rand_words(&ibex, kNumAddrs, dmem_offsets, max);
223 &num_matches_imem, &num_intg_errors_imem);
224 CHECK(num_matches_imem == kNumAddrs,
"%i unexpected IMEM mismatches",
225 kNumAddrs - num_matches_imem);
226 CHECK(!num_intg_errors_imem,
"%i unexpected IMEM integrity errors",
227 num_intg_errors_imem);
230 &num_matches_dmem, &num_intg_errors_dmem);
231 CHECK(num_matches_dmem == kNumAddrs,
"%i unexpected DMEM mismatches",
232 kNumAddrs - num_matches_dmem);
233 CHECK(!num_intg_errors_dmem,
"%i unexpected DMEM integrity errors",
234 num_intg_errors_dmem);
245 &num_matches_imem, &num_intg_errors_imem);
246 CHECK(num_intg_errors_imem >= kNumIntgErrorsThreshold,
247 "Expecting at least %i IMEM integrity errors, got %i",
248 kNumIntgErrorsThreshold, num_intg_errors_imem);
250 &num_matches_dmem, &num_intg_errors_dmem);
251 CHECK(num_intg_errors_dmem >= kNumIntgErrorsThreshold,
252 "Expecting at least %i DMEM integrity errors, got %i",
253 kNumIntgErrorsThreshold, num_intg_errors_dmem);