Software APIs
sysrst_ctrl_ec_rst_l_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/rstmgr_testutils.h"
13 #include "sw/device/lib/testing/sysrst_ctrl_testutils.h"
14 #include "sw/device/lib/testing/test_framework/check.h"
16 
18 
19 /* We need control flow for the ujson messages exchanged
20  * with the host in OTTF_WAIT_FOR on real devices. */
21 OTTF_DEFINE_TEST_CONFIG(.enable_uart_flow_control = true);
22 
23 static dif_pinmux_t pinmux;
24 static dif_sysrst_ctrl_t sysrst_ctrl;
25 static dif_pwrmgr_t pwrmgr;
26 static dif_rstmgr_t rstmgr;
27 static dif_rstmgr_reset_info_bitfield_t rstmgr_reset_info;
28 
29 enum {
30  kAllZero = 0x0,
31  kAllOne = 0x3,
32  kNumMioInputs = 0x2,
33 };
34 
35 static const dif_pinmux_index_t kPeripheralInputs[] = {
38 };
39 
40 static const dif_pinmux_index_t kInputPads[] = {
43 };
44 
45 // Threshold/Duration values are not specific to a real-world debounce
46 // scenario so are kept short to avoid excessive simulation time.
47 // Assuming a 5us aon clock period.
48 enum {
49  kDetectionTimeThreshold = 1024, // ~5ms
50  kEcResetStretchDurationMicros = 200 * 1000,
51  kDebounceTimeThreshold = 128, // ~0.6ms
52 };
53 
54 // Sets up the pinmux to assign input and output pads
55 // to the sysrst_ctrl peripheral as required.
56 static void pinmux_setup(void) {
57  for (int i = 0; i < kNumMioInputs; ++i) {
58  CHECK_DIF_OK(
59  dif_pinmux_input_select(&pinmux, kPeripheralInputs[i], kInputPads[i]));
60  }
61 }
62 
63 static void configure_combo_reset(void) {
65  &sysrst_ctrl, kDifSysrstCtrlKeyCombo0,
68  .detection_time_threshold = kDetectionTimeThreshold,
69  .embedded_controller_reset_duration = 0,
71  // Use testutils to computes the value using the actual aon clock frequency.
74  .debounce_time_threshold = kDebounceTimeThreshold,
75  .input_changes = kDifSysrstCtrlInputKey0H2L |
77  // Prepare rstmgr for a reset with sysrst_ctrl (source one).
78  CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
80  kDifPwrmgrResetRequestSourceOne,
82  // Issue WFI and wait for reset condition.
83  LOG_INFO("wait for combo (key0&1 low)");
84  test_status_set(kTestStatusInWfi);
86 }
87 
88 bool test_main(void) {
89  CHECK_DIF_OK(dif_pinmux_init(
91  CHECK_DIF_OK(dif_sysrst_ctrl_init(
93  &sysrst_ctrl));
94  CHECK_DIF_OK(dif_pwrmgr_init(
96  CHECK_DIF_OK(dif_rstmgr_init(
98 
99  pinmux_setup();
100  sysrst_ctrl_testutils_setup_dio(&pinmux);
101  rstmgr_reset_info = rstmgr_testutils_reason_get();
102 
103  // On a POR, start the test: prepare the sysrst_ctrl with a combo to reset
104  // the chip and wait for the host to reset the device using that combo.
105  if (rstmgr_reset_info == kDifRstmgrResetInfoPor) {
106  sysrst_ctrl_testutils_release_dio(&sysrst_ctrl, true, true);
107  configure_combo_reset();
108  LOG_ERROR("We should have reset before this line.");
109  } else {
110  // Otherwise, check that we got reset because of sysrst_ctrl.
111  CHECK(rstmgr_reset_info == kDifRstmgrResetInfoSysRstCtrl);
112  // Key0 is low since the reset was triggered by the combo. Wait until host
113  // pulls key0 up.
114  LOG_INFO("wait for key0 to go high");
115  test_status_set(kTestStatusInWfi);
116  bool key0_up = false;
117  while (!key0_up) {
118  CHECK_DIF_OK(dif_sysrst_ctrl_input_pin_read(
119  &sysrst_ctrl, kDifSysrstCtrlPinKey0In, &key0_up));
120  }
121  // Release the pins
122  LOG_INFO("releasing ec_rst and flash_wp");
123  // Now release the pins.
124  sysrst_ctrl_testutils_set_ec_rst_pulse_width(&sysrst_ctrl, 0);
125  sysrst_ctrl_testutils_release_dio(&sysrst_ctrl, true, true);
126  // Setup the EC reset stretch pulse width so that the host can check that it
127  // works.
128  sysrst_ctrl_testutils_set_ec_rst_pulse_width(&sysrst_ctrl,
129  kEcResetStretchDurationMicros);
130  test_status_set(kTestStatusInWfi);
131  }
132  return true;
133 }