Merge "Add tests chip_sw_example_rom and chip_sw_rv_dm_access_after_wakeup to edacloud"
diff --git a/hw/top_matcha/dv/chip_sim_cfg.hjson b/hw/top_matcha/dv/chip_sim_cfg.hjson
index adc626e..60f47e5 100644
--- a/hw/top_matcha/dv/chip_sim_cfg.hjson
+++ b/hw/top_matcha/dv/chip_sim_cfg.hjson
@@ -1839,7 +1839,7 @@
     {
       name: chip_sw_rv_dm_access_after_wakeup
       uvm_test_seq: chip_sw_rv_dm_access_after_wakeup_vseq
-      sw_images: ["//sw/device/tests/sim_dv:rv_dm_access_after_wakeup:1"]
+      sw_images: ["//sw/device/tests/sim_dv:rv_dm_access_after_wakeup:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_opts: ["+use_jtag_dmi=1"]
     }
@@ -2057,6 +2057,7 @@
         "chip_sw_csrng_smoketest",
         "chip_sw_dma_main_test",
         "chip_sw_example_flash",
+        "chip_sw_example_rom",
         "chip_sw_gpio",
         "chip_sw_i2c_host_tx_rx",
         "chip_sw_mem_test",
@@ -2128,6 +2129,7 @@
         "chip_sw_dma_main_test",
         "chip_sw_entropy_src_smoketest",
         "chip_sw_example_flash",
+        "chip_sw_example_rom",
         "chip_sw_flash_ctrl_access",
         "chip_sw_flash_ctrl_access_jitter_en",
         "chip_sw_flash_ctrl_access_jitter_en_reduced_freq",
@@ -2154,6 +2156,7 @@
         "chip_sw_rstmgr_sw_rst",
         "chip_sw_rv_core_ibex_nmi_irq",
         "chip_sw_rv_core_ibex_rnd",
+        "chip_sw_rv_dm_access_after_wakeup",
         "chip_sw_rv_dm_ndm_reset_req_when_cpu_halted",
         "chip_sw_rv_plic_smoketest",
         "chip_sw_rv_timer_irq",
@@ -2234,6 +2237,7 @@
         "chip_sw_dma_main_test",
         "chip_sw_entropy_src_smoketest",
         "chip_sw_example_flash",
+        "chip_sw_example_rom",
         "chip_sw_flash_ctrl_access",
         "chip_sw_flash_ctrl_access_jitter_en",
         "chip_sw_flash_ctrl_access_jitter_en_reduced_freq",
@@ -2268,6 +2272,7 @@
         "chip_sw_rstmgr_sw_rst",
         "chip_sw_rv_core_ibex_nmi_irq",
         "chip_sw_rv_core_ibex_rnd",
+        "chip_sw_rv_dm_access_after_wakeup",
         "chip_sw_rv_dm_ndm_reset_req_when_cpu_halted",
         "chip_sw_rv_plic_smoketest",
         "chip_sw_rv_timer_irq",
diff --git a/hw/top_matcha/dv/env/seq_lib/chip_sw_rv_dm_access_after_wakeup_vseq.sv b/hw/top_matcha/dv/env/seq_lib/chip_sw_rv_dm_access_after_wakeup_vseq.sv
index 67120a3..1516e8b 100644
--- a/hw/top_matcha/dv/env/seq_lib/chip_sw_rv_dm_access_after_wakeup_vseq.sv
+++ b/hw/top_matcha/dv/env/seq_lib/chip_sw_rv_dm_access_after_wakeup_vseq.sv
@@ -1,3 +1,4 @@
+// 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
@@ -17,6 +18,8 @@
     // Set up JTAG RV_DM TAP.
     cfg.chip_vif.tap_straps_if.drive(JtagTapRvDm);
     cfg.m_jtag_riscv_agent_cfg.is_rv_dm = 1;
+    // Wait a few clocks for the strap change to take effect before driving the JTAG interface
+    cfg.clk_rst_vif.wait_clks(5);
 
     // Attempt to activate RV_DM via JTAG.
     csr_wr(.ptr(cfg.jtag_dmi_ral.dmcontrol.dmactive), .value(1), .blocking(1), .predict(1));
@@ -96,6 +99,9 @@
 
     // We must reset the agent side also to stay synchronized with the design
     cfg.m_jtag_riscv_agent_cfg.m_jtag_agent_cfg.vif.do_trst_n(2);
+    // Wait for JTAG agent to come out of reset
+    cfg.clk_rst_vif.wait_clks(5);
+    // Reactivate DMI
     activate_jtag_dmi();
     exp_data = $urandom();
     csr_wr(
diff --git a/sw/device/tests/sim_dv/BUILD b/sw/device/tests/sim_dv/BUILD
index d5823a8..4686139 100644
--- a/sw/device/tests/sim_dv/BUILD
+++ b/sw/device/tests/sim_dv/BUILD
@@ -315,6 +315,31 @@
     ],
 )
 
