12 #include "otp_ctrl_regs.h"
23 static bool checks_are_locked(
const dif_otp_ctrl_t *otp,
bool check_config) {
24 ptrdiff_t reg_offset = check_config
25 ? OTP_CTRL_CHECK_REGWEN_REG_OFFSET
26 : OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET;
28 check_config ? OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT
29 : OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT;
30 uint32_t locked = mmio_region_read32(otp->base_addr, reg_offset);
39 if (checks_are_locked(otp,
true)) {
43 mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_TIMEOUT_REG_OFFSET,
45 mmio_region_write32(otp->base_addr,
46 OTP_CTRL_INTEGRITY_CHECK_PERIOD_REG_OFFSET,
48 mmio_region_write32(otp->base_addr,
49 OTP_CTRL_CONSISTENCY_CHECK_PERIOD_REG_OFFSET,
59 if (checks_are_locked(otp,
false)) {
65 mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_TRIGGER_REG_OFFSET, reg);
74 if (checks_are_locked(otp,
false)) {
80 mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_TRIGGER_REG_OFFSET, reg);
91 0, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT,
false);
92 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET,
100 if (otp == NULL || is_locked == NULL) {
104 uint32_t reg = mmio_region_read32(otp->base_addr,
105 OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET);
107 reg, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT);
119 mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_REGWEN_REG_OFFSET, reg);
126 if (otp == NULL || is_locked == NULL) {
130 *is_locked = checks_are_locked(otp,
true);
140 0, OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT,
false);
141 mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
149 if (otp == NULL || is_locked == NULL) {
153 *is_locked = checks_are_locked(otp,
false);
158 ptrdiff_t *reg_offset,
162 *reg_offset = OTP_CTRL_VENDOR_TEST_READ_LOCK_REG_OFFSET;
163 *index = OTP_CTRL_VENDOR_TEST_READ_LOCK_VENDOR_TEST_READ_LOCK_BIT;
166 *reg_offset = OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_REG_OFFSET;
167 *index = OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_CREATOR_SW_CFG_READ_LOCK_BIT;
170 *reg_offset = OTP_CTRL_OWNER_SW_CFG_READ_LOCK_REG_OFFSET;
171 *index = OTP_CTRL_OWNER_SW_CFG_READ_LOCK_OWNER_SW_CFG_READ_LOCK_BIT;
174 *reg_offset = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_REG_OFFSET;
176 OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_BIT;
179 *reg_offset = OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_REG_OFFSET;
181 OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_ROT_CREATOR_AUTH_STATE_READ_LOCK_BIT;
197 if (!sw_read_lock_reg_offset(partition, &offset, &index)) {
202 mmio_region_write32(otp->base_addr, offset, reg);
210 if (otp == NULL || is_locked == NULL) {
216 if (!sw_read_lock_reg_offset(partition, &offset, &index)) {
220 uint32_t reg = mmio_region_read32(otp->base_addr, offset);
227 if (otp == NULL ||
status == NULL) {
233 OTP_CTRL_STATUS_VENDOR_TEST_ERROR_BIT,
235 OTP_CTRL_STATUS_CREATOR_SW_CFG_ERROR_BIT,
237 OTP_CTRL_STATUS_OWNER_SW_CFG_ERROR_BIT,
239 OTP_CTRL_STATUS_ROT_CREATOR_AUTH_CODESIGN_ERROR_BIT,
241 OTP_CTRL_STATUS_ROT_CREATOR_AUTH_STATE_ERROR_BIT,
248 OTP_CTRL_STATUS_LIFE_CYCLE_ERROR_BIT,
254 OTP_CTRL_STATUS_SCRAMBLING_FSM_ERROR_BIT,
257 OTP_CTRL_STATUS_BUS_INTEG_ERROR_BIT,
263 uint32_t status_code =
264 mmio_region_read32(otp->base_addr, OTP_CTRL_STATUS_REG_OFFSET);
265 for (
int i = 0; i <
ARRAYSIZE(kIndices); ++i) {
281 .
mask = OTP_CTRL_ERR_CODE_0_ERR_CODE_0_MASK,
282 .index = OTP_CTRL_ERR_CODE_0_ERR_CODE_0_OFFSET,
286 OTP_CTRL_ERR_CODE_0_REG_OFFSET + i * (ptrdiff_t)
sizeof(uint32_t);
287 uint32_t error_code = mmio_region_read32(otp->base_addr, address);
291 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_NO_ERROR:
294 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ERROR:
297 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ECC_CORR_ERROR:
300 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ECC_UNCORR_ERROR:
303 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_WRITE_BLANK_ERROR:
306 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_ACCESS_ERROR:
309 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_CHECK_FAIL_ERROR:
312 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_FSM_STATE_ERROR:
367 .
start_addr = OTP_CTRL_PARAM_VENDOR_TEST_OFFSET,
368 .len = OTP_CTRL_PARAM_VENDOR_TEST_SIZE,
372 .is_lifecycle =
false},
374 .start_addr = OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET,
375 .len = OTP_CTRL_PARAM_CREATOR_SW_CFG_SIZE,
379 .is_lifecycle =
false},
381 .start_addr = OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET,
382 .len = OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE,
386 .is_lifecycle =
false},
388 .start_addr = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_OFFSET,
389 .len = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_SIZE,
393 .is_lifecycle =
false},
395 .start_addr = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_OFFSET,
396 .len = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_SIZE,
400 .is_lifecycle =
false},
402 .start_addr = OTP_CTRL_PARAM_HW_CFG0_OFFSET,
403 .len = OTP_CTRL_PARAM_HW_CFG0_SIZE,
405 .is_software =
false,
407 .is_lifecycle =
false},
409 .start_addr = OTP_CTRL_PARAM_HW_CFG1_OFFSET,
410 .len = OTP_CTRL_PARAM_HW_CFG1_SIZE,
412 .is_software =
false,
414 .is_lifecycle =
false},
416 .start_addr = OTP_CTRL_PARAM_SECRET0_OFFSET,
417 .len = OTP_CTRL_PARAM_SECRET0_SIZE,
419 .is_software =
false,
421 .is_lifecycle =
false},
423 .start_addr = OTP_CTRL_PARAM_SECRET1_OFFSET,
424 .len = OTP_CTRL_PARAM_SECRET1_SIZE,
426 .is_software =
false,
428 .is_lifecycle =
false},
430 .start_addr = OTP_CTRL_PARAM_SECRET2_OFFSET,
431 .len = OTP_CTRL_PARAM_SECRET2_SIZE,
433 .is_software =
false,
435 .is_lifecycle =
false},
437 .start_addr = OTP_CTRL_PARAM_LIFE_CYCLE_OFFSET,
438 .len = OTP_CTRL_PARAM_LIFE_CYCLE_SIZE,
440 .is_software =
false,
442 .is_lifecycle =
true},
447 uint32_t abs_address,
448 uint32_t *relative_address) {
449 *relative_address = 0;
451 if (partition >=
ARRAYSIZE(kPartitions)) {
455 if ((abs_address & kPartitions[partition].align_mask) != 0) {
459 if (abs_address < kPartitions[partition].start_addr) {
463 *relative_address = abs_address - kPartitions[partition].
start_addr;
464 if (*relative_address >= kPartitions[partition].len) {
465 *relative_address = 0;
475 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
479 if ((address & kPartitions[partition].align_mask) != 0) {
483 if (address >= kPartitions[partition].len) {
488 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
493 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
501 if (otp == NULL || value == NULL) {
505 *value = mmio_region_read32(otp->base_addr,
506 OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET);
512 if (otp == NULL || value == NULL) {
516 *value = mmio_region_read32(otp->base_addr,
517 OTP_CTRL_DIRECT_ACCESS_RDATA_1_REG_OFFSET);
519 *value |= mmio_region_read32(otp->base_addr,
520 OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET);
526 uint32_t address, uint32_t value) {
527 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
536 if (kPartitions[partition].align_mask != 0x3 ||
537 kPartitions[partition].is_lifecycle) {
541 if ((address & kPartitions[partition].align_mask) != 0) {
548 size_t digest_size = kPartitions[partition].
has_digest *
sizeof(uint64_t);
549 if (address >= kPartitions[partition].len - digest_size) {
554 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
557 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET,
562 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
570 uint32_t address, uint64_t value) {
571 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
577 if (kPartitions[partition].align_mask != 0x7) {
581 if ((address & kPartitions[partition].align_mask) != 0) {
587 size_t digest_size =
sizeof(uint64_t);
588 if (address >= kPartitions[partition].len - digest_size) {
593 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
596 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET,
598 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET,
603 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
612 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
617 if (!kPartitions[partition].has_digest) {
624 if (is_sw == (digest == 0)) {
628 uint32_t address = kPartitions[partition].
start_addr;
630 address += kPartitions[partition].
len -
sizeof(digest);
632 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
636 mmio_region_write32(otp->base_addr,
637 OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET,
638 digest & 0xffffffff);
639 mmio_region_write32(otp->base_addr,
640 OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET,
645 ? OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT
646 : OTP_CTRL_DIRECT_ACCESS_CMD_DIGEST_BIT;
648 mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
658 *reg0 = OTP_CTRL_VENDOR_TEST_DIGEST_0_REG_OFFSET;
659 *reg1 = OTP_CTRL_VENDOR_TEST_DIGEST_1_REG_OFFSET;
662 *reg0 = OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_REG_OFFSET;
663 *reg1 = OTP_CTRL_CREATOR_SW_CFG_DIGEST_1_REG_OFFSET;
666 *reg0 = OTP_CTRL_OWNER_SW_CFG_DIGEST_0_REG_OFFSET;
667 *reg1 = OTP_CTRL_OWNER_SW_CFG_DIGEST_1_REG_OFFSET;
670 *reg0 = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_REG_OFFSET;
671 *reg1 = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_1_REG_OFFSET;
674 *reg0 = OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0_REG_OFFSET;
675 *reg1 = OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_1_REG_OFFSET;
678 *reg0 = OTP_CTRL_HW_CFG0_DIGEST_0_REG_OFFSET;
679 *reg1 = OTP_CTRL_HW_CFG0_DIGEST_1_REG_OFFSET;
682 *reg0 = OTP_CTRL_HW_CFG1_DIGEST_0_REG_OFFSET;
683 *reg1 = OTP_CTRL_HW_CFG1_DIGEST_1_REG_OFFSET;
686 *reg0 = OTP_CTRL_SECRET0_DIGEST_0_REG_OFFSET;
687 *reg1 = OTP_CTRL_SECRET0_DIGEST_1_REG_OFFSET;
690 *reg0 = OTP_CTRL_SECRET1_DIGEST_0_REG_OFFSET;
691 *reg1 = OTP_CTRL_SECRET1_DIGEST_1_REG_OFFSET;
694 *reg0 = OTP_CTRL_SECRET2_DIGEST_0_REG_OFFSET;
695 *reg1 = OTP_CTRL_SECRET2_DIGEST_1_REG_OFFSET;
707 if (otp == NULL || is_computed == NULL) {
711 ptrdiff_t reg0, reg1;
712 if (!get_digest_regs(partition, ®0, ®1)) {
716 uint64_t value = mmio_region_read32(otp->base_addr, reg1);
718 value |= mmio_region_read32(otp->base_addr, reg0);
720 *is_computed = value != 0;
728 if (otp == NULL || digest == NULL) {
732 ptrdiff_t reg0, reg1;
733 if (!get_digest_regs(partition, ®0, ®1)) {
737 uint64_t value = mmio_region_read32(otp->base_addr, reg1);
739 value |= mmio_region_read32(otp->base_addr, reg0);
751 uint32_t address, uint32_t *buf,
753 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions) || buf == NULL) {
757 if (!kPartitions[partition].is_software) {
761 if ((address & kPartitions[partition].align_mask) != 0) {
765 if (address + len >= kPartitions[partition].len) {
769 uint32_t reg_offset = OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
772 len *
sizeof(uint32_t));