[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;