Software APIs
sysrst_ctrl_reset_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 
12 #include "sw/device/lib/testing/pwrmgr_testutils.h"
13 #include "sw/device/lib/testing/rstmgr_testutils.h"
14 #include "sw/device/lib/testing/sysrst_ctrl_testutils.h"
15 #include "sw/device/lib/testing/test_framework/check.h"
17 
19 
20 OTTF_DEFINE_TEST_CONFIG();
21 
22 static dif_pwrmgr_t pwrmgr;
23 static dif_rstmgr_t rstmgr;
24 static dif_sysrst_ctrl_t sysrst_ctrl;
25 static dif_gpio_t gpio;
26 
27 enum {
28  kTestPhaseCheckComboReset = 0,
29  kTestPhaseCheckDeepSleepWakeup = 1,
30  kTestPhaseCheckDeepSleepReset = 2,
31  kTestPhaseFinalCheck = 3,
32 };
33 
34 // Threshold/Duration values are not specific to a real-world debounce
35 // scenario so are kept short to avoid excessive simulation time.
36 // Assuming a 5us aon clock period.
37 enum {
38  kDetectionTimeThreshold = 1024, // ~5ms
39  kEcResetDuration = 512, // ~2.5ms
40  kDebounceTimeThreshold = 128, // ~0.6ms
41 };
42 
43 enum {
44  kOutputNumMioPads = 6,
45 };
46 
47 static const dif_pinmux_index_t kPeripheralInputs[] = {
54 };
55 
56 static const dif_pinmux_index_t kInputPadsDV[] = {
60 };
61 
62 // We need different pins on the hyperdebug boards since certain
63 // pins are not routed to the hyperdebug.
64 static const dif_pinmux_index_t kInputPadsReal[] = {
68 };
69 
70 // On DV this device is in the flash and written by the testbench.
71 static volatile const uint8_t kTestPhaseDV = 0;
72 // Mask of the GPIOs used on the real device to read the test phase.
73 static const uint32_t kGpioMask = 0x3;
74 
75 static void check_combo_reset(void) {
77  &sysrst_ctrl, kDifSysrstCtrlKeyCombo0,
81  .detection_time_threshold = kDetectionTimeThreshold,
82  .embedded_controller_reset_duration = kEcResetDuration,
84 
87  .debounce_time_threshold = kDebounceTimeThreshold,
88  .input_changes = kDifSysrstCtrlInputKey0H2L |
92  (dif_sysrst_ctrl_pin_config_t){.allow_one = true,
93  .allow_zero = true,
94  .enabled = kDifToggleEnabled,
95  .override_value = true}));
96  // Prepare rstmgr for a reset with sysrst_ctrl (source one).
97  CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
99  kDifPwrmgrResetRequestSourceOne,
101  // Issue WFI and wait for reset condition.
102  test_status_set(kTestStatusInWfi);
104 }
105 
106 static void check_deep_sleep_wakeup(void) {
108  &sysrst_ctrl, (dif_sysrst_ctrl_ulp_wakeup_config_t){
109  .ac_power_debounce_time_threshold = 0,
110  .lid_open_debounce_time_threshold = 0,
111  .power_button_debounce_time_threshold = 0,
112  .enabled = kDifToggleEnabled}));
113  // Setup low power.
114  // Wakeup source is from sysrst_ctrl (source one).
115  CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
116  CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(
117  &pwrmgr, kDifPwrmgrWakeupRequestSourceOne, 0));
118  // Issue WFI and wait for reset condition.
119  test_status_set(kTestStatusInWfi);
121 }
122 
123 static void check_deep_sleep_reset(void) {
125  &sysrst_ctrl, kDifSysrstCtrlKeyCombo1,
129  .detection_time_threshold = kDetectionTimeThreshold,
130  .embedded_controller_reset_duration = kEcResetDuration,
134  (dif_sysrst_ctrl_pin_config_t){.allow_one = true,
135  .allow_zero = true,
136  .enabled = kDifToggleEnabled,
137  .override_value = true}));
140  .debounce_time_threshold = kDebounceTimeThreshold,
141  .input_changes = kDifSysrstCtrlInputKey2H2L |
143  // Setup low power.
144  // Reset source is from sysrst_ctrl (source one).
145  CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
147  kDifPwrmgrResetRequestSourceOne,
149  // Enable low power with wakeup source other than
150  // sysrst_ctrl (e.g. source two) as we don't want
151  // a wakeup request but instead a reset.
152  CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(
153  &pwrmgr, kDifPwrmgrWakeupRequestSourceTwo, 0));
154  // Issue WFI and wait for reset condition.
155  test_status_set(kTestStatusInWfi);
157 }
158 
159 bool test_main(void) {
160  CHECK_DIF_OK(dif_pwrmgr_init(
162  CHECK_DIF_OK(dif_rstmgr_init(
164  CHECK_DIF_OK(dif_sysrst_ctrl_init(
166  &sysrst_ctrl));
167  CHECK_DIF_OK(
168  dif_gpio_init(mmio_region_from_addr(TOP_EARLGREY_GPIO_BASE_ADDR), &gpio));
169 
170  dif_rstmgr_reset_info_bitfield_t rstmgr_reset_info;
171  rstmgr_reset_info = rstmgr_testutils_reason_get();
172 
173  dif_pinmux_t pinmux;
174  CHECK_DIF_OK(dif_pinmux_init(
176  const dif_pinmux_index_t *kInputPads =
177  kDeviceType == kDeviceSimDV ? kInputPadsDV : kInputPadsReal;
178  for (int i = 0; i < kOutputNumMioPads; ++i) {
179  CHECK_DIF_OK(
180  dif_pinmux_input_select(&pinmux, kPeripheralInputs[i], kInputPads[i]));
181  }
182  // On real devices, we also need to configure the DIO pins and two more pins
183  // to read the test phase.
184  if (kDeviceType != kDeviceSimDV) {
185  sysrst_ctrl_testutils_setup_dio(&pinmux);
186  CHECK_DIF_OK(dif_pinmux_input_select(
189  CHECK_DIF_OK(dif_pinmux_input_select(
192  }
193 
196 
197  // On real device, we cannot do backdoor writes the flash so we read the
198  // test phase from GPIOs.
199  uint8_t kTestPhase = kTestPhaseDV;
200  if (kDeviceType != kDeviceSimDV) {
201  uint32_t gpio_state;
202  CHECK_DIF_OK(dif_gpio_read_all(&gpio, &gpio_state));
203  kTestPhase = gpio_state & kGpioMask;
204  }
205  LOG_INFO("test phase: %u", kTestPhase);
206 
207  switch (kTestPhase) {
208  case kTestPhaseCheckComboReset:
209  CHECK(rstmgr_reset_info == kDifRstmgrResetInfoPor);
210  check_combo_reset();
211  break;
212  case kTestPhaseCheckDeepSleepWakeup:
213  CHECK(rstmgr_reset_info == kDifRstmgrResetInfoSysRstCtrl);
214  check_deep_sleep_wakeup();
215  break;
216  case kTestPhaseCheckDeepSleepReset:
217  CHECK(rstmgr_reset_info == kDifRstmgrResetInfoLowPowerExit);
218  check_deep_sleep_reset();
219  break;
220  case kTestPhaseFinalCheck:
221  CHECK(rstmgr_reset_info ==
222  (kDifRstmgrResetInfoSysRstCtrl | kDifRstmgrResetInfoLowPowerExit));
223  return true;
224  break;
225  default:
226  LOG_ERROR("Unexpected test phase : %d", kTestPhase);
227  break;
228  }
229  return false;
230 }