Merge "Add pwrmgr wakeup tests"
diff --git a/hw/top_matcha/dv/chip_sim_cfg.hjson b/hw/top_matcha/dv/chip_sim_cfg.hjson
index 9057076..3a4964e 100644
--- a/hw/top_matcha/dv/chip_sim_cfg.hjson
+++ b/hw/top_matcha/dv/chip_sim_cfg.hjson
@@ -1766,20 +1766,20 @@
{
name: chip_sw_pwrmgr_normal_sleep_all_wake_ups
uvm_test_seq: "chip_sw_pwrmgr_deep_sleep_all_wake_ups_vseq"
- sw_images: ["//sw/device/tests/sim_dv:pwrmgr_normal_sleep_all_wake_ups:1"]
+ sw_images: ["//sw/device/tests/sim_dv:pwrmgr_normal_sleep_all_wake_ups:1:matcha"]
en_run_modes: ["sw_test_mode_test_rom"]
}
{
name: chip_sw_pwrmgr_deep_sleep_all_wake_ups
uvm_test_seq: "chip_sw_pwrmgr_deep_sleep_all_wake_ups_vseq"
- sw_images: ["//sw/device/tests/sim_dv:pwrmgr_deep_sleep_all_wake_ups:1"]
+ sw_images: ["//sw/device/tests/sim_dv:pwrmgr_deep_sleep_all_wake_ups:1:matcha"]
en_run_modes: ["sw_test_mode_test_rom"]
run_opts: ["+sw_test_timeout_ns=18_000_000"]
}
{
name: chip_sw_pwrmgr_random_sleep_all_wake_ups
uvm_test_seq: "chip_sw_pwrmgr_deep_sleep_all_wake_ups_vseq"
- sw_images: ["//sw/device/tests/sim_dv:pwrmgr_random_sleep_all_wake_ups:1"]
+ sw_images: ["//sw/device/tests/sim_dv:pwrmgr_random_sleep_all_wake_ups:1:matcha"]
en_run_modes: ["sw_test_mode_test_rom"]
run_opts: ["+sw_test_timeout_ns=18_000_000", "+do_random=1"]
}
@@ -2084,6 +2084,7 @@
"chip_sw_otp_ctrl_escalation",
"chip_sw_otp_ctrl_smoketest",
"chip_sw_pwrmgr_deep_sleep_power_glitch_reset",
+ "chip_sw_pwrmgr_normal_sleep_all_wake_ups"
"chip_sw_pwrmgr_sleep_power_glitch_reset",
"chip_sw_pwrmgr_sleep_sensor_ctrl_alert_wakeup",
"chip_sw_rom_ctrl_integrity_check",
@@ -2159,9 +2160,12 @@
"chip_sw_otp_ctrl_smoketest",
"chip_sw_pwrmgr_b2b_sleep_reset_req",
"chip_sw_pwrmgr_deep_sleep_all_reset_reqs",
+ "chip_sw_pwrmgr_deep_sleep_all_wake_ups"
"chip_sw_pwrmgr_deep_sleep_power_glitch_reset",
"chip_sw_pwrmgr_normal_sleep_all_reset_reqs",
+ "chip_sw_pwrmgr_normal_sleep_all_wake_ups",
"chip_sw_pwrmgr_random_sleep_all_reset_reqs",
+ "chip_sw_pwrmgr_random_sleep_all_wake_ups",
"chip_sw_pwrmgr_random_sleep_power_glitch_reset",
"chip_sw_pwrmgr_sleep_power_glitch_reset",
"chip_sw_pwrmgr_sleep_sensor_ctrl_alert_wakeup",
diff --git a/sw/device/lib/testing/pinmux_testutils.h b/sw/device/lib/testing/pinmux_testutils.h
index 657d6f0..6b401b4 100644
--- a/sw/device/lib/testing/pinmux_testutils.h
+++ b/sw/device/lib/testing/pinmux_testutils.h
@@ -3,8 +3,8 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
-#ifndef MATCHA_SW_DEVICE_LIB_TESTING_PINMUX_TESTUTILS_H_
-#define MATCHA_SW_DEVICE_LIB_TESTING_PINMUX_TESTUTILS_H_
+#ifndef SW_DEVICE_LIB_TESTING_PINMUX_TESTUTILS_H_
+#define SW_DEVICE_LIB_TESTING_PINMUX_TESTUTILS_H_
#include <stdint.h>
@@ -33,4 +33,4 @@
*/
uint32_t pinmux_testutils_get_testable_gpios_mask(void);
-#endif // MATCHA_SW_DEVICE_LIB_TESTING_PINMUX_TESTUTILS_H_
+#endif // SW_DEVICE_LIB_TESTING_PINMUX_TESTUTILS_H_
diff --git a/sw/device/tests/sim_dv/BUILD b/sw/device/tests/sim_dv/BUILD
index 66a73fd..8c516e3 100644
--- a/sw/device/tests/sim_dv/BUILD
+++ b/sw/device/tests/sim_dv/BUILD
@@ -135,6 +135,52 @@
],
)
+cc_library(
+ name = "pwrmgr_sleep_all_wake_ups_impl",
+ srcs = [
+ "pwrmgr_sleep_all_wake_ups_impl.c",
+ "pwrmgr_sleep_all_wake_ups_impl.h",
+ ],
+ deps = [
+ "//sw/device/lib/dif:pinmux",
+ "//sw/device/lib/dif:rv_plic_sec",
+ "//sw/device/lib/testing:isr_testutils",
+ "//sw/device/tests:test_dv_lib",
+ "@lowrisc_opentitan//sw/device/lib/dif:adc_ctrl",
+ "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr",
+ "@lowrisc_opentitan//sw/device/lib/dif:sensor_ctrl",
+ "@lowrisc_opentitan//sw/device/lib/dif:usbdev",
+ "@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:rv_plic_testutils",
+ ],
+)
+
+matcha_dv_test(
+ name = "pwrmgr_normal_sleep_all_wake_ups",
+ srcs = ["pwrmgr_normal_sleep_all_wake_ups.c"],
+ deps = [
+ ":pwrmgr_sleep_all_wake_ups_impl",
+ ],
+)
+
+matcha_dv_test(
+ name = "pwrmgr_deep_sleep_all_wake_ups",
+ srcs = ["pwrmgr_deep_sleep_all_wake_ups.c"],
+ deps = [
+ ":pwrmgr_sleep_all_wake_ups_impl",
+ ],
+)
+
+matcha_dv_test(
+ name = "pwrmgr_random_sleep_all_wake_ups",
+ srcs = ["pwrmgr_random_sleep_all_wake_ups.c"],
+ deps = [
+ ":pwrmgr_sleep_all_wake_ups_impl",
+ ],
+)
+
################################################################################
# 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/pwrmgr_deep_sleep_all_wake_ups.c b/sw/device/tests/sim_dv/pwrmgr_deep_sleep_all_wake_ups.c
new file mode 100644
index 0000000..4d2c489
--- /dev/null
+++ b/sw/device/tests/sim_dv/pwrmgr_deep_sleep_all_wake_ups.c
@@ -0,0 +1,91 @@
+// 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_flash_ctrl.h"
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+#include "sw/device/lib/dif/dif_rv_plic.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/aon_timer_testutils.h"
+#include "sw/device/lib/testing/autogen/isr_testutils.h"
+#include "sw/device/lib/testing/flash_ctrl_testutils.h"
+#include "sw/device/lib/testing/pwrmgr_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/tests/sim_dv/pwrmgr_sleep_all_wake_ups_impl.h"
+
+/*
+ PWRMGR DEEP SLEEP ALL WAKE UPS TEST
+
+ This test runs power manager wake up from deep sleep mode by
+ wake up inputs.
+
+ There are 6 wake up inputs.
+ 0: sysrst_ctrl
+ 1: adc_ctrl
+ 2: pinmux
+ 3: usb
+ 4: aon_timer
+ 5: sensor_ctrl
+
+ #5 is excluded because sensor_ctrl is not in the aon domain.
+ */
+
+OTTF_DEFINE_TEST_CONFIG();
+
+/**
+ * Clean up pwrmgr wakeup reason register for the next round.
+ */
+static void delay_n_clear(uint32_t delay_in_us) {
+ busy_spin_micros(delay_in_us);
+ CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_clear(&pwrmgr));
+}
+
+bool test_main(void) {
+ // Enable global and external IRQ at Ibex.
+ irq_global_ctrl(true);
+ irq_external_ctrl(true);
+
+ init_units();
+
+ // 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, 0, kDifToggleEnabled));
+
+ // Enable access to flash for storing info across resets.
+ LOG_INFO("Setting default region accesses");
+ 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);
+
+ uint32_t wakeup_count = flash_ctrl_testutils_counter_get(0);
+
+ if (pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) {
+ LOG_INFO("POR reset");
+ execute_test(wakeup_count, /*deep_sleep=*/true);
+ } else {
+ check_wakeup_reason(wakeup_count);
+ LOG_INFO("Woke up by source %d", wakeup_count);
+ cleanup(wakeup_count);
+ if (wakeup_count == PWRMGR_PARAM_AON_TIMER_AON_WKUP_REQ_IDX) {
+ return true;
+ }
+ flash_ctrl_testutils_counter_increment(&flash_ctrl, 0);
+ delay_n_clear(4);
+ execute_test(wakeup_count + 1, /*deep_sleep=*/true);
+ }
+
+ return false;
+}
diff --git a/sw/device/tests/sim_dv/pwrmgr_normal_sleep_all_wake_ups.c b/sw/device/tests/sim_dv/pwrmgr_normal_sleep_all_wake_ups.c
new file mode 100644
index 0000000..7d8aaf9
--- /dev/null
+++ b/sw/device/tests/sim_dv/pwrmgr_normal_sleep_all_wake_ups.c
@@ -0,0 +1,68 @@
+// 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_pwrmgr.h"
+#include "sw/device/lib/dif/dif_rv_plic.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/aon_timer_testutils.h"
+#include "sw/device/lib/testing/autogen/isr_testutils.h"
+#include "sw/device/lib/testing/pwrmgr_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/tests/sim_dv/pwrmgr_sleep_all_wake_ups_impl.h"
+
+/*
+ PWRMGR NORMAL SLEEP ALL WAKE UPS test
+
+ This test runs power manager wake up from deep sleep mode by
+ wake up inputs.
+
+ There are 6 wake up inputs.
+ 0: sysrst_ctrl
+ 1: adc_ctrl
+ 2: pinmux
+ 3: usb
+ 4: aon_timer
+ 5: sensor_ctrl
+
+ */
+
+OTTF_DEFINE_TEST_CONFIG();
+
+bool test_main(void) {
+ // Enable global and external IRQ at Ibex.
+ irq_global_ctrl(true);
+ irq_external_ctrl(true);
+
+ init_units();
+
+ // 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, 0, kDifToggleEnabled));
+
+ if (pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) {
+ LOG_INFO("POR reset");
+
+ for (size_t i = 0; i < PWRMGR_PARAM_NUM_WKUPS; ++i) {
+ LOG_INFO("Test %d begin", i);
+ execute_test(i, /*deep_sleep=*/false);
+ check_wakeup_reason(i);
+ LOG_INFO("Woke up by source %d", i);
+ cleanup(i);
+ LOG_INFO("clean up done source %d", i);
+ }
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/sw/device/tests/sim_dv/pwrmgr_random_sleep_all_wake_ups.c b/sw/device/tests/sim_dv/pwrmgr_random_sleep_all_wake_ups.c
new file mode 100644
index 0000000..248fd4d
--- /dev/null
+++ b/sw/device/tests/sim_dv/pwrmgr_random_sleep_all_wake_ups.c
@@ -0,0 +1,118 @@
+// 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_flash_ctrl.h"
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+#include "sw/device/lib/dif/dif_rv_plic.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/aon_timer_testutils.h"
+#include "sw/device/lib/testing/autogen/isr_testutils.h"
+#include "sw/device/lib/testing/flash_ctrl_testutils.h"
+#include "sw/device/lib/testing/pwrmgr_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/tests/sim_dv/pwrmgr_sleep_all_wake_ups_impl.h"
+
+/*
+ PWRMGR RANDOM SLEEP ALL WAKE UPS TEST
+
+ This test runs power manager wake up from normal or deep sleep mode by
+ wake up inputs.
+
+ There are 6 wake up inputs.
+ 0: sysrst_ctrl
+ 1: adc_ctrl
+ 2: pinmux
+ 3: usb
+ 4: aon_timer
+ 5: sensor_ctrl
+
+ #5 is excluded because sensor_ctrl is not in the aon domain.
+
+ There are 10 cases to be tested. For each wake up this tests the normal and
+ deep sleep in succession; for example, case 2 is adc_ctrl normal sleep and
+ case 3 is adc_ctrl deep sleep.
+
+ This is tracked by a flash_ctrl counter, given there are resets involved.
+ */
+
+OTTF_DEFINE_TEST_CONFIG();
+
+/**
+ * Clean up pwrmgr wakeup reason register for the next round.
+ */
+static void delay_n_clear(uint32_t delay_in_us) {
+ busy_spin_micros(delay_in_us);
+ CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_clear(&pwrmgr));
+}
+
+int get_wakeup_unit(uint32_t count) { return count / 2; }
+
+bool get_deep_sleep(uint32_t count) { return (count % 2) == 1; }
+
+bool test_main(void) {
+ // Enable global and external IRQ at Ibex.
+ irq_global_ctrl(true);
+ irq_external_ctrl(true);
+
+ init_units();
+
+ // 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, 0, kDifToggleEnabled));
+
+ // Enable access to flash for storing info across resets.
+ LOG_INFO("Setting default region accesses");
+ 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);
+
+ uint32_t wakeup_count = flash_ctrl_testutils_counter_get(0);
+ int wakeup_unit = get_wakeup_unit(wakeup_count);
+ bool deep_sleep = get_deep_sleep(wakeup_count);
+
+ if (pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) {
+ LOG_INFO("POR reset");
+ execute_test(wakeup_unit, deep_sleep);
+ check_wakeup_reason(wakeup_unit);
+ LOG_INFO("Woke up by source %d", wakeup_unit);
+ cleanup(wakeup_unit);
+ flash_ctrl_testutils_counter_increment(&flash_ctrl, 0);
+ wakeup_count = flash_ctrl_testutils_counter_get(0);
+ wakeup_unit = get_wakeup_unit(wakeup_count);
+ deep_sleep = get_deep_sleep(wakeup_count);
+ delay_n_clear(4);
+ execute_test(wakeup_unit, deep_sleep);
+ } else {
+ for (int i = 0; i < 2; ++i) {
+ check_wakeup_reason(wakeup_unit);
+ LOG_INFO("Woke up by source %d", wakeup_unit);
+ cleanup(wakeup_unit);
+ if (wakeup_unit == PWRMGR_PARAM_AON_TIMER_AON_WKUP_REQ_IDX &&
+ deep_sleep) {
+ return true;
+ }
+ flash_ctrl_testutils_counter_increment(&flash_ctrl, 0);
+ wakeup_count = flash_ctrl_testutils_counter_get(0);
+ wakeup_unit = get_wakeup_unit(wakeup_count);
+ deep_sleep = get_deep_sleep(wakeup_count);
+ delay_n_clear(4);
+ execute_test(wakeup_unit, deep_sleep);
+ }
+ }
+
+ return false;
+}
diff --git a/sw/device/tests/sim_dv/pwrmgr_sleep_all_wake_ups_impl.c b/sw/device/tests/sim_dv/pwrmgr_sleep_all_wake_ups_impl.c
new file mode 100644
index 0000000..a452741
--- /dev/null
+++ b/sw/device/tests/sim_dv/pwrmgr_sleep_all_wake_ups_impl.c
@@ -0,0 +1,292 @@
+// 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
+
+// Contains code that is common to deep, normal, and random sleep for
+// pwrmgr all_wake_ups test.
+
+#include "sw/device/tests/sim_dv/pwrmgr_sleep_all_wake_ups_impl.h"
+
+#include "hw/top_matcha/sw/autogen/top_matcha.h"
+#include "pwrmgr_regs.h"
+#include "sw/device/lib/dif/dif_adc_ctrl.h"
+#include "sw/device/lib/dif/dif_flash_ctrl.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_sensor_ctrl.h"
+#include "sw/device/lib/dif/dif_sysrst_ctrl.h"
+#include "sw/device/lib/dif/dif_usbdev.h"
+#include "sw/device/lib/testing/autogen/isr_testutils.h"
+
+static const uint32_t kPinmuxWkupDetector5 = 5;
+
+dif_adc_ctrl_t adc_ctrl;
+dif_aon_timer_t aon_timer;
+dif_flash_ctrl_state_t flash_ctrl;
+dif_pinmux_t pinmux;
+dif_pwrmgr_t pwrmgr;
+dif_rv_plic_t rv_plic;
+dif_sensor_ctrl_t sensor_ctrl;
+dif_sysrst_ctrl_t sysrst_ctrl;
+dif_usbdev_t usbdev;
+
+/**
+ * sysrst_ctrl config for test #1
+ * . set sysrst_ctrl.KEY_INTR_CTL.pwrb_in_H2L to 1
+ * . use IOR13 as pwrb_in
+ */
+static void prgm_sysrst_ctrl_wakeup(void *dif) {
+ 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(dif, config));
+ CHECK_DIF_OK(dif_pinmux_input_select(
+ &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonPwrbIn,
+ kTopMatchaPinmuxInselIor13));
+}
+
+/**
+ * adc_ctrl config for test #2
+ * . enable filter 5 and set voltage range (0,200)
+ */
+static void prgm_adc_ctrl_wakeup(void *dif) {
+ dif_adc_ctrl_config_t cfg = {
+ .mode = kDifAdcCtrlLowPowerScanMode,
+ .power_up_time_aon_cycles = 6,
+ .wake_up_time_aon_cycles = 100,
+ .num_low_power_samples = 2,
+ .num_normal_power_samples = 8,
+ };
+ CHECK_DIF_OK(dif_adc_ctrl_configure(dif, cfg));
+
+ dif_adc_ctrl_filter_config_t filter_cfg = {
+ .filter = kDifAdcCtrlFilter5,
+ .min_voltage = 0,
+ .max_voltage = 200,
+ .in_range = true,
+ .generate_wakeup_on_match = true,
+ .generate_irq_on_match = false,
+ };
+
+ CHECK_DIF_OK(dif_adc_ctrl_configure_filter(dif, kDifAdcCtrlChannel0,
+ filter_cfg, kDifToggleEnabled));
+ CHECK_DIF_OK(dif_adc_ctrl_configure_filter(dif, kDifAdcCtrlChannel1,
+ filter_cfg, kDifToggleEnabled));
+ CHECK_DIF_OK(dif_adc_ctrl_filter_match_wakeup_set_enabled(
+ dif, kDifAdcCtrlFilter5, kDifToggleEnabled));
+ CHECK_DIF_OK(dif_adc_ctrl_set_enabled(dif, kDifToggleEnabled));
+}
+
+/**
+ * pinmux config for test #3
+ * . use IOB7 as an input
+ * . set posedge detection
+ */
+static void prgm_pinmux_wakeup(void *dif) {
+ dif_pinmux_wakeup_config_t detector_cfg = {
+ .signal_filter = kDifToggleDisabled,
+ .pad_type = kDifPinmuxPadKindMio,
+ .pad_select = kTopMatchaPinmuxInselIob7,
+ .mode = kDifPinmuxWakeupModePositiveEdge,
+ .counter_threshold = 0 /* Don't need for posedge detection */,
+ };
+ CHECK_DIF_OK(dif_pinmux_wakeup_detector_enable(dif, kPinmuxWkupDetector5,
+ detector_cfg));
+}
+
+/**
+ * usb config for test #4
+ * . Fake low power entry through usb
+ * . Force usb to output suspend indication
+ * (*dif) handle is not used but leave as is
+ * to be called from execute_test
+ */
+static void prgm_usb_wakeup(void *dif) {
+ dif_usbdev_phy_pins_drive_t pins = {
+ .dp_pullup_en = true,
+ .dn_pullup_en = false,
+ };
+ CHECK_DIF_OK(dif_usbdev_set_phy_pins_state(dif, kDifToggleEnabled, pins));
+ CHECK_DIF_OK(dif_usbdev_set_wake_enable(dif, kDifToggleEnabled));
+
+ LOG_INFO("prgm_usb_wakeup: wait 20us (usb)");
+ // Give the hardware a chance to recognize the wakeup values are the same.
+ busy_spin_micros(20); // 20us
+}
+
+/**
+ * aon timer config for test #5
+ * set wakeup signal in 50us
+ */
+static void prgm_aontimer_wakeup(void *dif) {
+ aon_timer_testutils_wakeup_config(dif, 10);
+}
+
+/**
+ * sensor ctrl config for test #6
+ * setup event trigger0
+ */
+static void prgm_sensor_ctrl_wakeup(void *dif) {
+ CHECK_DIF_OK(
+ dif_sensor_ctrl_set_ast_event_trigger(dif, 0, kDifToggleEnabled));
+}
+
+const test_wakeup_sources_t kTestWakeupSources[PWRMGR_PARAM_NUM_WKUPS] = {
+ {
+ .name = "SYSRST_CTRL",
+ .dif_handle = &sysrst_ctrl,
+ .wakeup_src = kDifPwrmgrWakeupRequestSourceOne,
+ .config = prgm_sysrst_ctrl_wakeup,
+ },
+ {
+ .name = "ADC_CTRL",
+ .dif_handle = &adc_ctrl,
+ .wakeup_src = kDifPwrmgrWakeupRequestSourceTwo,
+ .config = prgm_adc_ctrl_wakeup,
+ },
+ {
+ .name = "PINMUX",
+ .dif_handle = &pinmux,
+ .wakeup_src = kDifPwrmgrWakeupRequestSourceThree,
+ .config = prgm_pinmux_wakeup,
+ },
+ {
+ .name = "USB",
+ .dif_handle = &usbdev,
+ .wakeup_src = kDifPwrmgrWakeupRequestSourceFour,
+ .config = prgm_usb_wakeup,
+ },
+ {
+ .name = "AONTIMER",
+ .dif_handle = &aon_timer,
+ .wakeup_src = kDifPwrmgrWakeupRequestSourceFive,
+ .config = prgm_aontimer_wakeup,
+ },
+ {
+ .name = "SENSOR_CTRL",
+ .dif_handle = &sensor_ctrl,
+ .wakeup_src = kDifPwrmgrWakeupRequestSourceSix,
+ .config = prgm_sensor_ctrl_wakeup,
+ },
+};
+
+void init_units() {
+ CHECK_DIF_OK(dif_adc_ctrl_init(
+ mmio_region_from_addr(TOP_MATCHA_ADC_CTRL_AON_BASE_ADDR), &adc_ctrl));
+ CHECK_DIF_OK(dif_aon_timer_init(
+ mmio_region_from_addr(TOP_MATCHA_AON_TIMER_AON_BASE_ADDR), &aon_timer));
+ CHECK_DIF_OK(dif_flash_ctrl_init_state(
+ &flash_ctrl,
+ mmio_region_from_addr(TOP_MATCHA_FLASH_CTRL_CORE_BASE_ADDR)));
+ 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));
+ CHECK_DIF_OK(dif_sensor_ctrl_init(
+ mmio_region_from_addr(TOP_MATCHA_SENSOR_CTRL_BASE_ADDR), &sensor_ctrl));
+ CHECK_DIF_OK(dif_usbdev_init(
+ mmio_region_from_addr(TOP_MATCHA_USBDEV_BASE_ADDR), &usbdev));
+}
+
+void execute_test(uint32_t wakeup_source, bool deep_sleep) {
+ // Configure wakeup device
+ kTestWakeupSources[wakeup_source].config(
+ kTestWakeupSources[wakeup_source].dif_handle);
+ 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, kTestWakeupSources[wakeup_source].wakeup_src, cfg);
+ LOG_INFO("Issue WFI to enter sleep %d", wakeup_source);
+ wait_for_interrupt();
+}
+
+void check_wakeup_reason(uint32_t wakeup_source) {
+ dif_pwrmgr_wakeup_reason_t wakeup_reason;
+ CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_get(&pwrmgr, &wakeup_reason));
+ CHECK(pwrmgr_testutils_is_wakeup_reason(
+ &pwrmgr, kTestWakeupSources[wakeup_source].wakeup_src) == true,
+ "wakeup reason wrong exp:%d obs:%d",
+ kTestWakeupSources[wakeup_source].wakeup_src, wakeup_reason);
+}
+
+static bool get_wakeup_status(void) {
+ dif_pwrmgr_request_sources_t wake_req = -1;
+ CHECK_DIF_OK(dif_pwrmgr_get_current_request_sources(
+ &pwrmgr, kDifPwrmgrReqTypeWakeup, &wake_req));
+ return (wake_req > 0);
+}
+
+/**
+ * Clean up wakeup sources.
+ */
+void cleanup(uint32_t test_idx) {
+ switch (test_idx) {
+ case PWRMGR_PARAM_SYSRST_CTRL_AON_WKUP_REQ_IDX:
+ CHECK_DIF_OK(dif_sysrst_ctrl_ulp_wakeup_clear_status(&sysrst_ctrl));
+ break;
+ case PWRMGR_PARAM_ADC_CTRL_AON_WKUP_REQ_IDX:
+ CHECK_DIF_OK(dif_adc_ctrl_filter_match_wakeup_set_enabled(
+ &adc_ctrl, kDifAdcCtrlFilter5, kDifToggleDisabled));
+ break;
+ case PWRMGR_PARAM_PINMUX_AON_PIN_WKUP_REQ_IDX:
+ CHECK_DIF_OK(dif_pinmux_wakeup_cause_clear(&pinmux));
+ break;
+ case PWRMGR_PARAM_PINMUX_AON_USB_WKUP_REQ_IDX:
+ CHECK_DIF_OK(dif_usbdev_set_wake_enable(&usbdev, kDifToggleDisabled));
+ CHECK_DIF_OK(dif_pinmux_wakeup_cause_clear(&pinmux));
+ break;
+ case PWRMGR_PARAM_AON_TIMER_AON_WKUP_REQ_IDX:
+ CHECK_DIF_OK(dif_aon_timer_wakeup_stop(&aon_timer));
+ CHECK_DIF_OK(dif_aon_timer_clear_wakeup_cause(&aon_timer));
+ break;
+ case PWRMGR_PARAM_SENSOR_CTRL_WKUP_REQ_IDX:
+ // clear event trigger
+ CHECK_DIF_OK(dif_sensor_ctrl_set_ast_event_trigger(&sensor_ctrl, 0,
+ kDifToggleDisabled));
+ CHECK_DIF_OK(dif_sensor_ctrl_clear_recov_event(&sensor_ctrl, 0));
+ break;
+ default:
+ LOG_ERROR("unknown test index %d", test_idx);
+ }
+
+ // Ensure the de-asserted events have cleared from the wakeup pipeline
+ // within 30us.
+ IBEX_SPIN_FOR(!get_wakeup_status(), 100);
+ CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_clear(&pwrmgr));
+}
+static plic_isr_ctx_t plic_ctx = {.rv_plic = &rv_plic,
+ .hart_id = kTopMatchaPlicTargetIbex0};
+
+static pwrmgr_isr_ctx_t pwrmgr_isr_ctx = {
+ .pwrmgr = &pwrmgr,
+ .plic_pwrmgr_start_irq_id = kTopMatchaPlicIrqIdPwrmgrAonWakeup,
+ .expected_irq = kDifPwrmgrIrqWakeup,
+ .is_only_irq = true};
+
+/**
+ * External interrupt handler.
+ */
+void ottf_external_isr(void) {
+ dif_pwrmgr_irq_t irq_id;
+ top_matcha_plic_peripheral_t peripheral;
+
+ isr_testutils_pwrmgr_isr(plic_ctx, pwrmgr_isr_ctx, &peripheral, &irq_id);
+
+ // Check that both the peripheral and the irq id is correct
+ CHECK(peripheral == kTopMatchaPlicPeripheralPwrmgrAon,
+ "IRQ peripheral: %d is incorrect", peripheral);
+ CHECK(irq_id == kDifPwrmgrIrqWakeup, "IRQ ID: %d is incorrect", irq_id);
+}
diff --git a/sw/device/tests/sim_dv/pwrmgr_sleep_all_wake_ups_impl.h b/sw/device/tests/sim_dv/pwrmgr_sleep_all_wake_ups_impl.h
new file mode 100644
index 0000000..9712c3e
--- /dev/null
+++ b/sw/device/tests/sim_dv/pwrmgr_sleep_all_wake_ups_impl.h
@@ -0,0 +1,68 @@
+// 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
+
+#ifndef SW_DEVICE_TESTS_SIM_DV_PWRMGR_SLEEP_ALL_WAKE_UPS_IMPL_H_
+#define SW_DEVICE_TESTS_SIM_DV_PWRMGR_SLEEP_ALL_WAKE_UPS_IMPL_H_
+
+// Contains header for code that is common to deep, normal, and random sleep for
+// pwrmgr all_wake_ups test.
+
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_adc_ctrl.h"
+#include "sw/device/lib/dif/dif_flash_ctrl.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_sensor_ctrl.h"
+#include "sw/device/lib/dif/dif_sysrst_ctrl.h"
+#include "sw/device/lib/dif/dif_usbdev.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/rv_plic_testutils.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+
+typedef struct test_wakeup_sources {
+ /**
+ * Name of the device.
+ */
+ const char *name;
+ /**
+ * Handle to the DIF object for this device.
+ */
+ void *dif_handle;
+ /**
+ * Wakeup Sources.
+ */
+ dif_pwrmgr_request_sources_t wakeup_src;
+ /**
+ * Configuration and initialization actions for the device.
+ * This will be passed the value of `dif` above.
+ */
+ void (*config)(void *dif);
+} test_wakeup_sources_t;
+
+extern dif_adc_ctrl_t adc_ctrl;
+extern dif_aon_timer_t aon_timer;
+extern dif_flash_ctrl_state_t flash_ctrl;
+extern dif_pinmux_t pinmux;
+extern dif_pwrmgr_t pwrmgr;
+extern dif_rv_plic_t rv_plic;
+extern dif_sensor_ctrl_t sensor_ctrl;
+extern dif_sysrst_ctrl_t sysrst_ctrl;
+extern dif_usbdev_t usbdev;
+
+void init_units();
+
+void check_wakeup_reason(uint32_t wakeup_source);
+
+void execute_test(uint32_t wakeup_source, bool deep_sleep);
+
+void cleanup(uint32_t test_idx);
+
+#endif // SW_DEVICE_TESTS_SIM_DV_PWRMGR_SLEEP_ALL_WAKE_UPS_IMPL_H_