m1n1.sysreg & co: Add support for op-like sysregs (e.g. TLBI)

Signed-off-by: Asahi Lina <lina@asahilina.net>
This commit is contained in:
Asahi Lina 2022-08-17 14:01:07 +09:00
parent 52492350ee
commit 8cd2865c1f
3 changed files with 41 additions and 8 deletions

View file

@ -6,20 +6,37 @@ from .utils import Register, Register64, Register32
__all__ = ["sysreg_fwd", "sysreg_rev"] __all__ = ["sysreg_fwd", "sysreg_rev"]
def _load_registers(): def _load_registers():
global sysreg_fwd, sysop_fwd
sysreg_fwd = {}
sysop_fwd = {}
for fname in ["arm_regs.json", "apple_regs.json"]: for fname in ["arm_regs.json", "apple_regs.json"]:
data = json.load(open(os.path.join(os.path.dirname(__file__), "..", "..", "tools", fname))) data = json.load(open(os.path.join(os.path.dirname(__file__), "..", "..", "tools", fname)))
for reg in data: for reg in data:
yield reg["name"], tuple(reg["enc"]) if "accessors" in reg:
for acc in reg["accessors"]:
if acc in ("MRS", "MSR"):
sysreg_fwd[reg["name"]] = tuple(reg["enc"])
else:
sysop_fwd[acc + " " + reg["name"]] = tuple(reg["enc"])
else:
sysreg_fwd[reg["name"]] = tuple(reg["enc"])
sysreg_fwd = dict(_load_registers()) _load_registers()
sysreg_rev = {v: k for k, v in sysreg_fwd.items()} sysreg_rev = {v: k for k, v in sysreg_fwd.items()}
sysop_rev = {v: k for k, v in sysop_fwd.items()}
sysop_fwd_id = {k.replace(" ", "_"): v for k,v in sysop_fwd.items()}
globals().update(sysreg_fwd) globals().update(sysreg_fwd)
__all__.extend(sysreg_fwd.keys()) __all__.extend(sysreg_fwd.keys())
globals().update(sysop_fwd_id)
__all__.extend(sysop_fwd_id.keys())
def sysreg_name(enc): def sysreg_name(enc):
if enc in sysreg_rev: if enc in sysreg_rev:
return sysreg_rev[enc] return sysreg_rev[enc]
if enc in sysop_rev:
return sysop_rev[enc]
return f"s{enc[0]}_{enc[1]}_c{enc[2]}_c{enc[3]}_{enc[4]}" return f"s{enc[0]}_{enc[1]}_c{enc[2]}_c{enc[3]}_{enc[4]}"
def sysreg_parse(s): def sysreg_parse(s):
@ -31,9 +48,13 @@ def sysreg_parse(s):
enc = tuple(map(int, m.groups())) enc = tuple(map(int, m.groups()))
break break
else: else:
try: for i in sysreg_fwd, sysop_fwd, sysop_fwd_id:
enc = sysreg_fwd[s] try:
except KeyError: enc = i[s]
except KeyError:
continue
break
else:
raise Exception(f"Unknown sysreg name {s}") raise Exception(f"Unknown sysreg name {s}")
return enc return enc
@ -350,5 +371,13 @@ class TCR(Register64):
EPD0 = 7 EPD0 = 7
T0SZ = 5, 0 T0SZ = 5, 0
class TLBI_RVA(Register64):
ASID = 63, 48
TG = 47, 46
SCALE = 45, 44
NUM = 43, 39
TTL = 38, 37
BaseADDR = 36, 0
__all__.extend(k for k, v in globals().items() __all__.extend(k for k, v in globals().items()
if (callable(v) or isinstance(v, type)) and v.__module__ == __name__) if (callable(v) or isinstance(v, type)) and v.__module__ == __name__)

File diff suppressed because one or more lines are too long

View file

@ -24,7 +24,7 @@ def parse_one(regs, xml):
name = reg.find('reg_short_name').text name = reg.find('reg_short_name').text
fullname = reg.find('reg_long_name').text fullname = reg.find('reg_long_name').text
if name.startswith("S3_"): if name.startswith("S3_") or name.startswith("SYS S1_"):
continue continue
array = reg.find('reg_array') array = reg.find('reg_array')
@ -36,11 +36,13 @@ def parse_one(regs, xml):
end = int(array.find("reg_array_end").text) end = int(array.find("reg_array_end").text)
encs = {} encs = {}
accessors = {}
for am in reg.findall('access_mechanisms/access_mechanism'): for am in reg.findall('access_mechanisms/access_mechanism'):
accessor = am.attrib["accessor"] accessor = am.attrib["accessor"]
if not accessor.startswith("MSRregister ") and not accessor.startswith("MRS "): if accessor.startswith("MSRimmediate"):
continue continue
ins = am.find("encoding/access_instruction").text.split(" ")[0]
regname = accessor.split(" ", 1)[1] regname = accessor.split(" ", 1)[1]
enc = {} enc = {}
for e in am.findall("encoding/enc"): for e in am.findall("encoding/enc"):
@ -50,6 +52,7 @@ def parse_one(regs, xml):
if regname in encs: if regname in encs:
assert encs[regname] == enc assert encs[regname] == enc
encs[regname] = enc encs[regname] = enc
accessors.setdefault(regname, set()).add(ins)
if not encs: if not encs:
continue continue
@ -114,6 +117,7 @@ def parse_one(regs, xml):
"name": name.replace("<n>", "%d" % n), "name": name.replace("<n>", "%d" % n),
"fullname": fullname, "fullname": fullname,
"enc": enc, "enc": enc,
"accessors": sorted(list(accessors[name])),
"fieldsets": fieldsets, "fieldsets": fieldsets,
} }