[dv/full_chip] Create pwrmgr testutils

There are many tests that need to trigger wakeups from different IPs,
so this abstracts one of the common pwrmgr operation.

Signed-off-by: Guillermo Maturana <maturana@google.com>
diff --git a/sw/device/lib/testing/meson.build b/sw/device/lib/testing/meson.build
index cd44d5a..30818ce 100644
--- a/sw/device/lib/testing/meson.build
+++ b/sw/device/lib/testing/meson.build
@@ -42,6 +42,34 @@
   ),
 )
 
+# pwrmgr test utilities.
+sw_lib_testing_pwrmgr_testutils = declare_dependency(
+  link_with: static_library(
+    'sw_lib_testing_pwrmgr_testutils',
+    sources: [
+      'pwrmgr_testutils.c'
+    ],
+    dependencies: [
+      sw_lib_mmio,
+      sw_lib_dif_pwrmgr,
+    ],
+  ),
+)
+
+# rstmgr test utilities.
+sw_lib_testing_rstmgr_testutils = declare_dependency(
+  link_with: static_library(
+    'sw_lib_testing_rstmgr_testutils',
+    sources: [
+      'rstmgr_testutils.c'
+    ],
+    dependencies: [
+      sw_lib_mmio,
+      sw_lib_dif_rstmgr,
+    ],
+  ),
+)
+
 sw_lib_testing_rv_plic_testutils = declare_dependency(
   link_with: static_library(
     'sw_lib_testing_rv_plic_testutils',
diff --git a/sw/device/lib/testing/pwrmgr_testutils.c b/sw/device/lib/testing/pwrmgr_testutils.c
new file mode 100644
index 0000000..01469c5
--- /dev/null
+++ b/sw/device/lib/testing/pwrmgr_testutils.c
@@ -0,0 +1,37 @@
+// 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/testing/pwrmgr_testutils.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+#include "sw/device/lib/testing/check.h"
+
+void pwrmgr_testutils_enable_low_power(
+    dif_pwrmgr_t *pwrmgr, dif_pwrmgr_request_sources_t wakeups,
+    dif_pwrmgr_domain_config_t domain_config) {
+  // Enable low power on the next WFI with clocks and power domains configured
+  // per domain_config.
+
+  // Issue #6504: USB clock in active power must be left enabled.
+  domain_config |= kDifPwrmgrDomainOptionUsbClockInActivePower;
+
+  CHECK_DIF_OK(
+      dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeWakeup, wakeups));
+  CHECK_DIF_OK(dif_pwrmgr_set_domain_config(pwrmgr, domain_config));
+  CHECK_DIF_OK(dif_pwrmgr_low_power_set_enabled(pwrmgr, kDifToggleEnabled));
+}
+
+bool pwrmgr_testutils_is_wakeup_reason(dif_pwrmgr_t *pwrmgr,
+                                       dif_pwrmgr_request_sources_t reasons) {
+  dif_pwrmgr_wakeup_reason_t wakeup_reason;
+  CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_get(pwrmgr, &wakeup_reason));
+
+  return (wakeup_reason.request_sources == 0 ||
+          wakeup_reason.types == kDifPwrmgrWakeupTypeRequest) &&
+         wakeup_reason.request_sources == reasons;
+}
diff --git a/sw/device/lib/testing/pwrmgr_testutils.h b/sw/device/lib/testing/pwrmgr_testutils.h
new file mode 100644
index 0000000..df65e4f
--- /dev/null
+++ b/sw/device/lib/testing/pwrmgr_testutils.h
@@ -0,0 +1,36 @@
+// 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_PWRMGR_TESTUTILS_H_
+#define OPENTITAN_SW_DEVICE_LIB_TESTING_PWRMGR_TESTUTILS_H_
+
+#include <stdint.h>
+
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+
+/**
+ * Set the device in low power mode.
+ *
+ * A WFI instruction needs to be separately run by the processor to actually
+ * enter low power.
+ *
+ * @param pwrmgr A power manager handle.
+ * @param wakeups The bit mask of wakeup requestors.
+ * @param domain_config The bit mask for configuring the clock and power
+ * domains.
+ */
+void pwrmgr_testutils_enable_low_power(
+    dif_pwrmgr_t *pwrmgr, dif_pwrmgr_request_sources_t wakeups,
+    dif_pwrmgr_domain_config_t domain_config);
+
+/**
+ * Determines if the wakeup reasons is as given.
+ *
+ * @param pwrmgr A power manager handle.
+ * @param reasons A bit mask of reasons.
+ */
+bool pwrmgr_testutils_is_wakeup_reason(dif_pwrmgr_t *pwrmgr,
+                                       dif_pwrmgr_request_sources_t reasons);
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_TESTING_PWRMGR_TESTUTILS_H_
diff --git a/sw/device/lib/testing/rstmgr_testutils.c b/sw/device/lib/testing/rstmgr_testutils.c
new file mode 100644
index 0000000..14e5805
--- /dev/null
+++ b/sw/device/lib/testing/rstmgr_testutils.c
@@ -0,0 +1,19 @@
+// 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/testing/rstmgr_testutils.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_rstmgr.h"
+#include "sw/device/lib/testing/check.h"
+
+bool rstmgr_testutils_is_reset_info(dif_rstmgr_t *rstmgr,
+                                    dif_rstmgr_reset_info_bitfield_t info) {
+  dif_rstmgr_reset_info_bitfield_t actual_info;
+  CHECK_DIF_OK(dif_rstmgr_reset_info_get(rstmgr, &actual_info));
+  return actual_info == info;
+}
diff --git a/sw/device/lib/testing/rstmgr_testutils.h b/sw/device/lib/testing/rstmgr_testutils.h
new file mode 100644
index 0000000..f685b7b
--- /dev/null
+++ b/sw/device/lib/testing/rstmgr_testutils.h
@@ -0,0 +1,21 @@
+// 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_RSTMGR_TESTUTILS_H_
+#define OPENTITAN_SW_DEVICE_LIB_TESTING_RSTMGR_TESTUTILS_H_
+
+#include <stdint.h>
+
+#include "sw/device/lib/dif/dif_rstmgr.h"
+
+/**
+ * Determines if the reset_info matches info.
+ *
+ * @param rstmgr A reset manager handle.
+ * @param info A bit mask of reset reasons.
+ */
+bool rstmgr_testutils_is_reset_info(dif_rstmgr_t *rstmgr,
+                                    dif_rstmgr_reset_info_bitfield_t info);
+
+#endif  // OPENTITAN_SW_DEVICE_LIB_TESTING_RSTMGR_TESTUTILS_H_
diff --git a/sw/device/tests/meson.build b/sw/device/tests/meson.build
index 514ba5d..c1e5833 100644
--- a/sw/device/tests/meson.build
+++ b/sw/device/tests/meson.build
@@ -291,11 +291,14 @@
     'pwrmgr_smoketest_lib',
     sources: ['pwrmgr_smoketest.c'],
     dependencies: [
+      sw_lib_dif_aon_timer,
       sw_lib_dif_pwrmgr,
       sw_lib_dif_rstmgr,
-      sw_lib_testing_aon_timer_testutils,
       sw_lib_mmio,
       sw_lib_runtime_log,
+      sw_lib_testing_aon_timer_testutils,
+      sw_lib_testing_pwrmgr_testutils,
+      sw_lib_testing_rstmgr_testutils,
     ],
   ),
 )
