5#include "sw/device/lib/testing/otp_ctrl_testutils.h"
10#include "sw/device/lib/testing/test_framework/check.h"
12#define MODULE_ID MAKE_MODULE_ID('o', 'c', 't')
20const uint16_t kOtpDaiTimeoutUs = 10000;
32status_t otp_ctrl_testutils_dai_access_error_check(
36 TRY(dif_otp_ctrl_get_status(otp_ctrl, &
status));
37 if (exp_result == kExpectFailed) {
39 LOG_ERROR(
"Expected a DAI error for access to 0x%x", address);
43 LOG_ERROR(
"Expected access locked error for access to 0x%x", address);
47 LOG_ERROR(
"No DAI error expected for access to 0x%x", address);
50 LOG_ERROR(
"No DAI error code expected for access to 0x%x", address);
56status_t otp_ctrl_testutils_wait_for_dai(
const dif_otp_ctrl_t *otp_ctrl) {
57 TRY(otp_ctrl_testutils_wait_for_dai_pre_hook(otp_ctrl));
59 TRY(otp_ctrl_testutils_wait_for_dai_post_hook(otp_ctrl));
63status_t otp_ctrl_testutils_lock_partition(
const dif_otp_ctrl_t *otp,
66 TRY(dif_otp_ctrl_dai_digest(otp, partition, digest));
67 return otp_ctrl_testutils_wait_for_dai(otp);
72 uint32_t address, uint32_t *result) {
73 TRY(otp_ctrl_testutils_wait_for_dai(otp));
74 TRY(otp_ctrl_testutils_dai_read_pre_hook(otp));
75 TRY(dif_otp_ctrl_dai_read_start(otp, partition, address));
76 TRY(otp_ctrl_testutils_wait_for_dai(otp));
77 TRY(dif_otp_ctrl_dai_read32_end(otp, result));
78 TRY(otp_ctrl_testutils_dai_read_post_hook(otp));
82status_t otp_ctrl_testutils_dai_read32_array(
const dif_otp_ctrl_t *otp,
84 uint32_t start_address,
85 uint32_t *buffer,
size_t len) {
86 uint32_t stop_address = start_address + (len *
sizeof(uint32_t));
87 for (uint32_t addr = start_address, i = 0; addr < stop_address;
88 addr +=
sizeof(uint32_t), ++i) {
89 TRY(otp_ctrl_testutils_wait_for_dai(otp));
90 TRY(otp_ctrl_testutils_dai_read_pre_hook(otp));
91 TRY(dif_otp_ctrl_dai_read_start(otp, partition, addr));
92 TRY(otp_ctrl_testutils_wait_for_dai(otp));
93 TRY(dif_otp_ctrl_dai_read32_end(otp, &buffer[i]));
94 TRY(otp_ctrl_testutils_dai_read_post_hook(otp));
101 uint32_t address, uint64_t *result) {
102 TRY(otp_ctrl_testutils_wait_for_dai(otp));
103 TRY(otp_ctrl_testutils_dai_read_pre_hook(otp));
104 TRY(dif_otp_ctrl_dai_read_start(otp, partition, address));
105 TRY(otp_ctrl_testutils_wait_for_dai(otp));
106 TRY(dif_otp_ctrl_dai_read64_end(otp, result));
107 TRY(otp_ctrl_testutils_dai_read_post_hook(otp));
111status_t otp_ctrl_testutils_dai_read64_array(
const dif_otp_ctrl_t *otp,
113 uint32_t start_address,
114 uint64_t *buffer,
size_t len) {
115 uint32_t stop_address = start_address + (len *
sizeof(uint64_t));
116 for (uint32_t addr = start_address, i = 0; addr < stop_address;
117 addr +=
sizeof(uint64_t), ++i) {
118 TRY(otp_ctrl_testutils_wait_for_dai(otp));
119 TRY(otp_ctrl_testutils_dai_read_pre_hook(otp));
120 TRY(dif_otp_ctrl_dai_read_start(otp, partition, addr));
121 TRY(otp_ctrl_testutils_wait_for_dai(otp));
122 TRY(dif_otp_ctrl_dai_read64_end(otp, &buffer[i]));
123 TRY(otp_ctrl_testutils_dai_read_post_hook(otp));
136static status_t otp_ctrl_dai_write_error_check(
const dif_otp_ctrl_t *otp) {
138 TRY(dif_otp_ctrl_get_status(otp, &
status));
151 uint32_t start_address,
152 const uint32_t *buffer,
size_t len) {
156 bool check_before_write = (
157#ifdef OPENTITAN_IS_EARLGREY
158 partition == kDifOtpCtrlPartitionRotCreatorAuthCodesign ||
159 partition == kDifOtpCtrlPartitionRotCreatorAuthState ||
163 uint32_t stop_address = start_address + (len *
sizeof(uint32_t));
164 for (uint32_t addr = start_address, i = 0; addr < stop_address;
165 addr +=
sizeof(uint32_t), ++i) {
167 if (check_before_write) {
168 TRY(otp_ctrl_testutils_dai_read32(otp, partition, addr, &read_data));
169 if (read_data == buffer[i]) {
172 if (read_data != 0) {
173 LOG_ERROR(
"OTP partition: %d addr[0x%x] got: 0x%08x, expected: 0x%08x",
174 partition, addr, read_data, buffer[i]);
179 TRY(otp_ctrl_testutils_wait_for_dai(otp));
180 TRY(otp_ctrl_testutils_dai_write_pre_hook(otp));
181 TRY(dif_otp_ctrl_dai_program32(otp, partition, addr, buffer[i]));
182 TRY(otp_ctrl_testutils_dai_write_post_hook(otp));
183 TRY(otp_ctrl_testutils_wait_for_dai(otp));
184 TRY(otp_ctrl_testutils_dai_write_pre_error_check_hook(otp));
185 TRY(otp_ctrl_dai_write_error_check(otp));
186 TRY(otp_ctrl_testutils_dai_write_post_error_check_hook(otp));
188 TRY(otp_ctrl_testutils_dai_read32(otp, partition, addr, &read_data));
189 if (read_data != buffer[i]) {
198 uint32_t start_address,
199 const uint64_t *buffer,
size_t len) {
200 uint32_t stop_address = start_address + (len *
sizeof(uint64_t));
201 for (uint32_t addr = start_address, i = 0; addr < stop_address;
202 addr +=
sizeof(uint64_t), ++i) {
203 TRY(otp_ctrl_testutils_wait_for_dai(otp));
204 TRY(otp_ctrl_testutils_dai_write_pre_hook(otp));
205 TRY(dif_otp_ctrl_dai_program64(otp, partition, addr, buffer[i]));
206 TRY(otp_ctrl_testutils_dai_write_post_hook(otp));
207 TRY(otp_ctrl_testutils_wait_for_dai(otp));
208 TRY(otp_ctrl_testutils_dai_write_pre_error_check_hook(otp));
209 TRY(otp_ctrl_dai_write_error_check(otp));
210 TRY(otp_ctrl_testutils_dai_write_post_error_check_hook(otp));
213 TRY(otp_ctrl_testutils_dai_read64(otp, partition, addr, &read_data));
214 if (read_data != buffer[i]) {
222status_t otp_ctrl_testutils_wait_for_dai_pre_hook(
228status_t otp_ctrl_testutils_wait_for_dai_post_hook(
234status_t otp_ctrl_testutils_dai_write_pre_hook(
const dif_otp_ctrl_t *otp_ctrl) {
239status_t otp_ctrl_testutils_dai_write_post_hook(
245status_t otp_ctrl_testutils_dai_read_pre_hook(
const dif_otp_ctrl_t *otp_ctrl) {
250status_t otp_ctrl_testutils_dai_read_post_hook(
const dif_otp_ctrl_t *otp_ctrl) {
255status_t otp_ctrl_testutils_dai_write_pre_error_check_hook(
261status_t otp_ctrl_testutils_dai_write_post_error_check_hook(