|
| 1 | +# SPDX-License-Identifier: MIT |
| 2 | +import struct |
| 3 | + |
| 4 | +from construct import * |
| 5 | +from m1n1.utils import * |
| 6 | +from m1n1.proxyutils import * |
| 7 | +from m1n1.constructutils import * |
| 8 | +from m1n1.trace.asc import ASCTracer, EP, EPState, msg, msg_log, DIR |
| 9 | +from m1n1.trace.dockchannel import DockChannelTracer |
| 10 | +from m1n1.trace.dart import DARTTracer |
| 11 | +from m1n1.fw.mtp import * |
| 12 | + |
| 13 | +class MTPTracer(ASCTracer): |
| 14 | + def handle_msg(self, direction, r0, r1): |
| 15 | + super().handle_msg(direction, r0, r1) |
| 16 | + |
| 17 | +mtp_tracer = MTPTracer(hv, "/arm-io/mtp", verbose=1) |
| 18 | +mtp_tracer.start() |
| 19 | + |
| 20 | +dart_tracer = DARTTracer(hv, "/arm-io/dart-mtp", verbose=1) |
| 21 | +dart_tracer.start() |
| 22 | + |
| 23 | +trace_device("/arm-io/dart-mtp", True) |
| 24 | + |
| 25 | +DockChannelTracer = DockChannelTracer._reloadcls() |
| 26 | + |
| 27 | +mon = RegMonitor(hv.u, ascii=True, bufsize=0x400000) |
| 28 | + |
| 29 | +class StreamState: |
| 30 | + def __init__(self): |
| 31 | + self.buf = bytes() |
| 32 | + |
| 33 | +class MTPStream: |
| 34 | + def __init__(self, tracer, name, state): |
| 35 | + self.tracer = tracer |
| 36 | + self.name = name |
| 37 | + self.state = state |
| 38 | + |
| 39 | + def put(self, d): |
| 40 | + buf = self.state.buf + d |
| 41 | + |
| 42 | + while buf: |
| 43 | + if len(buf) < 8: |
| 44 | + self.state.buf = buf |
| 45 | + return |
| 46 | + |
| 47 | + hlen, mtype, size, ctr, devid, pad = struct.unpack("<BBHBBH", buf[:8]) |
| 48 | + assert pad == 0 |
| 49 | + if hlen != 8: |
| 50 | + self.tracer.log(f"Bad hlen 0x{hlen:2x}, skipping a byte...") |
| 51 | + self.state.buf = buf[1:] |
| 52 | + return |
| 53 | + |
| 54 | + |
| 55 | + need = 8 + size + 4 |
| 56 | + if len(buf) < need: |
| 57 | + self.state.buf = buf |
| 58 | + return |
| 59 | + |
| 60 | + payload = buf[8:8 + size] |
| 61 | + self.packet(mtype, devid, ctr, payload) |
| 62 | + buf = buf[need:] |
| 63 | + |
| 64 | + self.state.buf = buf |
| 65 | + |
| 66 | + def packet(self, mtype, devid, ctr, pkt): |
| 67 | + self.tracer.packet(mtype, devid, ctr, pkt, dir=self.name) |
| 68 | + |
| 69 | + def log(self, msg): |
| 70 | + self.tracer.log(f"{self.name} " + msg) |
| 71 | + |
| 72 | +class MTPChannelTracer(DockChannelTracer): |
| 73 | + def init_state(self): |
| 74 | + self.state.rx = StreamState() |
| 75 | + self.state.tx = StreamState() |
| 76 | + self.state.rx_mem = StreamState() |
| 77 | + self.state.buf = None |
| 78 | + self.state.buf_size = None |
| 79 | + self.state.rptr = 0 |
| 80 | + |
| 81 | + def start(self, dart=None): |
| 82 | + super().start() |
| 83 | + self.dart = dart |
| 84 | + self.rx_stream = MTPStream(self, "<", self.state.rx) |
| 85 | + self.tx_stream = MTPStream(self, ">", self.state.tx) |
| 86 | + self.rx_mem_stream = MTPStream(self, "<", self.state.rx_mem) |
| 87 | + self.init_mon() |
| 88 | + |
| 89 | + def tx(self, d): |
| 90 | + self.tx_stream.put(d) |
| 91 | + |
| 92 | + def rx(self, d): |
| 93 | + self.rx_stream.put(d) |
| 94 | + |
| 95 | + def init_mon(self): |
| 96 | + pass |
| 97 | + #if self.state.buf is not None: |
| 98 | + #addr, size = self.dart.iotranslate(1, self.state.buf, self.state.buf_size)[0] |
| 99 | + #size = align_up(size, 4) |
| 100 | + #mon.add(addr, size) |
| 101 | + |
| 102 | + def poll_ring(self): |
| 103 | + wptr = struct.unpack("<I", self.dart.ioread(1, self.state.buf, 4))[0] |
| 104 | + rptr = self.state.rptr |
| 105 | + if wptr < rptr: |
| 106 | + size = self.state.buf_size - 8 - rptr |
| 107 | + d = self.dart.ioread(1, self.state.buf + 8 + rptr, size) |
| 108 | + self.rx_mem_stream.put(d) |
| 109 | + self.state.rptr = rptr = 0 |
| 110 | + |
| 111 | + size = wptr - rptr |
| 112 | + d = self.dart.ioread(1, self.state.buf + 8 + rptr, size) |
| 113 | + self.rx_mem_stream.put(d) |
| 114 | + self.state.rptr = rptr + size |
| 115 | + |
| 116 | + def packet(self, mcode, devid, ctr, data, dir): |
| 117 | + #mon.poll() |
| 118 | + chexdump(data, print_fn=self.log) |
| 119 | + |
| 120 | + if data == b"": |
| 121 | + self.poll_ring() |
| 122 | + msg = "<null>" |
| 123 | + elif dir == ">": |
| 124 | + msg = TXMessage.parse(data) |
| 125 | + elif dir == "<": |
| 126 | + msg = RXMessage.parse(data) |
| 127 | + if devid == 0: |
| 128 | + if (msg.hdr.flags & 0xc0) == 0x00: |
| 129 | + msg.msg = NotificationMsg.parse(msg.msg) |
| 130 | + elif (msg.hdr.flags & 0xc0) == 0x80: |
| 131 | + msg.msg = DeviceControlAck.parse(msg.msg) |
| 132 | + else: |
| 133 | + assert False |
| 134 | + |
| 135 | + try: |
| 136 | + mtype = msg.msg.name |
| 137 | + except: |
| 138 | + mtype = None |
| 139 | + |
| 140 | + if mtype == "InitAFEMsg": |
| 141 | + afe = self.dart.ioread(1, msg.msg.buf_addr, msg.msg.buf_size) |
| 142 | + chexdump(afe, print_fn=self.log) |
| 143 | + open("afe.bin", "wb").write(afe) |
| 144 | + elif mtype == "InitBufMsg": |
| 145 | + self.state.buf = msg.msg.buf_addr |
| 146 | + self.state.buf_size = msg.msg.buf_size |
| 147 | + self.init_mon() |
| 148 | + |
| 149 | + self.log(f"{dir} Type {mcode:02x} Dev {devid} #{ctr} {msg!s}") |
| 150 | + |
| 151 | +hid_tracer = MTPChannelTracer(hv, "/arm-io/dockchannel-mtp", verbose=3) |
| 152 | +hid_tracer.start(dart_tracer.dart) |
0 commit comments