Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions hw/ip_templates/otp_ctrl/util/dt.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class OtpCtrlExt(Extension):

OTP_PARTITION_INFO_STRUCT_START_ADDR_FIELD_NAME = Name(["start", "addr"])
OTP_PARTITION_INFO_STRUCT_SIZE_FIELD_NAME = Name(["size"])
OTP_PARTITION_INFO_STRUCT_DIGEST_ADDR_FIELD_NAME = Name(["digest", "addr"])
OTP_PARTITION_INFO_STRUCT_DIGEST_ADDR_FIELD_NAME = Name(["digest", "reg", "offset"])
OTP_PARTITION_INFO_STRUCT_ALIGN_MASK_FIELD_NAME = Name(["align", "mask"])
OTP_PARTITION_INFO_STRUCT_NAME = Name.from_snake_case("dt_otp_partition_info")

Expand Down Expand Up @@ -82,7 +82,8 @@ def __init__(self, ip_helper: IpHelper):
self._otp_partition_info_struct.add_field(
name = self.OTP_PARTITION_INFO_STRUCT_DIGEST_ADDR_FIELD_NAME,
field_type = ScalarType("uint32_t"),
docstring = "The absolute OTP address at which this partition's digest starts",
docstring = "The OTP digest CSR (where the digest is buffered) offset for " +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the new wording here suggests that the digest occupies one CSR but in actuality an OTP digest is 8 bytes and falls across 2 CSRs. Maybe this should just be "digest_offset" as a name and the wording should be more like "The OTP address (offset from this partition) at which this partition's digest starts."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not an otp_ctrl expert but I think your phrasing is incorrect because this value is set to the offset of a CSR, e.g. https://opentitan.org/book/hw/top_earlgrey/ip_autogen/otp_ctrl/doc/registers.html#hw_cfg0_digest (you can see the content here).
The idea of using the word "register" is to make it clear that this is the offset of a CSR and not the offset within the OTP partition.

Maybe I could change the wording to "The first (_DIGEST_0) OTP digest CSR" ?

Copy link
Contributor

@AlexJones0 AlexJones0 Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I misunderstood this as the DAI digest offset rather than the buffered CSR digest (I forgot there was that duplication there and thought that the change was just absolute -> relative address completely 😅) I agree with your new wording.

"this partition.",
)
self._otp_partition_info_struct.add_field(
name = self.OTP_PARTITION_INFO_STRUCT_ALIGN_MASK_FIELD_NAME,
Expand Down
5 changes: 3 additions & 2 deletions hw/top_darjeeling/ip_autogen/otp_ctrl/util/dt.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class OtpCtrlExt(Extension):

OTP_PARTITION_INFO_STRUCT_START_ADDR_FIELD_NAME = Name(["start", "addr"])
OTP_PARTITION_INFO_STRUCT_SIZE_FIELD_NAME = Name(["size"])
OTP_PARTITION_INFO_STRUCT_DIGEST_ADDR_FIELD_NAME = Name(["digest", "addr"])
OTP_PARTITION_INFO_STRUCT_DIGEST_ADDR_FIELD_NAME = Name(["digest", "reg", "offset"])
OTP_PARTITION_INFO_STRUCT_ALIGN_MASK_FIELD_NAME = Name(["align", "mask"])
OTP_PARTITION_INFO_STRUCT_NAME = Name.from_snake_case("dt_otp_partition_info")

Expand Down Expand Up @@ -82,7 +82,8 @@ def __init__(self, ip_helper: IpHelper):
self._otp_partition_info_struct.add_field(
name = self.OTP_PARTITION_INFO_STRUCT_DIGEST_ADDR_FIELD_NAME,
field_type = ScalarType("uint32_t"),
docstring = "The absolute OTP address at which this partition's digest starts",
docstring = "The OTP digest CSR (where the digest is buffered) offset for " +
"this partition.",
)
self._otp_partition_info_struct.add_field(
name = self.OTP_PARTITION_INFO_STRUCT_ALIGN_MASK_FIELD_NAME,
Expand Down
5 changes: 3 additions & 2 deletions hw/top_earlgrey/ip_autogen/otp_ctrl/util/dt.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class OtpCtrlExt(Extension):

OTP_PARTITION_INFO_STRUCT_START_ADDR_FIELD_NAME = Name(["start", "addr"])
OTP_PARTITION_INFO_STRUCT_SIZE_FIELD_NAME = Name(["size"])
OTP_PARTITION_INFO_STRUCT_DIGEST_ADDR_FIELD_NAME = Name(["digest", "addr"])
OTP_PARTITION_INFO_STRUCT_DIGEST_ADDR_FIELD_NAME = Name(["digest", "reg", "offset"])
OTP_PARTITION_INFO_STRUCT_ALIGN_MASK_FIELD_NAME = Name(["align", "mask"])
OTP_PARTITION_INFO_STRUCT_NAME = Name.from_snake_case("dt_otp_partition_info")

Expand Down Expand Up @@ -82,7 +82,8 @@ def __init__(self, ip_helper: IpHelper):
self._otp_partition_info_struct.add_field(
name = self.OTP_PARTITION_INFO_STRUCT_DIGEST_ADDR_FIELD_NAME,
field_type = ScalarType("uint32_t"),
docstring = "The absolute OTP address at which this partition's digest starts",
docstring = "The OTP digest CSR (where the digest is buffered) offset for " +
"this partition.",
)
self._otp_partition_info_struct.add_field(
name = self.OTP_PARTITION_INFO_STRUCT_ALIGN_MASK_FIELD_NAME,
Expand Down
3 changes: 2 additions & 1 deletion sw/device/silicon_creator/lib/drivers/otp.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ dt_otp_partition_info_t otp_readable_partition_info(otp_partition_t partition) {

uint64_t otp_partition_digest_read(otp_partition_t partition) {
uint32_t reg_offset =
otp_ctrl_base() + otp_readable_partition_info(partition).digest_addr;
otp_ctrl_base() +
otp_readable_partition_info(partition).digest_reg_offset;
uint64_t value = sec_mmio_read32(reg_offset + sizeof(uint32_t));
value <<= 32;
value |= sec_mmio_read32(reg_offset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ bool test_main(void) {
// - the digest of the CreatorSwCfg partition,
// - the digest of the OwnerSwCfg partition,
// - the SHA256 integrity hash of the first stage boot keys.
otp_dai_read(
kOtpPartitionCreatorSwCfg,
/*relative_address=*/
otp_readable_partition_info(kOtpPartitionCreatorSwCfg).digest_addr -
OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET,
otp_state,
/*num_words=*/2);
otp_dai_read(kOtpPartitionCreatorSwCfg,
/*relative_address=*/
otp_readable_partition_info(kOtpPartitionCreatorSwCfg)
.digest_reg_offset -
OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET,
otp_state,
/*num_words=*/2);
otp_dai_read(
kOtpPartitionOwnerSwCfg,
/*relative_address=*/
otp_readable_partition_info(kOtpPartitionOwnerSwCfg).digest_addr -
otp_readable_partition_info(kOtpPartitionOwnerSwCfg).digest_reg_offset -
OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET,
&otp_state[2],
/*num_words=*/2);
Expand Down
Loading