10 #include "sw/device/lib/runtime/irq.h" 
   12 #include "sw/device/lib/testing/csrng_testutils.h" 
   13 #include "sw/device/lib/testing/entropy_testutils.h" 
   15 #include "sw/device/lib/testing/rand_testutils.h" 
   16 #include "sw/device/lib/testing/rv_plic_testutils.h" 
   17 #include "sw/device/lib/testing/test_framework/check.h" 
   19 #include "sw/device/tests/otbn_randomness_impl.h" 
   22 #include "sw/device/lib/testing/autogen/isr_testutils.h" 
   24 static dif_csrng_t csrng;
 
   25 static dif_edn_t edn0;
 
   26 static dif_edn_t edn1;
 
   27 static dif_otbn_t otbn;
 
   28 static dif_rv_plic_t plic;
 
   30 OTTF_DEFINE_TEST_CONFIG();
 
   37   kTestParamFifoBufferSize = 12,
 
   41   kTestParamNumIterationsSim = 1,
 
   42   kTestParamNumIterationsOther = 20,
 
   48 typedef enum irq_flag_id {
 
   49   kTestIrqFlagIdCsrngEntropyReq,
 
   50   kTestIrqFlagIdEdn1CmdDone,
 
   51   kTestIrqFlagIdEdn0CmdDone,
 
   59 static volatile bool irq_flags[kTestIrqFlagCount];
 
   64 static void init_peripherals(
void) {
 
   65   CHECK_DIF_OK(dif_csrng_init(
 
   73   CHECK_DIF_OK(dif_rv_plic_init(
 
   80 static void plic_interrupts_enable(
void) {
 
   81   irq_external_ctrl(
false);
 
   82   irq_global_ctrl(
false);
 
   84   for (
size_t i = 0; i < kTestIrqFlagCount; ++i) {
 
   91   for (
size_t i = 0; i < 
ARRAYSIZE(irq_ids); ++i) {
 
  101   CHECK_DIF_OK(dif_csrng_irq_set_enabled(&csrng, kDifCsrngIrqCsEntropyReq,
 
  103   CHECK_DIF_OK(dif_edn_irq_set_enabled(&edn0, kDifEdnIrqEdnCmdReqDone,
 
  105   CHECK_DIF_OK(dif_edn_irq_set_enabled(&edn1, kDifEdnIrqEdnCmdReqDone,
 
  108   irq_global_ctrl(
true);
 
  109   irq_external_ctrl(
true);
 
  116 static void irq_block_wait(irq_flag_id_t isr_id) {
 
  117   ATOMIC_WAIT_FOR_INTERRUPT(irq_flags[isr_id]);
 
  119     case kTestIrqFlagIdCsrngEntropyReq:
 
  120       CHECK_DIF_OK(dif_csrng_irq_set_enabled(&csrng, kDifCsrngIrqCsEntropyReq,
 
  123     case kTestIrqFlagIdEdn0CmdDone:
 
  124       CHECK_DIF_OK(dif_edn_irq_set_enabled(&edn0, kDifEdnIrqEdnCmdReqDone,
 
  127     case kTestIrqFlagIdEdn1CmdDone:
 
  128       CHECK_DIF_OK(dif_edn_irq_set_enabled(&edn0, kDifEdnIrqEdnCmdReqDone,
 
  132       CHECK(
false, 
"Invalid isr_id: %d", isr_id);
 
  142 static void csrng_generate_output_check(
void) {
 
  143   uint32_t output[kTestParamFifoBufferSize] = {0};
 
  145       csrng_testutils_cmd_generate_run(&csrng, output, 
ARRAYSIZE(output)));
 
  147   uint32_t prev_data = 0;
 
  148   for (
size_t i = 0; i < 
ARRAYSIZE(output); ++i) {
 
  149     CHECK(prev_data != output[i],
 
  150           "Received duplicate data. Last index: %d, value: 0x%x", i, prev_data);
 
  158 static void test_csrng_sw_entropy_req_interrupt(
 
  160   CHECK_STATUS_OK(entropy_testutils_stop_all());
 
  161   CHECK_STATUS_OK(entropy_testutils_entropy_src_init());
 
  165   CHECK_STATUS_OK(csrng_testutils_cmd_ready_wait(&csrng));
 
  166   plic_interrupts_enable();
 
  169   irq_block_wait(kTestIrqFlagIdCsrngEntropyReq);
 
  170   csrng_generate_output_check();
 
  172   plic_interrupts_enable();
 
  174   irq_block_wait(kTestIrqFlagIdCsrngEntropyReq);
 
  175   csrng_generate_output_check();
 
  177   CHECK_STATUS_OK(csrng_testutils_cmd_status_check(&csrng));
 
  178   CHECK_STATUS_OK(csrng_testutils_recoverable_alerts_check(&csrng));
 
  186 static void edn_ready_wait(
const dif_edn_t *edn) {
 
  193   CHECK(!ack_err, 
"Unexpected CSRNG ack error");
 
  207 static void edn_configure(
const dif_edn_t *edn, irq_flag_id_t irq_flag_id,
 
  212   plic_interrupts_enable();
 
  215   irq_block_wait(kTestIrqFlagIdCsrngEntropyReq);
 
  216   irq_block_wait(irq_flag_id);
 
  219   plic_interrupts_enable();
 
  221   irq_block_wait(kTestIrqFlagIdCsrngEntropyReq);
 
  222   irq_block_wait(irq_flag_id);
 
  235   CHECK_STATUS_OK(entropy_testutils_stop_all());
 
  237   CHECK_STATUS_OK(entropy_testutils_entropy_src_init());
 
  240   edn_configure(&edn0, kTestIrqFlagIdEdn0CmdDone, seed_material);
 
  241   edn_configure(&edn1, kTestIrqFlagIdEdn1CmdDone, seed_material);
 
  243   plic_interrupts_enable();
 
  254   const size_t kEdnBlockSizeBits = 128;     
 
  255   const size_t kOtbnRequestSizeBits = 256;  
 
  256   const size_t kOtbnTestRequestCount =
 
  260   size_t edn1_generated_blocks = 0;
 
  265   edn_ready_wait(&edn0);
 
  266   edn_ready_wait(&edn1);
 
  267   CHECK_STATUS_OK(entropy_testutils_error_check(&csrng, &edn0, &edn1));
 
  270   otbn_randomness_test_start(&otbn, 0);
 
  276     if (irq_flags[kTestIrqFlagIdEdn0CmdDone]) {
 
  277       irq_flags[kTestIrqFlagIdEdn0CmdDone] = 
false;
 
  280     if (irq_flags[kTestIrqFlagIdEdn1CmdDone]) {
 
  281       edn1_generated_blocks++;
 
  282       if (edn1_generated_blocks <
 
  283           kOtbnTestRequestCount * kOtbnRequestSizeBits / kEdnBlockSizeBits) {
 
  284         irq_flags[kTestIrqFlagIdEdn1CmdDone] = 
false;
 
  292     busy = 
status != kDifOtbnStatusIdle && 
status != kDifOtbnStatusLocked;
 
  295   CHECK(otbn_randomness_test_end(&otbn, 
false));
 
  300   irq_block_wait(kTestIrqFlagIdEdn1CmdDone);
 
  301   irq_block_wait(kTestIrqFlagIdEdn0CmdDone);
 
  304   plic_interrupts_enable();
 
  306   irq_block_wait(kTestIrqFlagIdEdn0CmdDone);
 
  308   plic_interrupts_enable();
 
  310   irq_block_wait(kTestIrqFlagIdEdn1CmdDone);
 
  312   CHECK_STATUS_OK(csrng_testutils_recoverable_alerts_check(&csrng));
 
  313   CHECK_STATUS_OK(entropy_testutils_error_check(&csrng, &edn0, &edn1));
 
  316 void ottf_external_isr(uint32_t *exc_info) {
 
  330     dif_csrng_irq_t irq =
 
  332     CHECK(irq == kDifCsrngIrqCsEntropyReq, 
"Unexpected irq: 0x%x", irq);
 
  333     CHECK_DIF_OK(dif_csrng_irq_acknowledge(&csrng, irq));
 
  334     irq_flags[kTestIrqFlagIdCsrngEntropyReq] = 
true;
 
  338     CHECK(irq == kDifEdnIrqEdnCmdReqDone, 
"Unexpected irq: 0x%x", irq);
 
  339     CHECK_DIF_OK(dif_edn_irq_acknowledge(&edn0, irq));
 
  340     irq_flags[kTestIrqFlagIdEdn0CmdDone] = 
true;
 
  344     CHECK(irq == kDifEdnIrqEdnCmdReqDone, 
"Unexpected irq: 0x%x", irq);
 
  345     CHECK_DIF_OK(dif_edn_irq_acknowledge(&edn1, irq));
 
  346     irq_flags[kTestIrqFlagIdEdn1CmdDone] = 
true;
 
  368   for (
size_t i = 0; i < edn_seed.
len; ++i) {
 
  369     edn_seed.
data[i] = rand_testutils_gen32();
 
  372   uint32_t num_iterations = kTestParamNumIterationsSim;
 
  374     num_iterations = kTestParamNumIterationsOther;
 
  377   for (
size_t i = 0; i < num_iterations; ++i) {
 
  378     test_csrng_sw_entropy_req_interrupt(&csrng_seed);
 
  379     test_edn_cmd_done(&edn_seed);