[rom_ext] Add Verbose Logging to Generator
Signed-off-by: Sam Elliott <selliott@lowrisc.org>
diff --git a/util/rom-ext-manifest-generator.py b/util/rom-ext-manifest-generator.py
index fa222c5..9366625 100755
--- a/util/rom-ext-manifest-generator.py
+++ b/util/rom-ext-manifest-generator.py
@@ -36,12 +36,11 @@
"""
import argparse
-from pathlib import Path
import subprocess
+from pathlib import Path
import hjson
from mako.template import Template
-
from topgen.c import MemoryRegion, Name
DESC = """ROM_EXT manifest generator"""
@@ -60,6 +59,9 @@
c - C header file
rust - Rust module file
format - Format description file (plaintext)
+
+ rom-ext-manifest-generator --verbose:
+ Print extra information including resulting field offsets and alignment.
"""
@@ -72,7 +74,7 @@
return self.name + Name(["offset"])
-def generate_defines(fields):
+def generate_defines(fields, verbose=False):
""" Generates manifest defines.
This produces two lists of tuples. One with a field name and the
@@ -80,6 +82,15 @@
description at the top for more information on the differences between these
objects.
"""
+ def print_field_info(name, offset, size, alignment, required_alignment):
+ if verbose:
+ print("0x{:04x} - 0x{:04x}: {} (alignment: {} reqd: {})".format(
+ offset, offset + size, name, alignment, required_alignment))
+
+ def print_offset_info(name, offset, alignment, required_alignment):
+ if verbose:
+ print(" @ 0x{:04x}: {} (alignment: {} reqd: {})".format(
+ offset, name, alignment, required_alignment))
base_name = Name.from_snake_case("ROM_EXT")
@@ -92,23 +103,46 @@
required_alignment_bytes = required_alignment_bits // 8
# The 8-byte two-step https://zinascii.com/2014/the-8-byte-two-step.html
- # This ends up aligning `current_offset_bytes` to `required_alignment_bytes`
+ # This ends up aligning `new_offset_bytes` to `required_alignment_bytes`
# that is greater than or equal to `current_offset_bytes`.
- current_offset_bytes = (current_offset_bytes + required_alignment_bytes - 1) \
+ new_offset_bytes = (current_offset_bytes + required_alignment_bytes - 1) \
& ~(required_alignment_bytes - 1)
+ if new_offset_bytes != current_offset_bytes and verbose:
+ print("0x{:04x} - 0x{:04x}: - (realignment) -".format(
+ current_offset_bytes, new_offset_bytes))
+
+ current_offset_bytes = new_offset_bytes
+ # This works becuase e.g. 6 is `0b0...00110` and ~(6-1) is `0b1..11010`,
+ # giving a result of `0b0...010`, or 2.
+ current_offset_alignment = current_offset_bytes \
+ & ~(current_offset_bytes - 1)
+
if field['type'] == "offset":
offset_name = base_name + Name.from_snake_case(field['name'])
offset = MemoryOffset(offset_name, current_offset_bytes)
offsets.append((field['name'], offset))
+ print_offset_info(field['name'], current_offset_bytes,
+ current_offset_alignment,
+ required_alignment_bytes)
+
else:
assert field['size'] % 8 == 0
size_bytes = field['size'] // 8
if field['type'] == "field":
region_name = base_name + Name.from_snake_case(field['name'])
- region = MemoryRegion(region_name, current_offset_bytes, size_bytes)
+ region = MemoryRegion(region_name, current_offset_bytes,
+ size_bytes)
regions.append((field['name'], region))
+
+ print_field_info(field['name'], current_offset_bytes,
+ size_bytes, current_offset_alignment,
+ required_alignment_bytes)
+ elif field['type'] == 'reserved' and verbose:
+ print_field_info('- reserved -', current_offset_bytes,
+ size_bytes, current_offset_alignment, 0)
+
current_offset_bytes += size_bytes
return (regions, offsets)
@@ -170,14 +204,14 @@
output_path = output_dir / 'manifest.txt'
- truncate_length = 16 # bytes
+ truncate_length = 16 # bytes
bits_in_byte = 8
verbose_regions = []
- current_offset = 0 # bytes
+ current_offset = 0 # bytes
truncation_lines = []
- current_truncation_delta = 0 # bytes
+ current_truncation_delta = 0 # bytes
# We need to re-process this info to re-add reserved regions of the right
# size, and also to truncate really long fields.
@@ -187,15 +221,18 @@
# Pad with a reserved field to get to new offset
if new_offset != current_offset:
- verbose_regions.append("- reserved -:{}".format((new_offset - current_offset) * bits_in_byte))
+ verbose_regions.append("- reserved -:{}".format(
+ (new_offset - current_offset) * bits_in_byte))
current_offset = new_offset
# Add a (potentially truncated) field
if mem_region.size_bytes > truncate_length:
# We only allow truncated regions at 4-byte offsets.
- assert(current_offset % 4 == 0)
- verbose_regions.append("{} ({} bits):{}".format(name, mem_region.size_bytes * bits_in_byte, truncate_length * bits_in_byte))
+ assert (current_offset % 4 == 0)
+ verbose_regions.append("{} ({} bits):{}".format(
+ name, mem_region.size_bytes * bits_in_byte,
+ truncate_length * bits_in_byte))
# Save some information so we know where to insert the `~~ break ~~` line.
data_line = (current_offset - current_truncation_delta) // 4
@@ -203,16 +240,21 @@
current_truncation_delta += mem_region.size_bytes - truncate_length
else:
- verbose_regions.append("{}:{}".format(name, mem_region.size_bytes * bits_in_byte))
+ verbose_regions.append("{}:{}".format(
+ name, mem_region.size_bytes * bits_in_byte))
current_offset = new_offset + mem_region.size_bytes
# Add a field for the image itself:
- verbose_regions.append("code image:{}".format(truncate_length * bits_in_byte))
+ verbose_regions.append("code image:{}".format(truncate_length *
+ bits_in_byte))
truncation_lines.append((current_offset - current_truncation_delta) // 4)
protocol_input = ",".join(verbose_regions)
- protocol_result = subprocess.run(["protocol", "--bits", "32", protocol_input], universal_newlines=True, capture_output=True)
+ protocol_result = subprocess.run(
+ ["protocol", "--bits", "32", protocol_input],
+ universal_newlines=True,
+ capture_output=True)
protocol_output = protocol_result.stdout
truncation_mark = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break ~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
@@ -231,7 +273,6 @@
print('Format description successfully written to {}.'.format(output_path))
-
def main():
ALL_PARTS = ["c", "rust", "format"]
@@ -240,6 +281,12 @@
usage=USAGE,
description=DESC)
+ parser.add_argument('-v',
+ '--verbose',
+ action='store_true',
+ default=False,
+ help='Print Extra Information.')
+
parser.add_argument('--input-dir',
required=True,
type=Path,
@@ -268,7 +315,7 @@
if 'all' in args.output_files:
args.output_files += ALL_PARTS
- regions, offsets = generate_defines(obj['fields'])
+ regions, offsets = generate_defines(obj['fields'], args.verbose)
if "c" in args.output_files:
generate_cheader(regions, offsets, args.input_dir, args.output_dir)