Software APIs
pwrmgr_random_sleep_all_reset_reqs_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 <assert.h>
6 #include <limits.h>
7 #include <stdbool.h>
8 #include <stdint.h>
9 
16 #include "sw/device/lib/runtime/irq.h"
18 #include "sw/device/lib/testing/ret_sram_testutils.h"
19 #include "sw/device/lib/testing/rstmgr_testutils.h"
20 #include "sw/device/lib/testing/rv_plic_testutils.h"
21 #include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h"
22 #include "sw/device/lib/testing/test_framework/check.h"
24 #include "sw/device/tests/pwrmgr_sleep_resets_lib.h"
25 
27 
28 OTTF_DEFINE_TEST_CONFIG(.enable_uart_flow_control = true);
29 
30 static const uint32_t kPlicTarget = kTopEarlgreyPlicTargetIbex0;
31 
32 bool test_main(void) {
33  // Enable global and external IRQ at Ibex.
34  irq_global_ctrl(true);
35  irq_external_ctrl(true);
36 
37  init_peripherals();
38 
39  ret_sram_testutils_init();
40 
41  // Enable all the AON interrupts used in this test.
42  rv_plic_testutils_irq_range_enable(plic, kPlicTarget,
45 
46  config_alert_handler();
47 
48  // Check if there was a HW reset caused by expected cases.
50  rst_info = rstmgr_testutils_reason_get();
51  rstmgr_testutils_reason_clear();
52 
53  enum { kCounterResets = 0 };
54  if (rst_info == kDifRstmgrResetInfoPor) {
55  CHECK_STATUS_OK(ret_sram_testutils_counter_clear(kCounterResets));
56  }
57  CHECK_STATUS_OK(rstmgr_testutils_pre_reset(rstmgr));
58  CHECK(rst_info == kDifRstmgrResetInfoPor ||
59  rst_info == kDifRstmgrResetInfoSysRstCtrl ||
60  rst_info == kDifRstmgrResetInfoWatchdog ||
61  rst_info == kDifRstmgrResetInfoEscalation ||
62  rst_info == kDifRstmgrResetInfoLowPowerExit ||
63  rst_info == (kDifRstmgrResetInfoSysRstCtrl |
65  rst_info ==
67  rst_info == (kDifRstmgrResetInfoWatchdog |
69  rst_info == (kDifRstmgrResetInfoEscalation |
71  rst_info == kDifRstmgrResetInfoSw,
72  "Wrong reset reason %02X", rst_info);
73 
74  uint32_t event_idx = 0;
75  CHECK_STATUS_OK(ret_sram_testutils_counter_get(kCounterResets, &event_idx));
76  CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterResets));
77 
78  int reset_case = event_idx / 2;
79  bool deep_sleep = event_idx % 2 == 0;
80  const char *sleep_mode = deep_sleep ? "deep" : "normal";
81  pwrmgr_sleep_resets_lib_modes_t mode =
82  deep_sleep ? kPwrmgrSleepResetsLibModesDeepSleep
83  : kPwrmgrSleepResetsLibModesNormalSleep;
84  LOG_INFO("New reset event");
85  LOG_INFO(" case %d, %s mode", reset_case, sleep_mode);
86 
87  switch (reset_case) {
88  case 0:
91  prepare_for_sysrst(mode);
92  break;
93  case 1:
94  LOG_INFO("Watchdog reset in %s sleep mode", sleep_mode);
95  LOG_INFO("Let SV wait timer reset");
96  config_wdog(/*bark_micros=*/200, /*bite_micros=*/2 * 200);
97  prepare_for_wdog(mode);
98  break;
99  case 2:
100  LOG_INFO("Rstmgr software reset in %s sleep mode", sleep_mode);
101  LOG_INFO("Let SV wait timer reset");
102  // Triggering a sw reset will prevent the device from completing the
103  // setup required to enter sleep mode. This sets a watchdog, but it will
104  // most likely be wiped out by the software reset, unless they land in
105  // very close temporal proximity.
106  config_wdog(/*bark_micros=*/200, /*bite_micros=*/2 * 200);
107  // Assert rstmgr software reset request.
108  CHECK_DIF_OK(dif_rstmgr_software_device_reset(rstmgr));
109  prepare_for_wdog(mode);
110  break;
111  case 3:
112  LOG_INFO("Escalation reset in %s sleep mode", sleep_mode);
113  LOG_INFO("Let SV wait timer reset");
114  trigger_escalation();
115  break;
116  case 4:
117  LOG_INFO("Last Booting");
118  return true;
119  default:
120  LOG_INFO("Booting for undefined case %d, reset_info 0x%x", reset_case,
121  rst_info);
122  }
123 
124  return false;
125 }