Software APIs
alert_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 
5 #include "sw/device/silicon_creator/lib/drivers/alert.h"
6 
7 #include "gtest/gtest.h"
9 #include "sw/device/lib/base/mock_abs_mmio.h"
10 #include "sw/device/lib/base/mock_crc32.h"
11 #include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
12 #include "sw/device/silicon_creator/lib/drivers/mock_otp.h"
13 #include "sw/device/silicon_creator/testing/rom_test.h"
14 
15 #include "alert_handler_regs.h"
17 #include "otp_ctrl_regs.h"
18 
19 namespace alert_unittest {
20 namespace {
21 using ::testing::NotNull;
22 using ::testing::Return;
23 
24 class AlertTest : public rom_test::RomTest {
25  protected:
26  uint32_t base_ = TOP_EARLGREY_ALERT_HANDLER_BASE_ADDR;
27  rom_test::MockCrc32 crc32_;
28  rom_test::MockAbsMmio abs_mmio_;
29  rom_test::MockOtp otp_;
30 };
31 
32 class InitTest : public AlertTest {};
33 
34 TEST_F(InitTest, AlertConfigureAlertBadIndex) {
35  EXPECT_EQ(alert_configure(ALERT_HANDLER_ALERT_CLASS_SHADOWED_MULTIREG_COUNT,
36  kAlertClassA, kAlertEnableNone),
37  kErrorAlertBadIndex);
38 }
39 
40 TEST_F(InitTest, AlertConfigureAlertBadClass) {
41  EXPECT_EQ(
42  alert_configure(0, static_cast<alert_class_t>(-1), kAlertEnableNone),
43  kErrorAlertBadClass);
44 }
45 
46 TEST_F(InitTest, LocalAlertConfigureAlertBadClass) {
47  EXPECT_EQ(alert_local_configure(0, static_cast<alert_class_t>(-1),
48  kAlertEnableNone),
49  kErrorAlertBadClass);
50 }
51 
52 TEST_F(InitTest, AlertConfigureAlertBadEnable) {
53  // We expect the alert to get configured as class A, but then to
54  // experience an error when evaluating the enable parameter.
55  EXPECT_ABS_WRITE32_SHADOWED(
56  base_ + ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_REG_OFFSET, 0);
57  EXPECT_EQ(alert_configure(0, kAlertClassA, static_cast<alert_enable_t>(-1)),
58  kErrorAlertBadEnable);
59 }
60 
61 TEST_F(InitTest, LocalAlertConfigureAlertBadEnable) {
62  EXPECT_ABS_WRITE32_SHADOWED(
63  base_ + ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_0_REG_OFFSET, 0);
64  EXPECT_EQ(
65  alert_local_configure(0, kAlertClassA, static_cast<alert_enable_t>(-1)),
66  kErrorAlertBadEnable);
67 }
68 
69 TEST_F(InitTest, AlertConfigureAlertClassXNoOperation) {
70  EXPECT_EQ(alert_configure(0, kAlertClassX, kAlertEnableNone), kErrorOk);
71 }
72 
73 TEST_F(InitTest, LocalAlertConfigureAlertClassXNoOperation) {
74  EXPECT_EQ(alert_local_configure(0, kAlertClassX, kAlertEnableNone), kErrorOk);
75 }
76 
77 TEST_F(InitTest, AlertConfigure0AsClassA) {
78  EXPECT_ABS_WRITE32_SHADOWED(
79  base_ + ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_REG_OFFSET, 0);
80  EXPECT_ABS_WRITE32_SHADOWED(
81  base_ + ALERT_HANDLER_ALERT_EN_SHADOWED_0_REG_OFFSET, 1);
82  EXPECT_EQ(alert_configure(0, kAlertClassA, kAlertEnableEnabled), kErrorOk);
83 }
84 
85 TEST_F(InitTest, LocalAlertConfigure0AsClassA) {
86  EXPECT_ABS_WRITE32_SHADOWED(
87  base_ + ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_0_REG_OFFSET, 0);
88  EXPECT_ABS_WRITE32_SHADOWED(
89  base_ + ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_0_REG_OFFSET, 1);
90  EXPECT_EQ(alert_local_configure(0, kAlertClassA, kAlertEnableEnabled),
91  kErrorOk);
92 }
93 
94 TEST_F(InitTest, AlertConfigure1AsClassB) {
95  EXPECT_ABS_WRITE32_SHADOWED(
96  base_ + ALERT_HANDLER_ALERT_CLASS_SHADOWED_1_REG_OFFSET, 1);
97  EXPECT_ABS_WRITE32_SHADOWED(
98  base_ + ALERT_HANDLER_ALERT_EN_SHADOWED_1_REG_OFFSET, 1);
99  EXPECT_EQ(alert_configure(1, kAlertClassB, kAlertEnableEnabled), kErrorOk);
100 }
101 
102 TEST_F(InitTest, LocalAlertConfigure1AsClassB) {
103  EXPECT_ABS_WRITE32_SHADOWED(
104  base_ + ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_1_REG_OFFSET, 1);
105  EXPECT_ABS_WRITE32_SHADOWED(
106  base_ + ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_1_REG_OFFSET, 1);
107  EXPECT_EQ(alert_local_configure(1, kAlertClassB, kAlertEnableEnabled),
108  kErrorOk);
109 }
110 
111 TEST_F(InitTest, AlertConfigure2AsClassC) {
112  EXPECT_ABS_WRITE32_SHADOWED(
113  base_ + ALERT_HANDLER_ALERT_CLASS_SHADOWED_2_REG_OFFSET, 2);
114  EXPECT_ABS_WRITE32_SHADOWED(
115  base_ + ALERT_HANDLER_ALERT_EN_SHADOWED_2_REG_OFFSET, 1);
116  EXPECT_EQ(alert_configure(2, kAlertClassC, kAlertEnableEnabled), kErrorOk);
117 }
118 
119 TEST_F(InitTest, LocalAlertConfigure2AsClassC) {
120  EXPECT_ABS_WRITE32_SHADOWED(
121  base_ + ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_2_REG_OFFSET, 2);
122  EXPECT_ABS_WRITE32_SHADOWED(
123  base_ + ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_2_REG_OFFSET, 1);
124  EXPECT_EQ(alert_local_configure(2, kAlertClassC, kAlertEnableEnabled),
125  kErrorOk);
126 }
127 
128 TEST_F(InitTest, AlertConfigure3AsClassDLocked) {
129  EXPECT_ABS_WRITE32_SHADOWED(
130  base_ + ALERT_HANDLER_ALERT_CLASS_SHADOWED_3_REG_OFFSET, 3);
131  EXPECT_ABS_WRITE32_SHADOWED(
132  base_ + ALERT_HANDLER_ALERT_EN_SHADOWED_3_REG_OFFSET, 1);
133  EXPECT_ABS_WRITE32(base_ + ALERT_HANDLER_ALERT_REGWEN_3_REG_OFFSET, 0);
134  EXPECT_EQ(alert_configure(3, kAlertClassD, kAlertEnableLocked), kErrorOk);
135 }
136 
137 TEST_F(InitTest, LocalAlertConfigure3AsClassDLocked) {
138  EXPECT_ABS_WRITE32_SHADOWED(
139  base_ + ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_3_REG_OFFSET, 3);
140  EXPECT_ABS_WRITE32_SHADOWED(
141  base_ + ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_3_REG_OFFSET, 1);
142  EXPECT_ABS_WRITE32(base_ + ALERT_HANDLER_LOC_ALERT_REGWEN_3_REG_OFFSET, 0);
143  EXPECT_EQ(alert_local_configure(3, kAlertClassD, kAlertEnableLocked),
144  kErrorOk);
145 }
146 
147 TEST_F(InitTest, AlertConfigureClassXBadClass) {
148  alert_class_config_t config{};
149  EXPECT_EQ(alert_class_configure(kAlertClassX, &config), kErrorAlertBadClass);
150 }
151 
152 TEST_F(InitTest, AlertConfigureClassAlertBadEnable) {
153  alert_class_config_t config{};
154  EXPECT_EQ(alert_class_configure(kAlertClassA, &config), kErrorAlertBadEnable);
155 }
156 
157 TEST_F(InitTest, AlertConfigureClassAlertBadEscalation) {
158  alert_class_config_t config{.enabled = kAlertEnableLocked};
159  EXPECT_EQ(alert_class_configure(kAlertClassA, &config),
160  kErrorAlertBadEscalation);
161 }
162 
163 TEST_F(InitTest, AlertConfigureClassA) {
164  alert_class_config_t config = {
165  .enabled = kAlertEnableLocked,
166  .escalation = kAlertEscalatePhase3,
167  .accum_threshold = 1,
168  .timeout_cycles = 2,
169  .phase_cycles = {1, 10, 100, 1000},
170  };
171  EXPECT_ABS_WRITE32_SHADOWED(
172  base_ + ALERT_HANDLER_CLASSA_CTRL_SHADOWED_REG_OFFSET,
173  {
174  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_BIT, true},
175  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_LOCK_BIT, true},
176  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E3_BIT, true},
177  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E2_BIT, true},
178  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E1_BIT, true},
179  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E0_BIT, true},
180  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E0_OFFSET, 0},
181  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E1_OFFSET, 1},
182  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E2_OFFSET, 2},
183  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E3_OFFSET, 3},
184  });
185  EXPECT_ABS_WRITE32_SHADOWED(
186  base_ + ALERT_HANDLER_CLASSA_ACCUM_THRESH_SHADOWED_REG_OFFSET, 1);
187  EXPECT_ABS_WRITE32_SHADOWED(
188  base_ + ALERT_HANDLER_CLASSA_TIMEOUT_CYC_SHADOWED_REG_OFFSET, 2);
189  EXPECT_ABS_WRITE32_SHADOWED(
190  base_ + ALERT_HANDLER_CLASSA_PHASE0_CYC_SHADOWED_REG_OFFSET, 1);
191  EXPECT_ABS_WRITE32_SHADOWED(
192  base_ + ALERT_HANDLER_CLASSA_PHASE1_CYC_SHADOWED_REG_OFFSET, 10);
193  EXPECT_ABS_WRITE32_SHADOWED(
194  base_ + ALERT_HANDLER_CLASSA_PHASE2_CYC_SHADOWED_REG_OFFSET, 100);
195  EXPECT_ABS_WRITE32_SHADOWED(
196  base_ + ALERT_HANDLER_CLASSA_PHASE3_CYC_SHADOWED_REG_OFFSET, 1000);
197  EXPECT_ABS_WRITE32(base_ + ALERT_HANDLER_CLASSA_REGWEN_REG_OFFSET, 0);
198  EXPECT_EQ(alert_class_configure(kAlertClassA, &config), kErrorOk);
199 }
200 
201 TEST_F(InitTest, AlertConfigureClassB) {
202  alert_class_config_t config = {
203  .enabled = kAlertEnableEnabled,
204  .escalation = kAlertEscalatePhase2,
205  .accum_threshold = 1,
206  .timeout_cycles = 2,
207  .phase_cycles = {1, 10, 100, 1000},
208  };
209  EXPECT_ABS_WRITE32_SHADOWED(
210  base_ + ALERT_HANDLER_CLASSB_CTRL_SHADOWED_REG_OFFSET,
211  {
212  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_BIT, true},
213  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_LOCK_BIT, false},
214  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E3_BIT, false},
215  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E2_BIT, true},
216  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E1_BIT, true},
217  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E0_BIT, true},
218  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E0_OFFSET, 0},
219  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E1_OFFSET, 1},
220  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E2_OFFSET, 2},
221  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E3_OFFSET, 3},
222  });
223  EXPECT_ABS_WRITE32_SHADOWED(
224  base_ + ALERT_HANDLER_CLASSB_ACCUM_THRESH_SHADOWED_REG_OFFSET, 1);
225  EXPECT_ABS_WRITE32_SHADOWED(
226  base_ + ALERT_HANDLER_CLASSB_TIMEOUT_CYC_SHADOWED_REG_OFFSET, 2);
227  EXPECT_ABS_WRITE32_SHADOWED(
228  base_ + ALERT_HANDLER_CLASSB_PHASE0_CYC_SHADOWED_REG_OFFSET, 1);
229  EXPECT_ABS_WRITE32_SHADOWED(
230  base_ + ALERT_HANDLER_CLASSB_PHASE1_CYC_SHADOWED_REG_OFFSET, 10);
231  EXPECT_ABS_WRITE32_SHADOWED(
232  base_ + ALERT_HANDLER_CLASSB_PHASE2_CYC_SHADOWED_REG_OFFSET, 100);
233  EXPECT_ABS_WRITE32_SHADOWED(
234  base_ + ALERT_HANDLER_CLASSB_PHASE3_CYC_SHADOWED_REG_OFFSET, 1000);
235  EXPECT_EQ(alert_class_configure(kAlertClassB, &config), kErrorOk);
236 }
237 
238 TEST_F(InitTest, AlertConfigureClassC) {
239  alert_class_config_t config = {
240  .enabled = kAlertEnableEnabled,
241  .escalation = kAlertEscalatePhase1,
242  .accum_threshold = 1,
243  .timeout_cycles = 2,
244  .phase_cycles = {1, 10, 100, 1000},
245  };
246  EXPECT_ABS_WRITE32_SHADOWED(
247  base_ + ALERT_HANDLER_CLASSC_CTRL_SHADOWED_REG_OFFSET,
248  {
249  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_BIT, true},
250  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_LOCK_BIT, false},
251  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E3_BIT, false},
252  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E2_BIT, false},
253  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E1_BIT, true},
254  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E0_BIT, true},
255  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E0_OFFSET, 0},
256  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E1_OFFSET, 1},
257  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E2_OFFSET, 2},
258  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E3_OFFSET, 3},
259  });
260  EXPECT_ABS_WRITE32_SHADOWED(
261  base_ + ALERT_HANDLER_CLASSC_ACCUM_THRESH_SHADOWED_REG_OFFSET, 1);
262  EXPECT_ABS_WRITE32_SHADOWED(
263  base_ + ALERT_HANDLER_CLASSC_TIMEOUT_CYC_SHADOWED_REG_OFFSET, 2);
264  EXPECT_ABS_WRITE32_SHADOWED(
265  base_ + ALERT_HANDLER_CLASSC_PHASE0_CYC_SHADOWED_REG_OFFSET, 1);
266  EXPECT_ABS_WRITE32_SHADOWED(
267  base_ + ALERT_HANDLER_CLASSC_PHASE1_CYC_SHADOWED_REG_OFFSET, 10);
268  EXPECT_ABS_WRITE32_SHADOWED(
269  base_ + ALERT_HANDLER_CLASSC_PHASE2_CYC_SHADOWED_REG_OFFSET, 100);
270  EXPECT_ABS_WRITE32_SHADOWED(
271  base_ + ALERT_HANDLER_CLASSC_PHASE3_CYC_SHADOWED_REG_OFFSET, 1000);
272  EXPECT_EQ(alert_class_configure(kAlertClassC, &config), kErrorOk);
273 }
274 
275 TEST_F(InitTest, AlertConfigureClassD) {
276  alert_class_config_t config = {
277  .enabled = kAlertEnableEnabled,
278  .escalation = kAlertEscalateNone,
279  .accum_threshold = 1,
280  .timeout_cycles = 2,
281  .phase_cycles = {1, 10, 100, 1000},
282  };
283  EXPECT_ABS_WRITE32_SHADOWED(
284  base_ + ALERT_HANDLER_CLASSD_CTRL_SHADOWED_REG_OFFSET,
285  {
286  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_BIT, true},
287  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_LOCK_BIT, false},
288  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E3_BIT, false},
289  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E2_BIT, false},
290  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E1_BIT, false},
291  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E0_BIT, false},
292  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E0_OFFSET, 0},
293  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E1_OFFSET, 1},
294  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E2_OFFSET, 2},
295  {ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E3_OFFSET, 3},
296  });
297  EXPECT_ABS_WRITE32_SHADOWED(
298  base_ + ALERT_HANDLER_CLASSD_ACCUM_THRESH_SHADOWED_REG_OFFSET, 1);
299  EXPECT_ABS_WRITE32_SHADOWED(
300  base_ + ALERT_HANDLER_CLASSD_TIMEOUT_CYC_SHADOWED_REG_OFFSET, 2);
301  EXPECT_ABS_WRITE32_SHADOWED(
302  base_ + ALERT_HANDLER_CLASSD_PHASE0_CYC_SHADOWED_REG_OFFSET, 1);
303  EXPECT_ABS_WRITE32_SHADOWED(
304  base_ + ALERT_HANDLER_CLASSD_PHASE1_CYC_SHADOWED_REG_OFFSET, 10);
305  EXPECT_ABS_WRITE32_SHADOWED(
306  base_ + ALERT_HANDLER_CLASSD_PHASE2_CYC_SHADOWED_REG_OFFSET, 100);
307  EXPECT_ABS_WRITE32_SHADOWED(
308  base_ + ALERT_HANDLER_CLASSD_PHASE3_CYC_SHADOWED_REG_OFFSET, 1000);
309  EXPECT_EQ(alert_class_configure(kAlertClassD, &config), kErrorOk);
310 }
311 
312 class AlertPingTest : public AlertTest {};
313 
314 TEST_F(AlertPingTest, EnableSucess) {
315  EXPECT_ABS_WRITE32_SHADOWED(
316  base_ + ALERT_HANDLER_PING_TIMER_EN_SHADOWED_REG_OFFSET, 1);
317 
318  EXPECT_ABS_WRITE32(base_ + ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 0);
319 
320  EXPECT_EQ(alert_ping_enable(), kErrorOk);
321 }
322 
323 /**
324  * Functor for incrementing an offset by four.
325  */
326 class WordStepper {
327  public:
328  WordStepper(uint32_t offset) : offset_(offset - sizeof(uint32_t)) {}
329 
330  uint32_t operator()() { return offset_ += sizeof(uint32_t); }
331 
332  private:
333  uint32_t offset_;
334 };
335 
337  protected:
338  void ExpectConfigCrc32(uint32_t exp_crc32) {
339  std::vector<uint32_t> reg_offsets;
340  auto iter = std::back_inserter(reg_offsets);
341  std::generate_n(iter, ALERT_HANDLER_ALERT_REGWEN_MULTIREG_COUNT,
342  WordStepper(ALERT_HANDLER_ALERT_REGWEN_0_REG_OFFSET));
343  std::generate_n(iter, ALERT_HANDLER_ALERT_EN_SHADOWED_MULTIREG_COUNT,
344  WordStepper(ALERT_HANDLER_ALERT_EN_SHADOWED_0_REG_OFFSET));
345  std::generate_n(
346  iter, ALERT_HANDLER_ALERT_CLASS_SHADOWED_MULTIREG_COUNT,
347  WordStepper(ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_REG_OFFSET));
348  std::generate_n(iter, ALERT_HANDLER_LOC_ALERT_REGWEN_MULTIREG_COUNT,
349  WordStepper(ALERT_HANDLER_LOC_ALERT_REGWEN_0_REG_OFFSET));
350  std::generate_n(
351  iter, ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_MULTIREG_COUNT,
352  WordStepper(ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_0_REG_OFFSET));
353  std::generate_n(
354  iter, ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_MULTIREG_COUNT,
355  WordStepper(ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_0_REG_OFFSET));
356  for (size_t klass = 0; klass < ALERT_HANDLER_PARAM_N_CLASSES; ++klass) {
357  enum {
358  kClassStep = ALERT_HANDLER_CLASSB_REGWEN_REG_OFFSET -
359  ALERT_HANDLER_CLASSA_REGWEN_REG_OFFSET,
360  };
361  iter = ALERT_HANDLER_CLASSA_REGWEN_REG_OFFSET + kClassStep * klass;
362  iter = ALERT_HANDLER_CLASSA_CTRL_SHADOWED_REG_OFFSET + kClassStep * klass;
363  iter = ALERT_HANDLER_CLASSA_ACCUM_THRESH_SHADOWED_REG_OFFSET +
364  kClassStep * klass;
365  iter = ALERT_HANDLER_CLASSA_TIMEOUT_CYC_SHADOWED_REG_OFFSET +
366  kClassStep * klass;
367  std::generate_n(
368  iter, ALERT_HANDLER_PARAM_N_PHASES,
369  WordStepper(ALERT_HANDLER_CLASSA_PHASE0_CYC_SHADOWED_REG_OFFSET +
370  kClassStep * klass));
371  }
372 
373  EXPECT_CALL(crc32_, Init(NotNull()));
374  for (uint32_t offset : reg_offsets) {
375  EXPECT_ABS_READ32(base_ + offset, offset);
376  EXPECT_CALL(crc32_, Add32(NotNull(), offset));
377  }
378  EXPECT_CALL(crc32_, Finish(NotNull())).WillOnce(Return(exp_crc32));
379  }
380 };
381 
382 TEST_F(AlertConfigCheckTest, ConfigCrc32) {
383  constexpr uint32_t kExpCrc32 = 0xa5a5a5a5;
384  ExpectConfigCrc32(kExpCrc32);
385 
386  EXPECT_EQ(alert_config_crc32(), kExpCrc32);
387 }
388 
389 TEST_F(AlertConfigCheckTest, CheckInTestLcState) {
390  constexpr uint32_t kExpCrc32 = 0xa5a5a5a5;
391  ExpectConfigCrc32(kExpCrc32);
392 
393  EXPECT_EQ(alert_config_check(kLcStateTest), kErrorOk);
394 }
395 
397  lifecycle_state_t lc_state;
398  uint32_t otp_offset;
399 };
400 
402  : public AlertConfigCheckTest,
403  public testing::WithParamInterface<ConfigCheckTestCase> {};
404 
405 TEST_P(AlertConfigCheckNonTestLcStateTest, ConfigCheckGood) {
406  constexpr uint32_t kExpCrc32 = 0xa5a5a5a5;
407  ExpectConfigCrc32(kExpCrc32);
408  EXPECT_CALL(otp_, read32(GetParam().otp_offset))
409  .WillOnce(Return(kExpCrc32 ^ GetParam().lc_state ^ kErrorOk));
410 
411  EXPECT_EQ(alert_config_check(GetParam().lc_state), kErrorOk);
412 }
413 
414 TEST_P(AlertConfigCheckNonTestLcStateTest, ConfigCheckBad) {
415  constexpr uint32_t kExpCrc32 = 0xa5a5a5a5;
416  ExpectConfigCrc32(kExpCrc32);
417  EXPECT_CALL(otp_, read32(GetParam().otp_offset))
418  .WillOnce(Return((kExpCrc32 ^ 1) ^ GetParam().lc_state ^ kErrorOk));
419 
420  EXPECT_EQ(alert_config_check(GetParam().lc_state), kErrorAlertBadCrc32);
421 }
422 
423 INSTANTIATE_TEST_SUITE_P(
424  NonTestLcStates, AlertConfigCheckNonTestLcStateTest,
425  testing::Values(
426  ConfigCheckTestCase{
427  .lc_state = kLcStateDev,
428  .otp_offset =
429  OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_ALERT_DIGEST_DEV_OFFSET,
430  },
431  ConfigCheckTestCase{
432  .lc_state = kLcStateProd,
433  .otp_offset =
434  OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD_OFFSET,
435  },
436  ConfigCheckTestCase{
437  .lc_state = kLcStateProdEnd,
438  .otp_offset =
439  OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD_END_OFFSET,
440  },
441  ConfigCheckTestCase{
442  .lc_state = kLcStateRma,
443  .otp_offset =
444  OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_ALERT_DIGEST_RMA_OFFSET,
445  }));
446 
447 } // namespace
448 } // namespace alert_unittest