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)) {
205 mmio_region_write32(otp->
base_addr, offset, reg);
213 if (otp == NULL || is_locked == NULL) {
219 if (!sw_read_lock_reg_offset(partition, &offset, &index)) {
223 uint32_t reg = mmio_region_read32(otp->
base_addr, offset);
230 if (otp == NULL ||
status == NULL) {
236 OTP_CTRL_STATUS_VENDOR_TEST_ERROR_BIT,
238 OTP_CTRL_STATUS_CREATOR_SW_CFG_ERROR_BIT,
240 OTP_CTRL_STATUS_OWNER_SW_CFG_ERROR_BIT,
242 OTP_CTRL_STATUS_ROT_CREATOR_AUTH_CODESIGN_ERROR_BIT,
244 OTP_CTRL_STATUS_ROT_CREATOR_AUTH_STATE_ERROR_BIT,
251 OTP_CTRL_STATUS_LIFE_CYCLE_ERROR_BIT,
257 OTP_CTRL_STATUS_SCRAMBLING_FSM_ERROR_BIT,
260 OTP_CTRL_STATUS_BUS_INTEG_ERROR_BIT,
266 uint32_t status_code =
267 mmio_region_read32(otp->
base_addr, OTP_CTRL_STATUS_REG_OFFSET);
268 for (
int i = 0; i <
ARRAYSIZE(kIndices); ++i) {
284 .
mask = OTP_CTRL_ERR_CODE_0_ERR_CODE_0_MASK,
285 .index = OTP_CTRL_ERR_CODE_0_ERR_CODE_0_OFFSET,
289 OTP_CTRL_ERR_CODE_0_REG_OFFSET + i * (ptrdiff_t)
sizeof(uint32_t);
290 uint32_t error_code = mmio_region_read32(otp->
base_addr, address);
294 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_NO_ERROR:
297 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ERROR:
300 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ECC_CORR_ERROR:
303 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ECC_UNCORR_ERROR:
306 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_WRITE_BLANK_ERROR:
309 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_ACCESS_ERROR:
312 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_CHECK_FAIL_ERROR:
315 case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_FSM_STATE_ERROR:
370 .
start_addr = OTP_CTRL_PARAM_VENDOR_TEST_OFFSET,
371 .len = OTP_CTRL_PARAM_VENDOR_TEST_SIZE,
375 .is_lifecycle =
false},
377 .start_addr = OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET,
378 .len = OTP_CTRL_PARAM_CREATOR_SW_CFG_SIZE,
382 .is_lifecycle =
false},
384 .start_addr = OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET,
385 .len = OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE,
389 .is_lifecycle =
false},
391 .start_addr = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_OFFSET,
392 .len = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_SIZE,
396 .is_lifecycle =
false},
398 .start_addr = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_OFFSET,
399 .len = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_SIZE,
403 .is_lifecycle =
false},
405 .start_addr = OTP_CTRL_PARAM_HW_CFG0_OFFSET,
406 .len = OTP_CTRL_PARAM_HW_CFG0_SIZE,
408 .is_software =
false,
410 .is_lifecycle =
false},
412 .start_addr = OTP_CTRL_PARAM_HW_CFG1_OFFSET,
413 .len = OTP_CTRL_PARAM_HW_CFG1_SIZE,
415 .is_software =
false,
417 .is_lifecycle =
false},
419 .start_addr = OTP_CTRL_PARAM_SECRET0_OFFSET,
420 .len = OTP_CTRL_PARAM_SECRET0_SIZE,
422 .is_software =
false,
424 .is_lifecycle =
false},
426 .start_addr = OTP_CTRL_PARAM_SECRET1_OFFSET,
427 .len = OTP_CTRL_PARAM_SECRET1_SIZE,
429 .is_software =
false,
431 .is_lifecycle =
false},
433 .start_addr = OTP_CTRL_PARAM_SECRET2_OFFSET,
434 .len = OTP_CTRL_PARAM_SECRET2_SIZE,
436 .is_software =
false,
438 .is_lifecycle =
false},
440 .start_addr = OTP_CTRL_PARAM_LIFE_CYCLE_OFFSET,
441 .len = OTP_CTRL_PARAM_LIFE_CYCLE_SIZE,
443 .is_software =
false,
445 .is_lifecycle =
true},
450 uint32_t abs_address,
451 uint32_t *relative_address) {
452 *relative_address = 0;
454 if (partition >=
ARRAYSIZE(kPartitions)) {
458 if ((abs_address & kPartitions[partition].align_mask) != 0) {
462 if (abs_address < kPartitions[partition].start_addr) {
466 *relative_address = abs_address - kPartitions[partition].
start_addr;
467 if (*relative_address >= kPartitions[partition].len) {
468 *relative_address = 0;
478 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
482 if ((address & kPartitions[partition].align_mask) != 0) {
486 if (address >= kPartitions[partition].len) {
491 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
496 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
504 if (otp == NULL || value == NULL) {
508 *value = mmio_region_read32(otp->
base_addr,
509 OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET);
515 if (otp == NULL || value == NULL) {
519 *value = mmio_region_read32(otp->
base_addr,
520 OTP_CTRL_DIRECT_ACCESS_RDATA_1_REG_OFFSET);
522 *value |= mmio_region_read32(otp->
base_addr,
523 OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET);
529 uint32_t address, uint32_t value) {
530 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
539 if (kPartitions[partition].align_mask != 0x3 ||
540 kPartitions[partition].is_lifecycle) {
544 if ((address & kPartitions[partition].align_mask) != 0) {
551 size_t digest_size = kPartitions[partition].
has_digest *
sizeof(uint64_t);
552 if (address >= kPartitions[partition].len - digest_size) {
557 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
560 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET,
565 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
573 uint32_t address, uint64_t value) {
574 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
580 if (kPartitions[partition].align_mask != 0x7) {
584 if ((address & kPartitions[partition].align_mask) != 0) {
590 size_t digest_size =
sizeof(uint64_t);
591 if (address >= kPartitions[partition].len - digest_size) {
596 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
599 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET,
601 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET,
606 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
615 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions)) {
620 if (!kPartitions[partition].has_digest) {
627 if (is_sw == (digest == 0)) {
631 uint32_t address = kPartitions[partition].
start_addr;
633 address += kPartitions[partition].
len -
sizeof(digest);
635 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET,
640 OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET,
641 digest & 0xffffffff);
643 OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET,
648 ? OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT
649 : OTP_CTRL_DIRECT_ACCESS_CMD_DIGEST_BIT;
651 mmio_region_write32(otp->
base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET,
661 *reg0 = OTP_CTRL_VENDOR_TEST_DIGEST_0_REG_OFFSET;
662 *reg1 = OTP_CTRL_VENDOR_TEST_DIGEST_1_REG_OFFSET;
665 *reg0 = OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_REG_OFFSET;
666 *reg1 = OTP_CTRL_CREATOR_SW_CFG_DIGEST_1_REG_OFFSET;
669 *reg0 = OTP_CTRL_OWNER_SW_CFG_DIGEST_0_REG_OFFSET;
670 *reg1 = OTP_CTRL_OWNER_SW_CFG_DIGEST_1_REG_OFFSET;
673 *reg0 = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_REG_OFFSET;
674 *reg1 = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_1_REG_OFFSET;
677 *reg0 = OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0_REG_OFFSET;
678 *reg1 = OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_1_REG_OFFSET;
681 *reg0 = OTP_CTRL_HW_CFG0_DIGEST_0_REG_OFFSET;
682 *reg1 = OTP_CTRL_HW_CFG0_DIGEST_1_REG_OFFSET;
685 *reg0 = OTP_CTRL_HW_CFG1_DIGEST_0_REG_OFFSET;
686 *reg1 = OTP_CTRL_HW_CFG1_DIGEST_1_REG_OFFSET;
689 *reg0 = OTP_CTRL_SECRET0_DIGEST_0_REG_OFFSET;
690 *reg1 = OTP_CTRL_SECRET0_DIGEST_1_REG_OFFSET;
693 *reg0 = OTP_CTRL_SECRET1_DIGEST_0_REG_OFFSET;
694 *reg1 = OTP_CTRL_SECRET1_DIGEST_1_REG_OFFSET;
697 *reg0 = OTP_CTRL_SECRET2_DIGEST_0_REG_OFFSET;
698 *reg1 = OTP_CTRL_SECRET2_DIGEST_1_REG_OFFSET;
710 if (otp == NULL || is_computed == NULL) {
714 ptrdiff_t reg0, reg1;
715 if (!get_digest_regs(partition, ®0, ®1)) {
719 uint64_t value = mmio_region_read32(otp->
base_addr, reg1);
721 value |= mmio_region_read32(otp->
base_addr, reg0);
723 *is_computed = value != 0;
731 if (otp == NULL || digest == NULL) {
735 ptrdiff_t reg0, reg1;
736 if (!get_digest_regs(partition, ®0, ®1)) {
740 uint64_t value = mmio_region_read32(otp->
base_addr, reg1);
742 value |= mmio_region_read32(otp->
base_addr, reg0);
754 uint32_t address, uint32_t *buf,
756 if (otp == NULL || partition >=
ARRAYSIZE(kPartitions) || buf == NULL) {
760 if (!kPartitions[partition].is_software) {
764 if ((address & kPartitions[partition].align_mask) != 0) {
768 if (address + len >= kPartitions[partition].len) {
772 uint32_t reg_offset = OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
775 len *
sizeof(uint32_t));