mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
scripts: Added SVD to Pattern Language converter
This commit is contained in:
74
scripts/svd2pat.py
Normal file
74
scripts/svd2pat.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
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)
|
||||||
Reference in New Issue
Block a user