Software APIs
otp_ctrl_testutils.h
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#ifndef OPENTITAN_SW_DEVICE_LIB_TESTING_OTP_CTRL_TESTUTILS_H_
6#define OPENTITAN_SW_DEVICE_LIB_TESTING_OTP_CTRL_TESTUTILS_H_
7
8#include "sw/device/lib/base/status.h"
10
11/**
12 * Enum that encodes the expectation for the check_dai_access_error function.
13 */
14typedef enum { kExpectPassed, kExpectFailed } exp_test_result_t;
15
16/**
17 * Check whether we got an access error in the DAI.
18 *
19 * The test passes depending on the expectation argument.
20 * I.e., if the expectation is that we get an access error (exp_result ==
21 * kExpectFailed), but the DAI does not report any error, the test will fail.
22 */
24status_t otp_ctrl_testutils_dai_access_error_check(
25 const dif_otp_ctrl_t *otp_ctrl, exp_test_result_t exp_result,
26 int32_t address);
27
28/**
29 * Waits for the DAI operation to finish (busy wait).
30 */
32status_t otp_ctrl_testutils_wait_for_dai(const dif_otp_ctrl_t *otp_ctrl);
33
34/**
35 * Issues a partition lock and waits for the DAI operation to finish (busy
36 * wait).
37 *
38 * If `partition` is a SW partition, `digest` must be non-zero; if it is a
39 * partition with a hardware-managed digest, `digest` *must* be zero (since the
40 * digest will be generated by the hardware). An error is returned if either
41 * precondition is not met.
42 *
43 * @param otp otp_ctrl instance.
44 * @param partition OTP partition.
45 * @param digest The digest to program (for SW partitions).
46 * @return OK_STATUS on successful read.
47 */
49status_t otp_ctrl_testutils_lock_partition(const dif_otp_ctrl_t *otp,
51 uint64_t digest);
52
53/**
54 * Reads a 32bit value from OTP using the DAI interface.
55 *
56 * @param otp otp_ctrl instance.
57 * @param partition OTP partition.
58 * @param address Address relative to the start of the `partition`. Must be a
59 * 32bit aligned address.
60 * @param[out] result The 32bit value result.
61 * @return OK_STATUS on successful read.
62 */
64status_t otp_ctrl_testutils_dai_read32(const dif_otp_ctrl_t *otp,
66 uint32_t address, uint32_t *result);
67
68/**
69 * Reads a 32bit array from OTP using the DAI interface.
70 *
71 * @param otp otp_ctrl instance.
72 * @param partition OTP partition.
73 * @param start_address Address of array relative to the start of the
74 * `partition`. Must be a 32bit aligned address.
75 * @param[out] buffer The 32bit array buffer.
76 * @param len The number of 32bit words to read into the buffer.
77 * @return OK_STATUS on successful read.
78 */
80status_t otp_ctrl_testutils_dai_read32_array(const dif_otp_ctrl_t *otp,
82 uint32_t start_address,
83 uint32_t *buffer, size_t len);
84
85/**
86 * Reads a 64bit value from OTP using the DAI interface.
87 *
88 * @param otp otp_ctrl instance.
89 * @param partition OTP partition.
90 * @param address Address relative to the start of the `partition`. Must be a
91 * 64bit aligned address.
92 * @param[out] result The 64bit value result.
93 * @return OK_STATUS on successful read.
94 */
96status_t otp_ctrl_testutils_dai_read64(const dif_otp_ctrl_t *otp,
98 uint32_t address, uint64_t *result);
99
100/**
101 * Reads a 64bit array from OTP using the DAI interface.
102 *
103 * @param otp otp_ctrl instance.
104 * @param partition OTP partition.
105 * @param start_address Address of array relative to the start of the
106 * `partition`. Must be a 64bit aligned address.
107 * @param[out] buffer The 64bit array buffer.
108 * @param len The number of 64bit words to read into the buffer.
109 * @return OK_STATUS on successful read.
110 */
112status_t otp_ctrl_testutils_dai_read64_array(const dif_otp_ctrl_t *otp,
113 dif_otp_ctrl_partition_t partition,
114 uint32_t start_address,
115 uint64_t *buffer, size_t len);
116
117/**
118 * Writes `len` number of 32bit words from buffer into otp `partition` starting
119 * at `start_address` using the DAI interface.
120 *
121 * For software partitions (`kDifOtpCtrlPartitionCreatorSwCfg`,
122 * `kDifOtpCtrlPartitionOwnerSwCfg`,
123 * `kDifOtpCtrlPartitionRotCreatorAuthCodesign`, or
124 * `kDifOtpCtrlPartitionRotCreatorAuthState`), the function will attempt to read
125 * the target OTP offsets and skip the write if the existing value matches the
126 * expected one. This is possible due to the fact that software partitions are
127 * not scrambled nor ECC protected.
128 *
129 * @param otp otp_ctrl instance.
130 * @param partition OTP partition.
131 * @param start_address Address relative to the start of the `partition`. Must
132 * be a 32bit aligned address.
133 * @param buffer The buffer containing the data to be written into OTP.
134 * @param len The number of 32bit words to write into otp. `buffer` must have at
135 * least `len` 32bit words.
136 * @return OK_STATUS on success.
137 */
139status_t otp_ctrl_testutils_dai_write32(const dif_otp_ctrl_t *otp,
140 dif_otp_ctrl_partition_t partition,
141 uint32_t start_address,
142 const uint32_t *buffer, size_t len);
143
144/**
145 * Writes `len` number of 64bit words from buffer into otp `partition` starting
146 * at `start_address` using the DAI interface.
147 *
148 * @param otp otp_ctrl instance.
149 * @param partition OTP partition.
150 * @param start_address Address relative to the start of the `partition`. Must
151 * be a 64bit aligned address.
152 * @param buffer The buffer containing the data to be written into OTP.
153 * @param len The number of 64bit words to write into otp. `buffer` must have at
154 * least `len` 64bit words.
155 * @return OK_STATUS on success.
156 */
158status_t otp_ctrl_testutils_dai_write64(const dif_otp_ctrl_t *otp,
159 dif_otp_ctrl_partition_t partition,
160 uint32_t start_address,
161 const uint64_t *buffer, size_t len);
162
163#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_OTP_CTRL_TESTUTILS_H_