forked from WerWolv/ImHex-Patterns
-
Notifications
You must be signed in to change notification settings - Fork 0
/
svd2pat.py
74 lines (55 loc) · 2.33 KB
/
svd2pat.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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)