mirror of
https://github.com/AsahiLinux/m1n1
synced 2025-02-16 13:48:29 +00:00
Add tools for ARM sysreg database management
Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
parent
7bb490eb58
commit
a489a646bd
6 changed files with 159 additions and 4 deletions
|
@ -49,8 +49,6 @@ class ADTNode:
|
||||||
self.children = []
|
self.children = []
|
||||||
self.properties = {}
|
self.properties = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if val is not None:
|
if val is not None:
|
||||||
for p in val.properties:
|
for p in val.properties:
|
||||||
if p.name == "name":
|
if p.name == "name":
|
||||||
|
|
|
@ -4,7 +4,7 @@ from tgtypes import *
|
||||||
import malloc
|
import malloc
|
||||||
|
|
||||||
def load_registers():
|
def load_registers():
|
||||||
data = json.load(open(os.path.join(os.path.dirname(__file__), "regs.json")))
|
data = json.load(open(os.path.join(os.path.dirname(__file__), "..", "tools", "arm_regs.json")))
|
||||||
for reg in data:
|
for reg in data:
|
||||||
yield reg["name"], reg["enc"]
|
yield reg["name"], reg["enc"]
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
1
tools/arm_regs.json
Normal file
1
tools/arm_regs.json
Normal file
File diff suppressed because one or more lines are too long
24
tools/gen_reg_include.py
Normal file
24
tools/gen_reg_include.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import json, sys
|
||||||
|
|
||||||
|
data = json.load(open(sys.argv[1]))
|
||||||
|
for reg in data:
|
||||||
|
name = reg['name']
|
||||||
|
|
||||||
|
print(f"#define SYS_{name} sys_reg({', '.join(str(i) for i in reg['enc'])})")
|
||||||
|
|
||||||
|
if name[-4:-1] == "_EL":
|
||||||
|
name = name[:-4]
|
||||||
|
|
||||||
|
for fieldset in reg["fieldsets"]:
|
||||||
|
if "instance" in fieldset:
|
||||||
|
print(f"// {fieldset['instance']}")
|
||||||
|
for f in fieldset["fields"]:
|
||||||
|
fname = f["name"]
|
||||||
|
msb, lsb = f["msb"], f["lsb"]
|
||||||
|
|
||||||
|
if msb == lsb:
|
||||||
|
print(f"#define {name}_{fname} BIT({lsb})")
|
||||||
|
else:
|
||||||
|
print(f"#define {name}_{fname} GENMASK({msb}, {lsb})")
|
||||||
|
|
||||||
|
print()
|
133
tools/reg2json.py
Normal file
133
tools/reg2json.py
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
import sys, re, json
|
||||||
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
|
def insert_n(s, nb):
|
||||||
|
sout = ""
|
||||||
|
def sub(g):
|
||||||
|
if g.group(2):
|
||||||
|
a, b = int(g.group(1)), int(g.group(2)[1:])
|
||||||
|
return nb[-a - 1:-b or None]
|
||||||
|
else:
|
||||||
|
a = int(g.group(1))
|
||||||
|
return nb[-a - 1]
|
||||||
|
|
||||||
|
s = re.sub(r'n\[(\d+)(:\d+)?\]', sub, s)
|
||||||
|
s = "".join(s.split(":"))
|
||||||
|
return int(s.replace("0b", ""), 2)
|
||||||
|
|
||||||
|
def parse_one(regs, xml):
|
||||||
|
t = ElementTree.parse(xml)
|
||||||
|
|
||||||
|
for reg in t.findall('registers/register'):
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
name = reg.find('reg_short_name').text
|
||||||
|
fullname = reg.find('reg_long_name').text
|
||||||
|
|
||||||
|
if name.startswith("S3_"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
array = reg.find('reg_array')
|
||||||
|
|
||||||
|
start = end = 0
|
||||||
|
|
||||||
|
if array:
|
||||||
|
start = int(array.find("reg_array_start").text)
|
||||||
|
end = int(array.find("reg_array_end").text)
|
||||||
|
|
||||||
|
encs = {}
|
||||||
|
|
||||||
|
for am in reg.findall('access_mechanisms/access_mechanism'):
|
||||||
|
accessor = am.attrib["accessor"]
|
||||||
|
if not accessor.startswith("MSRregister ") and not accessor.startswith("MRS "):
|
||||||
|
continue
|
||||||
|
regname = accessor.split(" ", 1)[1]
|
||||||
|
enc = {}
|
||||||
|
for e in am.findall("encoding/enc"):
|
||||||
|
enc[e.attrib["n"]] = e.attrib["v"]
|
||||||
|
|
||||||
|
enc = enc["op0"], enc["op1"], enc["CRn"], enc["CRm"], enc["op2"]
|
||||||
|
if regname in encs:
|
||||||
|
assert encs[regname] == enc
|
||||||
|
encs[regname] = enc
|
||||||
|
|
||||||
|
if not encs:
|
||||||
|
continue
|
||||||
|
|
||||||
|
fieldsets = []
|
||||||
|
|
||||||
|
width = None
|
||||||
|
|
||||||
|
for fields_elem in reg.findall('reg_fieldsets/fields'):
|
||||||
|
|
||||||
|
fieldset = {}
|
||||||
|
|
||||||
|
if (instance_elem := fields_elem.find('fields_instance')) is not None:
|
||||||
|
fieldset["instance"] = instance_elem.text
|
||||||
|
|
||||||
|
fields = []
|
||||||
|
|
||||||
|
set_width = int(fields_elem.attrib["length"])
|
||||||
|
|
||||||
|
if width is None:
|
||||||
|
width = set_width
|
||||||
|
else:
|
||||||
|
assert width == set_width
|
||||||
|
|
||||||
|
single_field = False
|
||||||
|
|
||||||
|
for f in fields_elem.findall('field'):
|
||||||
|
|
||||||
|
if f.attrib.get("rwtype", None) in ("RES0", "RES1", "RAZ", "RAZ/WI", "RAO/WI", "UNKNOWN"):
|
||||||
|
continue
|
||||||
|
msb, lsb = int(f.find('field_msb').text), int(f.find('field_lsb').text)
|
||||||
|
|
||||||
|
assert not single_field
|
||||||
|
|
||||||
|
if msb == width - 1 and lsb == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if (name_elem := f.find('field_name')) is not None:
|
||||||
|
name = name_elem.text
|
||||||
|
else:
|
||||||
|
assert not fields
|
||||||
|
continue
|
||||||
|
|
||||||
|
field = {
|
||||||
|
"name": name,
|
||||||
|
"msb": msb,
|
||||||
|
"lsb": lsb,
|
||||||
|
}
|
||||||
|
fields.append(field)
|
||||||
|
|
||||||
|
fields.sort(key=lambda x: x["lsb"], reverse=True)
|
||||||
|
|
||||||
|
fieldset["fields"] = fields
|
||||||
|
fieldsets.append(fieldset)
|
||||||
|
|
||||||
|
for idx, n in enumerate(range(start, end + 1)):
|
||||||
|
nb = "{0:064b}".format(n)[::-1]
|
||||||
|
for name, enc in sorted(encs.items()):
|
||||||
|
enc = tuple(insert_n(i, nb) for i in enc)
|
||||||
|
data = {
|
||||||
|
"index": idx,
|
||||||
|
"name": name.replace("<n>", "%d" % n),
|
||||||
|
"fullname": fullname,
|
||||||
|
"enc": enc,
|
||||||
|
"fieldsets": fieldsets,
|
||||||
|
}
|
||||||
|
|
||||||
|
if width is not None:
|
||||||
|
data["width"] = width
|
||||||
|
|
||||||
|
yield data
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
regs = []
|
||||||
|
for i in sys.argv[1:]:
|
||||||
|
regs.extend(parse_one(regs, i))
|
||||||
|
|
||||||
|
json.dump(regs, sys.stdout)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue