Software APIs
dif_alert_handler_unittest.cc
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 
6 
7 #include <cstring>
8 #include <limits>
9 #include <ostream>
10 #include <tuple>
11 #include <vector>
12 
13 #include "gtest/gtest.h"
15 #include "sw/device/lib/base/mock_mmio.h"
17 
18 #include "alert_handler_regs.h" // Generated.
19 
20 namespace dif_alert_handler_unittest {
21 namespace {
22 using ::mock_mmio::LeInt;
23 using ::mock_mmio::MmioTest;
24 using ::mock_mmio::MockDevice;
25 using ::testing::_;
26 using ::testing::Return;
27 
28 // If the assert below fails, please look at #14038.
29 // A digest is calculated for the configuration of the alerts,
30 // so if the number of alerts change, the digest will be changed
31 // as well. This process is not yet automated, so the user
32 // must be aware on how to update the value.
33 static_assert(ALERT_HANDLER_PARAM_N_ALERTS == 65,
34  "The number of alerts have changed.");
35 
36 constexpr int kAlerts = ALERT_HANDLER_PARAM_N_ALERTS;
37 constexpr int kLocalAlerts = ALERT_HANDLER_PARAM_N_LOC_ALERT;
38 constexpr int kClasses = ALERT_HANDLER_PARAM_N_CLASSES;
39 constexpr int kEscSignals = ALERT_HANDLER_PARAM_N_ESC_SEV;
40 
41 class AlertHandlerTest : public testing::Test, public MmioTest {
42  protected:
43  dif_alert_handler_t alert_handler_ = {.base_addr = dev().region()};
44 };
45 
47  public testing::WithParamInterface<
48  std::tuple<int, dif_alert_handler_class_t>> {};
49 
50 TEST_F(AlertConfigTest, BadArgs) {
52  dif_alert_handler_configure_alert(nullptr, 0, kDifAlertHandlerClassA,
54 
56  &alert_handler_, kAlerts, kDifAlertHandlerClassA, kDifToggleEnabled,
58 
60  &alert_handler_, 0, static_cast<dif_alert_handler_class_t>(kClasses),
62 
64  &alert_handler_, 0, kDifAlertHandlerClassA, static_cast<dif_toggle_t>(2),
66 
68  &alert_handler_, 0, kDifAlertHandlerClassA, kDifToggleEnabled,
69  static_cast<dif_toggle_t>(2)));
70 }
71 
72 TEST_F(AlertConfigTest, Locked) {
73  EXPECT_READ32(ALERT_HANDLER_ALERT_REGWEN_0_REG_OFFSET, 0);
75  &alert_handler_, 0, kDifAlertHandlerClassA, kDifToggleEnabled,
77  kDifLocked);
78 
79  EXPECT_READ32(ALERT_HANDLER_ALERT_REGWEN_0_REG_OFFSET +
80  (kAlerts - 1) * sizeof(uint32_t),
81  0);
83  &alert_handler_, kAlerts - 1, kDifAlertHandlerClassD,
85  kDifLocked);
86 }
87 
88 TEST_P(AlertConfigTest, EnableOnly) {
89  dif_alert_handler_alert_t alert = std::get<0>(GetParam());
90  dif_alert_handler_class_t alert_class = std::get<1>(GetParam());
91 
92  EXPECT_READ32(
93  ALERT_HANDLER_ALERT_REGWEN_0_REG_OFFSET + alert * sizeof(uint32_t),
94  ALERT_HANDLER_ALERT_REGWEN_0_REG_RESVAL);
95  EXPECT_WRITE32_SHADOWED(
96  ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_REG_OFFSET +
97  alert * sizeof(uint32_t),
98  {{ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_CLASS_A_0_OFFSET, alert_class}});
99  EXPECT_WRITE32_SHADOWED(
100  ALERT_HANDLER_ALERT_EN_SHADOWED_0_REG_OFFSET + alert * sizeof(uint32_t),
101  {{ALERT_HANDLER_ALERT_EN_SHADOWED_0_EN_A_0_BIT, true}});
102 
104  dif_alert_handler_configure_alert(&alert_handler_, alert, alert_class,
106 }
107 
108 TEST_P(AlertConfigTest, EnableAndLock) {
109  dif_alert_handler_alert_t alert = std::get<0>(GetParam());
110  dif_alert_handler_class_t alert_class = std::get<1>(GetParam());
111 
112  EXPECT_READ32(
113  ALERT_HANDLER_ALERT_REGWEN_0_REG_OFFSET + alert * sizeof(uint32_t),
114  ALERT_HANDLER_ALERT_REGWEN_0_REG_RESVAL);
115  EXPECT_WRITE32_SHADOWED(
116  ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_REG_OFFSET +
117  alert * sizeof(uint32_t),
118  {{ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_CLASS_A_0_OFFSET, alert_class}});
119  EXPECT_WRITE32_SHADOWED(
120  ALERT_HANDLER_ALERT_EN_SHADOWED_0_REG_OFFSET + alert * sizeof(uint32_t),
121  {{ALERT_HANDLER_ALERT_EN_SHADOWED_0_EN_A_0_BIT, true}});
122  EXPECT_WRITE32(
123  ALERT_HANDLER_ALERT_REGWEN_0_REG_OFFSET + alert * sizeof(uint32_t), 0);
124 
126  dif_alert_handler_configure_alert(&alert_handler_, alert, alert_class,
128 }
129 
130 INSTANTIATE_TEST_SUITE_P(
131  AllAlertsAndClasses, AlertConfigTest,
132  testing::Combine(testing::Range(0, kAlerts),
133  testing::Values(kDifAlertHandlerClassA,
134  kDifAlertHandlerClassB,
135  kDifAlertHandlerClassC,
136  kDifAlertHandlerClassD)));
137 
139  : public AlertHandlerTest,
140  public testing::WithParamInterface<std::tuple<
141  dif_alert_handler_local_alert_t, dif_alert_handler_class_t>> {};
142 
143 TEST_F(LocalAlertConfigTest, BadArgs) {
145  nullptr, kDifAlertHandlerLocalAlertBusIntegrityFail,
146  kDifAlertHandlerClassA, kDifToggleEnabled, kDifToggleDisabled));
147 
149  &alert_handler_,
150  static_cast<dif_alert_handler_local_alert_t>(kLocalAlerts),
151  kDifAlertHandlerClassA, kDifToggleEnabled, kDifToggleDisabled));
152 
154  &alert_handler_, kDifAlertHandlerLocalAlertAlertPingFail,
155  static_cast<dif_alert_handler_class_t>(kClasses), kDifToggleEnabled,
157 
159  &alert_handler_, kDifAlertHandlerLocalAlertAlertPingFail,
160  kDifAlertHandlerClassA, static_cast<dif_toggle_t>(2),
162 
164  &alert_handler_, kDifAlertHandlerLocalAlertAlertPingFail,
165  kDifAlertHandlerClassA, kDifToggleEnabled, static_cast<dif_toggle_t>(2)));
166 }
167 
168 TEST_F(LocalAlertConfigTest, Locked) {
169  EXPECT_READ32(ALERT_HANDLER_LOC_ALERT_REGWEN_0_REG_OFFSET, 0);
171  &alert_handler_, kDifAlertHandlerLocalAlertAlertPingFail,
172  kDifAlertHandlerClassA, kDifToggleEnabled, kDifToggleDisabled),
173  kDifLocked);
174 
175  EXPECT_READ32(ALERT_HANDLER_LOC_ALERT_REGWEN_6_REG_OFFSET, 0);
177  &alert_handler_, kDifAlertHandlerLocalAlertShadowedStorageError,
178  kDifAlertHandlerClassD, kDifToggleEnabled, kDifToggleEnabled),
179  kDifLocked);
180 }
181 
182 TEST_P(LocalAlertConfigTest, EnableOnly) {
183  dif_alert_handler_local_alert_t local_alert = std::get<0>(GetParam());
184  dif_alert_handler_class_t alert_class = std::get<1>(GetParam());
185 
186  EXPECT_READ32(ALERT_HANDLER_LOC_ALERT_REGWEN_0_REG_OFFSET +
187  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
188  ALERT_HANDLER_LOC_ALERT_REGWEN_0_REG_RESVAL);
189  EXPECT_WRITE32_SHADOWED(
190  ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_0_REG_OFFSET +
191  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
192  {{ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_0_CLASS_LA_0_OFFSET,
193  alert_class}});
194  EXPECT_WRITE32_SHADOWED(
195  ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_0_REG_OFFSET +
196  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
197  {{ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_0_EN_LA_0_BIT, true}});
198 
200  &alert_handler_, local_alert, alert_class, kDifToggleEnabled,
202 }
203 
204 TEST_P(LocalAlertConfigTest, EnableAndLock) {
205  dif_alert_handler_local_alert_t local_alert = std::get<0>(GetParam());
206  dif_alert_handler_class_t alert_class = std::get<1>(GetParam());
207 
208  EXPECT_READ32(ALERT_HANDLER_LOC_ALERT_REGWEN_0_REG_OFFSET +
209  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
210  ALERT_HANDLER_LOC_ALERT_REGWEN_0_REG_RESVAL);
211  EXPECT_WRITE32_SHADOWED(
212  ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_0_REG_OFFSET +
213  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
214  {{ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_0_CLASS_LA_0_OFFSET,
215  alert_class}});
216  EXPECT_WRITE32_SHADOWED(
217  ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_0_REG_OFFSET +
218  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
219  {{ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_0_EN_LA_0_BIT, true}});
220  EXPECT_WRITE32(ALERT_HANDLER_LOC_ALERT_REGWEN_0_REG_OFFSET +
221  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
222  0);
223 
225  &alert_handler_, local_alert, alert_class, kDifToggleEnabled,
227 }
228 
229 INSTANTIATE_TEST_SUITE_P(
230  AllLocalAlertsAndClasses, LocalAlertConfigTest,
231  testing::Combine(
232  testing::Values(kDifAlertHandlerLocalAlertAlertPingFail,
233  kDifAlertHandlerLocalAlertEscalationPingFail,
234  kDifAlertHandlerLocalAlertAlertIntegrityFail,
235  kDifAlertHandlerLocalAlertEscalationIntegrityFail,
236  kDifAlertHandlerLocalAlertBusIntegrityFail,
237  kDifAlertHandlerLocalAlertShadowedUpdateError,
238  kDifAlertHandlerLocalAlertShadowedStorageError),
239  testing::Values(kDifAlertHandlerClassA, kDifAlertHandlerClassB,
240  kDifAlertHandlerClassC, kDifAlertHandlerClassD)));
241 
243 
244 TEST_F(ClassConfigTest, BadArgs) {
245  dif_alert_handler_class_config_t valid_config = {
247  .accumulator_threshold = 10,
248  .irq_deadline_cycles = 10000,
249  .escalation_phases = nullptr,
250  .escalation_phases_len = 0,
251  .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase1,
252  };
253 
255  nullptr, kDifAlertHandlerClassB, valid_config, kDifToggleEnabled,
257 
259  &alert_handler_, static_cast<dif_alert_handler_class_t>(kClasses),
260  valid_config, kDifToggleEnabled, kDifToggleDisabled));
261 
263  &alert_handler_, static_cast<dif_alert_handler_class_t>(kClasses),
264  valid_config, static_cast<dif_toggle_t>(2), kDifToggleDisabled));
265 
267  &alert_handler_, static_cast<dif_alert_handler_class_t>(kClasses),
268  valid_config, kDifToggleEnabled, static_cast<dif_toggle_t>(2)));
269 }
270 
271 TEST_F(ClassConfigTest, BadConfig) {
274  .accumulator_threshold = 10,
275  .irq_deadline_cycles = 10000,
276  .escalation_phases = nullptr,
277  .escalation_phases_len = 0,
278  .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase1};
281  .signal = 0,
282  .duration_cycles = 10000};
283 
284  // Bad auto_lock_accumulation_counter flag.
285  config.auto_lock_accumulation_counter = static_cast<dif_toggle_t>(2);
287  dif_alert_handler_configure_class(nullptr, kDifAlertHandlerClassB, config,
290 
291  // Bad escalation_phases array dimension.
292  config.escalation_phases_len = 1;
294  dif_alert_handler_configure_class(nullptr, kDifAlertHandlerClassB, config,
296  config.escalation_phases_len = 0;
297  config.escalation_phases = &esc_phase;
299  dif_alert_handler_configure_class(nullptr, kDifAlertHandlerClassB, config,
301  config.escalation_phases = nullptr;
302 
303  // Bad crashdump_escalation_phase.
306  dif_alert_handler_configure_class(nullptr, kDifAlertHandlerClassB, config,
310  dif_alert_handler_configure_class(nullptr, kDifAlertHandlerClassB, config,
313 }
314 
315 TEST_F(ClassConfigTest, BadEscPhaseConfig) {
316  std::vector<dif_alert_handler_escalation_phase_t> esc_phases = {
318  .signal = 3,
319  .duration_cycles = 5000},
321  .signal = 1,
322  .duration_cycles = 1000},
323  };
326  .accumulator_threshold = 10,
327  .irq_deadline_cycles = 10000,
328  .escalation_phases = esc_phases.data(),
329  .escalation_phases_len = 1,
330  .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase1,
331  };
332 
333  // Bad phase.
334  esc_phases[0].phase = kDifAlertHandlerClassStateTerminal;
336  dif_alert_handler_configure_class(nullptr, kDifAlertHandlerClassB, config,
338  esc_phases[0].phase = kDifAlertHandlerClassStatePhase2;
339 
340  // Bad signal.
341  esc_phases[0].signal = kEscSignals;
343  dif_alert_handler_configure_class(nullptr, kDifAlertHandlerClassB, config,
345  esc_phases[0].signal = 0;
346 }
347 
348 TEST_F(ClassConfigTest, Locked) {
351  .accumulator_threshold = 10,
352  .irq_deadline_cycles = 10000,
353  .escalation_phases = nullptr,
354  .escalation_phases_len = 0,
355  .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase1,
356  };
357 
358  EXPECT_READ32(ALERT_HANDLER_CLASSC_REGWEN_REG_OFFSET, 0);
360  &alert_handler_, kDifAlertHandlerClassC, config,
362  kDifLocked);
363 }
364 
365 TEST_F(ClassConfigTest, EnableOnly) {
366  std::vector<dif_alert_handler_escalation_phase_t> esc_phases = {
368  .signal = 3,
369  .duration_cycles = 5000},
371  .signal = 1,
372  .duration_cycles = 1000},
373  };
376  .accumulator_threshold = 10,
377  .irq_deadline_cycles = 10000,
378  .escalation_phases = esc_phases.data(),
379  .escalation_phases_len = esc_phases.size(),
380  .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase1,
381  };
382 
383  EXPECT_READ32(ALERT_HANDLER_CLASSC_REGWEN_REG_OFFSET, 1);
384 
385  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_CLASSC_PHASE0_CYC_SHADOWED_REG_OFFSET,
386  esc_phases[0].duration_cycles);
387  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_CLASSC_PHASE2_CYC_SHADOWED_REG_OFFSET,
388  esc_phases[1].duration_cycles);
389 
390  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_CLASSC_ACCUM_THRESH_SHADOWED_REG_OFFSET,
391  config.accumulator_threshold);
392 
393  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_CLASSC_TIMEOUT_CYC_SHADOWED_REG_OFFSET,
394  config.irq_deadline_cycles);
395 
396  EXPECT_WRITE32_SHADOWED(
397  ALERT_HANDLER_CLASSC_CRASHDUMP_TRIGGER_SHADOWED_REG_OFFSET, 1);
398 
399  uint32_t ctrl_reg = 0;
400  ctrl_reg = bitfield_bit32_write(ctrl_reg,
401  ALERT_HANDLER_CLASSC_CTRL_SHADOWED_EN_BIT, 1);
402  ctrl_reg = bitfield_bit32_write(
403  ctrl_reg, ALERT_HANDLER_CLASSC_CTRL_SHADOWED_EN_E3_BIT, 1);
404  ctrl_reg = bitfield_bit32_write(
405  ctrl_reg, ALERT_HANDLER_CLASSC_CTRL_SHADOWED_EN_E1_BIT, 1);
406  ctrl_reg = bitfield_field32_write(
407  ctrl_reg, ALERT_HANDLER_CLASSC_CTRL_SHADOWED_MAP_E3_FIELD, 0);
408  ctrl_reg = bitfield_field32_write(
409  ctrl_reg, ALERT_HANDLER_CLASSC_CTRL_SHADOWED_MAP_E1_FIELD, 2);
410  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_CLASSC_CTRL_SHADOWED_REG_OFFSET,
411  ctrl_reg);
412 
414  &alert_handler_, kDifAlertHandlerClassC, config, kDifToggleEnabled,
416 }
417 
418 TEST_F(ClassConfigTest, EnableAndLock) {
419  std::vector<dif_alert_handler_escalation_phase_t> esc_phases = {
421  .signal = 1,
422  .duration_cycles = 5000},
424  .signal = 3,
425  .duration_cycles = 1000},
426  };
429  .accumulator_threshold = 10,
430  .irq_deadline_cycles = 10000,
431  .escalation_phases = esc_phases.data(),
432  .escalation_phases_len = esc_phases.size(),
433  .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase1,
434  };
435 
436  EXPECT_READ32(ALERT_HANDLER_CLASSC_REGWEN_REG_OFFSET, 1);
437 
438  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_CLASSC_PHASE0_CYC_SHADOWED_REG_OFFSET,
439  esc_phases[0].duration_cycles);
440  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_CLASSC_PHASE2_CYC_SHADOWED_REG_OFFSET,
441  esc_phases[1].duration_cycles);
442 
443  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_CLASSC_ACCUM_THRESH_SHADOWED_REG_OFFSET,
444  config.accumulator_threshold);
445 
446  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_CLASSC_TIMEOUT_CYC_SHADOWED_REG_OFFSET,
447  config.irq_deadline_cycles);
448 
449  EXPECT_WRITE32_SHADOWED(
450  ALERT_HANDLER_CLASSC_CRASHDUMP_TRIGGER_SHADOWED_REG_OFFSET, 1);
451 
452  uint32_t ctrl_reg = 0;
453  ctrl_reg = bitfield_bit32_write(ctrl_reg,
454  ALERT_HANDLER_CLASSC_CTRL_SHADOWED_EN_BIT, 1);
455  ctrl_reg = bitfield_bit32_write(
456  ctrl_reg, ALERT_HANDLER_CLASSC_CTRL_SHADOWED_LOCK_BIT, 1);
457  ctrl_reg = bitfield_bit32_write(
458  ctrl_reg, ALERT_HANDLER_CLASSC_CTRL_SHADOWED_EN_E1_BIT, 1);
459  ctrl_reg = bitfield_bit32_write(
460  ctrl_reg, ALERT_HANDLER_CLASSC_CTRL_SHADOWED_EN_E3_BIT, 1);
461  ctrl_reg = bitfield_field32_write(
462  ctrl_reg, ALERT_HANDLER_CLASSC_CTRL_SHADOWED_MAP_E1_FIELD, 0);
463  ctrl_reg = bitfield_field32_write(
464  ctrl_reg, ALERT_HANDLER_CLASSC_CTRL_SHADOWED_MAP_E3_FIELD, 2);
465  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_CLASSC_CTRL_SHADOWED_REG_OFFSET,
466  ctrl_reg);
467 
468  EXPECT_WRITE32(ALERT_HANDLER_CLASSC_REGWEN_REG_OFFSET, 0);
469 
471  &alert_handler_, kDifAlertHandlerClassC, config, kDifToggleEnabled,
473 }
474 
476 
477 TEST_F(PingTimerConfigTest, BadArgs) {
479  nullptr, 0, kDifToggleDisabled, kDifToggleDisabled));
480 
482  &alert_handler_, 0, static_cast<dif_toggle_t>(2), kDifToggleDisabled));
483 
485  &alert_handler_, 0, kDifToggleDisabled, static_cast<dif_toggle_t>(2)));
486 }
487 
488 TEST_F(PingTimerConfigTest, TimeoutTooBig) {
489  uint32_t ping_timeout =
490  ALERT_HANDLER_PING_TIMEOUT_CYC_SHADOWED_PING_TIMEOUT_CYC_SHADOWED_MASK +
491  1;
492 
494  &alert_handler_, ping_timeout, kDifToggleDisabled, kDifToggleDisabled));
495 }
496 
497 TEST_F(PingTimerConfigTest, Locked) {
498  EXPECT_READ32(ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 0);
499 
501  &alert_handler_, 5000, kDifToggleDisabled, kDifToggleDisabled),
502  kDifLocked);
503 }
504 
505 TEST_F(PingTimerConfigTest, ConfigureAndEnable) {
506  uint32_t ping_timeout = 5000;
507 
508  EXPECT_READ32(ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 1);
509  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_PING_TIMEOUT_CYC_SHADOWED_REG_OFFSET,
510  ping_timeout);
511  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_PING_TIMER_EN_SHADOWED_REG_OFFSET, 1);
512 
514  &alert_handler_, ping_timeout, kDifToggleEnabled, kDifToggleDisabled));
515 }
516 
517 TEST_F(PingTimerConfigTest, ConfigureEnableAndLock) {
518  uint32_t ping_timeout = 5000;
519 
520  EXPECT_READ32(ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 1);
521  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_PING_TIMEOUT_CYC_SHADOWED_REG_OFFSET,
522  ping_timeout);
523  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_PING_TIMER_EN_SHADOWED_REG_OFFSET, 1);
524  EXPECT_WRITE32(ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 0);
525 
527  &alert_handler_, ping_timeout, kDifToggleEnabled, kDifToggleEnabled));
528 }
529 
531 
532 TEST_F(PingTimerSetEnabledTest, BadArgs) {
535 
537  &alert_handler_, static_cast<dif_toggle_t>(2)));
538 }
539 
540 TEST_F(PingTimerSetEnabledTest, Locked) {
541  EXPECT_READ32(ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 0);
542 
543  EXPECT_EQ(dif_alert_handler_ping_timer_set_enabled(&alert_handler_,
545  kDifLocked);
546 }
547 
548 TEST_F(PingTimerSetEnabledTest, SetEnabled) {
549  EXPECT_READ32(ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 1);
550  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_PING_TIMER_EN_SHADOWED_REG_OFFSET, 1);
551 
554 }
555 
556 TEST_F(PingTimerSetEnabledTest, SetEnabledAndLock) {
557  EXPECT_READ32(ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 1);
558  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_PING_TIMER_EN_SHADOWED_REG_OFFSET, 1);
559  EXPECT_WRITE32(ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 0);
560 
563 }
564 
566  public testing::WithParamInterface<int> {};
567 
568 TEST_P(AlertLockTest, IsAlertLocked) {
569  dif_alert_handler_alert_t alert = GetParam();
570  bool is_locked = true;
571 
572  ptrdiff_t regwen_offset =
573  ALERT_HANDLER_ALERT_REGWEN_0_REG_OFFSET + alert * sizeof(uint32_t);
574  EXPECT_READ32(regwen_offset, ALERT_HANDLER_ALERT_REGWEN_0_REG_RESVAL);
576  dif_alert_handler_is_alert_locked(&alert_handler_, alert, &is_locked));
577  EXPECT_FALSE(is_locked);
578 
579  is_locked = false;
580  EXPECT_READ32(regwen_offset, 0);
582  dif_alert_handler_is_alert_locked(&alert_handler_, alert, &is_locked));
583  EXPECT_TRUE(is_locked);
584 }
585 
586 INSTANTIATE_TEST_SUITE_P(AllAlertsLockedAndUnlocked, AlertLockTest,
587  testing::Range(0, kAlerts));
588 
589 TEST_P(AlertLockTest, LockAlert) {
590  dif_alert_handler_alert_t alert = GetParam();
591 
592  ptrdiff_t regwen_offset =
593  ALERT_HANDLER_ALERT_REGWEN_0_REG_OFFSET + alert * sizeof(uint32_t);
594  EXPECT_WRITE32(regwen_offset, 0);
595  EXPECT_DIF_OK(dif_alert_handler_lock_alert(&alert_handler_, alert));
596 }
597 
598 INSTANTIATE_TEST_SUITE_P(LockAllAlerts, AlertLockTest,
599  testing::Range(0, kAlerts));
600 
601 TEST_F(AlertLockTest, BadArgs) {
602  bool is_locked;
603  EXPECT_DIF_BADARG(dif_alert_handler_is_alert_locked(nullptr, 0, &is_locked));
605  dif_alert_handler_is_alert_locked(&alert_handler_, kAlerts, &is_locked));
607  dif_alert_handler_is_alert_locked(&alert_handler_, 0, nullptr));
608 
610  EXPECT_DIF_BADARG(dif_alert_handler_lock_alert(&alert_handler_, kAlerts));
611 }
612 
614  : public AlertHandlerTest,
615  public testing::WithParamInterface<dif_alert_handler_local_alert_t> {};
616 
617 TEST_P(LocalAlertLockTest, IsLocalAlertLocked) {
618  dif_alert_handler_local_alert_t local_alert = GetParam();
619  bool is_locked = true;
620 
621  EXPECT_READ32(ALERT_HANDLER_LOC_ALERT_REGWEN_0_REG_OFFSET +
622  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
623  ALERT_HANDLER_LOC_ALERT_REGWEN_0_REG_RESVAL);
625  &alert_handler_, local_alert, &is_locked));
626  EXPECT_FALSE(is_locked);
627 
628  is_locked = false;
629  EXPECT_READ32(ALERT_HANDLER_LOC_ALERT_REGWEN_0_REG_OFFSET +
630  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
631  0);
633  &alert_handler_, local_alert, &is_locked));
634  EXPECT_TRUE(is_locked);
635 }
636 
637 INSTANTIATE_TEST_SUITE_P(
638  AllLocalAlertsLockedAndUnlocked, LocalAlertLockTest,
639  testing::Values(kDifAlertHandlerLocalAlertAlertPingFail,
640  kDifAlertHandlerLocalAlertEscalationPingFail,
641  kDifAlertHandlerLocalAlertAlertIntegrityFail,
642  kDifAlertHandlerLocalAlertEscalationIntegrityFail,
643  kDifAlertHandlerLocalAlertBusIntegrityFail,
644  kDifAlertHandlerLocalAlertShadowedUpdateError,
645  kDifAlertHandlerLocalAlertShadowedStorageError));
646 
647 TEST_P(LocalAlertLockTest, LockLocalAlert) {
648  dif_alert_handler_local_alert_t local_alert = GetParam();
649 
650  EXPECT_WRITE32(ALERT_HANDLER_LOC_ALERT_REGWEN_0_REG_OFFSET +
651  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
652  0);
654  dif_alert_handler_lock_local_alert(&alert_handler_, local_alert));
655 }
656 
657 INSTANTIATE_TEST_SUITE_P(
658  LockAllLocalAlerts, LocalAlertLockTest,
659  testing::Values(kDifAlertHandlerLocalAlertAlertPingFail,
660  kDifAlertHandlerLocalAlertEscalationPingFail,
661  kDifAlertHandlerLocalAlertAlertIntegrityFail,
662  kDifAlertHandlerLocalAlertEscalationIntegrityFail,
663  kDifAlertHandlerLocalAlertBusIntegrityFail,
664  kDifAlertHandlerLocalAlertShadowedUpdateError,
665  kDifAlertHandlerLocalAlertShadowedStorageError));
666 
667 TEST_F(LocalAlertLockTest, BadArgs) {
668  bool is_locked;
670  nullptr, kDifAlertHandlerLocalAlertShadowedStorageError, &is_locked));
672  &alert_handler_,
673  static_cast<dif_alert_handler_local_alert_t>(kLocalAlerts), &is_locked));
675  &alert_handler_, kDifAlertHandlerLocalAlertAlertPingFail, nullptr));
676 
678  nullptr, kDifAlertHandlerLocalAlertAlertPingFail));
680  &alert_handler_,
681  static_cast<dif_alert_handler_local_alert_t>(kLocalAlerts)));
682 }
683 
685  public testing::WithParamInterface<
686  std::tuple<dif_alert_handler_class_t, uint32_t>> {};
687 
688 static std::vector<std::tuple<dif_alert_handler_class_t, uint32_t>>
689  class_regwen_pairs{
690  std::tuple<dif_alert_handler_class_t, uint32_t>{
691  kDifAlertHandlerClassA, ALERT_HANDLER_CLASSA_REGWEN_REG_OFFSET},
692  std::tuple<dif_alert_handler_class_t, uint32_t>{
693  kDifAlertHandlerClassB, ALERT_HANDLER_CLASSB_REGWEN_REG_OFFSET},
694  std::tuple<dif_alert_handler_class_t, uint32_t>{
695  kDifAlertHandlerClassC, ALERT_HANDLER_CLASSC_REGWEN_REG_OFFSET},
696  std::tuple<dif_alert_handler_class_t, uint32_t>{
697  kDifAlertHandlerClassD, ALERT_HANDLER_CLASSD_REGWEN_REG_OFFSET}};
698 
699 TEST_P(ClassLockTest, IsClassLocked) {
700  dif_alert_handler_class_t alert_class = std::get<0>(GetParam());
701  uint32_t regwen_offset = std::get<1>(GetParam());
702  bool is_locked = true;
703 
704  EXPECT_READ32(regwen_offset, ALERT_HANDLER_CLASSA_REGWEN_REG_RESVAL);
705  EXPECT_DIF_OK(dif_alert_handler_is_class_locked(&alert_handler_, alert_class,
706  &is_locked));
707  EXPECT_FALSE(is_locked);
708 
709  is_locked = false;
710  EXPECT_READ32(regwen_offset, 0);
711  EXPECT_DIF_OK(dif_alert_handler_is_class_locked(&alert_handler_, alert_class,
712  &is_locked));
713  EXPECT_TRUE(is_locked);
714 }
715 
716 INSTANTIATE_TEST_SUITE_P(AllClassesLockedAndUnlocked, ClassLockTest,
717  testing::ValuesIn(class_regwen_pairs));
718 
719 TEST_P(ClassLockTest, LockClass) {
720  dif_alert_handler_class_t alert_class = std::get<0>(GetParam());
721  uint32_t regwen_offset = std::get<1>(GetParam());
722 
723  EXPECT_WRITE32(regwen_offset, 0);
724  EXPECT_DIF_OK(dif_alert_handler_lock_class(&alert_handler_, alert_class));
725 }
726 
727 INSTANTIATE_TEST_SUITE_P(LockAllClasses, ClassLockTest,
728  testing::ValuesIn(class_regwen_pairs));
729 
730 TEST_F(ClassLockTest, BadArgs) {
731  bool is_locked;
733  nullptr, kDifAlertHandlerClassA, &is_locked));
735  &alert_handler_, static_cast<dif_alert_handler_class_t>(kClasses),
736  &is_locked));
738  &alert_handler_, kDifAlertHandlerClassD, nullptr));
739 
741  dif_alert_handler_lock_class(nullptr, kDifAlertHandlerClassA));
743  &alert_handler_, static_cast<dif_alert_handler_class_t>(kClasses)));
744 }
745 
747 
748 TEST_F(PingTimerLockTest, IsPingTimerLocked) {
749  bool flag;
750 
751  EXPECT_READ32(ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 1);
752  EXPECT_DIF_OK(dif_alert_handler_is_ping_timer_locked(&alert_handler_, &flag));
753  EXPECT_FALSE(flag);
754 
755  EXPECT_READ32(ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 0);
756  EXPECT_DIF_OK(dif_alert_handler_is_ping_timer_locked(&alert_handler_, &flag));
757  EXPECT_TRUE(flag);
758 }
759 
760 TEST_F(PingTimerLockTest, LockPingTimer) {
761  EXPECT_WRITE32(ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 0);
763 }
764 
765 TEST_F(PingTimerLockTest, NullArgs) {
766  bool flag;
769  dif_alert_handler_is_ping_timer_locked(&alert_handler_, nullptr));
770 
772 }
773 
775  public testing::WithParamInterface<int> {};
776 
777 TEST_P(AlertCauseTest, IsCause) {
778  dif_alert_handler_alert_t alert = GetParam();
779  bool is_cause;
780 
781  ptrdiff_t cause_offset =
782  ALERT_HANDLER_ALERT_CAUSE_0_REG_OFFSET + alert * sizeof(uint32_t);
783 
784  EXPECT_READ32(cause_offset, 0x1);
786  dif_alert_handler_alert_is_cause(&alert_handler_, alert, &is_cause));
787  EXPECT_TRUE(is_cause);
788 
789  EXPECT_READ32(cause_offset, 0x0);
791  dif_alert_handler_alert_is_cause(&alert_handler_, alert, &is_cause));
792  EXPECT_FALSE(is_cause);
793 }
794 
795 INSTANTIATE_TEST_SUITE_P(AllCauses, AlertCauseTest, testing::Range(0, kAlerts));
796 
797 TEST_P(AlertCauseTest, Ack) {
798  dif_alert_handler_alert_t alert = GetParam();
799 
800  ptrdiff_t cause_offset =
801  ALERT_HANDLER_ALERT_CAUSE_0_REG_OFFSET + alert * sizeof(uint32_t);
802  EXPECT_WRITE32(cause_offset, 0x1);
803  EXPECT_DIF_OK(dif_alert_handler_alert_acknowledge(&alert_handler_, alert));
804 }
805 
806 INSTANTIATE_TEST_SUITE_P(AllAcks, AlertCauseTest, testing::Range(0, kAlerts));
807 
808 TEST_F(AlertCauseTest, BadAlert) {
809  bool is_cause;
811  dif_alert_handler_alert_is_cause(&alert_handler_, kAlerts, &is_cause));
813  dif_alert_handler_alert_acknowledge(&alert_handler_, kAlerts));
814 }
815 
816 TEST_F(AlertCauseTest, NullArgs) {
817  bool is_cause;
818  EXPECT_DIF_BADARG(dif_alert_handler_alert_is_cause(nullptr, 5, &is_cause));
820  dif_alert_handler_alert_is_cause(&alert_handler_, 5, nullptr));
822 }
823 
825  : public AlertHandlerTest,
826  public testing::WithParamInterface<dif_alert_handler_local_alert_t> {};
827 
828 TEST_P(LocalAlertCauseTest, IsCause) {
829  dif_alert_handler_local_alert_t local_alert = GetParam();
830  bool is_cause;
831 
832  EXPECT_READ32(ALERT_HANDLER_LOC_ALERT_CAUSE_0_REG_OFFSET +
833  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
834  0x1);
836  local_alert, &is_cause));
837  EXPECT_TRUE(is_cause);
838 
839  EXPECT_READ32(ALERT_HANDLER_LOC_ALERT_CAUSE_0_REG_OFFSET +
840  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
841  0x0);
843  local_alert, &is_cause));
844  EXPECT_FALSE(is_cause);
845 }
846 
847 INSTANTIATE_TEST_SUITE_P(
848  AllCauses, LocalAlertCauseTest,
849  testing::Values(kDifAlertHandlerLocalAlertAlertPingFail,
850  kDifAlertHandlerLocalAlertEscalationPingFail,
851  kDifAlertHandlerLocalAlertAlertIntegrityFail,
852  kDifAlertHandlerLocalAlertEscalationIntegrityFail,
853  kDifAlertHandlerLocalAlertBusIntegrityFail,
854  kDifAlertHandlerLocalAlertShadowedUpdateError,
855  kDifAlertHandlerLocalAlertShadowedStorageError));
856 
857 TEST_P(LocalAlertCauseTest, Ack) {
858  dif_alert_handler_local_alert_t local_alert = GetParam();
859 
860  EXPECT_WRITE32(ALERT_HANDLER_LOC_ALERT_CAUSE_0_REG_OFFSET +
861  static_cast<uint32_t>(local_alert) * sizeof(uint32_t),
862  0x1);
864  dif_alert_handler_local_alert_acknowledge(&alert_handler_, local_alert));
865 }
866 
867 INSTANTIATE_TEST_SUITE_P(
868  AllAcks, LocalAlertCauseTest,
869  testing::Values(kDifAlertHandlerLocalAlertAlertPingFail,
870  kDifAlertHandlerLocalAlertEscalationPingFail,
871  kDifAlertHandlerLocalAlertAlertIntegrityFail,
872  kDifAlertHandlerLocalAlertEscalationIntegrityFail,
873  kDifAlertHandlerLocalAlertBusIntegrityFail,
874  kDifAlertHandlerLocalAlertShadowedUpdateError,
875  kDifAlertHandlerLocalAlertShadowedStorageError));
876 
877 TEST_F(LocalAlertCauseTest, BadLocalAlert) {
878  bool is_cause;
880  &alert_handler_,
881  static_cast<dif_alert_handler_local_alert_t>(kLocalAlerts), &is_cause));
883  &alert_handler_,
884  static_cast<dif_alert_handler_local_alert_t>(kLocalAlerts)));
885 }
886 
887 TEST_F(LocalAlertCauseTest, NullArgs) {
888  bool is_cause;
890  nullptr, kDifAlertHandlerLocalAlertEscalationPingFail, &is_cause));
892  &alert_handler_, kDifAlertHandlerLocalAlertEscalationPingFail, nullptr));
894  nullptr, kDifAlertHandlerLocalAlertEscalationIntegrityFail));
895 }
896 
898 
899 TEST_F(EscalationTest, CanClear) {
900  bool can_clear;
901 
902  EXPECT_READ32(ALERT_HANDLER_CLASSB_CLR_REGWEN_REG_OFFSET, true);
904  &alert_handler_, kDifAlertHandlerClassB, &can_clear));
905  EXPECT_TRUE(can_clear);
906 
907  EXPECT_READ32(ALERT_HANDLER_CLASSA_CLR_REGWEN_REG_OFFSET, false);
909  &alert_handler_, kDifAlertHandlerClassA, &can_clear));
910  EXPECT_FALSE(can_clear);
911 }
912 
913 TEST_F(EscalationTest, Disable) {
914  EXPECT_WRITE32(ALERT_HANDLER_CLASSC_CLR_REGWEN_REG_OFFSET, 0);
916  &alert_handler_, kDifAlertHandlerClassC));
917 }
918 
919 TEST_F(EscalationTest, Clear) {
920  EXPECT_WRITE32_SHADOWED(ALERT_HANDLER_CLASSD_CLR_SHADOWED_REG_OFFSET, true);
922  kDifAlertHandlerClassD));
923 }
924 
925 TEST_F(EscalationTest, NullArgs) {
926  bool can_clear;
927 
929  nullptr, kDifAlertHandlerClassB, &can_clear));
931  &alert_handler_, kDifAlertHandlerClassB, nullptr));
933  nullptr, kDifAlertHandlerClassC));
935  dif_alert_handler_escalation_clear(nullptr, kDifAlertHandlerClassD));
936 }
937 
938 class GetterTest : public AlertHandlerTest {};
939 
940 TEST_F(GetterTest, GetAcc) {
941  uint16_t num_alerts;
942  EXPECT_READ32(ALERT_HANDLER_CLASSB_ACCUM_CNT_REG_OFFSET, 0xaaaa);
944  &alert_handler_, kDifAlertHandlerClassB, &num_alerts));
945  EXPECT_EQ(num_alerts, 0xaaaa);
946 }
947 
948 TEST_F(GetterTest, GetCycles) {
949  uint32_t cycles;
950  EXPECT_READ32(ALERT_HANDLER_CLASSD_ESC_CNT_REG_OFFSET, 0xaaaaaaaa);
952  &alert_handler_, kDifAlertHandlerClassD, &cycles));
953  EXPECT_EQ(cycles, 0xaaaaaaaa);
954 }
955 
956 TEST_F(GetterTest, GetState) {
958 
959  EXPECT_READ32(ALERT_HANDLER_CLASSC_STATE_REG_OFFSET,
960  ALERT_HANDLER_CLASSA_STATE_CLASSA_STATE_VALUE_TIMEOUT);
962  &alert_handler_, kDifAlertHandlerClassC, &state));
963  EXPECT_EQ(state, kDifAlertHandlerClassStateTimeout);
964 
965  EXPECT_READ32(ALERT_HANDLER_CLASSA_STATE_REG_OFFSET,
966  ALERT_HANDLER_CLASSA_STATE_CLASSA_STATE_VALUE_PHASE2);
968  &alert_handler_, kDifAlertHandlerClassA, &state));
969  EXPECT_EQ(state, kDifAlertHandlerClassStatePhase2);
970 }
971 
972 TEST_F(GetterTest, NullArgs) {
973  uint16_t alerts;
975  nullptr, kDifAlertHandlerClassB, &alerts));
977  &alert_handler_, kDifAlertHandlerClassB, nullptr));
978 
979  uint32_t cycles;
981  nullptr, kDifAlertHandlerClassB, &cycles));
983  &alert_handler_, kDifAlertHandlerClassB, nullptr));
984 
987  nullptr, kDifAlertHandlerClassC, &state));
989  &alert_handler_, kDifAlertHandlerClassC, nullptr));
990 }
991 
992 } // namespace
993 } // namespace dif_alert_handler_unittest