Software APIs
pwrmgr_sleep_power_glitch_test.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "dt/dt_aon_timer.h"
10 #include "sw/device/lib/testing/pwrmgr_testutils.h"
11 #include "sw/device/lib/testing/rstmgr_testutils.h"
12 #include "sw/device/lib/testing/test_framework/check.h"
14 
15 OTTF_DEFINE_TEST_CONFIG();
16 
17 static const dt_rstmgr_t kRstmgrDt = 0;
18 static_assert(kDtRstmgrCount == 1, "this test expects a rstmgr");
19 static const dt_pwrmgr_t kPwrmgrDt = 0;
20 static_assert(kDtPwrmgrCount == 1, "this test expects a pwrmgr");
21 
22 // When the test first runs the rstmgr's `reset_info` CSR should have the POR
23 // bit set, the code clears reset_info and puts the chip in shallow sleep. WFI
24 // causes core_sleeping to rise, and that causes the SV side to glitch the main
25 // power rail, causing a pwrmgr internally generated reset. The next time the
26 // test runs is after the power glitch reset, which is confirmed reading the
27 // `reset_info` CSR.
28 bool test_main(void) {
29  dif_pwrmgr_t pwrmgr;
30  dif_rstmgr_t rstmgr;
31 
32  // Initialize pwrmgr since this will put the chip in shallow sleep.
33  CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kPwrmgrDt, &pwrmgr));
34 
35  // Initialize rstmgr since this will check some registers.
36  CHECK_DIF_OK(dif_rstmgr_init_from_dt(kRstmgrDt, &rstmgr));
37 
38  // Notice we are clearing rstmgr's RESET_INFO, so after the power glitch there
39  // is only one bit set.
40 
41  if (UNWRAP(rstmgr_testutils_is_reset_info(&rstmgr, kDifRstmgrResetInfoPor))) {
42  LOG_INFO("Powered up for the first time, begin test");
43 
44  CHECK(UNWRAP(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) == true);
45 
46  CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
47 
48  // Configure shallow sleep.
49  dif_pwrmgr_request_sources_t wakeup_sources;
50  CHECK_DIF_OK(dif_pwrmgr_find_request_source(
51  &pwrmgr, kDifPwrmgrReqTypeWakeup,
52  dt_aon_timer_instance_id(kDtAonTimerAon), kDtAonTimerWakeupWkupReq,
53  &wakeup_sources));
54 
55  CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(
56  &pwrmgr, wakeup_sources, kDifPwrmgrDomainOptionMainPowerInLowPower));
57 
58  // This causes core_sleeping to rise and triggers the injection of the
59  // power glitch. Enter shallow sleep mode.
60  LOG_INFO("Issue WFI to enter sleep");
62 
63  } else {
64  LOG_INFO("Checking reset status.");
66  CHECK_STATUS_OK(rstmgr_testutils_post_reset(
67  &rstmgr, kDifRstmgrResetInfoPowerUnstable, 0, 0, 0, 0));
68  LOG_INFO(
69  "Reset status indicates a main power glitch and low power exit reset");
70  }
71  return true;
72 }