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/test_framework/check.h"
15 #include "sw/device/lib/testing/test_framework/ottf_utils.h"
16 
18 
19 OTTF_DEFINE_TEST_CONFIG();
20 
21 static dif_pinmux_t pinmux;
22 static dif_sysrst_ctrl_t sysrst_ctrl;
23 static dif_pwrmgr_t pwrmgr;
24 static dif_rstmgr_t rstmgr;
25 static dif_rstmgr_reset_info_bitfield_t rstmgr_reset_info;
26 
27 const uint32_t kTestPhaseTimeoutUsec = 10000;
28 
29 typedef enum {
30  kTestPhaseSetup = 0,
31  kTestPhaseCheckComboReset = 1,
32  kTestPhaseOverrideSetup = 2,
33  kTestPhaseOverrideZeros = 3,
34  kTestPhaseOverrideOnes = 4,
35  kTestPhaseDone = 5,
36 } test_phases_e;
37 
38 enum {
39  kAllZero = 0x0,
40  kAllOne = 0xff,
41  kLoopbackPartial = 0x5,
42  kNumMioInputs = 0x4,
43  kNumMioOutputs = 0x6,
44  kOutputNumPads = 0x8,
45 };
46 
47 static const dif_pinmux_index_t kPeripheralInputs[] = {
52 };
53 
54 static const dif_pinmux_index_t kInputPads[] = {
59 };
60 
61 static const dif_pinmux_index_t kPeripheralOutputs[] = {
68 };
69 
70 static const dif_pinmux_index_t kOutputPads[] = {
74 };
75 
76 static const dif_sysrst_ctrl_pin_t kSysrstCtrlOutputs[] = {
81 };
82 
83 // Threshold/Duration values are not specific to a real-world debounce
84 // scenario so are kept short to avoid excessive simulation time.
85 // Assuming a 5us aon clock period.
86 enum {
87  kDetectionTimeThreshold = 1024, // ~5ms
88  kEcResetDuration = 512, // ~2.5ms
89  kDebounceTimeThreshold = 128, // ~0.6ms
90 };
91 
92 // Test phase written by testbench.
93 static volatile const uint8_t kTestPhase = 0;
94 
95 // Sets up the pinmux to assign input and output pads
96 // to the sysrst_ctrl peripheral as required.
97 static void pinmux_setup(void) {
98  for (int i = 0; i < kNumMioInputs; ++i) {
99  CHECK_DIF_OK(
100  dif_pinmux_input_select(&pinmux, kPeripheralInputs[i], kInputPads[i]));
101  }
102  for (int i = 0; i < kNumMioOutputs; ++i) {
103  CHECK_DIF_OK(dif_pinmux_output_select(&pinmux, kOutputPads[i],
104  kPeripheralOutputs[i]));
105  }
106 }
107 
108 static void configure_combo_reset(void) {
110  &sysrst_ctrl, kDifSysrstCtrlKeyCombo0,
114  .detection_time_threshold = kDetectionTimeThreshold,
115  .embedded_controller_reset_duration = kEcResetDuration,
117 
120  .debounce_time_threshold = kDebounceTimeThreshold,
121  .input_changes = kDifSysrstCtrlInputKey0H2L |
123  // Release the flash_wp signal
126  (dif_sysrst_ctrl_pin_config_t){.allow_one = true,
127  .allow_zero = true,
128  .enabled = kDifToggleEnabled,
129  .override_value = true}));
130  // Prepare rstmgr for a reset with sysrst_ctrl.
131  CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
132  dif_pwrmgr_request_sources_t reset_sources;
133  CHECK_DIF_OK(dif_pwrmgr_find_request_source(
134  &pwrmgr, kDifPwrmgrReqTypeReset,
135  dt_sysrst_ctrl_instance_id(kDtSysrstCtrlAon), kDtSysrstCtrlResetReqRstReq,
136  &reset_sources));
137  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(
138  &pwrmgr, kDifPwrmgrReqTypeReset, reset_sources, kDifToggleEnabled));
139  // Issue WFI and wait for reset condition.
140  test_status_set(kTestStatusInWfi);
142 }
143 
144 // Waits for the kTestPhase variable to be changed by a backdoor overwrite
145 // from the testbench in `chip_sw_sysrst_ctrl_ec_rst_l_vseq.sv`. This will
146 // indicate that the testbench is ready to proceed with the next phase of the
147 // test.
148 static void sync_with_testbench(uint8_t prior_phase) {
149  // Set WFI status for testbench synchronization,
150  // no actual WFI instruction is issued.
151  test_status_set(kTestStatusInWfi);
152  test_status_set(kTestStatusInTest);
153  IBEX_SPIN_FOR(OTTF_BACKDOOR_READ(kTestPhase) != prior_phase,
154  kTestPhaseTimeoutUsec);
155 }
156 
157 // Enables the sysrst_ctrl overrides for the output pins. Allows
158 // both low and high override values.
159 static void override_setup(uint8_t pins_to_override) {
160  for (int i = 0; i < kOutputNumPads; ++i) {
161  if ((pins_to_override >> i) & 0x1) {
163  &sysrst_ctrl, kSysrstCtrlOutputs[i], kDifToggleEnabled));
165  &sysrst_ctrl, kSysrstCtrlOutputs[i], true, true));
166  }
167  }
168 }
169 
170 // Sets the values of the output overrides as required.
171 static void set_output_overrides(uint8_t override_value) {
172  for (int i = 0; i < kOutputNumPads; ++i) {
174  &sysrst_ctrl, kSysrstCtrlOutputs[i], (override_value >> i) & 0x1));
175  }
176 }
177 
178 bool test_main(void) {
179  CHECK_DIF_OK(dif_pinmux_init(
181  CHECK_DIF_OK(dif_sysrst_ctrl_init(
183  &sysrst_ctrl));
184  CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kDtPwrmgrAon, &pwrmgr));
185  CHECK_DIF_OK(dif_rstmgr_init(
187 
188  pinmux_setup();
189  rstmgr_reset_info = rstmgr_testutils_reason_get();
190 
191  // Disable EC rst override.
194 
195  uint8_t current_test_phase = kTestPhase;
196  while (current_test_phase < kTestPhaseDone) {
197  LOG_INFO("Test phase %d", current_test_phase);
198  switch (current_test_phase) {
199  case kTestPhaseSetup:
200  CHECK(rstmgr_reset_info == kDifRstmgrResetInfoPor);
201  configure_combo_reset();
202  LOG_ERROR("We should have reset before this line.");
203  break;
204  case kTestPhaseCheckComboReset:
205  CHECK(rstmgr_reset_info == kDifRstmgrResetInfoSysRstCtrl);
206  break;
207  case kTestPhaseOverrideSetup:
208  override_setup(kAllOne);
209  break;
210  case kTestPhaseOverrideZeros:
211  set_output_overrides(kAllZero);
212  break;
213  case kTestPhaseOverrideOnes:
214  set_output_overrides(kAllOne);
215  break;
216  default:
217  LOG_ERROR("Unexpected test phase : %d", current_test_phase);
218  break;
219  }
220  sync_with_testbench(current_test_phase);
221  current_test_phase = kTestPhase;
222  }
223  return true;
224 }