[sw/testing] Introduce entropy_testutils module

The entropy_testutils module implements common functionality
required to initialize the entropy complex for testing purposes.

Updated test cases to use the testutils functionality provided by the
new module.

Signed-off-by: Miguel Osorio <miguelosorio@google.com>
diff --git a/sw/device/lib/testing/entropy_testutils.c b/sw/device/lib/testing/entropy_testutils.c
new file mode 100644
index 0000000..c629e76
--- /dev/null
+++ b/sw/device/lib/testing/entropy_testutils.c
@@ -0,0 +1,67 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_csrng.h"
+#include "sw/device/lib/dif/dif_entropy.h"
+#include "sw/device/lib/testing/check.h"
+
+#include "edn_regs.h"  // Generated
+#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
+
+static void setup_entropy_src(void) {
+  const dif_entropy_params_t params = {
+      .base_addr = mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
+  };
+  dif_entropy_t entropy;
+  CHECK(dif_entropy_init(params, &entropy) == kDifEntropyOk);
+
+  // Disable entropy for test purpose, as it has been turned on by ROM
+  CHECK(dif_entropy_disable(&entropy) == kDifEntropyOk);
+
+  const dif_entropy_config_t config = {
+      .mode = kDifEntropyModeLfsr,
+      .tests =
+          {
+              [kDifEntropyTestRepCount] = false,
+              [kDifEntropyTestAdaptiveProportion] = false,
+              [kDifEntropyTestBucket] = false,
+              [kDifEntropyTestMarkov] = false,
+              [kDifEntropyTestMailbox] = false,
+              [kDifEntropyTestVendorSpecific] = false,
+          },
+      // this field needs to manually toggled by software.  Disable for now
+      .reset_health_test_registers = false,
+      .single_bit_mode = kDifEntropySingleBitModeDisabled,
+      .route_to_firmware = false,
+      .sample_rate = 2,
+      .lfsr_seed = 0,
+  };
+  CHECK(dif_entropy_configure(&entropy, config) == kDifEntropyOk);
+}
+
+static void setup_csrng(void) {
+  const dif_csrng_params_t params = {
+      .base_addr = mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
+  };
+  dif_csrng_t csrng;
+  CHECK(dif_csrng_init(params, &csrng) == kDifCsrngOk);
+  CHECK(dif_csrng_configure(&csrng) == kDifCsrngOk);
+}
+
+static void setup_edn(void) {
+  // Temporary solution to configure/enable the EDN and CSRNG to allow OTBN to
+  // run before a DIF is available,
+  // https://github.com/lowRISC/opentitan/issues/6082
+  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
+                      EDN_CTRL_REG_OFFSET, 0xaa);
+  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
+                      EDN_CTRL_REG_OFFSET, 0xaa);
+}
+
+void entropy_testutils_boot_mode_init(void) {
+  setup_entropy_src();
+  setup_csrng();
+  setup_edn();
+}
diff --git a/sw/device/lib/testing/entropy_testutils.h b/sw/device/lib/testing/entropy_testutils.h
new file mode 100644
index 0000000..6466039
--- /dev/null
+++ b/sw/device/lib/testing/entropy_testutils.h
@@ -0,0 +1,16 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_TESTING_ENTROPY_TESTUTILS_H_
+#define OPENTITAN_SW_DEVICE_LIB_TESTING_ENTROPY_TESTUTILS_H_
+
+/**
+ * Initializes the entropy complex to serve random bits to EDN0 and EDN1.
+ *
+ * Initializes entropy_src, csrng, EDN0 and EDN1 with default boot time
+ * configuration to enable entropy distribution for testing purposes.
+ */
+void entropy_testutils_boot_mode_init(void);
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_TESTING_ENTROPY_TESTUTILS_H_
diff --git a/sw/device/lib/testing/meson.build b/sw/device/lib/testing/meson.build
index e207301..3ef237e 100644
--- a/sw/device/lib/testing/meson.build
+++ b/sw/device/lib/testing/meson.build
@@ -15,6 +15,24 @@
   )
 )
 
