[otp_ctrl/dif] Fix up lock reg handling
Update for regwen change from rw1c to rw0c. Also, use the check trigger
lock for check triggers and the check lock for check configuration.
Signed-off-by: Alexander Williams <awill@google.com>
diff --git a/sw/device/lib/dif/dif_otp_ctrl.c b/sw/device/lib/dif/dif_otp_ctrl.c
index 7ef720b..a79b7d6 100644
--- a/sw/device/lib/dif/dif_otp_ctrl.c
+++ b/sw/device/lib/dif/dif_otp_ctrl.c
@@ -17,11 +17,19 @@
*
* This is a convenience function to avoid superfluous error-checking in all the
* functions that can be locked out by this register.
+ *
+ * @param check_config True to check the config regwen. False to check the
+ * trigger regwen.
*/
-static bool checks_are_locked(const dif_otp_ctrl_t *otp) {
- uint32_t locked =
- mmio_region_read32(otp->base_addr, OTP_CTRL_CHECK_REGWEN_REG_OFFSET);
- return !bitfield_bit32_read(locked, OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT);
+static bool checks_are_locked(const dif_otp_ctrl_t *otp, bool check_config) {
+ uintptr_t reg_offset = check_config
+ ? OTP_CTRL_CHECK_REGWEN_REG_OFFSET
+ : OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET;
+ size_t regwen_bit =
+ check_config ? OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT
+ : OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT;
+ uint32_t locked = mmio_region_read32(otp->base_addr, reg_offset);
+ return !bitfield_bit32_read(locked, regwen_bit);
}
dif_result_t dif_otp_ctrl_configure(const dif_otp_ctrl_t *otp,
@@ -29,7 +37,7 @@
if (otp == NULL) {
return kDifBadArg;
}
- if (checks_are_locked(otp)) {
+ if (checks_are_locked(otp, /*check_config=*/true)) {
return kDifLocked;
}
@@ -49,7 +57,7 @@
if (otp == NULL) {
return kDifBadArg;
}
- if (checks_are_locked(otp)) {
+ if (checks_are_locked(otp, /*check_config=*/false)) {
return kDifLocked;
}
@@ -64,7 +72,7 @@
if (otp == NULL) {
return kDifBadArg;
}
- if (checks_are_locked(otp)) {
+ if (checks_are_locked(otp, /*check_config=*/false)) {
return kDifLocked;
}
@@ -81,7 +89,7 @@
}
uint32_t reg =
- bitfield_bit32_write(0, OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, true);
+ bitfield_bit32_write(0, OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, false);
mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_REGWEN_REG_OFFSET, reg);
return kDifOk;
@@ -93,7 +101,30 @@
return kDifBadArg;
}
- *is_locked = checks_are_locked(otp);
+ *is_locked = checks_are_locked(otp, /*check_config=*/true);
+ return kDifOk;
+}
+
+dif_result_t dif_otp_ctrl_lock_check_trigger(const dif_otp_ctrl_t *otp) {
+ if (otp == NULL) {
+ return kDifBadArg;
+ }
+
+ uint32_t reg = bitfield_bit32_write(
+ 0, OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, false);
+ mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
+ reg);
+
+ return kDifOk;
+}
+
+dif_result_t dif_otp_ctrl_check_trigger_is_locked(const dif_otp_ctrl_t *otp,
+ bool *is_locked) {
+ if (otp == NULL || is_locked == NULL) {
+ return kDifBadArg;
+ }
+
+ *is_locked = checks_are_locked(otp, /*check_config=*/false);
return kDifOk;
}
@@ -131,7 +162,14 @@
return kDifBadArg;
}
- uint32_t reg = bitfield_bit32_write(0, index, true);
+ uint32_t busy = mmio_region_read32(otp->base_addr,
+ OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET);
+ if (!bitfield_bit32_read(
+ busy, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT)) {
+ return kDifUnavailable;
+ }
+
+ uint32_t reg = bitfield_bit32_write(0, index, false);
mmio_region_write32(otp->base_addr, offset, reg);
return kDifOk;
diff --git a/sw/device/lib/dif/dif_otp_ctrl.h b/sw/device/lib/dif/dif_otp_ctrl.h
index 52edc19..ae7ca7f 100644
--- a/sw/device/lib/dif/dif_otp_ctrl.h
+++ b/sw/device/lib/dif/dif_otp_ctrl.h
@@ -329,8 +329,7 @@
dif_result_t dif_otp_ctrl_check_consistency(const dif_otp_ctrl_t *otp);
/**
- * Locks out `dif_otp_ctrl_configure()` and the
- * `dif_otp_ctrl_check_*()` functions.
+ * Locks out `dif_otp_ctrl_configure()` function.
*
* This function is reentrant: calling it while functionality is locked will
* have no effect and return `kDifOtpCtrlOk`.
@@ -342,8 +341,7 @@
dif_result_t dif_otp_ctrl_lock_config(const dif_otp_ctrl_t *otp);
/**
- * Checks whether `dif_otp_ctrl_configure()` and the `dif_otp_ctrl_check_*()`
- * functions are locked-out.
+ * Checks whether `dif_otp_ctrl_configure()` function is locked-out.
*
* @param otp An OTP handle.
* @param[out] is_locked Out-param for the locked state.
@@ -354,6 +352,29 @@
bool *is_locked);
/**
+ * Locks out `dif_otp_ctrl_check_*()` functions.
+ *
+ * This function is reentrant: calling it while functionality is locked will
+ * have no effect and return `kDifOtpCtrlOk`.
+ *
+ * @param otp An OTP handle.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_otp_ctrl_lock_check_trigger(const dif_otp_ctrl_t *otp);
+
+/**
+ * Checks whether the `dif_otp_ctrl_check_*()` functions are locked-out.
+ *
+ * @param otp An OTP handle.
+ * @param[out] is_locked Out-param for the locked state.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_otp_ctrl_check_trigger_is_locked(const dif_otp_ctrl_t *otp,
+ bool *is_locked);
+
+/**
* Locks out reads to a SW partition.
*
* This function should only be called on SW partitions; doing otherwise will
diff --git a/sw/device/lib/dif/dif_otp_ctrl_unittest.cc b/sw/device/lib/dif/dif_otp_ctrl_unittest.cc
index 8d72262..7643ea9 100644
--- a/sw/device/lib/dif/dif_otp_ctrl_unittest.cc
+++ b/sw/device/lib/dif/dif_otp_ctrl_unittest.cc
@@ -72,7 +72,7 @@
TEST_F(ConfigTest, LockConfig) {
EXPECT_WRITE32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET,
- {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, true}});
+ {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, false}});
EXPECT_DIF_OK(dif_otp_ctrl_lock_config(&otp_));
}
@@ -89,8 +89,9 @@
class CheckTest : public OtpTest {};
TEST_F(CheckTest, Integrity) {
- EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET,
- {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, true}});
+ EXPECT_READ32(
+ OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
+ {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, true}});
EXPECT_WRITE32(OTP_CTRL_CHECK_TRIGGER_REG_OFFSET,
{{OTP_CTRL_CHECK_TRIGGER_INTEGRITY_BIT, true}});
@@ -98,21 +99,31 @@
}
TEST_F(CheckTest, Consistency) {
- EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET,
- {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, true}});
+ EXPECT_READ32(
+ OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
+ {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, true}});
EXPECT_WRITE32(OTP_CTRL_CHECK_TRIGGER_REG_OFFSET,
{{OTP_CTRL_CHECK_TRIGGER_CONSISTENCY_BIT, true}});
EXPECT_DIF_OK(dif_otp_ctrl_check_consistency(&otp_));
}
+TEST_F(CheckTest, LockTrigger) {
+ EXPECT_WRITE32(
+ OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
+ {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, false}});
+ EXPECT_DIF_OK(dif_otp_ctrl_lock_check_trigger(&otp_));
+}
+
TEST_F(CheckTest, Locked) {
- EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET,
- {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, false}});
+ EXPECT_READ32(
+ OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
+ {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, false}});
EXPECT_EQ(dif_otp_ctrl_check_integrity(&otp_), kDifLocked);
- EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET,
- {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, false}});
+ EXPECT_READ32(
+ OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET,
+ {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, false}});
EXPECT_EQ(dif_otp_ctrl_check_consistency(&otp_), kDifLocked);
}
@@ -158,21 +169,25 @@
}
TEST_F(ReadLockTest, Lock) {
+ EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET, 1);
EXPECT_WRITE32(
OTP_CTRL_VENDOR_TEST_READ_LOCK_REG_OFFSET,
- {{OTP_CTRL_VENDOR_TEST_READ_LOCK_VENDOR_TEST_READ_LOCK_BIT, true}});
+ {{OTP_CTRL_VENDOR_TEST_READ_LOCK_VENDOR_TEST_READ_LOCK_BIT, false}});
EXPECT_DIF_OK(
dif_otp_ctrl_lock_reading(&otp_, kDifOtpCtrlPartitionVendorTest));
+ EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET, 1);
EXPECT_WRITE32(
OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_REG_OFFSET,
- {{OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_CREATOR_SW_CFG_READ_LOCK_BIT, true}});
+ {{OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_CREATOR_SW_CFG_READ_LOCK_BIT,
+ false}});
EXPECT_DIF_OK(
dif_otp_ctrl_lock_reading(&otp_, kDifOtpCtrlPartitionCreatorSwCfg));
+ EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET, 1);
EXPECT_WRITE32(
OTP_CTRL_OWNER_SW_CFG_READ_LOCK_REG_OFFSET,
- {{OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_CREATOR_SW_CFG_READ_LOCK_BIT, true}});
+ {{OTP_CTRL_OWNER_SW_CFG_READ_LOCK_OWNER_SW_CFG_READ_LOCK_BIT, false}});
EXPECT_DIF_OK(
dif_otp_ctrl_lock_reading(&otp_, kDifOtpCtrlPartitionOwnerSwCfg));
}