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 (source one).
131  CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
133  kDifPwrmgrResetRequestSourceOne,
135  // Issue WFI and wait for reset condition.
136  test_status_set(kTestStatusInWfi);
138 }
139 
140 // Waits for the kTestPhase variable to be changed by a backdoor overwrite
141 // from the testbench in `chip_sw_sysrst_ctrl_ec_rst_l_vseq.sv`. This will
142 // indicate that the testbench is ready to proceed with the next phase of the
143 // test.
144 static void sync_with_testbench(uint8_t prior_phase) {
145  // Set WFI status for testbench synchronization,
146  // no actual WFI instruction is issued.
147  test_status_set(kTestStatusInWfi);
148  test_status_set(kTestStatusInTest);
149  IBEX_SPIN_FOR(OTTF_BACKDOOR_READ(kTestPhase) != prior_phase,
150  kTestPhaseTimeoutUsec);
151 }
152 
153 // Enables the sysrst_ctrl overrides for the output pins. Allows
154 // both low and high override values.
155 static void override_setup(uint8_t pins_to_override) {
156  for (int i = 0; i < kOutputNumPads; ++i) {
157  if ((pins_to_override >> i) & 0x1) {
159  &sysrst_ctrl, kSysrstCtrlOutputs[i], kDifToggleEnabled));
161  &sysrst_ctrl, kSysrstCtrlOutputs[i], true, true));
162  }
163  }
164 }
165 
166 // Sets the values of the output overrides as required.
167 static void set_output_overrides(uint8_t override_value) {
168  for (int i = 0; i < kOutputNumPads; ++i) {
170  &sysrst_ctrl, kSysrstCtrlOutputs[i], (override_value >> i) & 0x1));
171  }
172 }
173 
174 bool test_main(void) {
175  CHECK_DIF_OK(dif_pinmux_init(
177  CHECK_DIF_OK(dif_sysrst_ctrl_init(
179  &sysrst_ctrl));
180  CHECK_DIF_OK(dif_pwrmgr_init(
182  CHECK_DIF_OK(dif_rstmgr_init(
184 
185  pinmux_setup();
186  rstmgr_reset_info = rstmgr_testutils_reason_get();
187 
188  // Disable EC rst override.
191 
192  uint8_t current_test_phase = kTestPhase;
193  while (current_test_phase < kTestPhaseDone) {
194  LOG_INFO("Test phase %d", current_test_phase);
195  switch (current_test_phase) {
196  case kTestPhaseSetup:
197  CHECK(rstmgr_reset_info == kDifRstmgrResetInfoPor);
198  configure_combo_reset();
199  LOG_ERROR("We should have reset before this line.");
200  break;
201  case kTestPhaseCheckComboReset:
202  CHECK(rstmgr_reset_info == kDifRstmgrResetInfoSysRstCtrl);
203  break;
204  case kTestPhaseOverrideSetup:
205  override_setup(kAllOne);
206  break;
207  case kTestPhaseOverrideZeros:
208  set_output_overrides(kAllZero);
209  break;
210  case kTestPhaseOverrideOnes:
211  set_output_overrides(kAllOne);
212  break;
213  default:
214  LOG_ERROR("Unexpected test phase : %d", current_test_phase);
215  break;
216  }
217  sync_with_testbench(current_test_phase);
218  current_test_phase = kTestPhase;
219  }
220  return true;
221 }