+# hardware entropy complex (entropy_src, csrng, edn) test utilities.
+sw_lib_testing_entropy_testutils_lib = declare_dependency(
+  link_with: static_library(
+    'sw_lib_testing_entropy_testutils_lib',
+    sources: [
+      hw_ip_edn_reg_h,
+      'entropy_testutils.c'
+    ],
+    dependencies: [
+      top_earlgrey,
+      sw_lib_mmio,
+      sw_lib_dif_entropy,
+      sw_lib_dif_csrng,
+      top_earlgrey,
+    ],
+  ),
+)
+
 # Random number generator.
 sw_lib_testing_random = declare_dependency(
   link_with: static_library(
diff --git a/sw/device/tests/dif/dif_aes_smoketest.c b/sw/device/tests/dif/dif_aes_smoketest.c
index 2300d08..70c3baa 100644
--- a/sw/device/tests/dif/dif_aes_smoketest.c
+++ b/sw/device/tests/dif/dif_aes_smoketest.c
@@ -7,14 +7,11 @@
 #include "sw/device/lib/dif/dif_aes.h"
 #include "sw/device/lib/runtime/log.h"
 #include "sw/device/lib/testing/check.h"
+#include "sw/device/lib/testing/entropy_testutils.h"
 #include "sw/device/lib/testing/test_main.h"
 
 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
 
-#define ENTROPY_SRC_CONF_REG_OFFSET 0x18
-#define CSRNG_CTRL_REG_OFFSET 0x14
-#define EDN_CTRL_REG_OFFSET 0x14
-
 // The following plaintext, key and ciphertext are extracted from Appendix C of
 // the Advanced Encryption Standard (AES) FIPS Publication 197 available at
 // https://www.nist.gov/publications/advanced-encryption-standard-aes
@@ -71,12 +68,7 @@
   LOG_INFO("Running AES test");
 
   // First of all, we need to get the entropy complex up and running.
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
-                      ENTROPY_SRC_CONF_REG_OFFSET, 0x2);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
-                      CSRNG_CTRL_REG_OFFSET, 0xaa);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
-                      EDN_CTRL_REG_OFFSET, 0xaa);
+  entropy_testutils_boot_mode_init();
 
   // Initialise AES.
   dif_aes_params_t params = {
diff --git a/sw/device/tests/dif/meson.build b/sw/device/tests/dif/meson.build
index ed17ca0..18645cb 100644
--- a/sw/device/tests/dif/meson.build
+++ b/sw/device/tests/dif/meson.build
@@ -216,6 +216,7 @@
       sw_lib_dif_aes,
       sw_lib_mmio,
       sw_lib_runtime_log,
+      sw_lib_testing_entropy_testutils_lib,
       sw_lib_testing_test_status,
     ],
   ),
