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);
51 LOG_ERROR(
"No DAI error code expected for access to 0x%x", address);
57status_t otp_ctrl_testutils_wait_for_dai(
const dif_otp_ctrl_t *otp_ctrl) {
58 TRY(otp_ctrl_testutils_wait_for_dai_pre_hook(otp_ctrl));
60 TRY(otp_ctrl_testutils_wait_for_dai_post_hook(otp_ctrl));
64status_t otp_ctrl_testutils_lock_partition(
const dif_otp_ctrl_t *otp,
67 TRY(dif_otp_ctrl_dai_digest(otp, partition, digest));
68 return otp_ctrl_testutils_wait_for_dai(otp);
73 uint32_t address, uint32_t *result) {
74 TRY(otp_ctrl_testutils_wait_for_dai(otp));
75 TRY(otp_ctrl_testutils_dai_read_pre_hook(otp));
76 TRY(dif_otp_ctrl_dai_read_start(otp, partition, address));
77 TRY(otp_ctrl_testutils_wait_for_dai(otp));
78 TRY(dif_otp_ctrl_dai_read32_end(otp, result));
79 TRY(otp_ctrl_testutils_dai_read_post_hook(otp));
83status_t otp_ctrl_testutils_dai_read32_array(
const dif_otp_ctrl_t *otp,
85 uint32_t start_address,
86 uint32_t *buffer,
size_t len) {
87 uint32_t stop_address = start_address + (len *
sizeof(uint32_t));
88 for (uint32_t addr = start_address, i = 0; addr < stop_address;
89 addr +=
sizeof(uint32_t), ++i) {
90 TRY(otp_ctrl_testutils_wait_for_dai(otp));
91 TRY(otp_ctrl_testutils_dai_read_pre_hook(otp));
92 TRY(dif_otp_ctrl_dai_read_start(otp, partition, addr));
93 TRY(otp_ctrl_testutils_wait_for_dai(otp));
94 TRY(dif_otp_ctrl_dai_read32_end(otp, &buffer[i]));
95 TRY(otp_ctrl_testutils_dai_read_post_hook(otp));
102 uint32_t address, uint64_t *result) {
103 TRY(otp_ctrl_testutils_wait_for_dai(otp));
104 TRY(otp_ctrl_testutils_dai_read_pre_hook(otp));
105 TRY(dif_otp_ctrl_dai_read_start(otp, partition, address));
106 TRY(otp_ctrl_testutils_wait_for_dai(otp));
107 TRY(dif_otp_ctrl_dai_read64_end(otp, result));
108 TRY(otp_ctrl_testutils_dai_read_post_hook(otp));
112status_t otp_ctrl_testutils_dai_read64_array(
const dif_otp_ctrl_t *otp,
114 uint32_t start_address,
115 uint64_t *buffer,
size_t len) {
116 uint32_t stop_address = start_address + (len *
sizeof(uint64_t));
117 for (uint32_t addr = start_address, i = 0; addr < stop_address;
118 addr +=
sizeof(uint64_t), ++i) {
119 TRY(otp_ctrl_testutils_wait_for_dai(otp));
120 TRY(otp_ctrl_testutils_dai_read_pre_hook(otp));
121 TRY(dif_otp_ctrl_dai_read_start(otp, partition, addr));
122 TRY(otp_ctrl_testutils_wait_for_dai(otp));
123 TRY(dif_otp_ctrl_dai_read64_end(otp, &buffer[i]));
124 TRY(otp_ctrl_testutils_dai_read_post_hook(otp));
137static status_t otp_ctrl_dai_write_error_check(
const dif_otp_ctrl_t *otp) {
139 TRY(dif_otp_ctrl_get_status(otp, &
status));
152 uint32_t start_address,
153 const uint32_t *buffer,
size_t len) {
157 bool check_before_write = (
158#ifdef OPENTITAN_IS_EGRET
159 partition == kOtpPartitionRotCreatorAuthCodesign ||
160 partition == kOtpPartitionRotCreatorAuthState ||
162 partition == kOtpPartitionCreatorSwCfg ||
163 partition == kOtpPartitionOwnerSwCfg);
164 uint32_t stop_address = start_address + (len *
sizeof(uint32_t));
165 for (uint32_t addr = start_address, i = 0; addr < stop_address;
166 addr +=
sizeof(uint32_t), ++i) {
168 if (check_before_write) {
169 TRY(otp_ctrl_testutils_dai_read32(otp, partition, addr, &read_data));
170 if (read_data == buffer[i]) {
173 if (read_data != 0) {
174 LOG_ERROR(
"OTP partition: %d addr[0x%x] got: 0x%08x, expected: 0x%08x",
175 partition, addr, read_data, buffer[i]);
180 TRY(otp_ctrl_testutils_wait_for_dai(otp));
181 TRY(otp_ctrl_testutils_dai_write_pre_hook(otp));
182 TRY(dif_otp_ctrl_dai_program32(otp, partition, addr, buffer[i]));
183 TRY(otp_ctrl_testutils_dai_write_post_hook(otp));
184 TRY(otp_ctrl_testutils_wait_for_dai(otp));
185 TRY(otp_ctrl_testutils_dai_write_pre_error_check_hook(otp));
186 TRY(otp_ctrl_dai_write_error_check(otp));
187 TRY(otp_ctrl_testutils_dai_write_post_error_check_hook(otp));
189 TRY(otp_ctrl_testutils_dai_read32(otp, partition, addr, &read_data));
190 if (read_data != buffer[i]) {
199 uint32_t start_address,
200 const uint64_t *buffer,
size_t len) {
201 uint32_t stop_address = start_address + (len *
sizeof(uint64_t));
202 for (uint32_t addr = start_address, i = 0; addr < stop_address;
203 addr +=
sizeof(uint64_t), ++i) {
204 TRY(otp_ctrl_testutils_wait_for_dai(otp));
205 TRY(otp_ctrl_testutils_dai_write_pre_hook(otp));
206 TRY(dif_otp_ctrl_dai_program64(otp, partition, addr, buffer[i]));
207 TRY(otp_ctrl_testutils_dai_write_post_hook(otp));
208 TRY(otp_ctrl_testutils_wait_for_dai(otp));
209 TRY(otp_ctrl_testutils_dai_write_pre_error_check_hook(otp));
210 TRY(otp_ctrl_dai_write_error_check(otp));
211 TRY(otp_ctrl_testutils_dai_write_post_error_check_hook(otp));
214 TRY(otp_ctrl_testutils_dai_read64(otp, partition, addr, &read_data));
215 if (read_data != buffer[i]) {
223status_t otp_ctrl_testutils_wait_for_dai_pre_hook(
229status_t otp_ctrl_testutils_wait_for_dai_post_hook(
235status_t otp_ctrl_testutils_dai_write_pre_hook(
const dif_otp_ctrl_t *otp_ctrl) {
240status_t otp_ctrl_testutils_dai_write_post_hook(
246status_t otp_ctrl_testutils_dai_read_pre_hook(
const dif_otp_ctrl_t *otp_ctrl) {
251status_t otp_ctrl_testutils_dai_read_post_hook(
const dif_otp_ctrl_t *otp_ctrl) {
256status_t otp_ctrl_testutils_dai_write_pre_error_check_hook(
262status_t otp_ctrl_testutils_dai_write_post_error_check_hook(