15 #include "otp_ctrl_regs.h"
26 static bool checks_are_locked(
const dif_otp_ctrl_t *otp,
bool check_config) {
27 ptrdiff_t reg_offset = check_config
28 ? OTP_CTRL_CHECK_REGWEN_REG_OFFSET
29 : OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET;
31 check_config ? OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT
32 : OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT;
33 uint32_t locked = mmio_region_read32(otp->
base_addr, reg_offset);
42 if (checks_are_locked(otp,
true)) {
46 mmio_region_write32(otp->
base_addr, OTP_CTRL_CHECK_TIMEOUT_REG_OFFSET,
49 OTP_CTRL_INTEGRITY_CHECK_PERIOD_REG_OFFSET,
52 OTP_CTRL_CONSISTENCY_CHECK_PERIOD_REG_OFFSET,
62 if (checks_are_locked(otp,
false)) {
68 mmio_region_write32(otp->
base_addr, OTP_CTRL_CHECK_TRIGGER_REG_OFFSET, reg);
77 if (checks_are_locked(otp,
false)) {
83 mmio_region_write32(otp->
base_addr, OTP_CTRL_CHECK_TRIGGER_REG_OFFSET, reg);
94 0, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT,
false);
95 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET,
103 if (otp == NULL || is_locked == NULL) {
107 uint32_t reg = mmio_region_read32(otp->
base_addr,
108 OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET);
110 reg, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT);
122 mmio_region_write32(otp->
base_addr, OTP_CTRL_CHECK_REGWEN_REG_OFFSET, reg);
129 if (otp == NULL || is_locked == NULL) {
133 *is_locked = checks_are_locked(otp,
true);
143 0, OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT,
false);
144 mmio_region_write32(otp->
base_addr, OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
152 if (otp == NULL || is_locked == NULL) {
156 *is_locked = checks_are_locked(otp,
false);
161 ptrdiff_t *reg_offset,
165 *reg_offset = OTP_CTRL_VENDOR_TEST_READ_LOCK_REG_OFFSET;
166 *index = OTP_CTRL_VENDOR_TEST_READ_LOCK_VENDOR_TEST_READ_LOCK_BIT;
169 *reg_offset = OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_REG_OFFSET;
170 *index = OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_CREATOR_SW_CFG_READ_LOCK_BIT;
173 *reg_offset = OTP_CTRL_OWNER_SW_CFG_READ_LOCK_REG_OFFSET;
174 *index = OTP_CTRL_OWNER_SW_CFG_READ_LOCK_OWNER_SW_CFG_READ_LOCK_BIT;
177 *reg_offset = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_REG_OFFSET;
179 OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_BIT;
182 *reg_offset = OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_REG_OFFSET;
184 OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_ROT_CREATOR_AUTH_STATE_READ_LOCK_BIT;
200 if (!sw_read_lock_reg_offset(partition, &offset, &index)) {
204 uint32_t busy = mmio_region_read32(otp->
base_addr,
205 OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET);
207 busy, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT)) {
212 mmio_region_write32(otp->
base_addr, offset, reg);
220 if (otp == NULL || is_locked == NULL) {
226 if (!sw_read_lock_reg_offset(partition, &offset, &index)) {
230 uint32_t reg = mmio_region_read32(otp->
base_addr, offset);
237 if (otp == NULL ||
status == NULL) {
243 OTP_CTRL_STATUS_VENDOR_TEST_ERROR_BIT,
245 OTP_CTRL_STATUS_CREATOR_SW_CFG_ERROR_BIT,
247 OTP_CTRL_STATUS_OWNER_SW_CFG_ERROR_BIT,
249 OTP_CTRL_STATUS_ROT_CREATOR_AUTH_CODESIGN_ERROR_BIT,
251 OTP_CTRL_STATUS_ROT_CREATOR_AUTH_STATE_ERROR_BIT,
258 OTP_CTRL_STATUS_LIFE_CYCLE_ERROR_BIT,
264 OTP_CTRL_STATUS_SCRAMBLING_FSM_ERROR_BIT,
267 OTP_CTRL_STATUS_BUS_INTEG_ERROR_BIT,
273 uint32_t status_code =
274 mmio_region_read32(otp->
base_addr, OTP_CTRL_STATUS_REG_OFFSET);
275 for (
int i = 0; i <
ARRAYSIZE(kIndices); ++i) {
291 .
mask = OTP_CTRL_ERR_CODE_0_ERR_CODE_0_MASK,
292 .index = OTP_CTRL_ERR_CODE_0_ERR_CODE_0_OFFSET,
296 OTP_CTRL_ERR_CODE_0_REG_OFFSET + i * (ptrdiff_t)
sizeof(uint32_t);
297 uint32_t error_code = mmio_region_read32(otp->
base_addr, address);
301 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_NO_ERROR:
304 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ERROR:
307 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ECC_CORR_ERROR:
310 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ECC_UNCORR_ERROR:
313 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_WRITE_BLANK_ERROR:
316 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_ACCESS_ERROR:
319 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_CHECK_FAIL_ERROR:
322 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_FSM_STATE_ERROR:
377 .
start_addr = OTP_CTRL_PARAM_VENDOR_TEST_OFFSET,
378 .len = OTP_CTRL_PARAM_VENDOR_TEST_SIZE,
382 .is_lifecycle =
false},
384 .start_addr = OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET,
385 .len = OTP_CTRL_PARAM_CREATOR_SW_CFG_SIZE,
389 .is_lifecycle =
false},
391 .start_addr = OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET,
392 .len = OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE,
396 .is_lifecycle =
false},
398 .start_addr = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_OFFSET,
399 .len = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_SIZE,
403 .is_lifecycle =
false},
405 .start_addr = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_OFFSET,
406 .len = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_SIZE,
410 .is_lifecycle =
false},
412 .start_addr = OTP_CTRL_PARAM_HW_CFG0_OFFSET,
413 .len = OTP_CTRL_PARAM_HW_CFG0_SIZE,
415 .is_software =
false,
417 .is_lifecycle =
false},
419 .start_addr = OTP_CTRL_PARAM_HW_CFG1_OFFSET,
420 .len = OTP_CTRL_PARAM_HW_CFG1_SIZE,
422 .is_software =
false,
424 .is_lifecycle =
false},
426 .start_addr = OTP_CTRL_PARAM_SECRET0_OFFSET,
427 .len = OTP_CTRL_PARAM_SECRET0_SIZE,
429 .is_software =
false,
431 .is_lifecycle =
false},
433 .start_addr = OTP_CTRL_PARAM_SECRET1_OFFSET,
434 .len = OTP_CTRL_PARAM_SECRET1_SIZE,
436 .is_software =
false,
438 .is_lifecycle =
false},
440 .start_addr = OTP_CTRL_PARAM_SECRET2_OFFSET,
441 .len = OTP_CTRL_PARAM_SECRET2_SIZE,
443 .is_software =
false,
445 .is_lifecycle =
false},
447 .start_addr = OTP_CTRL_PARAM_LIFE_CYCLE_OFFSET,
448 .len = OTP_CTRL_PARAM_LIFE_CYCLE_SIZE,
450 .is_software =
false,
452 .is_lifecycle =
true},
457 uint32_t abs_address,
458 uint32_t *relative_address) {
459 *relative_address = 0;
461 if (partition >=
ARRAYSIZE(kPartitions)) {
465 if ((abs_address & kPartitions[partition].align_mask) != 0) {
469 if (abs_address < kPartitions[partition].start_addr) {
473 *relative_address = abs_address - kPartitions[partition].
start_addr;
474 if (*relative_address >= kPartitions[partition].len) {
475 *relative_address = 0;
485 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
489 if ((address & kPartitions[partition].align_mask) != 0) {
493 if (address >= kPartitions[partition].len) {
497 uint32_t busy = mmio_region_read32(otp->
base_addr,
498 OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET);
500 busy, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT)) {
505 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
510 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
518 if (otp == NULL || value == NULL) {
522 uint32_t busy = mmio_region_read32(otp->
base_addr,
523 OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET);
525 busy, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT)) {
529 *value = mmio_region_read32(otp->
base_addr,
530 OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET);
536 if (otp == NULL || value == NULL) {
540 uint32_t busy = mmio_region_read32(otp->
base_addr,
541 OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET);
543 busy, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT)) {
547 *value = mmio_region_read32(otp->
base_addr,
548 OTP_CTRL_DIRECT_ACCESS_RDATA_1_REG_OFFSET);
550 *value |= mmio_region_read32(otp->
base_addr,
551 OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET);
557 uint32_t address, uint32_t value) {
558 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
567 if (kPartitions[partition].align_mask != 0x3 ||
568 kPartitions[partition].is_lifecycle) {
572 if ((address & kPartitions[partition].align_mask) != 0) {
579 size_t digest_size = kPartitions[partition].
has_digest *
sizeof(uint64_t);
580 if (address >= kPartitions[partition].len - digest_size) {
584 uint32_t busy = mmio_region_read32(otp->
base_addr,
585 OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET);
587 busy, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT)) {
592 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
595 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET,
600 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
608 uint32_t address, uint64_t value) {
609 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
615 if (kPartitions[partition].align_mask != 0x7) {
619 if ((address & kPartitions[partition].align_mask) != 0) {
625 size_t digest_size =
sizeof(uint64_t);
626 if (address >= kPartitions[partition].len - digest_size) {
630 uint32_t busy = mmio_region_read32(otp->
base_addr,
631 OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET);
633 busy, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT)) {
638 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
641 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET,
643 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET,
648 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
657 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
662 if (!kPartitions[partition].has_digest) {
669 if (is_sw == (digest == 0)) {
673 uint32_t busy = mmio_region_read32(otp->
base_addr,
674 OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET);
676 busy, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT)) {
680 uint32_t address = kPartitions[partition].
start_addr;
682 address += kPartitions[partition].
len -
sizeof(digest);
684 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
689 OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET,
690 digest & 0xffffffff);
692 OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET,
697 ? OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT
698 : OTP_CTRL_DIRECT_ACCESS_CMD_DIGEST_BIT;
700 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
710 *reg0 = OTP_CTRL_VENDOR_TEST_DIGEST_0_REG_OFFSET;
711 *reg1 = OTP_CTRL_VENDOR_TEST_DIGEST_1_REG_OFFSET;
714 *reg0 = OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_REG_OFFSET;
715 *reg1 = OTP_CTRL_CREATOR_SW_CFG_DIGEST_1_REG_OFFSET;
718 *reg0 = OTP_CTRL_OWNER_SW_CFG_DIGEST_0_REG_OFFSET;
719 *reg1 = OTP_CTRL_OWNER_SW_CFG_DIGEST_1_REG_OFFSET;
722 *reg0 = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_REG_OFFSET;
723 *reg1 = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_1_REG_OFFSET;
726 *reg0 = OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0_REG_OFFSET;
727 *reg1 = OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_1_REG_OFFSET;
730 *reg0 = OTP_CTRL_HW_CFG0_DIGEST_0_REG_OFFSET;
731 *reg1 = OTP_CTRL_HW_CFG0_DIGEST_1_REG_OFFSET;
734 *reg0 = OTP_CTRL_HW_CFG1_DIGEST_0_REG_OFFSET;
735 *reg1 = OTP_CTRL_HW_CFG1_DIGEST_1_REG_OFFSET;
738 *reg0 = OTP_CTRL_SECRET0_DIGEST_0_REG_OFFSET;
739 *reg1 = OTP_CTRL_SECRET0_DIGEST_1_REG_OFFSET;
742 *reg0 = OTP_CTRL_SECRET1_DIGEST_0_REG_OFFSET;
743 *reg1 = OTP_CTRL_SECRET1_DIGEST_1_REG_OFFSET;
746 *reg0 = OTP_CTRL_SECRET2_DIGEST_0_REG_OFFSET;
747 *reg1 = OTP_CTRL_SECRET2_DIGEST_1_REG_OFFSET;
759 if (otp == NULL || is_computed == NULL) {
763 ptrdiff_t reg0, reg1;
764 if (!get_digest_regs(partition, ®0, ®1)) {
768 uint64_t value = mmio_region_read32(otp->
base_addr, reg1);
770 value |= mmio_region_read32(otp->
base_addr, reg0);
772 *is_computed = value != 0;
780 if (otp == NULL || digest == NULL) {
784 ptrdiff_t reg0, reg1;
785 if (!get_digest_regs(partition, ®0, ®1)) {
789 uint64_t value = mmio_region_read32(otp->
base_addr, reg1);
791 value |= mmio_region_read32(otp->
base_addr, reg0);
803 uint32_t address, uint32_t *buf,
805 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions) || buf == NULL) {
809 if (!kPartitions[partition].is_software) {
813 if ((address & kPartitions[partition].align_mask) != 0) {
817 if (address + len >= kPartitions[partition].len) {
821 uint32_t reg_offset = OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
824 len *
sizeof(uint32_t));