11 #include "sw/device/lib/runtime/irq.h"
13 #include "sw/device/lib/testing/aon_timer_testutils.h"
14 #include "sw/device/lib/testing/pwrmgr_testutils.h"
15 #include "sw/device/lib/testing/rv_plic_testutils.h"
16 #include "sw/device/lib/testing/test_framework/check.h"
19 #include "pwrmgr_regs.h"
25 static dif_pwrmgr_t pwrmgr;
26 static dif_rv_plic_t rv_plic;
27 static dif_aon_timer_t timer;
29 static const dt_pwrmgr_t kPwrmgrDt = 0;
30 static_assert(kDtPwrmgrCount == 1,
"this test expects a pwrmgr");
31 static const dt_aon_timer_t kAonTimerDt = 0;
32 static_assert(kDtAonTimerCount == 1,
"this test expects an aon_timer");
33 static const dt_rv_plic_t kRvPlicDt = 0;
34 static_assert(kDtRvPlicCount == 1,
"this test expects exactly one rv_plic");
38 bool ottf_handle_irq(uint32_t *exc_info, dt_instance_id_t devid,
40 if (devid == dt_aon_timer_instance_id(kAonTimerDt)) {
42 dif_aon_timer_irq_t irq =
43 dt_aon_timer_irq_from_plic_id(kAonTimerDt, irq_id);
45 if (irq == kDtAonTimerIrqWkupTimerExpired) {
47 }
else if (irq == kDtAonTimerIrqWdogTimerBark) {
50 CHECK_DIF_OK(dif_aon_timer_irq_acknowledge(&timer, irq));
51 bool is_pending =
true;
52 CHECK_DIF_OK(dif_aon_timer_irq_is_pending(
53 &timer, kDifAonTimerIrqWkupTimerExpired, &is_pending));
56 }
else if (devid == dt_pwrmgr_instance_id(kPwrmgrDt)) {
58 CHECK(irq_id == dt_pwrmgr_irq_to_plic_id(kPwrmgrDt, kDtPwrmgrIrqWakeup),
59 "Pwrmgr IRQ ID: %d is incorrect", irq_id);
60 CHECK_DIF_OK(dif_pwrmgr_irq_acknowledge(&pwrmgr, kDtPwrmgrIrqWakeup));
67 static bool get_wakeup_status(
void) {
71 return (wake_req > 0);
74 static void clear_wakeup(
void) {
82 static void test_init(
void) {
83 irq_global_ctrl(
true);
84 irq_external_ctrl(
true);
86 CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kPwrmgrDt, &pwrmgr));
87 CHECK_DIF_OK(dif_rv_plic_init_from_dt(kRvPlicDt, &rv_plic));
91 dt_aon_timer_instance_id(kDtAonTimerAon),
92 kDtAonTimerWakeupWkupReq, &wakeup_src));
96 dt_pwrmgr_irq_to_plic_id(kPwrmgrDt, kDtPwrmgrIrqWakeup);
97 rv_plic_testutils_irq_range_enable(&rv_plic, kPlicTarget, plic_id, plic_id);
98 rv_plic_testutils_irq_range_enable(
99 &rv_plic, kPlicTarget,
100 dt_aon_timer_irq_to_plic_id(kAonTimerDt, kDtAonTimerIrqWkupTimerExpired),
101 dt_aon_timer_irq_to_plic_id(kAonTimerDt, kDtAonTimerIrqWdogTimerBark));
106 CHECK_DIF_OK(dif_aon_timer_init_from_dt(kAonTimerDt, &timer));
110 static void set_timer(uint64_t time) {
112 CHECK_STATUS_OK(aon_timer_testutils_get_aon_cycles_32_from_us(time, &cycles));
113 CHECK_STATUS_OK(aon_timer_testutils_wakeup_config(&timer, cycles));
116 static bool lowpower_hint_is_cleared(
void) {
122 static void test_sleep(
bool wfi_fallthrough) {
123 LOG_INFO(
"Low power WFI (fallthrough=%d)", wfi_fallthrough);
126 kDifPwrmgrDomainOptionMainPowerInLowPower;
128 pwrmgr_testutils_enable_low_power(&pwrmgr, wakeup_src, domain_config));
129 irq_global_ctrl(
false);
130 if (wfi_fallthrough) {
131 LOG_INFO(
"Fallthough WFI due to timer pending");
138 LOG_INFO(
"Woke up by source %x", wakeup_src);
142 irq_global_ctrl(
true);
147 irq_global_ctrl(
false);
150 irq_global_ctrl(
true);
153 OTTF_DEFINE_TEST_CONFIG();
157 if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) !=
true) {