Add sensor_ctrl related tests for edacloud

Change-Id: I4fce1dda32991728e0fb2615389169cf33c8b5fb
diff --git a/hw/top_matcha/dv/chip_sim_cfg.hjson b/hw/top_matcha/dv/chip_sim_cfg.hjson
index d5a8768..4eaebca 100644
--- a/hw/top_matcha/dv/chip_sim_cfg.hjson
+++ b/hw/top_matcha/dv/chip_sim_cfg.hjson
@@ -1597,7 +1597,7 @@
     {
       name: chip_sw_sensor_ctrl_alert
       uvm_test_seq: chip_sw_base_vseq
-      sw_images: ["//sw/device/tests:sensor_ctrl_alert_test:1"]
+      sw_images: ["//sw/device/tests:sensor_ctrl_alert_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_opts: ["+sw_test_timeout_ns=40_000_000"]
       reseed: 5
@@ -1605,14 +1605,14 @@
     {
       name: chip_sw_sensor_ctrl_status
       uvm_test_seq: chip_sw_sensor_ctrl_status_intr_vseq
-      sw_images: ["//sw/device/tests/sim_dv:sensor_ctrl_status_test:1"]
+      sw_images: ["//sw/device/tests/sim_dv:sensor_ctrl_status_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_opts: ["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_pwrmgr_sleep_sensor_ctrl_alert_wakeup
       uvm_test_seq: chip_sw_base_vseq
-      sw_images: ["//sw/device/tests:sensor_ctrl_wakeup_test:1"]
+      sw_images: ["//sw/device/tests:sensor_ctrl_wakeup_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_opts: ["+sw_test_timeout_ns=8_000_000"]
     }
@@ -2025,6 +2025,7 @@
         "chip_sw_rstmgr_sw_rst",
         "chip_sw_rv_plic_smoketest",
         "chip_sw_rv_timer_irq",
+        "chip_sw_sensor_ctrl_status",
         "chip_sw_smc_cam_irq_test",
         "chip_sw_smc_ctrl_test",
         "chip_sw_smc_env_test",
@@ -2075,9 +2076,10 @@
         "chip_sw_keymgr_key_derivation",
         "chip_sw_kmac_idle",
         "chip_sw_kmac_smoketest",
+        "chip_sw_lc_ctrl_otp_hw_cfg",
         "chip_sw_otbn_smoketest",
         "chip_sw_otp_ctrl_smoketest",
-        "chip_sw_lc_ctrl_otp_hw_cfg",
+        "chip_sw_pwrmgr_sleep_sensor_ctrl_alert_wakeup",
         "chip_sw_rom_ctrl_integrity_check",
         "chip_sw_rstmgr_smoketest",
         "chip_sw_rstmgr_sw_req",
@@ -2085,6 +2087,8 @@
         "chip_sw_rv_dm_ndm_reset_req_when_cpu_halted",
         "chip_sw_rv_plic_smoketest",
         "chip_sw_rv_timer_irq",
+        "chip_sw_sensor_ctrl_alert",
+        "chip_sw_sensor_ctrl_status",
         "chip_sw_smc_cam_irq_test",
         "chip_sw_smc_ctrl_test",
         "chip_sw_smc_env_test",
@@ -2139,9 +2143,10 @@
         "chip_sw_keymgr_key_derivation",
         "chip_sw_kmac_idle",
         "chip_sw_kmac_smoketest",
+        "chip_sw_lc_ctrl_otp_hw_cfg",
         "chip_sw_otbn_smoketest",
         "chip_sw_otp_ctrl_smoketest",
-        "chip_sw_lc_ctrl_otp_hw_cfg",
+        "chip_sw_pwrmgr_sleep_sensor_ctrl_alert_wakeup",
         "chip_sw_rom_ctrl_integrity_check",
         "chip_sw_rstmgr_smoketest",
         "chip_sw_rstmgr_sw_req",
@@ -2149,6 +2154,8 @@
         "chip_sw_rv_dm_ndm_reset_req_when_cpu_halted",
         "chip_sw_rv_plic_smoketest",
         "chip_sw_rv_timer_irq",
+        "chip_sw_sensor_ctrl_alert",
+        "chip_sw_sensor_ctrl_status",
         "chip_sw_smc_cam_irq_test",
         "chip_sw_smc_ctrl_test",
         "chip_sw_smc_env_test",
diff --git a/hw/top_matcha/dv/env/seq_lib/chip_sw_sensor_ctrl_status_intr_vseq.sv b/hw/top_matcha/dv/env/seq_lib/chip_sw_sensor_ctrl_status_intr_vseq.sv
index 7766a34..f8f6266 100644
--- a/hw/top_matcha/dv/env/seq_lib/chip_sw_sensor_ctrl_status_intr_vseq.sv
+++ b/hw/top_matcha/dv/env/seq_lib/chip_sw_sensor_ctrl_status_intr_vseq.sv
@@ -10,7 +10,7 @@
   localparam int TOTAL_IO = 2;
   localparam string VIOA_POK_PATH = "tb.dut.u_ast.u_vioa_pok.vio_pok_o";
   localparam string VIOB_POK_PATH = "tb.dut.u_ast.u_viob_pok.vio_pok_o";
-  localparam string SLEEPING_PATH = "tb.dut.top_matcha.u_rv_core_ibex.u_core_sleeping_buf.out_o";
+  localparam string SLEEPING_PATH = "tb.dut.top_matcha.u_rv_core_ibex_sec.u_core_sleeping_buf.out_o";
   string io_paths[2] = '{VIOA_POK_PATH, VIOB_POK_PATH};
   int iterations = 10;
 
diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD
index 50fbf06..800e410 100644
--- a/sw/device/tests/BUILD
+++ b/sw/device/tests/BUILD
@@ -818,6 +818,39 @@
     ],
 )
 
+matcha_dv_test(
+    name = "sensor_ctrl_alert_test",
+    srcs = ["sensor_ctrl_alerts.c"],
+    deps = [
+        ":test_dv_lib",
+        "//hw/top_matcha/ip/sensor_ctrl/data:sensor_ctrl_regs",
+        "//sw/device/lib/dif:alert_handler",
+        "//sw/device/lib/dif:rstmgr",
+        "//sw/device/lib/dif:rv_plic_sec",
+        "@lowrisc_opentitan//sw/device/lib/base:abs_mmio",
+        "@lowrisc_opentitan//sw/device/lib/dif:sensor_ctrl",
+        "@lowrisc_opentitan//sw/device/lib/testing:flash_ctrl_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rand_testutils",
+    ],
+)
+
+matcha_dv_test(
+    name = "sensor_ctrl_wakeup_test",
+    srcs = ["@lowrisc_opentitan//sw/device/tests:sensor_ctrl_wakeup.c"],
+    deps = [
+        ":test_dv_lib_opentitan",
+        "//hw/top_matcha/ip/sensor_ctrl/data:sensor_ctrl_regs",
+        "//sw/device/lib/dif:rv_plic_sec",
+        "@lowrisc_opentitan//sw/device/lib/arch:device",
+        "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr",
+        "@lowrisc_opentitan//sw/device/lib/dif:sensor_ctrl",
+        "@lowrisc_opentitan//sw/device/lib/testing:isr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rv_plic_testutils",
+    ],
+)
+
 # Smoke tests
 matcha_dv_test(
     name = "aes_smoketest",
diff --git a/sw/device/tests/sensor_ctrl_alerts.c b/sw/device/tests/sensor_ctrl_alerts.c
new file mode 100644
index 0000000..8b01da3
--- /dev/null
+++ b/sw/device/tests/sensor_ctrl_alerts.c
@@ -0,0 +1,212 @@
+// Copyright 2023 Google LLC.
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "hw/top_matcha/sw/autogen/top_matcha.h"
+#include "sensor_ctrl_regs.h"  // Generated.
+#include "sw/device/lib/base/abs_mmio.h"
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_alert_handler.h"
+#include "sw/device/lib/dif/dif_flash_ctrl.h"
+#include "sw/device/lib/dif/dif_rstmgr.h"
+#include "sw/device/lib/dif/dif_rv_plic.h"
+#include "sw/device/lib/dif/dif_sensor_ctrl.h"
+#include "sw/device/lib/runtime/ibex.h"
+#include "sw/device/lib/runtime/irq.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/flash_ctrl_testutils.h"
+#include "sw/device/lib/testing/pwrmgr_testutils.h"
+#include "sw/device/lib/testing/rand_testutils.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+
+OTTF_DEFINE_TEST_CONFIG();
+
+/**
+ * This test checks that incoming ast events can be
+ * configured as both recoverable and fatal.
+ * Further, this test checks that recoverable and fatal
+ * events are able to reach their proper alert_handler
+ * destination.
+ *
+ * Since fatal events do not stop firing once asserted,
+ * this test performs a self reset after every fatal
+ * event.  In order to keep track of how far the test
+ * has advanced, a non-volatile counter in flash is
+ * used to track current progress.
+ */
+static dif_rstmgr_t rstmgr;
+static dif_flash_ctrl_state_t flash_ctrl;
+static dif_sensor_ctrl_t sensor_ctrl;
+static dif_alert_handler_t alert_handler;
+
+/**
+ *  Clear event trigger and recoverable status.
+ */
+static void clear_event(uint32_t idx, dif_toggle_t fatal) {
+  CHECK_DIF_OK(dif_sensor_ctrl_set_ast_event_trigger(&sensor_ctrl, idx,
+                                                     kDifToggleDisabled));
+
+  if (!dif_toggle_to_bool(fatal)) {
+    CHECK_DIF_OK(dif_sensor_ctrl_clear_recov_event(&sensor_ctrl, idx));
+  }
+}
+
+static uint32_t get_events(dif_toggle_t fatal) {
+  dif_sensor_ctrl_events_t events = 0;
+  if (dif_toggle_to_bool(fatal)) {
+    CHECK_DIF_OK(dif_sensor_ctrl_get_fatal_events(&sensor_ctrl, &events));
+  } else {
+    CHECK_DIF_OK(dif_sensor_ctrl_get_recov_events(&sensor_ctrl, &events));
+  }
+  return events;
+}
+
+/**
+ *  Check alert cause registers are correctly set
+ */
+static void check_alert_state(dif_toggle_t fatal) {
+  bool fatal_cause = false;
+  bool recov_cause = false;
+
+  CHECK_DIF_OK(dif_alert_handler_alert_is_cause(
+      &alert_handler, kTopMatchaAlertIdSensorCtrlFatalAlert, &fatal_cause));
+
+  CHECK_DIF_OK(dif_alert_handler_alert_is_cause(
+      &alert_handler, kTopMatchaAlertIdSensorCtrlRecovAlert, &recov_cause));
+
+  if (dif_toggle_to_bool(fatal)) {
+    CHECK(fatal_cause & !recov_cause,
+          "Fatal alert not correctly observed in alert handler");
+  } else {
+    CHECK(recov_cause & !fatal_cause,
+          "Recov alert not correctly observed in alert handler");
+  }
+
+  CHECK_DIF_OK(dif_alert_handler_alert_acknowledge(
+      &alert_handler, kTopMatchaAlertIdSensorCtrlRecovAlert));
+  CHECK_DIF_OK(dif_alert_handler_alert_acknowledge(
+      &alert_handler, kTopMatchaAlertIdSensorCtrlFatalAlert));
+};
+
+/**
+ *  First configure fatality of the desired event.
+ *  Then trigger the event from sensor_ctrl to ast.
+ *  Next poll for setting of correct events inside sensor_ctrl status.
+ *  When a recoverable event is triggerd, make sure only recoverable
+ *  status is seen, likewise for fatal events.
+ *  Finally, check for correct capture of cause in alert handler.
+ */
+static void test_event(uint32_t idx, dif_toggle_t fatal) {
+  // Configure event fatality
+  CHECK_DIF_OK(dif_sensor_ctrl_set_alert_fatal(&sensor_ctrl, idx, fatal));
+
+  // Trigger event
+  CHECK_DIF_OK(dif_sensor_ctrl_set_ast_event_trigger(&sensor_ctrl, idx,
+                                                     kDifToggleEnabled));
+
+  // wait for events to set
+  IBEX_SPIN_FOR(get_events(fatal) > 0, 1);
+
+  // Check for the event in ast sensor_ctrl
+  // if the event is not set, error
+  CHECK(((get_events(fatal) >> idx) & 0x1) == 1, "Event %d not observed in AST",
+        idx);
+
+  // check the opposite fatality setting, should not be set
+  CHECK(((get_events(!fatal) >> idx) & 0x1) == 0,
+        "Event %d observed in AST when it should not be", idx);
+
+  // clear event trigger
+  clear_event(idx, fatal);
+
+  // check whether alert handler captured the event
+  check_alert_state(fatal);
+};
+
+enum {
+  // Counter for event index.
+  kCounterEventIdx,
+  // Counter for number of events tested.
+  kCounterNumTests,
+  // Max number of events to test per run.
+  kNumTestsMax = SENSOR_CTRL_PARAM_NUM_ALERT_EVENTS >> 1,
+};
+
+static uint32_t get_next_event_to_test(void) {
+  uint32_t event_idx;
+  // Reseed so that we don't see the same sequence after each reset.
+  rand_testutils_reseed();
+  do {
+    event_idx = flash_ctrl_testutils_counter_get(kCounterEventIdx);
+    flash_ctrl_testutils_counter_increment(&flash_ctrl, kCounterEventIdx);
+    // Drop each event randomly to reduce run time.
+  } while (rand_testutils_gen32() <= UINT32_MAX >> 1 &&
+           event_idx < SENSOR_CTRL_PARAM_NUM_ALERT_EVENTS);
+  return event_idx;
+}
+
+bool test_main(void) {
+  // Initialize flash_ctrl
+  CHECK_DIF_OK(dif_flash_ctrl_init_state(
+      &flash_ctrl,
+      mmio_region_from_addr(TOP_MATCHA_FLASH_CTRL_CORE_BASE_ADDR)));
+
+  // Initialize sensor_ctrl
+  CHECK_DIF_OK(dif_sensor_ctrl_init(
+      mmio_region_from_addr(TOP_MATCHA_SENSOR_CTRL_BASE_ADDR), &sensor_ctrl));
+
+  // Initialize alert_handler
+  CHECK_DIF_OK(dif_alert_handler_init(
+      mmio_region_from_addr(TOP_MATCHA_ALERT_HANDLER_BASE_ADDR),
+      &alert_handler));
+
+  CHECK_DIF_OK(dif_rstmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_RSTMGR_AON_BASE_ADDR), &rstmgr));
+
+  // Enable both recoverable and fatal alerts
+  CHECK_DIF_OK(dif_alert_handler_configure_alert(
+      &alert_handler, kTopMatchaAlertIdSensorCtrlRecovAlert,
+      kDifAlertHandlerClassA, kDifToggleEnabled, kDifToggleEnabled));
+  CHECK_DIF_OK(dif_alert_handler_configure_alert(
+      &alert_handler, kTopMatchaAlertIdSensorCtrlFatalAlert,
+      kDifAlertHandlerClassA, kDifToggleEnabled, kDifToggleEnabled));
+
+  // Enable flash access
+  flash_ctrl_testutils_default_region_access(&flash_ctrl,
+                                             /*rd_en*/ true,
+                                             /*prog_en*/ true,
+                                             /*erase_en*/ true,
+                                             /*scramble_en*/ false,
+                                             /*ecc_en*/ false,
+                                             /*he_en*/ false);
+
+  // Make sure we do not try to test more than half of all available events
+  // in a single test.  Testing too many would just make the run time too
+  // long.
+  uint32_t event_idx = get_next_event_to_test();
+  if (event_idx == SENSOR_CTRL_PARAM_NUM_ALERT_EVENTS ||
+      flash_ctrl_testutils_counter_get(kCounterNumTests) >= kNumTestsMax) {
+    LOG_INFO("Tested all events");
+    return true;
+  } else {
+    LOG_INFO("Testing event %d", event_idx);
+  }
+
+  // test recoverable event
+  test_event(event_idx, /*fatal*/ kDifToggleDisabled);
+
+  // test fatal event
+  test_event(event_idx, /*fatal*/ kDifToggleEnabled);
+
+  // increment flash counter to know where we are
+  flash_ctrl_testutils_counter_increment(&flash_ctrl, kCounterNumTests);
+
+  // Now request system to reset and test again
+  LOG_INFO("Rebooting system");
+  CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
+  wait_for_interrupt();
+
+  return false;
+}
diff --git a/sw/device/tests/sim_dv/BUILD b/sw/device/tests/sim_dv/BUILD
index 0425930..9bccd8c 100644
--- a/sw/device/tests/sim_dv/BUILD
+++ b/sw/device/tests/sim_dv/BUILD
@@ -120,3 +120,17 @@
         "@lowrisc_opentitan//sw/device/lib/testing:rstmgr_testutils",
     ],
 )
+
+matcha_dv_test(
+    name = "sensor_ctrl_status_test",
+    srcs = ["@lowrisc_opentitan//sw/device/tests/sim_dv:sensor_ctrl_status.c"],
+    deps = [
+        "//hw/top_matcha/ip/sensor_ctrl/data:sensor_ctrl_regs",
+        "//sw/device/lib/dif:rv_plic_sec",
+        "//sw/device/tests:test_dv_lib_opentitan",
+        "@lowrisc_opentitan//sw/device/lib/base:abs_mmio",
+        "@lowrisc_opentitan//sw/device/lib/dif:sensor_ctrl",
+        "@lowrisc_opentitan//sw/device/lib/testing:isr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rv_plic_testutils",
+    ],
+)