mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-27 00:40:17 +00:00
30e14f1a0b
Signed-off-by: Hector Martin <marcan@marcan.st>
98 lines
2.6 KiB
Python
98 lines
2.6 KiB
Python
#!/usr/bin/python3
|
|
import asm, struct
|
|
import sysreg
|
|
from proxyutils import GuardedHeap
|
|
|
|
def _all():
|
|
for op1 in range(1 << 3):
|
|
for CRn in (0b1011, 0b1111):
|
|
for CRm in range(1 << 4):
|
|
for op2 in range(1 << 3):
|
|
yield 3, op1, CRn, CRm, op2
|
|
|
|
dynamic_regs = [
|
|
sysreg.CNTVCT_ALIAS_EL0,
|
|
sysreg.CNTPCT_ALIAS_EL0,
|
|
]
|
|
|
|
impdef_regs = list(_all())
|
|
static_regs = [i for i in _all() if i not in dynamic_regs]
|
|
|
|
def find_regs(u, regs=None, block=1024, call=None, values=True):
|
|
if regs is None:
|
|
regs = impdef_regs
|
|
|
|
p = u.proxy
|
|
iface = u.iface
|
|
|
|
data_len = 8 * block
|
|
|
|
with GuardedHeap(u.heap) as heap:
|
|
data_buffer = heap.malloc(data_len)
|
|
|
|
template = asm.ARMAsm("""
|
|
mov x2, x0
|
|
mrs x2, s3_0_c0_c0_0
|
|
str x2, [x1], #8
|
|
""", 0x1000)
|
|
|
|
mov, mrs, st = struct.unpack("3I", template.data)
|
|
|
|
data = []
|
|
|
|
BAD = 0xacce5515abad1dea
|
|
OOPS = 0xdeadc0dedeadc0de
|
|
|
|
rblock = []
|
|
iregs = iter(regs)
|
|
|
|
while True:
|
|
insns = []
|
|
bregs = []
|
|
for i in iregs:
|
|
op0, op1, CRn, CRm, op2 = enc = sysreg.sysreg_parse(i)
|
|
bregs.append(enc)
|
|
assert op0 == 3
|
|
|
|
insns.extend((mov, mrs | (op1 << 16) | (CRn << 12) | (CRm << 8) | (op2 << 5), st))
|
|
|
|
if len(bregs) >= block:
|
|
break
|
|
|
|
if not bregs:
|
|
break
|
|
|
|
p.memset64(data_buffer, OOPS, data_len)
|
|
u.exec(insns, BAD, data_buffer, call=call, silent=True, ignore_exceptions=True)
|
|
data = iface.readmem(data_buffer, 8 * len(bregs))
|
|
for reg, val in zip(bregs, struct.unpack(f"<{len(bregs)}Q", data)):
|
|
if val == OOPS:
|
|
raise Exception(f"Failed to execute reg-finder code at {reg}")
|
|
if val != BAD:
|
|
if values:
|
|
yield reg, val
|
|
else:
|
|
yield reg
|
|
|
|
if __name__ == "__main__":
|
|
from setup import *
|
|
|
|
p.iodev_set_usage(IODEV.FB, 0)
|
|
|
|
for reg, val in find_regs(u):
|
|
print(f"{sysreg_name(reg)} ({', '.join(map(str, reg))}) = 0x{val:x}")
|
|
|
|
try:
|
|
u.msr(reg, v, silent=True)
|
|
except:
|
|
print(" - READONLY")
|
|
try:
|
|
u.mrs(reg, silent=True, call="el1")
|
|
except:
|
|
print(" - ### EL2 only ###")
|
|
try:
|
|
u.mrs(reg, silent=True, call="el0")
|
|
except:
|
|
pass
|
|
else:
|
|
print(" - *** EL0 accessible ***")
|