Software APIs
dif_otp_ctrl_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
5 
6 #include <cstring>
7 #include <limits>
8 #include <ostream>
9 
10 #include "gtest/gtest.h"
12 #include "sw/device/lib/base/mock_mmio.h"
14 
15 #include "otp_ctrl_regs.h" // Generated.
16 
17 namespace dif_otp_ctrl_unittest {
18 namespace {
19 using ::mock_mmio::LeInt;
20 using ::mock_mmio::MmioTest;
21 using ::mock_mmio::MockDevice;
22 using ::testing::Each;
23 using ::testing::ElementsAre;
24 
25 class OtpTest : public testing::Test, public MmioTest {
26  protected:
27  dif_otp_ctrl_t otp_ = {.base_addr = dev().region()};
28 };
29 
30 class DaiRegwenTest : public OtpTest {};
31 
32 TEST_F(DaiRegwenTest, LockDai) {
33  EXPECT_WRITE32(
34  OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET,
35  {{OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT, false}});
37 }
38 
39 TEST_F(DaiRegwenTest, IsDaiLocked) {
40  bool flag;
41 
42  EXPECT_READ32(
43  OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET,
44  {{OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT, true}});
46  EXPECT_FALSE(flag);
47 
48  EXPECT_READ32(
49  OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET,
50  {{OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT, false}});
52  EXPECT_TRUE(flag);
53 }
54 
55 TEST_F(DaiRegwenTest, NullArgs) {
57 
58  bool flag;
61 }
62 
63 class ConfigTest : public OtpTest {};
64 
65 TEST_F(ConfigTest, Basic) {
66  dif_otp_ctrl_config_t config = {
67  .check_timeout = 100'000,
68  .integrity_period_mask = 0x3'ffff,
69  .consistency_period_mask = 0x3ff'ffff,
70  };
71 
72  EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET,
73  {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, true}});
74 
75  EXPECT_WRITE32(OTP_CTRL_CHECK_TIMEOUT_REG_OFFSET, config.check_timeout);
76  EXPECT_WRITE32(OTP_CTRL_INTEGRITY_CHECK_PERIOD_REG_OFFSET,
77  config.integrity_period_mask);
78  EXPECT_WRITE32(OTP_CTRL_CONSISTENCY_CHECK_PERIOD_REG_OFFSET,
80 
81  EXPECT_DIF_OK(dif_otp_ctrl_configure(&otp_, config));
82 }
83 
84 TEST_F(ConfigTest, Locked) {
85  EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET,
86  {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, false}});
87 
88  EXPECT_EQ(dif_otp_ctrl_configure(&otp_, {}), kDifLocked);
89 }
90 
91 TEST_F(ConfigTest, IsConfigLocked) {
92  bool flag;
93 
94  EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET,
95  {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, true}});
97  EXPECT_FALSE(flag);
98 
99  EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET,
100  {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, false}});
102  EXPECT_TRUE(flag);
103 }
104 
105 TEST_F(ConfigTest, LockConfig) {
106  EXPECT_WRITE32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET,
107  {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, false}});
109 }
110 
111 TEST_F(ConfigTest, NullArgs) {
113 
114  bool flag;
117 
119 }
120 
121 class CheckTest : public OtpTest {};
122 
123 TEST_F(CheckTest, Integrity) {
124  EXPECT_READ32(
125  OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
126  {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, true}});
127  EXPECT_WRITE32(OTP_CTRL_CHECK_TRIGGER_REG_OFFSET,
128  {{OTP_CTRL_CHECK_TRIGGER_INTEGRITY_BIT, true}});
129 
131 }
132 
133 TEST_F(CheckTest, Consistency) {
134  EXPECT_READ32(
135  OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
136  {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, true}});
137  EXPECT_WRITE32(OTP_CTRL_CHECK_TRIGGER_REG_OFFSET,
138  {{OTP_CTRL_CHECK_TRIGGER_CONSISTENCY_BIT, true}});
139 
141 }
142 
143 TEST_F(CheckTest, LockTrigger) {
144  EXPECT_WRITE32(
145  OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
146  {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, false}});
148 }
149 
150 TEST_F(CheckTest, Locked) {
151  EXPECT_READ32(
152  OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
153  {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, false}});
154  EXPECT_EQ(dif_otp_ctrl_check_integrity(&otp_), kDifLocked);
155 
156  EXPECT_READ32(
157  OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
158  {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, false}});
159  EXPECT_EQ(dif_otp_ctrl_check_consistency(&otp_), kDifLocked);
160 }
161 
162 TEST_F(CheckTest, NullArgs) {
165 }
166 
167 class ReadLockTest : public OtpTest {};
168 
169 // Too many formatting variants in template code, so disabling clang-format.
170 // clang-format off
171 TEST_F(ReadLockTest, IsLocked) {
172  bool flag;
173 
174  EXPECT_READ32(
175  OTP_CTRL_VENDOR_TEST_READ_LOCK_REG_OFFSET,
176  {{OTP_CTRL_VENDOR_TEST_READ_LOCK_VENDOR_TEST_READ_LOCK_BIT,
177  true}});
179  &otp_, kDifOtpCtrlPartitionVendorTest, &flag));
180  EXPECT_FALSE(flag);
181 
182  EXPECT_READ32(
183  OTP_CTRL_VENDOR_TEST_READ_LOCK_REG_OFFSET,
184  {{OTP_CTRL_VENDOR_TEST_READ_LOCK_VENDOR_TEST_READ_LOCK_BIT,
185  false}});
187  &otp_, kDifOtpCtrlPartitionVendorTest, &flag));
188  EXPECT_TRUE(flag);
189 
190  EXPECT_READ32(
191  OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_REG_OFFSET,
192  {{OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_CREATOR_SW_CFG_READ_LOCK_BIT,
193  true}});
195  &otp_, kDifOtpCtrlPartitionCreatorSwCfg, &flag));
196  EXPECT_FALSE(flag);
197 
198  EXPECT_READ32(
199  OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_REG_OFFSET,
200  {{OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_CREATOR_SW_CFG_READ_LOCK_BIT,
201  false}});
203  &otp_, kDifOtpCtrlPartitionCreatorSwCfg, &flag));
204  EXPECT_TRUE(flag);
205 
206  EXPECT_READ32(
207  OTP_CTRL_OWNER_SW_CFG_READ_LOCK_REG_OFFSET,
208  {{OTP_CTRL_OWNER_SW_CFG_READ_LOCK_OWNER_SW_CFG_READ_LOCK_BIT,
209  true}});
211  &otp_, kDifOtpCtrlPartitionOwnerSwCfg, &flag));
212  EXPECT_FALSE(flag);
213 
214  EXPECT_READ32(
215  OTP_CTRL_OWNER_SW_CFG_READ_LOCK_REG_OFFSET,
216  {{OTP_CTRL_OWNER_SW_CFG_READ_LOCK_OWNER_SW_CFG_READ_LOCK_BIT,
217  false}});
219  &otp_, kDifOtpCtrlPartitionOwnerSwCfg, &flag));
220  EXPECT_TRUE(flag);
221 
222  EXPECT_READ32(
223  OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_REG_OFFSET,
224  {{OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_BIT,
225  true}});
227  &otp_, kDifOtpCtrlPartitionRotCreatorAuthCodesign, &flag));
228  EXPECT_FALSE(flag);
229 
230  EXPECT_READ32(
231  OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_REG_OFFSET,
232  {{OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_BIT,
233  false}});
235  &otp_, kDifOtpCtrlPartitionRotCreatorAuthCodesign, &flag));
236  EXPECT_TRUE(flag);
237 
238  EXPECT_READ32(
239  OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_REG_OFFSET,
240  {{OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_ROT_CREATOR_AUTH_STATE_READ_LOCK_BIT,
241  true}});
243  &otp_, kDifOtpCtrlPartitionRotCreatorAuthState, &flag));
244  EXPECT_FALSE(flag);
245 
246  EXPECT_READ32(
247  OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_REG_OFFSET,
248  {{OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_ROT_CREATOR_AUTH_STATE_READ_LOCK_BIT,
249  false}});
251  &otp_, kDifOtpCtrlPartitionRotCreatorAuthState, &flag));
252  EXPECT_TRUE(flag);
253 }
254 
255 TEST_F(ReadLockTest, Lock) {
256  EXPECT_WRITE32(
257  OTP_CTRL_VENDOR_TEST_READ_LOCK_REG_OFFSET,
258  {{OTP_CTRL_VENDOR_TEST_READ_LOCK_VENDOR_TEST_READ_LOCK_BIT,
259  false}});
262 
263  EXPECT_WRITE32(
264  OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_REG_OFFSET,
265  {{OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_CREATOR_SW_CFG_READ_LOCK_BIT,
266  false}});
269 
270  EXPECT_WRITE32(
271  OTP_CTRL_OWNER_SW_CFG_READ_LOCK_REG_OFFSET,
272  {{OTP_CTRL_OWNER_SW_CFG_READ_LOCK_OWNER_SW_CFG_READ_LOCK_BIT,
273  false}});
276 
277  EXPECT_WRITE32(
278  OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_REG_OFFSET,
279  {{OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_BIT,
280  false}});
282  &otp_, kDifOtpCtrlPartitionRotCreatorAuthCodesign));
283 
284  EXPECT_WRITE32(
285  OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_REG_OFFSET,
286  {{OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_ROT_CREATOR_AUTH_STATE_READ_LOCK_BIT,
287  false}});
289  &otp_, kDifOtpCtrlPartitionRotCreatorAuthState));
290 }
291 
292 TEST_F(ReadLockTest, NotLockablePartitions) {
293  bool flag;
297  &otp_, kDifOtpCtrlPartitionHwCfg0, &flag));
298 
302  &otp_, kDifOtpCtrlPartitionHwCfg1, &flag));
303 
307  &otp_, kDifOtpCtrlPartitionSecret0, &flag));
308 
312  &otp_, kDifOtpCtrlPartitionSecret1, &flag));
313 
317  &otp_, kDifOtpCtrlPartitionSecret2, &flag));
318 
322  &otp_, kDifOtpCtrlPartitionLifeCycle, &flag));
323 }
324 // clang-format on
325 
326 TEST_F(ReadLockTest, NullArgs) {
327  bool flag;
329  nullptr, kDifOtpCtrlPartitionVendorTest, &flag));
331  &otp_, kDifOtpCtrlPartitionVendorTest, nullptr));
334 
336  nullptr, kDifOtpCtrlPartitionCreatorSwCfg, &flag));
338  &otp_, kDifOtpCtrlPartitionCreatorSwCfg, nullptr));
341 
343  nullptr, kDifOtpCtrlPartitionOwnerSwCfg, &flag));
345  &otp_, kDifOtpCtrlPartitionOwnerSwCfg, nullptr));
348 
350  nullptr, kDifOtpCtrlPartitionRotCreatorAuthCodesign, &flag));
352  &otp_, kDifOtpCtrlPartitionRotCreatorAuthCodesign, nullptr));
354  nullptr, kDifOtpCtrlPartitionRotCreatorAuthCodesign));
355 
357  nullptr, kDifOtpCtrlPartitionRotCreatorAuthState, &flag));
359  &otp_, kDifOtpCtrlPartitionRotCreatorAuthState, nullptr));
361  nullptr, kDifOtpCtrlPartitionRotCreatorAuthState));
362 }
363 
364 class StatusTest : public OtpTest {};
365 
366 TEST_F(StatusTest, Idle) {
368 
369  EXPECT_READ32(OTP_CTRL_STATUS_REG_OFFSET,
370  {{OTP_CTRL_STATUS_DAI_IDLE_BIT, true}});
372 
373  EXPECT_EQ(status.codes, 1 << kDifOtpCtrlStatusCodeDaiIdle);
374  EXPECT_THAT(status.causes, Each(kDifOtpCtrlErrorOk));
375 }
376 
377 TEST_F(StatusTest, Errors) {
379 
380  EXPECT_READ32(OTP_CTRL_STATUS_REG_OFFSET,
381  {
382  {OTP_CTRL_STATUS_DAI_IDLE_BIT, true},
383  {OTP_CTRL_STATUS_HW_CFG0_ERROR_BIT, true},
384  {OTP_CTRL_STATUS_LCI_ERROR_BIT, true},
385  });
386 
387  EXPECT_READ32(OTP_CTRL_ERR_CODE_5_REG_OFFSET,
388  {{OTP_CTRL_ERR_CODE_0_ERR_CODE_0_OFFSET,
389  OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ECC_CORR_ERROR}});
390  EXPECT_READ32(OTP_CTRL_ERR_CODE_12_REG_OFFSET,
391  {{OTP_CTRL_ERR_CODE_0_ERR_CODE_0_OFFSET,
392  OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ERROR}});
393 
395  EXPECT_EQ(status.codes, (1 << kDifOtpCtrlStatusCodeDaiIdle) |
398  EXPECT_EQ(status.causes[kDifOtpCtrlStatusCodeHwCfg0Error],
400  EXPECT_EQ(status.causes[kDifOtpCtrlStatusCodeLciError],
402 }
403 
404 TEST_F(StatusTest, NullArgs) {
406 
409 }
410 
412  std::string name;
413  dif_otp_ctrl_partition_t partition;
414  uint32_t abs_address;
415  dif_result_t expected_result;
416  uint32_t expected_relative_address;
417 };
418 
420  : public OtpTest,
421  public testing::WithParamInterface<RelativeAddressParams> {};
422 
424  uint32_t got_relative_address;
426  GetParam().partition, GetParam().abs_address, &got_relative_address);
427  EXPECT_EQ(got_result, GetParam().expected_result);
428  EXPECT_EQ(got_relative_address, GetParam().expected_relative_address);
429 }
430 
431 INSTANTIATE_TEST_SUITE_P(
432  AllPartitions, RelativeAddress,
433  testing::Values(
434  RelativeAddressParams{
435  "VendorTestOkay",
437  OTP_CTRL_PARAM_VENDOR_TEST_OFFSET + 4,
438  kDifOk,
439  4,
440  },
441  RelativeAddressParams{
442  "VendorTestUnaligned",
444  OTP_CTRL_PARAM_VENDOR_TEST_OFFSET + 1,
446  0,
447  },
448  RelativeAddressParams{
449  "VendorTestOutOfRangePastEnd",
451  OTP_CTRL_PARAM_VENDOR_TEST_OFFSET + OTP_CTRL_PARAM_VENDOR_TEST_SIZE,
453  0,
454  },
455  RelativeAddressParams{
456  "CreatorSwCfgOkay",
458  OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET + 4,
459  kDifOk,
460  4,
461  },
462  RelativeAddressParams{
463  "CreatorSwCfgUnaligned",
465  OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET + 1,
467  0,
468  },
469  RelativeAddressParams{
470  "CreatorSwCfgOutOfRangeBeforeStart",
472  OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET - 4,
474  0,
475  },
476  RelativeAddressParams{
477  "CreatorSwCfgOutOfRangePastEnd",
479  OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET +
480  OTP_CTRL_PARAM_CREATOR_SW_CFG_SIZE,
482  0,
483  },
484  RelativeAddressParams{
485  "OwnerSwCfgOkay",
487  OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET + 4,
488  kDifOk,
489  4,
490  },
491  RelativeAddressParams{
492  "OwnerSwCfgUnaligned",
494  OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET + 1,
496  0,
497  },
498  RelativeAddressParams{
499  "OwnerSwCfgOutOfRangeBeforeStart",
501  OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET - 4,
503  0,
504  },
505  RelativeAddressParams{
506  "OwnerSwCfgOutOfRangePastEnd",
508  OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET +
509  OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE,
511  0,
512  },
513  RelativeAddressParams{
514  "RotCreatorAuthCodesignOkay",
515  kDifOtpCtrlPartitionRotCreatorAuthCodesign,
516  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_OFFSET + 4,
517  kDifOk,
518  4,
519  },
520  RelativeAddressParams{
521  "RotCreatorAuthCodesignUnaligned",
522  kDifOtpCtrlPartitionRotCreatorAuthCodesign,
523  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_OFFSET + 1,
525  0,
526  },
527  RelativeAddressParams{
528  "RotCreatorAuthCodesignOutOfRangeBeforeStart",
529  kDifOtpCtrlPartitionRotCreatorAuthCodesign,
530  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_OFFSET - 4,
532  0,
533  },
534  RelativeAddressParams{
535  "RotCreatorAuthCodesignOutOfRangePastEnd",
536  kDifOtpCtrlPartitionRotCreatorAuthCodesign,
537  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_OFFSET +
538  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_SIZE,
540  0,
541  },
542  RelativeAddressParams{
543  "RotCreatorAuthStateOkay",
544  kDifOtpCtrlPartitionRotCreatorAuthState,
545  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_OFFSET + 4,
546  kDifOk,
547  4,
548  },
549  RelativeAddressParams{
550  "RotCreatorAuthStateUnaligned",
551  kDifOtpCtrlPartitionRotCreatorAuthState,
552  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_OFFSET + 1,
554  0,
555  },
556  RelativeAddressParams{
557  "RotCreatorAuthStateOutOfRangeBeforeStart",
558  kDifOtpCtrlPartitionRotCreatorAuthState,
559  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_OFFSET - 4,
561  0,
562  },
563  RelativeAddressParams{
564  "RotCreatorAuthStateOutOfRangePastEnd",
565  kDifOtpCtrlPartitionRotCreatorAuthState,
566  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_OFFSET +
567  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_SIZE,
569  0,
570  },
571  RelativeAddressParams{
572  "HwCfg0Okay",
574  OTP_CTRL_PARAM_HW_CFG0_OFFSET + 4,
575  kDifOk,
576  4,
577  },
578  RelativeAddressParams{
579  "HwCfg0Unaligned",
581  OTP_CTRL_PARAM_HW_CFG0_OFFSET + 1,
583  0,
584  },
585  RelativeAddressParams{
586  "HwCfg0OutOfRangeBeforeStart",
588  OTP_CTRL_PARAM_HW_CFG0_OFFSET - 4,
590  0,
591  },
592  RelativeAddressParams{
593  "HwCfg0OutOfRangePastEnd",
595  OTP_CTRL_PARAM_HW_CFG0_OFFSET + OTP_CTRL_PARAM_HW_CFG0_SIZE,
597  0,
598  },
599  RelativeAddressParams{
600  "HwCfg1Okay",
602  OTP_CTRL_PARAM_HW_CFG1_OFFSET + 4,
603  kDifOk,
604  4,
605  },
606  RelativeAddressParams{
607  "HwCfg1Unaligned",
609  OTP_CTRL_PARAM_HW_CFG1_OFFSET + 1,
611  0,
612  },
613  RelativeAddressParams{
614  "HwCfg1OutOfRangeBeforeStart",
616  OTP_CTRL_PARAM_HW_CFG1_OFFSET - 4,
618  0,
619  },
620  RelativeAddressParams{
621  "HwCfg1OutOfRangePastEnd",
623  OTP_CTRL_PARAM_HW_CFG1_OFFSET + OTP_CTRL_PARAM_HW_CFG1_SIZE,
625  0,
626  },
627  RelativeAddressParams{
628  "Secret0Okay",
630  OTP_CTRL_PARAM_SECRET0_OFFSET + 8,
631  kDifOk,
632  8,
633  },
634  RelativeAddressParams{
635  "Secret0Unaligned",
637  OTP_CTRL_PARAM_SECRET0_OFFSET + 1,
639  0,
640  },
641  RelativeAddressParams{
642  "Secret0OutOfRangeBeforeStart",
644  OTP_CTRL_PARAM_SECRET0_OFFSET - 8,
646  0,
647  },
648  RelativeAddressParams{
649  "Secret0OutOfRangePastEnd",
651  OTP_CTRL_PARAM_SECRET0_OFFSET + OTP_CTRL_PARAM_SECRET0_SIZE,
653  0,
654  },
655  RelativeAddressParams{
656  "Secret1Okay",
658  OTP_CTRL_PARAM_SECRET1_OFFSET + 8,
659  kDifOk,
660  8,
661  },
662  RelativeAddressParams{
663  "Secret1Unaligned",
665  OTP_CTRL_PARAM_SECRET1_OFFSET + 1,
667  0,
668  },
669  RelativeAddressParams{
670  "Secret1OutOfRangeBeforeStart",
672  OTP_CTRL_PARAM_SECRET1_OFFSET - 8,
674  0,
675  },
676  RelativeAddressParams{
677  "Secret1OutOfRangePastEnd",
679  OTP_CTRL_PARAM_SECRET1_OFFSET + OTP_CTRL_PARAM_SECRET1_SIZE,
681  0,
682  },
683  RelativeAddressParams{
684  "Secret2Okay",
686  OTP_CTRL_PARAM_SECRET2_OFFSET + 8,
687  kDifOk,
688  8,
689  },
690  RelativeAddressParams{
691  "Secret2Unaligned",
693  OTP_CTRL_PARAM_SECRET2_OFFSET + 1,
695  0,
696  },
697  RelativeAddressParams{
698  "Secret2OutOfRangeBeforeStart",
700  OTP_CTRL_PARAM_SECRET2_OFFSET - 8,
702  0,
703  },
704  RelativeAddressParams{
705  "Secret2OutOfRangePastEnd",
707  OTP_CTRL_PARAM_SECRET2_OFFSET + OTP_CTRL_PARAM_SECRET2_SIZE,
709  0,
710  },
711  RelativeAddressParams{
712  "LifeCycleOkay",
714  OTP_CTRL_PARAM_LIFE_CYCLE_OFFSET + 4,
715  kDifOk,
716  4,
717  },
718  RelativeAddressParams{
719  "LifeCycleUnaligned",
721  OTP_CTRL_PARAM_LIFE_CYCLE_OFFSET + 1,
723  0,
724  },
725  RelativeAddressParams{
726  "LifeCycleOutOfRangeBeforeStart",
728  OTP_CTRL_PARAM_LIFE_CYCLE_OFFSET - 4,
730  0,
731  },
732  RelativeAddressParams{
733  "LifeCycleOutOfRangePastEnd",
735  OTP_CTRL_PARAM_LIFE_CYCLE_OFFSET + OTP_CTRL_PARAM_LIFE_CYCLE_SIZE,
737  0,
738  }),
739  [](const testing::TestParamInfo<RelativeAddress::ParamType> &info) {
740  return info.param.name;
741  });
742 
743 class DaiReadTest : public OtpTest {};
744 
745 TEST_F(DaiReadTest, Read32) {
746  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
747  OTP_CTRL_PARAM_MANUF_STATE_OFFSET);
748  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
749  {{OTP_CTRL_DIRECT_ACCESS_CMD_RD_BIT, true}});
750 
752  /*address=*/0x20));
753 
754  EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET, 0x12345678);
755 
756  uint32_t val;
758  EXPECT_EQ(val, 0x12345678);
759 }
760 
761 TEST_F(DaiReadTest, Read64) {
762  uint64_t val;
763  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
764  OTP_CTRL_PARAM_SECRET0_OFFSET + 0x8);
765  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
766  {{OTP_CTRL_DIRECT_ACCESS_CMD_RD_BIT, true}});
767 
769  /*address=*/0x8));
770 
771  EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_RDATA_1_REG_OFFSET, 0x12345678);
772  EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET, 0x90abcdef);
773 
775  EXPECT_EQ(val, 0x1234567890abcdef);
776 
777  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
778  OTP_CTRL_PARAM_SECRET1_OFFSET + 0x8);
779  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
780  {{OTP_CTRL_DIRECT_ACCESS_CMD_RD_BIT, true}});
781 
783  /*address=*/0x8));
784 
785  EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_RDATA_1_REG_OFFSET, 0x12345678);
786  EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET, 0x90abcdef);
787 
789  EXPECT_EQ(val, 0x1234567890abcdef);
790 
791  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
792  OTP_CTRL_PARAM_SECRET2_OFFSET + 0x8);
793  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
794  {{OTP_CTRL_DIRECT_ACCESS_CMD_RD_BIT, true}});
795 
797  /*address=*/0x8));
798 
799  EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_RDATA_1_REG_OFFSET, 0x12345678);
800  EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET, 0x90abcdef);
801 
803  EXPECT_EQ(val, 0x1234567890abcdef);
804 }
805 
806 TEST_F(DaiReadTest, Unaligned) {
808  /*address=*/0b01),
809  kDifUnaligned);
811  /*address=*/0b100),
812  kDifUnaligned);
813 }
814 
815 TEST_F(DaiReadTest, OutOfRange) {
817  /*address=*/0x100),
819 }
820 
821 TEST_F(DaiReadTest, NullArgs) {
824  /*address=*/0x0));
825 
826  uint32_t val32;
829 
830  uint64_t val64;
833 }
834 
835 class DaiProgramTest : public OtpTest {};
836 
837 TEST_F(DaiProgramTest, Program32) {
838  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
839  OTP_CTRL_PARAM_MANUF_STATE_OFFSET);
840  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, 0x12345678);
841  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
842  {{OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true}});
843 
845  /*address=*/0x20,
846  /*value=*/0x12345678));
847 }
848 
849 TEST_F(DaiProgramTest, Program64) {
850  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
851  OTP_CTRL_PARAM_SECRET2_OFFSET + 0x8);
852  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, 0x90abcdef);
853  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET, 0x12345678);
854  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
855  {{OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true}});
856 
858  /*address=*/0x8,
859  /*value=*/0x1234567890abcdef));
860 }
861 
862 TEST_F(DaiProgramTest, BadPartition) {
864  /*address=*/0x0, /*value=*/42),
865  kDifError);
867  /*address=*/0x0, /*value=*/42),
868  kDifError);
869 
870  // LC is never writeable.
872  /*address=*/0x0, /*value=*/42),
873  kDifError);
874 }
875 
876 TEST_F(DaiProgramTest, Unaligned) {
878  /*address=*/0b01, /*value=*/42),
879  kDifUnaligned);
881  /*address=*/0b100, /*value=*/42),
882  kDifUnaligned);
883 }
884 
885 TEST_F(DaiProgramTest, OutOfRange) {
886  // Check that we can't write a digest directly.
887  EXPECT_EQ(dif_otp_ctrl_dai_program32(
889  /*address=*/OTP_CTRL_PARAM_CREATOR_SW_CFG_DIGEST_OFFSET,
890  /*value=*/42),
892 
893  // Same digest check for 64-bit.
894  EXPECT_EQ(dif_otp_ctrl_dai_program64(
896  /*address=*/OTP_CTRL_PARAM_SECRET2_DIGEST_OFFSET, /*value=*/42),
898 }
899 
900 TEST_F(DaiProgramTest, NullArgs) {
903  /*address=*/0x0, /*value=*/42));
906  /*address=*/0x0, /*value=*/42));
907 }
908 
909 class DaiDigestTest : public OtpTest {};
910 
911 TEST_F(DaiDigestTest, DigestSw) {
912  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
913  OTP_CTRL_PARAM_VENDOR_TEST_DIGEST_OFFSET);
914  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, 0x00abcdef);
915  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET, 0xabcdef00);
916  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
917  {{OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true}});
918 
920  /*digest=*/0xabcdef0000abcdef));
921 
922  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
923  OTP_CTRL_PARAM_CREATOR_SW_CFG_DIGEST_OFFSET);
924  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, 0x00abcdef);
925  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET, 0xabcdef00);
926  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
927  {{OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true}});
928 
930  /*digest=*/0xabcdef0000abcdef));
931 
932  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
933  OTP_CTRL_PARAM_OWNER_SW_CFG_DIGEST_OFFSET);
934  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, 0x00abcdef);
935  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET, 0xabcdef00);
936  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
937  {{OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true}});
938 
940  /*digest=*/0xabcdef0000abcdef));
941 
942  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
943  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_DIGEST_OFFSET);
944  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, 0x00abcdef);
945  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET, 0xabcdef00);
946  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
947  {{OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true}});
948 
950  dif_otp_ctrl_dai_digest(&otp_, kDifOtpCtrlPartitionRotCreatorAuthCodesign,
951  /*digest=*/0xabcdef0000abcdef));
952 
953  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
954  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_DIGEST_OFFSET);
955  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, 0x00abcdef);
956  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET, 0xabcdef00);
957  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
958  {{OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true}});
959 
961  kDifOtpCtrlPartitionRotCreatorAuthState,
962  /*digest=*/0xabcdef0000abcdef));
963 }
964 
965 TEST_F(DaiDigestTest, DigestHw) {
966  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
967  OTP_CTRL_PARAM_HW_CFG0_OFFSET);
968  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
969  {{OTP_CTRL_DIRECT_ACCESS_CMD_DIGEST_BIT, true}});
970 
972  /*digest=*/0));
973 
974  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
975  OTP_CTRL_PARAM_HW_CFG1_OFFSET);
976  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
977  {{OTP_CTRL_DIRECT_ACCESS_CMD_DIGEST_BIT, true}});
978 
980  /*digest=*/0));
981 
982  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
983  OTP_CTRL_PARAM_SECRET0_OFFSET);
984  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
985  {{OTP_CTRL_DIRECT_ACCESS_CMD_DIGEST_BIT, true}});
986 
988  /*digest=*/0));
989 
990  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
991  OTP_CTRL_PARAM_SECRET1_OFFSET);
992  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
993  {{OTP_CTRL_DIRECT_ACCESS_CMD_DIGEST_BIT, true}});
994 
996  /*digest=*/0));
997 
998  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
999  OTP_CTRL_PARAM_SECRET2_OFFSET);
1000  EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
1001  {{OTP_CTRL_DIRECT_ACCESS_CMD_DIGEST_BIT, true}});
1002 
1004  /*digest=*/0));
1005 }
1006 
1007 TEST_F(DaiDigestTest, BadPartition) {
1009  /*digest=*/0),
1010  kDifError);
1011 }
1012 
1013 TEST_F(DaiDigestTest, BadDigest) {
1015  /*digest=*/0xabcdef0000abcdef));
1018  /*digest=*/0));
1019 }
1020 
1021 TEST_F(DaiDigestTest, NullArgs) {
1024  /*digest=*/0xabcdef0000abcdef));
1025 }
1026 
1027 class IsDigestComputed : public OtpTest {};
1028 
1029 TEST_F(IsDigestComputed, NullArgs) {
1030  bool is_computed;
1032  nullptr, kDifOtpCtrlPartitionSecret2, &is_computed));
1034  &otp_, kDifOtpCtrlPartitionSecret2, nullptr));
1036  nullptr, kDifOtpCtrlPartitionSecret2, nullptr));
1037 }
1038 
1039 TEST_F(IsDigestComputed, BadPartition) {
1040  bool is_computed;
1042  &otp_, kDifOtpCtrlPartitionLifeCycle, &is_computed));
1043 }
1044 
1045 TEST_F(IsDigestComputed, Success) {
1046  bool is_computed;
1047 
1048  EXPECT_READ32(OTP_CTRL_SECRET2_DIGEST_1_REG_OFFSET, 0x98abcdef);
1049  EXPECT_READ32(OTP_CTRL_SECRET2_DIGEST_0_REG_OFFSET, 0xabcdef01);
1051  &otp_, kDifOtpCtrlPartitionSecret2, &is_computed));
1052  EXPECT_TRUE(is_computed);
1053 
1054  EXPECT_READ32(OTP_CTRL_SECRET2_DIGEST_1_REG_OFFSET, 0);
1055  EXPECT_READ32(OTP_CTRL_SECRET2_DIGEST_0_REG_OFFSET, 0);
1057  &otp_, kDifOtpCtrlPartitionSecret2, &is_computed));
1058  EXPECT_FALSE(is_computed);
1059 }
1060 
1062  dif_otp_ctrl_partition_t partition;
1063  bool has_digest;
1064  ptrdiff_t reg0, reg1;
1065 };
1066 
1067 class GetDigest : public OtpTest,
1068  public testing::WithParamInterface<DigestParams> {};
1069 
1070 TEST_P(GetDigest, GetDigest) {
1071  if (!GetParam().has_digest) {
1072  uint64_t digest;
1074  dif_otp_ctrl_get_digest(&otp_, GetParam().partition, &digest));
1075  return;
1076  }
1077 
1078  EXPECT_READ32(GetParam().reg1, 0xabcdef99);
1079  EXPECT_READ32(GetParam().reg0, 0x99abcdef);
1080 
1081  uint64_t digest;
1082  EXPECT_DIF_OK(dif_otp_ctrl_get_digest(&otp_, GetParam().partition, &digest));
1083  EXPECT_EQ(digest, 0xabcdef9999abcdef);
1084 }
1085 
1086 TEST_P(GetDigest, BadDigest) {
1087  if (!GetParam().has_digest) {
1088  return;
1089  }
1090 
1091  EXPECT_READ32(GetParam().reg1, 0x0);
1092  EXPECT_READ32(GetParam().reg0, 0x0);
1093 
1094  uint64_t digest;
1095  EXPECT_EQ(dif_otp_ctrl_get_digest(&otp_, GetParam().partition, &digest),
1096  kDifError);
1097 }
1098 
1099 TEST_P(GetDigest, NullArgs) {
1100  uint64_t digest;
1102  dif_otp_ctrl_get_digest(nullptr, GetParam().partition, &digest));
1104  dif_otp_ctrl_get_digest(&otp_, GetParam().partition, nullptr));
1105 }
1106 
1107 // This depends on the maximum length of partition names, which will
1108 // be changing, so turn formatting off.
1109 // clang-format off
1110 INSTANTIATE_TEST_SUITE_P(
1111  AllDigests, GetDigest,
1112  testing::Values(
1113  DigestParams{
1115  true,
1116  OTP_CTRL_VENDOR_TEST_DIGEST_0_REG_OFFSET,
1117  OTP_CTRL_VENDOR_TEST_DIGEST_1_REG_OFFSET,
1118  },
1119  DigestParams{
1121  true,
1122  OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_REG_OFFSET,
1123  OTP_CTRL_CREATOR_SW_CFG_DIGEST_1_REG_OFFSET,
1124  },
1125  DigestParams{
1127  true,
1128  OTP_CTRL_OWNER_SW_CFG_DIGEST_0_REG_OFFSET,
1129  OTP_CTRL_OWNER_SW_CFG_DIGEST_1_REG_OFFSET,
1130  },
1131  DigestParams{
1132  kDifOtpCtrlPartitionRotCreatorAuthCodesign,
1133  true,
1134  OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_REG_OFFSET,
1135  OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_1_REG_OFFSET,
1136  },
1137  DigestParams{
1138  kDifOtpCtrlPartitionRotCreatorAuthState,
1139  true,
1140  OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0_REG_OFFSET,
1141  OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_1_REG_OFFSET,
1142  },
1143  DigestParams{
1145  true,
1146  OTP_CTRL_HW_CFG0_DIGEST_0_REG_OFFSET,
1147  OTP_CTRL_HW_CFG0_DIGEST_1_REG_OFFSET,
1148  },
1149  DigestParams{
1151  true,
1152  OTP_CTRL_HW_CFG1_DIGEST_0_REG_OFFSET,
1153  OTP_CTRL_HW_CFG1_DIGEST_1_REG_OFFSET,
1154  },
1155  DigestParams{
1157  true,
1158  OTP_CTRL_SECRET0_DIGEST_0_REG_OFFSET,
1159  OTP_CTRL_SECRET0_DIGEST_1_REG_OFFSET,
1160  },
1161  DigestParams{
1163  true,
1164  OTP_CTRL_SECRET1_DIGEST_0_REG_OFFSET,
1165  OTP_CTRL_SECRET1_DIGEST_1_REG_OFFSET,
1166  },
1167  DigestParams{
1169  true,
1170  OTP_CTRL_SECRET2_DIGEST_0_REG_OFFSET,
1171  OTP_CTRL_SECRET2_DIGEST_1_REG_OFFSET,
1172  },
1173  DigestParams{
1175  false,
1176  0,
1177  0,
1178  }));
1179 // clang-format on
1180 
1181 class BlockingIoTest : public OtpTest {
1182  protected:
1183  static constexpr size_t kWords = 4;
1184 };
1185 
1186 TEST_F(BlockingIoTest, Read) {
1187  for (size_t i = 0; i < kWords; ++i) {
1188  auto offset =
1189  OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET + 0x10 + i * sizeof(uint32_t);
1190  EXPECT_READ32(OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET + offset, i + 1);
1191  }
1192 
1193  std::vector<uint32_t> buf(kWords);
1195  &otp_, kDifOtpCtrlPartitionOwnerSwCfg, 0x10, buf.data(), buf.size()));
1196  EXPECT_THAT(buf, ElementsAre(1, 2, 3, 4));
1197 }
1198 
1199 TEST_F(BlockingIoTest, BadPartition) {
1200  std::vector<uint32_t> buf(kWords);
1202  buf.data(), buf.size()),
1203  kDifError);
1204 }
1205 
1206 TEST_F(BlockingIoTest, Unaligned) {
1207  std::vector<uint32_t> buf(kWords);
1209  0x11, buf.data(), buf.size()),
1210  kDifUnaligned);
1211 }
1212 
1213 TEST_F(BlockingIoTest, OutOfRange) {
1214  std::vector<uint32_t> buf(0x2f0);
1216  0x300, buf.data(), buf.size()),
1217  kDifOutOfRange);
1219  0x10, buf.data(), 0x330),
1220  kDifOutOfRange);
1221 }
1222 
1223 TEST_F(BlockingIoTest, NullArgs) {
1224  std::vector<uint32_t> buf(kWords);
1226  nullptr, kDifOtpCtrlPartitionOwnerSwCfg, 0x10, buf.data(), buf.size()));
1228  &otp_, kDifOtpCtrlPartitionOwnerSwCfg, 0x10, nullptr, buf.size()));
1229 }
1230 
1231 } // namespace
1232 } // namespace dif_otp_ctrl_unittest