Software APIs
sysrst_ctrl_outputs_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 
5 #include "dt/dt_pinmux.h" // Generated
6 #include "dt/dt_sysrst_ctrl.h" // Generated
12 #include "sw/device/lib/testing/sysrst_ctrl_testutils.h"
13 #include "sw/device/lib/testing/test_framework/check.h"
15 #include "sw/device/lib/testing/test_framework/ottf_utils.h"
16 
17 /* We need control flow for the ujson messages exchanged
18  * with the host in OTTF_WAIT_FOR on real devices. */
19 OTTF_DEFINE_TEST_CONFIG(.enable_uart_flow_control = true);
20 
21 static dif_pinmux_t pinmux;
22 static const dt_pinmux_t kPinmuxDt = kDtPinmuxAon;
23 static const dt_sysrst_ctrl_t kSysrstCtrlDt = kDtSysrstCtrlAon;
24 static dif_sysrst_ctrl_t sysrst_ctrl;
25 
26 enum {
27  kTestPhaseTimeoutUsecDV = 100,
28  kTestPhaseTimeoutUsecReal = 1000000,
29 };
30 
31 enum {
32  kTestPhaseSetup = 0,
33  kTestPhaseLoopback = 1,
34  kTestPhaseOverrideSetup = 2,
35  kTestPhaseOverrideZeros = 3,
36  kTestPhaseOverrideOnes = 4,
37  kTestPhaseOverrideRelease = 5,
38  kTestPhaseOverrideAndLoopback = 6,
39  kTestPhaseDone = 7,
40 };
41 
42 enum {
43  kAllZero = 0x0,
44  kAllOne = 0xff,
45  kLoopbackPartial = 0x5,
46  kNumMioInputs = 0x4,
47  kNumMioOutputs = 0x6,
48  kOutputNumPads = 0x8,
49 };
50 
51 static const dt_sysrst_ctrl_periph_io_t kPeripheralInputs[] = {
52  kDtSysrstCtrlPeriphIoKey0In,
53  kDtSysrstCtrlPeriphIoKey1In,
54  kDtSysrstCtrlPeriphIoKey2In,
55  kDtSysrstCtrlPeriphIoPwrbIn,
56 };
57 
58 static const dt_pad_t kInputPadsDV[] = {
59  kDtPadIob3,
60  kDtPadIob6,
61  kDtPadIob8,
62  kDtPadIor13,
63 };
64 
65 static const dt_pad_t kInputPadsReal[] = {
66  kDtPadIor10,
67  kDtPadIor11,
68  kDtPadIor12,
69  kDtPadIor5,
70 };
71 
72 static const dt_sysrst_ctrl_periph_io_t kPeripheralOutputs[] = {
73  kDtSysrstCtrlPeriphIoKey0Out, kDtSysrstCtrlPeriphIoKey1Out,
74  kDtSysrstCtrlPeriphIoKey2Out, kDtSysrstCtrlPeriphIoPwrbOut,
75  kDtSysrstCtrlPeriphIoBatDisable, kDtSysrstCtrlPeriphIoZ3Wakeup,
76 };
77 
78 static const dt_pad_t kOutputPadsDV[] = {
79  kDtPadIob9, kDtPadIor5, kDtPadIor6, kDtPadIoc7, kDtPadIoc9, kDtPadIob7,
80 };
81 static const dt_pad_t kOutputPadsReal[] = {
82  kDtPadIor6, kDtPadIor7, kDtPadIob0, kDtPadIob1, kDtPadIob2, kDtPadIob3,
83 };
84 
85 static const dif_sysrst_ctrl_pin_t kSysrstCtrlOutputs[] = {
90 };
91 
92 // Test phase written by testbench/host.
93 // On DV, we must use variables in flash but on a real device,
94 // we must use variables in RAM.
95 OT_SECTION(".rodata")
96 static volatile const uint8_t kTestPhaseDV = 0;
97 OT_SECTION(".data")
98 static volatile const uint8_t kTestPhaseReal = kTestPhaseSetup;
99 
100 // Sets up the pinmux to assign input and output pads
101 // to the sysrst_ctrl peripheral as required.
102 static void pinmux_setup(void) {
103  /* On real devices, we also need to configure the DIO pins */
104  if (kDeviceType != kDeviceSimDV) {
105  sysrst_ctrl_testutils_setup_dio(&pinmux);
106  // Release pins so the host can control them.
107  sysrst_ctrl_testutils_release_dio(&sysrst_ctrl, true, true);
108  // Disable the EC reset pulse so that it does not interfere with the test.
109  sysrst_ctrl_testutils_set_ec_rst_pulse_width(&sysrst_ctrl, 0);
110  }
111  const dif_pinmux_index_t *kInputPads =
112  kDeviceType == kDeviceSimDV ? kInputPadsDV : kInputPadsReal;
113  for (int i = 0; i < kNumMioInputs; ++i) {
114  CHECK_DIF_OK(dif_pinmux_mio_select_input(
115  &pinmux, dt_sysrst_ctrl_periph_io(kSysrstCtrlDt, kPeripheralInputs[i]),
116  kInputPads[i]));
117  }
118  const dif_pinmux_index_t *kOutputPads =
119  kDeviceType == kDeviceSimDV ? kOutputPadsDV : kOutputPadsReal;
120  for (int i = 0; i < kNumMioOutputs; ++i) {
121  CHECK_DIF_OK(dif_pinmux_mio_select_output(
122  &pinmux, kOutputPads[i],
123  dt_sysrst_ctrl_periph_io(kSysrstCtrlDt, kPeripheralOutputs[i])));
124  }
125 }
126 
127 // Waits for the kTestPhase variable to be changed by a backdoor overwrite
128 // from the testbench in `chip_sw_sysrst_ctrl_ec_rst_l_vseq.sv`. This will
129 // indicate that the testbench is ready to proceed with the next phase of the
130 // test.
131 static void sync_with_testbench(uint8_t prior_phase) {
132  // Set WFI status for testbench synchronization,
133  // no actual WFI instruction is issued.
134  test_status_set(kTestStatusInWfi);
135  test_status_set(kTestStatusInTest);
136  if (kDeviceType == kDeviceSimDV) {
137  OTTF_WAIT_FOR(OTTF_BACKDOOR_READ(kTestPhaseDV) != prior_phase,
138  kTestPhaseTimeoutUsecDV);
139  } else {
140  OTTF_WAIT_FOR(prior_phase != kTestPhaseReal, kTestPhaseTimeoutUsecReal);
141  }
142 }
143 
144 // Enables the sysrst_ctrl overrides for the output pins. Allows
145 // both low and high override values.
146 static void override_setup(uint8_t pins_to_override) {
147  for (int i = 0; i < kOutputNumPads; ++i) {
148  if ((pins_to_override >> i) & 0x1) {
150  &sysrst_ctrl, kSysrstCtrlOutputs[i], kDifToggleEnabled));
152  &sysrst_ctrl, kSysrstCtrlOutputs[i], true, true));
153  }
154  }
155 }
156 
157 // Disables the overrides. Allows the outputs to pass-through the
158 // values from the relevant input pins.
159 static void override_disable(void) {
160  for (int i = 0; i < kOutputNumPads; ++i) {
162  &sysrst_ctrl, kSysrstCtrlOutputs[i], kDifToggleDisabled));
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_from_dt(kPinmuxDt, &pinmux));
176  CHECK_DIF_OK(dif_sysrst_ctrl_init_from_dt(kSysrstCtrlDt, &sysrst_ctrl));
177 
178  const volatile uint8_t *kTestPhase =
179  kDeviceType == kDeviceSimDV ? &kTestPhaseDV : &kTestPhaseReal;
180  uint8_t current_test_phase = *kTestPhase;
181  while (current_test_phase < kTestPhaseDone) {
182  LOG_INFO("Test phase %d", current_test_phase);
183  switch (current_test_phase) {
184  case kTestPhaseSetup:
185  pinmux_setup();
186  break;
187  case kTestPhaseLoopback:
188  break;
189  case kTestPhaseOverrideSetup:
190  override_setup(kAllOne);
191  break;
192  case kTestPhaseOverrideZeros:
193  set_output_overrides(kAllZero);
194  break;
195  case kTestPhaseOverrideOnes:
196  set_output_overrides(kAllOne);
197  break;
198  case kTestPhaseOverrideRelease:
199  override_disable();
200  break;
201  case kTestPhaseOverrideAndLoopback:
202  override_setup(kLoopbackPartial);
203  set_output_overrides(kLoopbackPartial);
204  break;
205  default:
206  LOG_ERROR("Unexpected test phase : %d", *kTestPhase);
207  break;
208  }
209  sync_with_testbench(current_test_phase);
210  current_test_phase = *kTestPhase;
211  }
212  return true;
213 }