[dv,full_chip,aon_timer] Add sleep_wdog_sleep_pause test
Add watchdog configuration for pause in sleep mode.
Minor fix in aon_timer_wdog_bite_reset test.
Signed-off-by: Guillermo Maturana <maturana@google.com>
diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
index 4a64539..991b591 100644
--- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson
+++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
@@ -327,6 +327,13 @@
run_opts: ["+sw_test_timeout_ns=18000000"]
}
{
+ name: chip_sw_aon_timer_sleep_wdog_sleep_pause
+ uvm_test_seq: chip_sw_base_vseq
+ sw_images: ["sw/device/tests/aon_timer_sleep_wdog_sleep_pause_test:1"]
+ en_run_modes: ["sw_test_mode_test_rom"]
+ run_opts: ["+sw_test_timeout_ns=18000000"]
+ }
+ {
name: chip_sw_aon_timer_wdog_bite_reset
uvm_test_seq: chip_sw_base_vseq
sw_images: ["sw/device/tests/aon_timer_wdog_bite_reset_test:1"]
diff --git a/sw/device/lib/testing/aon_timer_testutils.c b/sw/device/lib/testing/aon_timer_testutils.c
index 372f736..841967c 100644
--- a/sw/device/lib/testing/aon_timer_testutils.c
+++ b/sw/device/lib/testing/aon_timer_testutils.c
@@ -33,7 +33,8 @@
void aon_timer_testutils_watchdog_config(const dif_aon_timer_t *aon_timer,
uint32_t bark_cycles,
- uint32_t bite_cycles) {
+ uint32_t bite_cycles,
+ bool pause_in_sleep) {
// Make sure that watchdog timer is stopped.
CHECK_DIF_OK(dif_aon_timer_watchdog_stop(aon_timer));
@@ -45,5 +46,5 @@
aon_timer, kDifAonTimerIrqWdogTimerBark, &is_pending));
CHECK(!is_pending);
CHECK_DIF_OK(dif_aon_timer_watchdog_start(aon_timer, bark_cycles, bite_cycles,
- false, false));
+ pause_in_sleep, false));
}
diff --git a/sw/device/lib/testing/aon_timer_testutils.h b/sw/device/lib/testing/aon_timer_testutils.h
index 742a166..6c20026 100644
--- a/sw/device/lib/testing/aon_timer_testutils.h
+++ b/sw/device/lib/testing/aon_timer_testutils.h
@@ -23,9 +23,11 @@
* pause for low power.
* @param bark_cycles The number of AON clock cycles till barking.
* @param bite_cycles The number of AON clock cycles till biting.
+ * @param pause_in_sleep Don't increment while sleeping.
*/
void aon_timer_testutils_watchdog_config(const dif_aon_timer_t *aon_timer,
uint32_t bark_cycles,
- uint32_t bite_cycles);
+ uint32_t bite_cycles,
+ bool pause_in_sleep);
#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_AON_TIMER_TESTUTILS_H_
diff --git a/sw/device/tests/aon_timer_irq_test.c b/sw/device/tests/aon_timer_irq_test.c
index 9f28d4f..3cc5272 100644
--- a/sw/device/tests/aon_timer_irq_test.c
+++ b/sw/device/tests/aon_timer_irq_test.c
@@ -118,7 +118,8 @@
// Setup the wdog bark interrupt.
aon_timer_testutils_watchdog_config(aon_timer,
/*bark_cycles=*/count_cycles,
- /*bite_cycles=*/count_cycles * 4);
+ /*bite_cycles=*/count_cycles * 4,
+ /*pause_in_sleep=*/false);
}
// Disable interrupts to be certain interrupt doesn't occur between while
diff --git a/sw/device/tests/aon_timer_sleep_wdog_sleep_pause_test.c b/sw/device/tests/aon_timer_sleep_wdog_sleep_pause_test.c
new file mode 100644
index 0000000..c2741d1
--- /dev/null
+++ b/sw/device/tests/aon_timer_sleep_wdog_sleep_pause_test.c
@@ -0,0 +1,112 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "sw/device/lib/base/freestanding/limits.h"
+#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/test_framework/ottf.h"
+#include "sw/device/lib/testing/test_framework/test_status.h"
+
+#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
+
+#define WDOG_BARK_TIME_US 1300
+#define WDOG_BITE_TIME_US 1600
+#define WKUP_TIME_US 2000
+const test_config_t kTestConfig;
+
+static uint64_t us_to_aon_cycles(uint64_t time_us) {
+ return time_us * kClockFreqAonHz / 1000000;
+}
+
+static uint32_t cycles_to_32_bits(uint64_t cycles, const char *label) {
+ CHECK(cycles < UINT32_MAX,
+ "The %s value 0x%08x%08x can't fit into the 32 bits timer counter",
+ label, (uint32_t)(cycles >> 32), (uint32_t)cycles);
+ return (uint32_t)cycles;
+}
+
+bool test_main(void) {
+ // Initialize pwrmgr.
+ dif_pwrmgr_t pwrmgr;
+ CHECK_DIF_OK(dif_pwrmgr_init(
+ mmio_region_from_addr(TOP_EARLGREY_PWRMGR_AON_BASE_ADDR), &pwrmgr));
+
+ // Initialize rstmgr to check the reset reason.
+ dif_rstmgr_t rstmgr;
+ CHECK_DIF_OK(dif_rstmgr_init(
+ mmio_region_from_addr(TOP_EARLGREY_RSTMGR_AON_BASE_ADDR), &rstmgr));
+
+ // Initialize aon timer to use the wdog.
+ dif_aon_timer_t aon_timer;
+ CHECK_DIF_OK(dif_aon_timer_init(
+ mmio_region_from_addr(TOP_EARLGREY_AON_TIMER_AON_BASE_ADDR), &aon_timer));
+
+ // Enable aon_timer watchdog reset.
+ // Set wdog as a reset source.
+ CHECK_DIF_OK(dif_pwrmgr_set_request_sources(&pwrmgr, kDifPwrmgrReqTypeReset,
+ kDifPwrmgrResetRequestSourceTwo,
+ kDifToggleEnabled));
+
+ // Check if there was a HW reset caused by the wdog bite.
+ dif_rstmgr_reset_info_bitfield_t rst_info;
+ CHECK_DIF_OK(dif_rstmgr_reset_info_get(&rstmgr, &rst_info));
+ CHECK_DIF_OK(dif_rstmgr_reset_info_clear(&rstmgr));
+
+ if (rst_info == kDifRstmgrResetInfoPor) {
+ LOG_INFO("Booting for the first time, setting wdog");
+
+ // Configure watchdog sooner then wakeup, but with pause enabled.
+ CHECK(WKUP_TIME_US > WDOG_BITE_TIME_US);
+ CHECK(WDOG_BARK_TIME_US < WDOG_BITE_TIME_US);
+ uint32_t wkup_cycles =
+ cycles_to_32_bits(us_to_aon_cycles(WKUP_TIME_US), "wkup_time");
+ uint32_t bark_cycles =
+ cycles_to_32_bits(us_to_aon_cycles(WDOG_BARK_TIME_US), "bark_time");
+ uint32_t bite_cycles =
+ cycles_to_32_bits(us_to_aon_cycles(WDOG_BITE_TIME_US), "bite_time");
+ aon_timer_testutils_wakeup_config(&aon_timer, wkup_cycles);
+ aon_timer_testutils_watchdog_config(&aon_timer, bark_cycles, bite_cycles,
+ true);
+ // Deep sleep.
+ pwrmgr_testutils_enable_low_power(&pwrmgr,
+ kDifPwrmgrWakeupRequestSourceFive,
+ /*domain_config=*/0);
+
+ // Enter low power mode.
+ LOG_INFO("Issue WFI to enter sleep");
+ wait_for_interrupt();
+ } else if (rst_info == kDifRstmgrResetInfoLowPowerExit) {
+ bool is_pending;
+ LOG_INFO("Booting for the second time due to wakeup");
+ // Executing the wdog bite reset during sleep test.
+
+ // Wait for the remaining time to the wdog bark.
+ usleep(WDOG_BARK_TIME_US);
+ CHECK_DIF_OK(dif_aon_timer_irq_is_pending(
+ &aon_timer, kDifAonTimerIrqWkupTimerExpired, &is_pending));
+ CHECK(is_pending);
+
+ CHECK_DIF_OK(dif_aon_timer_wakeup_stop(&aon_timer));
+
+ CHECK_DIF_OK(dif_aon_timer_irq_acknowledge(
+ &aon_timer, kDifAonTimerIrqWkupTimerExpired));
+ usleep(WDOG_BITE_TIME_US - WDOG_BARK_TIME_US + 10);
+ LOG_ERROR("Should have got a watchdog reset");
+ } else if (rst_info == kDifRstmgrResetInfoWatchdog) {
+ LOG_INFO("Booting for the third time due to wdog bite reset");
+ } else {
+ LOG_ERROR("Got unexpected reset_info=0x%x", rst_info);
+ }
+
+ return true;
+}
diff --git a/sw/device/tests/aon_timer_smoketest.c b/sw/device/tests/aon_timer_smoketest.c
index 9a3809d..35ffb43 100644
--- a/sw/device/tests/aon_timer_smoketest.c
+++ b/sw/device/tests/aon_timer_smoketest.c
@@ -40,7 +40,7 @@
// Test the watchdog timer functionality by setting a single cycle "bark"
// counter. Delay to compensate for AON Timer 200kHz clock (less should
// suffice, but to be on a cautious side - lets keep it at 100 for now).
- aon_timer_testutils_watchdog_config(aon, 1, UINT32_MAX);
+ aon_timer_testutils_watchdog_config(aon, 1, UINT32_MAX, false);
usleep(100);
// Make sure that the timer has expired.
diff --git a/sw/device/tests/aon_timer_wdog_bite_reset_test.c b/sw/device/tests/aon_timer_wdog_bite_reset_test.c
index 1f2ce1e..eb803bc 100644
--- a/sw/device/tests/aon_timer_wdog_bite_reset_test.c
+++ b/sw/device/tests/aon_timer_wdog_bite_reset_test.c
@@ -39,11 +39,12 @@
// Set wdog as a reset source.
CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
- kDifPwrmgrWakeupRequestSourceTwo,
+ kDifPwrmgrResetRequestSourceTwo,
kDifToggleEnabled));
// Setup the wdog bark and bite timeouts.
- aon_timer_testutils_watchdog_config(aon_timer, bark_cycles, bite_cycles);
+ aon_timer_testutils_watchdog_config(aon_timer, bark_cycles, bite_cycles,
+ false);
}
/**
diff --git a/sw/device/tests/meson.build b/sw/device/tests/meson.build
index face690..fba6809 100644
--- a/sw/device/tests/meson.build
+++ b/sw/device/tests/meson.build
@@ -780,6 +780,32 @@
}
}
+# AON Timer sleep wdog sleep pause test.
+aon_timer_sleep_wdog_sleep_pause_test = declare_dependency(
+ link_with: static_library(
+ 'aon_timer_sleep_wdog_sleep_pause_test',
+ sources: [
+ hw_ip_rstmgr_reg_h,
+ 'aon_timer_sleep_wdog_sleep_pause_test.c',
+ ],
+ dependencies: [
+ sw_lib_dif_rstmgr,
+ sw_lib_dif_aon_timer,
+ sw_lib_dif_pwrmgr,
+ sw_lib_runtime_log,
+ sw_lib_testing_aon_timer_testutils,
+ sw_lib_testing_rstmgr_testutils,
+ sw_lib_testing_pwrmgr_testutils,
+ top_earlgrey,
+ ],
+ ),
+)
+sw_tests += {
+ 'aon_timer_sleep_wdog_sleep_pause_test': {
+ 'library': aon_timer_sleep_wdog_sleep_pause_test,
+ }
+}
+
###############################################################################
# Auto-generated tests
###############################################################################