diff --git a/sw/device/tests/pwrmgr_smoketest.c b/sw/device/tests/pwrmgr_smoketest.c
index 648118b..de7b4e7 100644
--- a/sw/device/tests/pwrmgr_smoketest.c
+++ b/sw/device/tests/pwrmgr_smoketest.c
@@ -3,33 +3,20 @@
 // SPDX-License-Identifier: Apache-2.0
 
 #include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_aon_timer.h"
 #include "sw/device/lib/dif/dif_pwrmgr.h"
 #include "sw/device/lib/dif/dif_rstmgr.h"
 #include "sw/device/lib/runtime/log.h"
 #include "sw/device/lib/testing/aon_timer_testutils.h"
 #include "sw/device/lib/testing/check.h"
+#include "sw/device/lib/testing/pwrmgr_testutils.h"
+#include "sw/device/lib/testing/rstmgr_testutils.h"
 #include "sw/device/lib/testing/test_framework/test_main.h"
 
 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
 
-static const dif_pwrmgr_wakeup_reason_t kWakeUpReasonTest = {
-    .types = kDifPwrmgrWakeupTypeRequest,
-    .request_sources = kDifPwrmgrWakeupRequestSourceFive,
-};
-
-static const dif_pwrmgr_wakeup_reason_t kWakeUpReasonPor = {
-    .types = 0,
-    .request_sources = 0,
-};
-
 const test_config_t kTestConfig;
 
