m1n1.hv.HV: Run passive tracers *before* issuing the MMIO write

E.g. this means tracers run *before* an ASC command gets sent, which
might be relevant if the same memory is used for commands and responses.

Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2021-06-22 01:19:28 +09:00
parent d255a74271
commit d025574e1d

View file

@ -382,18 +382,12 @@ class HV(Reloadable):
first = 0 first = 0
val = data.data val = data.data
if data.flags.WRITE:
if data.flags.WIDTH < 3:
wval = val[0]
else:
wval = val
if mode not in (TraceMode.HOOK, TraceMode.SYNC):
raise Exception(f"VM hook with unexpected mapping at {data.addr:#x}: {maps[0][0].name}")
if not data.flags.WRITE:
if mode == TraceMode.HOOK: if mode == TraceMode.HOOK:
if data.flags.WRITE:
self.shellwrap(lambda: write(data.addr, wval, 8 << data.flags.WIDTH, **kwargs),
f"Tracer {ident}:write (HOOK)", update=do_update)
else:
val = self.shellwrap(lambda: read(data.addr, 8 << data.flags.WIDTH, **kwargs), val = self.shellwrap(lambda: read(data.addr, 8 << data.flags.WIDTH, **kwargs),
f"Tracer {ident}:read (HOOK)", update=do_update, needs_ret=True) f"Tracer {ident}:read (HOOK)", update=do_update, needs_ret=True)
@ -401,19 +395,16 @@ class HV(Reloadable):
val = [val] val = [val]
first += 1 first += 1
elif mode == TraceMode.SYNC: elif mode == TraceMode.SYNC:
if data.flags.WRITE:
self.u.write(data.addr, wval, 8 << data.flags.WIDTH)
else:
val = self.u.read(data.addr, 8 << data.flags.WIDTH) val = self.u.read(data.addr, 8 << data.flags.WIDTH)
if not isinstance(val, list) and not isinstance(val, tuple): if not isinstance(val, list) and not isinstance(val, tuple):
val = [val] val = [val]
else:
raise Exception(f"VM hook with unexpected mapping at {data.addr:#x}: {maps[0][0].name}")
if not data.flags.WRITE:
for i in range(1 << max(0, data.flags.WIDTH - 3)): for i in range(1 << max(0, data.flags.WIDTH - 3)):
self.p.write64(ctx.data + 16 + 8 * i, val[i]) self.p.write64(ctx.data + 16 + 8 * i, val[i])
elif mode == TraceMode.HOOK:
first += 1
flags = data.flags.copy() flags = data.flags.copy()
width = data.flags.WIDTH width = data.flags.WIDTH
@ -440,6 +431,20 @@ class HV(Reloadable):
self.shellwrap(lambda: read(evt, **kwargs), self.shellwrap(lambda: read(evt, **kwargs),
f"Tracer {ident}:read ({mode.name})", update=do_update) f"Tracer {ident}:read ({mode.name})", update=do_update)
if data.flags.WRITE:
mode, ident, read, write, kwargs = maps[0]
if data.flags.WIDTH < 3:
wval = val[0]
else:
wval = val
if mode == TraceMode.HOOK:
self.shellwrap(lambda: write(data.addr, wval, 8 << data.flags.WIDTH, **kwargs),
f"Tracer {ident}:write (HOOK)", update=do_update)
elif mode == TraceMode.SYNC:
self.u.write(data.addr, wval, 8 << data.flags.WIDTH)
return True return True
def handle_vm_hook(self, ctx): def handle_vm_hook(self, ctx):