diff --git a/sw/device/tests/otbn/meson.build b/sw/device/tests/otbn/meson.build
index 1d0805b..256f95b 100644
--- a/sw/device/tests/otbn/meson.build
+++ b/sw/device/tests/otbn/meson.build
@@ -7,6 +7,7 @@
     'otbn_rsa_test_lib',
     sources: ['otbn_rsa_test.c'],
     dependencies: [
+      sw_lib_testing_entropy_testutils_lib,
       sw_lib_runtime_otbn,
       sw_lib_runtime_log,
       sw_lib_runtime_ibex,
@@ -26,6 +27,7 @@
     'otbn_ecdsa_p256_test_lib',
     sources: ['otbn_ecdsa_p256_test.c'],
     dependencies: [
+      sw_lib_testing_entropy_testutils_lib,
       sw_lib_runtime_otbn,
       sw_lib_runtime_log,
       sw_lib_runtime_ibex,
@@ -45,6 +47,7 @@
     'otbn_randomness_test_lib',
     sources: ['otbn_randomness_test.c'],
     dependencies: [
+      sw_lib_testing_entropy_testutils_lib,
       sw_lib_runtime_otbn,
       sw_lib_runtime_log,
       sw_lib_runtime_ibex,
diff --git a/sw/device/tests/otbn/otbn_ecdsa_p256_test.c b/sw/device/tests/otbn/otbn_ecdsa_p256_test.c
index e668567..663243f 100644
--- a/sw/device/tests/otbn/otbn_ecdsa_p256_test.c
+++ b/sw/device/tests/otbn/otbn_ecdsa_p256_test.c
@@ -7,27 +7,11 @@
 #include "sw/device/lib/runtime/log.h"
 #include "sw/device/lib/runtime/otbn.h"
 #include "sw/device/lib/testing/check.h"
+#include "sw/device/lib/testing/entropy_testutils.h"
 #include "sw/device/lib/testing/test_main.h"
 
 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
 
-// Temporary solution to configure/enable the EDN and CSRNG to allow OTBN to run
-// before a DIF is available, https://github.com/lowRISC/opentitan/issues/6082
-static const uint32_t kEntropySrcConfRegOffset = 0x18;
-static const uint32_t kCsrngCtrlRegOffset = 0x14;
-static const uint32_t kEdnCtrlRegOffset = 0x14;
-
-static void setup_edn(void) {
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
-                      kEntropySrcConfRegOffset, 0x2);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
-                      kCsrngCtrlRegOffset, 0xaa);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
-                      kEdnCtrlRegOffset, 0xaa);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
-                      kEdnCtrlRegOffset, 0xaa);
-}
-
 /**
  * ECDSA sign and verify test with the NIST P-256 curve using OTBN.
  *
@@ -349,7 +333,7 @@
 }
 
 bool test_main() {
-  setup_edn();
+  entropy_testutils_boot_mode_init();
 
   test_ecdsa_p256_roundtrip();
 
diff --git a/sw/device/tests/otbn/otbn_randomness_test.c b/sw/device/tests/otbn/otbn_randomness_test.c
index cdf94d9..0734607 100644
--- a/sw/device/tests/otbn/otbn_randomness_test.c
+++ b/sw/device/tests/otbn/otbn_randomness_test.c
@@ -7,27 +7,11 @@
 #include "sw/device/lib/runtime/log.h"
 #include "sw/device/lib/runtime/otbn.h"
 #include "sw/device/lib/testing/check.h"
+#include "sw/device/lib/testing/entropy_testutils.h"
 #include "sw/device/lib/testing/test_main.h"
 
 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
 
-// Temporary solution to configure/enable the EDN and CSRNG to allow OTBN to run
-// before a DIF is available, https://github.com/lowRISC/opentitan/issues/6082
-static const uint32_t kEntropySrcConfRegOffset = 0x18;
-static const uint32_t kCsrngCtrlRegOffset = 0x14;
-static const uint32_t kEdnCtrlRegOffset = 0x14;
-
-static void setup_edn(void) {
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
-                      kEntropySrcConfRegOffset, 0x2);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
-                      kCsrngCtrlRegOffset, 0xaa);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
-                      kEdnCtrlRegOffset, 0xaa);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
-                      kEdnCtrlRegOffset, 0xaa);
-}
-
 OTBN_DECLARE_APP_SYMBOLS(randomness);
 OTBN_DECLARE_PTR_SYMBOL(randomness, main);
 OTBN_DECLARE_PTR_SYMBOL(randomness, rv);
@@ -56,7 +40,7 @@
 }
 
 bool test_main() {
-  setup_edn();
+  entropy_testutils_boot_mode_init();
 
   // Initialize
   otbn_t otbn_ctx;
diff --git a/sw/device/tests/otbn/otbn_rsa_test.c b/sw/device/tests/otbn/otbn_rsa_test.c
index c643f37..0f4e7e9 100644
--- a/sw/device/tests/otbn/otbn_rsa_test.c
+++ b/sw/device/tests/otbn/otbn_rsa_test.c
@@ -7,27 +7,11 @@
 #include "sw/device/lib/runtime/log.h"
 #include "sw/device/lib/runtime/otbn.h"
 #include "sw/device/lib/testing/check.h"
+#include "sw/device/lib/testing/entropy_testutils.h"
 #include "sw/device/lib/testing/test_main.h"
 
 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
 
-// Temporary solution to configure/enable the EDN and CSRNG to allow OTBN to run
-// before a DIF is available, https://github.com/lowRISC/opentitan/issues/6082
-static const uint32_t kEntropySrcConfRegOffset = 0x18;
-static const uint32_t kCsrngCtrlRegOffset = 0x14;
-static const uint32_t kEdnCtrlRegOffset = 0x14;
-
-static void setup_edn(void) {
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
-                      kEntropySrcConfRegOffset, 0x2);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
-                      kCsrngCtrlRegOffset, 0xaa);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
-                      kEdnCtrlRegOffset, 0xaa);
-  mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
-                      kEdnCtrlRegOffset, 0xaa);
-}
-
 /**
  * End-to-end RSA encryption and decryption test using OTBN.
  *
@@ -713,7 +697,7 @@
 }
 
 bool test_main() {
-  setup_edn();
+  entropy_testutils_boot_mode_init();
 
   test_rsa512_roundtrip();
   test_rsa1024_roundtrip();