+matcha_dv_test(
+    name = "rv_dm_access_after_wakeup",
+    srcs = ["rv_dm_access_after_wakeup.c"],
+    deps = [
+        "//sw/device/lib/dif:alert_handler",
+        "//sw/device/lib/dif:pinmux",
+        "//sw/device/lib/dif:rstmgr",
+        "//sw/device/lib/dif:rv_plic_sec",
+        "//sw/device/lib/testing:alert_handler_testutils",
+        "//sw/device/lib/testing:pinmux_testutils",
+        "//sw/device/tests:test_dv_lib",
+        "@lowrisc_opentitan//sw/device/lib/base:abs_mmio",
+        "@lowrisc_opentitan//sw/device/lib/dif:aon_timer",
+        "@lowrisc_opentitan//sw/device/lib/dif:flash_ctrl",
+        "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr",
+        "@lowrisc_opentitan//sw/device/lib/dif:rv_timer",
+        "@lowrisc_opentitan//sw/device/lib/dif:sysrst_ctrl",
+        "@lowrisc_opentitan//sw/device/lib/testing:aon_timer_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:flash_ctrl_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rstmgr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rv_plic_testutils",
+    ],
+)
+
 ################################################################################
 #  Place the Opentitan-sourced DV test below.                                  #
 #  Opentitan DV binary build flow does not support centOS7, so we pull the     #
