mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-24 23:53:04 +00:00
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:
parent
52492350ee
commit
8cd2865c1f
3 changed files with 41 additions and 8 deletions
|
@ -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
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue