Software APIs
otp_ctrl_vendor_test_ecc_error_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 
9 #include "sw/device/lib/testing/otp_ctrl_testutils.h"
10 #include "sw/device/lib/testing/test_framework/check.h"
11 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
13 
15 
16 // This is the address that has an ecc error injected.
17 static volatile const uint32_t kTestAddress = 0;
18 
19 static dif_otp_ctrl_t otp;
20 
21 OTTF_DEFINE_TEST_CONFIG();
22 
23 static void init_peripherals(void) {
24  dif_otp_ctrl_config_t config = {
25  .check_timeout = 100000,
26  .integrity_period_mask = 0x3ffff,
27  .consistency_period_mask = 0x3ffffff,
28  };
29  // OTP
30  CHECK_DIF_OK(dif_otp_ctrl_init(
32  CHECK_DIF_OK(dif_otp_ctrl_configure(&otp, config));
33 }
34 
35 static void check_status(uint32_t expected_code,
36  dif_otp_ctrl_error_t expected_cause) {
38  CHECK_DIF_OK(dif_otp_ctrl_get_status(&otp, &status));
39  // Clear the non-error status.codes.
40  status.codes &= ~((1u << kDifOtpCtrlStatusCodeDaiIdle) |
42  if (expected_code == 0) {
43  CHECK(status.codes == 0,
44  "Unexpected OTP status codes, got 0x%x, expected 0", status.codes);
45  } else {
46  CHECK(status.codes == (1 << expected_code),
47  "Unexpected OTP status, got 0x%x, expected 0x%x", status.codes,
48  (1 << expected_cause));
49  CHECK(status.causes[expected_code] == expected_cause,
50  "Unexpected error cause, got 0x%x, expected 0x%x",
51  status.causes[expected_code], expected_cause);
52  }
53 }
54 
55 /**
56  * A simple SW test to read from vendor test partition at a location that had
57  * an ecc error injected. The expectation is that no error or fault will be
58  * triggered. The ecc eror is injected in the associated SV sequence.
59  */
60 bool test_main(void) {
61  static const uint32_t kTestPartition = 0;
62 
63  init_peripherals();
64 
65  uint32_t value;
66  LOG_INFO("Testing at OTP address 0x%x", kTestAddress);
67  LOG_INFO("Ready for single fault injection");
69  CHECK_STATUS_OK(otp_ctrl_testutils_dai_read32(&otp, kTestPartition,
70  kTestAddress, &value));
71  check_status(0, kDifOtpCtrlErrorOk);
72  LOG_INFO("Ready for double fault injection");
74  CHECK_STATUS_OK(otp_ctrl_testutils_dai_read32(&otp, kTestPartition,
75  kTestAddress, &value));
76  check_status(0, kDifOtpCtrlErrorOk);
77  LOG_INFO("Address done");
78  return true;
79 }