-bool compare_wakeup_reasons(const dif_pwrmgr_wakeup_reason_t *lhs,
-                            const dif_pwrmgr_wakeup_reason_t *rhs) {
-  return lhs->types == rhs->types &&
-         lhs->request_sources == rhs->request_sources;
-}
-
 bool test_main(void) {
   dif_pwrmgr_t pwrmgr;
   dif_rstmgr_t rstmgr;
@@ -43,19 +30,13 @@
       mmio_region_from_addr(TOP_EARLGREY_RSTMGR_AON_BASE_ADDR), &rstmgr));
 
   // Assuming the chip hasn't slept yet, wakeup reason should be empty.
-  // Notice we are clear rstmgr's RESET_INFO, so after the aon wakeup there
-  // is only one bit set.
-  dif_pwrmgr_wakeup_reason_t wakeup_reason;
-  CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_get(&pwrmgr, &wakeup_reason));
 
-  if (compare_wakeup_reasons(&wakeup_reason, &kWakeUpReasonPor)) {
+  // Notice we are clearing rstmgr's RESET_INFO, so after the aon wakeup there
+  // is only one bit set.
+  if (pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) {
     LOG_INFO("Powered up for the first time, begin test");
 
-    LOG_INFO("Check the rstmgr reset_info is POR");
-    dif_rstmgr_reset_info_bitfield_t info;
-    CHECK_DIF_OK(dif_rstmgr_reset_info_get(&rstmgr, &info));
-    CHECK(info == (dif_rstmgr_reset_info_bitfield_t)(kDifRstmgrResetInfoPor));
-
+    CHECK(rstmgr_testutils_is_reset_info(&rstmgr, kDifRstmgrResetInfoPor));
     // Clear reset_info.
     CHECK_DIF_OK(dif_rstmgr_reset_info_clear(&rstmgr));
 
@@ -80,31 +61,22 @@
               },
               &aon_timer) == kDifAonTimerOk);
     aon_timer_testutils_wakeup_config(&aon_timer, wakeup_threshold);
-
-    // Enable low power on the next WFI with default settings.
-    // All clocks and power domains are turned off during low power.
-    dif_pwrmgr_domain_config_t config;
-    // Issue #6504: USB clock in active power must be left enabled.
-    config = kDifPwrmgrDomainOptionUsbClockInActivePower;
-
-    CHECK_DIF_OK(dif_pwrmgr_set_request_sources(
-        &pwrmgr, kDifPwrmgrReqTypeWakeup, kDifPwrmgrWakeupRequestSourceFive));
-    CHECK_DIF_OK(dif_pwrmgr_set_domain_config(&pwrmgr, config));
-    CHECK_DIF_OK(dif_pwrmgr_low_power_set_enabled(&pwrmgr, kDifToggleEnabled));
-
+    pwrmgr_testutils_enable_low_power(
+        &pwrmgr, kDifPwrmgrWakeupRequestSourceFive,
+        kDifPwrmgrDomainOptionUsbClockInActivePower);
     // Enter low power mode.
     wait_for_interrupt();
 
-  } else if (compare_wakeup_reasons(&wakeup_reason, &kWakeUpReasonTest)) {
+  } else if (pwrmgr_testutils_is_wakeup_reason(
+                 &pwrmgr, kDifPwrmgrWakeupRequestSourceFive)) {
     LOG_INFO("Aon timer wakeup detected");
-    LOG_INFO("Check the rstmgr reset_info is LOW_POWER timer wakeup detected");
-    dif_rstmgr_reset_info_bitfield_t info;
-    CHECK_DIF_OK(dif_rstmgr_reset_info_get(&rstmgr, &info));
-    CHECK(info ==
-          (dif_rstmgr_reset_info_bitfield_t)(kDifRstmgrResetInfoLowPowerExit));
+    CHECK(rstmgr_testutils_is_reset_info(&rstmgr,
+                                         kDifRstmgrResetInfoLowPowerExit));
     return true;
 
   } else {
+    dif_pwrmgr_wakeup_reason_t wakeup_reason;
+    CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_get(&pwrmgr, &wakeup_reason));
     LOG_ERROR("Unexpected wakeup detected: type = %d, request_source = %d",
               wakeup_reason.types, wakeup_reason.request_sources);
     return false;