m1n1.hv: Add support for dumping MMIO accesses in Python syntax to a log

Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2021-11-04 03:58:51 +09:00
parent bfc91be170
commit 74dece703e
3 changed files with 25 additions and 8 deletions

View file

@ -166,8 +166,12 @@ class HV(Reloadable):
def log(self, s, *args, **kwargs): def log(self, s, *args, **kwargs):
if self.ctx is not None: if self.ctx is not None:
print(f"[cpu{self.ctx.cpu_id}] " + s, *args, **kwargs) print(f"[cpu{self.ctx.cpu_id}] " + s, *args, **kwargs)
if self.print_tracer.log_file:
print(f"# [cpu{self.ctx.cpu_id}] " + s, *args, file=self.print_tracer.log_file, **kwargs)
else: else:
print(s, *args, **kwargs) print(s, *args, **kwargs)
if self.print_tracer.log_file:
print("# " + s, *args, file=self.print_tracer.log_file, **kwargs)
def unmap(self, ipa, size): def unmap(self, ipa, size):
assert self.p.hv_map(ipa, 0, size, 0) >= 0 assert self.p.hv_map(ipa, 0, size, 0) >= 0
@ -578,21 +582,18 @@ class HV(Reloadable):
self.log(f"Skip: msr {name}, x{iss.Rt} = {value:x}") self.log(f"Skip: msr {name}, x{iss.Rt} = {value:x}")
else: else:
if iss.DIR == MSR_DIR.READ: if iss.DIR == MSR_DIR.READ:
self.log(f"Pass: mrs x{iss.Rt}, {name}", end=" ")
sys.stdout.flush()
enc2 = self.MSR_REDIRECTS.get(enc, enc) enc2 = self.MSR_REDIRECTS.get(enc, enc)
value = self.u.mrs(enc2) value = self.u.mrs(enc2)
print(f"= {value:x} ({sysreg_name(enc2)})") self.log(f"Pass: mrs x{iss.Rt}, {name} = {value:x} ({sysreg_name(enc2)})")
if iss.Rt != 31: if iss.Rt != 31:
ctx.regs[iss.Rt] = value ctx.regs[iss.Rt] = value
else: else:
if iss.Rt != 31: if iss.Rt != 31:
value = ctx.regs[iss.Rt] value = ctx.regs[iss.Rt]
self.log(f"Pass: msr {name}, x{iss.Rt} = {value:x}", end=" ")
enc2 = self.MSR_REDIRECTS.get(enc, enc) enc2 = self.MSR_REDIRECTS.get(enc, enc)
sys.stdout.flush() sys.stdout.flush()
self.u.msr(enc2, value, call=self.p.gl2_call) self.u.msr(enc2, value, call=self.p.gl2_call)
print(f"(OK) ({sysreg_name(enc2)})") self.log(f"Pass: msr {name}, x{iss.Rt} = {value:x} (OK) ({sysreg_name(enc2)})")
ctx.elr += 4 ctx.elr += 4
@ -960,6 +961,8 @@ class HV(Reloadable):
self.vbar_el1 = vbar self.vbar_el1 = vbar
def set_logfile(self, fd):
self.print_tracer.log_file = fd
def init(self): def init(self):
self.adt = load_adt(self.u.get_adt()) self.adt = load_adt(self.u.get_adt())
@ -1114,7 +1117,7 @@ class HV(Reloadable):
self.add_tracer(irange(addr, 4), "PMGR HACK", TraceMode.RESERVED) self.add_tracer(irange(addr, 4), "PMGR HACK", TraceMode.RESERVED)
def cpustart_wh(base, off, data, width): def cpustart_wh(base, off, data, width):
print(f"CPUSTART W {base:x}+{off:x}:{width} = 0x{data:x}") self.log(f"CPUSTART W {base:x}+{off:x}:{width} = 0x{data:x}")
if off >= 8: if off >= 8:
assert width == 32 assert width == 32
cluster = (off - 8) // 4 cluster = (off - 8) // 4

View file

@ -149,13 +149,23 @@ class PrintTracer(Tracer):
def __init__(self, hv, device_addr_tbl): def __init__(self, hv, device_addr_tbl):
super().__init__(hv) super().__init__(hv)
self.device_addr_tbl = device_addr_tbl self.device_addr_tbl = device_addr_tbl
self.log_file = None
def event_mmio(self, evt): def event_mmio(self, evt):
dev, zone = self.device_addr_tbl.lookup(evt.addr) dev, zone = self.device_addr_tbl.lookup(evt.addr)
t = "W" if evt.flags.WRITE else "R" t = "W" if evt.flags.WRITE else "R"
m = "+" if evt.flags.MULTI else " " m = "+" if evt.flags.MULTI else " "
print(f"[cpu{evt.flags.CPU}][0x{evt.pc:016x}] MMIO: {t}.{1<<evt.flags.WIDTH:<2}{m} " + logline = (f"[cpu{evt.flags.CPU}][0x{evt.pc:016x}] MMIO: {t}.{1<<evt.flags.WIDTH:<2}{m} " +
f"0x{evt.addr:x} ({dev}, offset {evt.addr - zone.start:#04x}) = 0x{evt.data:x}") f"0x{evt.addr:x} ({dev}, offset {evt.addr - zone.start:#04x}) = 0x{evt.data:x}")
print(logline)
if self.log_file:
self.log_file.write(f"# {logline}\n")
width = 8 << evt.flags.WIDTH
if evt.flags.WRITE:
stmt = f"p.write{width}({zone.start:#x} + {evt.addr - zone.start:#x}, {evt.data:#x})\n"
else:
stmt = f"p.read{width}({zone.start:#x} + {evt.addr - zone.start:#x})\n"
self.log_file.write(stmt)
class ADTDevTracer(Tracer): class ADTDevTracer(Tracer):
REGMAPS = [] REGMAPS = []

View file

@ -12,6 +12,7 @@ parser.add_argument('-c', '--command', action="append", default=[])
parser.add_argument('-S', '--shell', action="store_true") parser.add_argument('-S', '--shell', action="store_true")
parser.add_argument('-e', '--hook-exceptions', action="store_true") parser.add_argument('-e', '--hook-exceptions', action="store_true")
parser.add_argument('-d', '--debug-xnu', action="store_true") parser.add_argument('-d', '--debug-xnu', action="store_true")
parser.add_argument('-l', '--logfile', type=pathlib.Path)
parser.add_argument('payload', type=pathlib.Path) parser.add_argument('payload', type=pathlib.Path)
parser.add_argument('boot_args', default=[], nargs="*") parser.add_argument('boot_args', default=[], nargs="*")
args = parser.parse_args() args = parser.parse_args()
@ -36,6 +37,9 @@ hv.init()
if args.debug_xnu: if args.debug_xnu:
hv.adt["chosen"].debug_enabled = 1 hv.adt["chosen"].debug_enabled = 1
if args.logfile:
hv.set_logfile(args.logfile.open("w"))
if len(args.boot_args) > 0: if len(args.boot_args) > 0:
boot_args = " ".join(args.boot_args) boot_args = " ".join(args.boot_args)
hv.set_bootargs(boot_args) hv.set_bootargs(boot_args)