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 static const dt_pwrmgr_t kPwrmgrDt = 0;
30 static_assert(kDtPwrmgrCount == 1, "this test expects a pwrmgr");
31 static const dt_pinmux_t kPinmuxDt = 0;
32 static_assert(kDtPinmuxCount == 1, "this test expects a pinmux");
33 static const dt_rstmgr_t kRstmgrDt = 0;
34 static_assert(kDtRstmgrCount == 1, "this test expects a rstmgr");
35 static const dt_sysrst_ctrl_t kSysrstCtrlDt = 0;
36 static_assert(kDtSysrstCtrlCount == 1, "this test expects a sysrst_ctrl");
37 
38 enum {
39  kAllZero = 0x0,
40  kAllOne = 0x3,
41  kNumMioInputs = 0x2,
42 };
43 
44 static const dif_pinmux_index_t kPeripheralInputs[] = {
47 };
48 
49 static const dif_pinmux_index_t kInputPads[] = {
52 };
53 
54 // Threshold/Duration values are not specific to a real-world debounce
55 // scenario so are kept short to avoid excessive simulation time.
56 // Assuming a 5us aon clock period.
57 enum {
58  kDetectionTimeThreshold = 1024, // ~5ms
59  kEcResetStretchDurationMicros = 200 * 1000,
60  kDebounceTimeThreshold = 128, // ~0.6ms
61 };
62 
63 // Sets up the pinmux to assign input and output pads
64 // to the sysrst_ctrl peripheral as required.
65 static void pinmux_setup(void) {
66  for (int i = 0; i < kNumMioInputs; ++i) {
67  CHECK_DIF_OK(
68  dif_pinmux_input_select(&pinmux, kPeripheralInputs[i], kInputPads[i]));
69  }
70 }
71 
72 static void configure_combo_reset(void) {
74  &sysrst_ctrl, kDifSysrstCtrlKeyCombo0,
77  .detection_time_threshold = kDetectionTimeThreshold,
78  .embedded_controller_reset_duration = 0,
80  // Use testutils to computes the value using the actual aon clock frequency.
83  .debounce_time_threshold = kDebounceTimeThreshold,
84  .input_changes = kDifSysrstCtrlInputKey0H2L |
86  // Prepare rstmgr for a reset with sysrst_ctrl.
87  dif_pwrmgr_request_sources_t reset_sources;
88  CHECK_DIF_OK(dif_pwrmgr_find_request_source(
89  &pwrmgr, kDifPwrmgrReqTypeReset,
90  dt_sysrst_ctrl_instance_id(kSysrstCtrlDt), kDtSysrstCtrlResetReqRstReq,
91  &reset_sources));
92  CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
93  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(
94  &pwrmgr, kDifPwrmgrReqTypeReset, reset_sources, kDifToggleEnabled));
95  // Issue WFI and wait for reset condition.
96  LOG_INFO("wait for combo (key0&1 low)");
97  test_status_set(kTestStatusInWfi);
99 }
100 
101 bool test_main(void) {
102  CHECK_DIF_OK(dif_pinmux_init_from_dt(kPinmuxDt, &pinmux));
103  CHECK_DIF_OK(dif_sysrst_ctrl_init_from_dt(kSysrstCtrlDt, &sysrst_ctrl));
104  CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kPwrmgrDt, &pwrmgr));
105  CHECK_DIF_OK(dif_rstmgr_init_from_dt(kRstmgrDt, &rstmgr));
106 
107  pinmux_setup();
108  sysrst_ctrl_testutils_setup_dio(&pinmux);
109  rstmgr_reset_info = rstmgr_testutils_reason_get();
110 
111  // On a POR, start the test: prepare the sysrst_ctrl with a combo to reset
112  // the chip and wait for the host to reset the device using that combo.
113  if (rstmgr_reset_info == kDifRstmgrResetInfoPor) {
114  sysrst_ctrl_testutils_release_dio(&sysrst_ctrl, true, true);
115  configure_combo_reset();
116  LOG_ERROR("We should have reset before this line.");
117  } else {
118  // Otherwise, check that we got reset because of sysrst_ctrl.
119  CHECK(rstmgr_reset_info == kDifRstmgrResetInfoSysRstCtrl);
120  // Key0 is low since the reset was triggered by the combo. Wait until host
121  // pulls key0 up.
122  LOG_INFO("wait for key0 to go high");
123  test_status_set(kTestStatusInWfi);
124  bool key0_up = false;
125  while (!key0_up) {
126  CHECK_DIF_OK(dif_sysrst_ctrl_input_pin_read(
127  &sysrst_ctrl, kDifSysrstCtrlPinKey0In, &key0_up));
128  }
129  // Release the pins
130  LOG_INFO("releasing ec_rst and flash_wp");
131  // Now release the pins.
132  sysrst_ctrl_testutils_set_ec_rst_pulse_width(&sysrst_ctrl, 0);
133  sysrst_ctrl_testutils_release_dio(&sysrst_ctrl, true, true);
134  // Setup the EC reset stretch pulse width so that the host can check that it
135  // works.
136  sysrst_ctrl_testutils_set_ec_rst_pulse_width(&sysrst_ctrl,
137  kEcResetStretchDurationMicros);
138  test_status_set(kTestStatusInWfi);
139  }
140  return true;
141 }