[util/design] Ensure digests are always placed at the end of a partition
This change makes sure that digests are always placed at the end of a
partition. The RTL invalid default vector is adjusted such that
unallocated space within a partition is accounted for.
This commit also removes the HW_CFG_CONTENT item since it is not needed
anymore.
Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_mmap.hjson b/hw/ip/otp_ctrl/data/otp_ctrl_mmap.hjson
index ed13db6..9bcf4b5 100644
--- a/hw/ip/otp_ctrl/data/otp_ctrl_mmap.hjson
+++ b/hw/ip/otp_ctrl/data/otp_ctrl_mmap.hjson
@@ -126,7 +126,7 @@
{
name: "HW_CFG",
variant: "Buffered",
- size: "208", // in bytes
+ size: "240", // in bytes
secret: "False",
sw_digest: "False",
hw_digest: "True",
@@ -143,10 +143,6 @@
// a value of '0 will be used.
inv_default: "<random>",
}
- {
- name: "HW_CFG_CONTENT",
- size: "168"
- }
],
desc: '''Hardware configuration bits used to hardwire
specific hardware functionality. E.g., raw entropy
@@ -217,7 +213,7 @@
{
name: "SECRET2",
variant: "Buffered",
- size: "120", // in bytes
+ size: "88", // in bytes
secret: "True",
sw_digest: "False",
hw_digest: "True",
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv.tpl b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv.tpl
index b36fd40..7720220 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv.tpl
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv.tpl
@@ -159,13 +159,16 @@
} otp_${part["name"].lower()}_t;
% endif
% endfor
-
+<% offset = int(otp_mmap.config["otp"]["depth"]) * int(otp_mmap.config["otp"]["width"]) %>
// OTP invalid partition default for buffered partitions.
parameter logic [${int(otp_mmap.config["otp"]["depth"])*int(otp_mmap.config["otp"]["width"])*8-1}:0] PartInvDefault = ${int(otp_mmap.config["otp"]["depth"])*int(otp_mmap.config["otp"]["width"])*8}'({
% for k, part in enumerate(otp_mmap.config["partitions"][::-1]):
${int(part["size"])*8}'({
% for item in part["items"][::-1]:
- ${"{}'h{:0X}".format(item["size"] * 8, item["inv_default"])}${("\n })," if k < len(otp_mmap.config["partitions"])-1 else "\n })});") if loop.last else ","}
+ % if offset != item['offset'] + item['size']:
+ ${"{}'h{:0X}".format((offset - item['size'] - item['offset']) * 8, 0)}, // unallocated space <% offset = item['offset'] + item['size'] %>
+ % endif
+ ${"{}'h{:0X}".format(item["size"] * 8, item["inv_default"])}${("\n })," if k < len(otp_mmap.config["partitions"])-1 else "\n })});") if loop.last else ","}<% offset -= item['size'] %>
% endfor
% endfor
diff --git a/util/design/lib/OtpMemMap.py b/util/design/lib/OtpMemMap.py
index 0763bd4..a85e712 100644
--- a/util/design/lib/OtpMemMap.py
+++ b/util/design/lib/OtpMemMap.py
@@ -163,9 +163,8 @@
key_names.append(key["name"])
offset = 0
- num_part = 0
part_index = {}
- for part in config["partitions"]:
+ for j, part in enumerate(config["partitions"]):
_validate_part(part, offset, key_names)
if part['name'] in part_index:
@@ -173,9 +172,8 @@
exit(1)
# Loop over items within a partition
- num_items = 0
item_index = {}
- for item in part["items"]:
+ for k, item in enumerate(part["items"]):
_validate_item(item, offset)
if item['name'] in item_index:
log.error('Item name {} is not unique'.format(item['name']))
@@ -183,8 +181,7 @@
log.info("> Item {} at offset {} with size {}".format(
item["name"], offset, item["size"]))
offset += check_int(item["size"])
- item_index[item['name']] = num_items
- num_items += 1
+ item_index[item['name']] = k
# Place digest at the end of a partition.
if part["sw_digest"] or part["hw_digest"]:
@@ -192,7 +189,7 @@
if digest_name in item_index:
log.error('Digest name {} is not unique'.format(digest_name))
exit(1)
- item_index[digest_name] = num_items
+ item_index[digest_name] = len(part["items"])
part["items"].append({
"name":
digest_name,
@@ -210,6 +207,20 @@
random_or_hexvalue(part["items"][-1], "inv_default",
DIGEST_SIZE * 8)
+ # We always place the digest into the last 64bit word
+ # of a partition.
+ canonical_offset = (check_int(part["offset"]) +
+ check_int(part["size"]) -
+ DIGEST_SIZE)
+ if offset > canonical_offset:
+ log.error("Not enough space in partitition "
+ "{} to accommodate a digest. Bytes available "
+ "= {}, bytes allocated to items = {}".format(
+ part["name"], part["size"],
+ offset - part["offset"]))
+ exit(1)
+
+ offset = canonical_offset
log.info("> Adding digest {} at offset {} with size {}".format(
digest_name, offset, DIGEST_SIZE))
offset += DIGEST_SIZE
@@ -225,10 +236,9 @@
offset = check_int(part["offset"]) + check_int(part["size"])
part_index.setdefault(part['name'], {
- 'index': num_part,
+ 'index': j,
'items': item_index
})
- num_part += 1
if offset > config["otp"]["size"]:
log.error(
@@ -237,7 +247,7 @@
offset)
exit(1)
- log.info("Total number of partitions: {}".format(num_part))
+ log.info("Total number of partitions: {}".format(len(config["partitions"])))
log.info("Bytes available in OTP: {}".format(config["otp"]["size"]))
log.info("Bytes required for partitions: {}".format(offset))