diff --git a/sw/device/tests/sim_dv/rv_dm_access_after_wakeup.c b/sw/device/tests/sim_dv/rv_dm_access_after_wakeup.c
new file mode 100644
index 0000000..bf0f97b
--- /dev/null
+++ b/sw/device/tests/sim_dv/rv_dm_access_after_wakeup.c
@@ -0,0 +1,142 @@
+// 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 "pwrmgr_regs.h"
+#include "sw/device/lib/dif/dif_pinmux.h"
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+#include "sw/device/lib/dif/dif_rv_plic.h"
+#include "sw/device/lib/dif/dif_sysrst_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/aon_timer_testutils.h"
+#include "sw/device/lib/testing/pwrmgr_testutils.h"
+#include "sw/device/lib/testing/rstmgr_testutils.h"
+#include "sw/device/lib/testing/rv_plic_testutils.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+#include "sw/device/lib/testing/test_framework/status.h"
+
+/*
+ * RV_DM access after wakeup test.
+ */
+
+OTTF_DEFINE_TEST_CONFIG();
+
+enum {
+  kSoftwareBarrierTimeoutUsec = 24,
+};
+
+// This location will be update from SV
+static volatile const uint8_t kSoftwareBarrier = 0;
+
+// Handle to the plic
+dif_rv_plic_t rv_plic;
+
+/**
+ * External interrupt handler.
+ *
+ * Simply claim the interrupt and does nothing else.
+ */
+void ottf_external_isr(void) {
+  dif_rv_plic_irq_id_t plic_irq_id;
+  CHECK_DIF_OK(
+      dif_rv_plic_irq_claim(&rv_plic, kTopMatchaPlicTargetIbex0, &plic_irq_id));
+}
+
+/**
+ * Put the device to sleep.
+ *
+ * @param pwrmgr A handle to the power manager.
+ * @param deep_sleep Whether or not to enter a deep sleep.
+ */
+static void put_to_sleep(dif_pwrmgr_t *pwrmgr, bool deep_sleep) {
+  dif_pwrmgr_domain_config_t cfg;
+  CHECK_DIF_OK(dif_pwrmgr_get_domain_config(pwrmgr, &cfg));
+  cfg = cfg & (kDifPwrmgrDomainOptionIoClockInLowPower |
+               kDifPwrmgrDomainOptionUsbClockInLowPower |
+               kDifPwrmgrDomainOptionUsbClockInActivePower) |
+        (!deep_sleep ? kDifPwrmgrDomainOptionMainPowerInLowPower : 0);
+
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceOne,
+                                    cfg);
+  LOG_INFO("%s",
+           deep_sleep ? "Entering deep sleep." : "Entering normal sleep.");
+  wait_for_interrupt();
+}
+
+bool test_main(void) {
+  // Enable global and external IRQ at Ibex.
+  irq_global_ctrl(true);
+  irq_external_ctrl(true);
+
+  dif_pinmux_t pinmux;
+  dif_pwrmgr_t pwrmgr;
+  dif_sysrst_ctrl_t sysrst_ctrl;
+
+  CHECK_DIF_OK(dif_pinmux_init(
+      mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux));
+  CHECK_DIF_OK(dif_pwrmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR), &pwrmgr));
+  CHECK_DIF_OK(dif_rv_plic_init(
+      mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR), &rv_plic));
+  CHECK_DIF_OK(dif_sysrst_ctrl_init(
+      mmio_region_from_addr(TOP_MATCHA_SYSRST_CTRL_AON_BASE_ADDR),
+      &sysrst_ctrl));
+
+  switch (rstmgr_testutils_reason_get()) {
+    case kDifRstmgrResetInfoPor:  // The first power-up.
+      LOG_INFO("Software Setup.");
+      // Wait for sequence to run its checks.
+      IBEX_SPIN_FOR(kSoftwareBarrier == 1, kSoftwareBarrierTimeoutUsec);
+
+      // Enable all the AON interrupts used in this test.
+      rv_plic_testutils_irq_range_enable(&rv_plic, kTopMatchaPlicTargetIbex0,
+                                         kTopMatchaPlicIrqIdPwrmgrAonWakeup,
+                                         kTopMatchaPlicIrqIdPwrmgrAonWakeup);
+
+      // Enable pwrmgr interrupt.
+      CHECK_DIF_OK(dif_pwrmgr_irq_set_enabled(&pwrmgr, kDifPwrmgrIrqWakeup,
+                                              kDifToggleEnabled));
+
+      // Set up power button as wake up source.
+      dif_sysrst_ctrl_input_change_config_t config = {
+          .input_changes = kDifSysrstCtrlInputPowerButtonH2L,
+          .debounce_time_threshold = 1,  // 5us
+      };
+      CHECK_DIF_OK(
+          dif_sysrst_ctrl_input_change_detect_configure(&sysrst_ctrl, config));
+      CHECK_DIF_OK(dif_pinmux_input_select(
+          &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonPwrbIn,
+          kTopMatchaPinmuxInselIor13));
+
+      // Put the device in a normal sleep.
+      put_to_sleep(&pwrmgr, /*deep_sleep=*/false);
+      LOG_INFO("Waking up from normal sleep.");
+
+      // Clean up wakeup source after sleep.
+      CHECK_DIF_OK(dif_sysrst_ctrl_ulp_wakeup_clear_status(&sysrst_ctrl));
+
+      // Wait for sequence to run its checks.
+      IBEX_SPIN_FOR(kSoftwareBarrier == 2, kSoftwareBarrierTimeoutUsec);
+
+      // Put the device in a deep sleep.
+      put_to_sleep(&pwrmgr, /*deep_sleep=*/true);
+      break;
+
+    case kDifRstmgrResetInfoLowPowerExit:  // The power up after deep sleep.
+      LOG_INFO("Waking up from deep sleep.");
+
+      // Wait for sequence to finish before returning.
+      IBEX_SPIN_FOR(kSoftwareBarrier == 3, kSoftwareBarrierTimeoutUsec);
+      return true;
+
+    default:
+      LOG_ERROR("Device was reset by an unexpected source.");
+      break;
+  }
+  return false;
+}