Files
ImHex-Patterns/scripts/svd2pat.py

74 lines
2.3 KiB
Python

import io
import sys
import xml.etree.ElementTree as ET
import math
def sortchildrenby(parent, attr):
parent[:] = sorted(parent, key=lambda child: int(child.find(attr).text, 16))
# Print usage information
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <file.svd>")
exit()
# Parse SVD file
svd = ET.parse(sys.argv[1]).getroot()
# Read processor information
processor_name = svd.find("name").text
register_width = svd.find("width").text
register_type = f"u{register_width}"
code = ""
# Add header
code += f"// MMIO Register definition for {processor_name}\n\n"
# Add type definition for register type of correct size
code += f"using reg_t = {register_type};\n\n\n"
for peripheral in svd.find("peripherals"):
derived = peripheral.attrib.get("derivedFrom")
peripheral_name = peripheral.find("name").text
peripheral_address = int(peripheral.find("baseAddress").text, 16)
# Generate struct header
code += f"struct {peripheral_name}_t"
# If register definition has been derived from somewhere else, derive the struct from the other struct
if derived != None:
code += f" : {derived}_t"
code += " {\n"
prev_offset = 0
registers = peripheral.find("registers")
if registers != None:
sortchildrenby(registers, "addressOffset")
for register in registers:
register_name = register.find("name").text
register_offset = int(register.find("addressOffset").text, 16)
# Check if padding has to be inserted
if prev_offset == 0:
pass
elif register_offset - prev_offset > 4:
code += f" padding[{register_offset - prev_offset - 4}];\n"
elif (register_offset - prev_offset != 0) and (register_offset - prev_offset != 4):
print(f"Overlapping register {register_name}!")
exit()
# Add register variable declaration
code += f" reg_t {register_name}; // 0x{register_offset:03X}\n"
prev_offset = register_offset
code += "};\n"
# Place instance of register type in memory
code += f"{peripheral_name}_t {peripheral_name} @ 0x{peripheral_address:08X};\n\n"
# Write generated code to a file
with open(sys.argv[1] + ".pat", "w") as file:
file.write(code)