Skip to content

Commit 99ac3a9

Browse files
committed
bluetooth: bunch of ring fixes
1 parent 213612d commit 99ac3a9

File tree

1 file changed

+93
-65
lines changed

1 file changed

+93
-65
lines changed

proxyclient/hv/trace_bt.py

Lines changed: 93 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from m1n1.trace.dart import DARTTracer
33
from m1n1.utils import *
44
from collections import namedtuple
5+
import itertools
56
import struct
67

78

@@ -134,7 +135,7 @@ class BTBAR1Regs(RegMap):
134135

135136
IMG_ADDR_LO = 0x200478, Register32
136137
IMG_ADDR_HI = 0x20047c, Register32
137-
IMG_ADDR_SZ = 0x200480, Register32
138+
IMG_SZ = 0x200480, Register32
138139
BTI_EXITCODE_RTI_IMG_RESPONSE = 0x200488, Register32
139140
RTI_CONTEXT_LO = 0x20048c, Register32
140141
RTI_CONTEXT_HI = 0x200490, Register32
@@ -290,7 +291,7 @@ def hook(name, iova, sz):
290291
print(f"hooking {name} @ IOVA {iova:016X} phys {physaddr:016X}")
291292
self.trace(physaddr, sz, TraceMode.SYNC, prefix=name)
292293

293-
hook('perInfo', context.perInfo, 0x10)
294+
# hook('perInfo', context.perInfo, 0x10)
294295
# hook('crHIA', context.crHIA, 12)
295296
# hook('crTIA', context.crTIA, 12)
296297
# hook('trHIA', context.trHIA, 18)
@@ -307,8 +308,8 @@ def hook(name, iova, sz):
307308
None
308309
)
309310

311+
self._crhia_physaddr = crhia_physaddr
310312
self._ctx = context
311-
self._last_ring_idx = {}
312313
self._open_pipes = {}
313314
self._open_crs = {}
314315

@@ -320,90 +321,117 @@ def w_DOORBELL_05(self, val):
320321
if val & 0x20 != 0x20:
321322
print(f"UNKNOWN write to doorbell {val:X}")
322323
else:
323-
pipe = (val >> 8) & 0xFF
324+
db_idx = (val >> 8) & 0xFF
324325
ring_idx = (val >> 16) & 0xFFFF
325-
print(f"doorbell rung for pipe {pipe} @ {ring_idx}")
326-
327-
if pipe not in self._last_ring_idx:
328-
self._last_ring_idx[pipe] = 0
326+
print(f"doorbell #{db_idx} rung @ {ring_idx}")
329327

330328
try:
331-
if pipe == 0:
332-
for i in range(self._last_ring_idx[pipe], ring_idx):
333-
tr_data_addr = self._ctx.mtr + 0x10 * i
334-
print(f"TR idx {i} @ iova {tr_data_addr:016X}")
335-
tr_data = self.dart_tracer.dart.ioread(STREAM, tr_data_addr, 0x10)
336-
chexdump(tr_data)
329+
tr_heads = struct.unpack("<HHHHHHHHH", self.dart_tracer.dart.ioread(STREAM, self._ctx.trHIA, 18))
330+
tr_tails = struct.unpack("<HHHHHHHHH", self.dart_tracer.dart.ioread(STREAM, self._ctx.trTIA, 18))
331+
except Exception as e:
332+
print(e)
333+
return
334+
335+
for pipe_idx in range(9):
336+
try:
337+
if pipe_idx == 0:
338+
tr_iova_base = self._ctx.mtr
339+
tr_ent_sz = 0x10
340+
tr_ring_sz = self._ctx.mtrEntry
341+
elif pipe_idx in self._open_pipes:
342+
tr_iova_base = self._open_pipes[pipe_idx].ring_iova
343+
tr_ent_sz = self._open_pipes[pipe_idx].foot_size * 4 + 0x10
344+
tr_ring_sz = self._open_pipes[pipe_idx].ring_count
345+
else:
346+
# print(f"TR{pipe_idx} not open")
347+
continue
348+
349+
print(f"TR{pipe_idx} head {tr_heads[pipe_idx]} tail {tr_tails[pipe_idx]}")
350+
351+
if tr_heads[pipe_idx] >= tr_tails[pipe_idx]:
352+
range_ = range(tr_tails[pipe_idx], tr_heads[pipe_idx])
353+
else:
354+
range_ = itertools.chain(range(tr_tails[pipe_idx], tr_ring_sz), range(0, tr_heads[pipe_idx]))
337355

338-
_, buf_addr, _ = struct.unpack("<IQI", tr_data)
339-
print(f"buf iova {buf_addr:016X}")
340-
data = self.dart_tracer.dart.ioread(STREAM, buf_addr, 0x34)
341-
chexdump(data)
342-
343-
msg_type = data[0]
344-
if msg_type == 1:
345-
open_pipe = OpenPipeMessage._make(struct.unpack(OPENPIPE_STR, data))
346-
print(open_pipe)
347-
348-
self._open_pipes[open_pipe.pipe_idx] = open_pipe
349-
elif msg_type == 2:
350-
open_cr = OpenCompletionRingMessage._make(struct.unpack(OPENCOMPLETIONRING_STR, data))
351-
print(open_cr)
352-
353-
self._open_crs[open_cr.cr_idx] = open_cr
354-
elif msg_type == 3:
355-
close_pipe = ClosePipeMessage._make(struct.unpack(CLOSEPIPE_STR, data))
356-
print(close_pipe)
357-
358-
del self._open_pipes[close_pipe.pipe_idx]
359-
self._last_ring_idx[close_pipe.pipe_idx] = 0
360-
elif msg_type == 4:
361-
close_cr = CloseCompletionRingMessage._make(struct.unpack(CLOSECOMPLETIONRING_STR, data))
362-
print(close_cr)
363-
364-
del self._open_crs[close_cr.cr_idx]
365-
366-
elif pipe in self._open_pipes:
367-
tr_iova = self._open_pipes[pipe].ring_iova
368-
tr_ent_sz = self._open_pipes[pipe].foot_size * 4 + 0x10
369-
370-
for i in range(self._last_ring_idx[pipe], ring_idx):
371-
tr_data_addr = tr_iova + tr_ent_sz * i
372-
print(f"TR idx {i} @ iova {tr_data_addr:016X}")
356+
for i in range_:
357+
tr_data_addr = tr_iova_base + tr_ent_sz * i
358+
print(f"TR{pipe_idx} idx {i} @ iova {tr_data_addr:016X}")
373359
tr_data = self.dart_tracer.dart.ioread(STREAM, tr_data_addr, tr_ent_sz)
374360
chexdump(tr_data)
375-
except Exception as e:
376-
print(e)
377361

378-
self._last_ring_idx[pipe] = ring_idx
362+
if tr_data[0] & 3 == 1:
363+
buf_addr = struct.unpack("<Q", tr_data[4:12])[0]
364+
print(f"buf iova {buf_addr:016X}")
365+
payload = self.dart_tracer.dart.ioread(STREAM, buf_addr, 0x34)
366+
chexdump(payload)
367+
elif tr_data[0] & 3 == 2:
368+
payload = tr_data[0x10:]
369+
else:
370+
print("***** ERROR UNKNOWN WHAT TO DO HERE *****")
371+
payload = b''
372+
373+
if pipe_idx == 0:
374+
msg_type = payload[0]
375+
if msg_type == 1:
376+
open_pipe = OpenPipeMessage._make(struct.unpack(OPENPIPE_STR, payload))
377+
print(open_pipe)
378+
self._open_pipes[open_pipe.pipe_idx] = open_pipe
379+
elif msg_type == 2:
380+
open_cr = OpenCompletionRingMessage._make(struct.unpack(OPENCOMPLETIONRING_STR, payload))
381+
print(open_cr)
382+
self._open_crs[open_cr.cr_idx] = open_cr
383+
elif msg_type == 3:
384+
close_pipe = ClosePipeMessage._make(struct.unpack(CLOSEPIPE_STR, payload))
385+
print(close_pipe)
386+
del self._open_pipes[close_pipe.pipe_idx]
387+
elif msg_type == 4:
388+
close_cr = CloseCompletionRingMessage._make(struct.unpack(CLOSECOMPLETIONRING_STR, payload))
389+
print(close_cr)
390+
del self._open_crs[close_cr.cr_idx]
391+
except Exception as e:
392+
print(e)
393+
379394

380395
def completion_hax_event(self, evt):
396+
if evt.addr != self._crhia_physaddr:
397+
return
398+
381399
print("Checking completion rings!")
382400
try:
383401
cr_heads = struct.unpack("<HHHHHH", self.dart_tracer.dart.ioread(STREAM, self._ctx.crHIA, 12))
384402
cr_tails = struct.unpack("<HHHHHH", self.dart_tracer.dart.ioread(STREAM, self._ctx.crTIA, 12))
403+
except Exception as e:
404+
print(e)
405+
return
385406

386-
for cr_idx in range(6):
387-
print(f"CR {cr_idx} head {cr_heads[cr_idx]} tail {cr_tails[cr_idx]}")
388-
407+
for cr_idx in range(6):
408+
try:
389409
if cr_idx == 0:
390410
cr_iova_base = self._ctx.mcr
391411
cr_ent_sz = 0x10
392-
else:
393-
if cr_idx not in self._open_crs:
394-
print(f"CR {cr_idx} not open")
395-
continue
396-
412+
cr_ring_sz = self._ctx.mcrEntry
413+
elif cr_idx in self._open_crs:
397414
cr_iova_base = self._open_crs[cr_idx].ring_iova
398415
cr_ent_sz = self._open_crs[cr_idx].foot_size * 4 + 0x10
416+
cr_ring_sz = self._open_crs[cr_idx].ring_count
417+
else:
418+
# print(f"CR{cr_idx} not open")
419+
continue
420+
421+
print(f"CR{cr_idx} head {cr_heads[cr_idx]} tail {cr_tails[cr_idx]}")
399422

400-
for cr_ring_idx in range(cr_tails[cr_idx], cr_heads[cr_idx]):
401-
cr_data_addr = cr_iova_base + cr_ent_sz * cr_ring_idx
402-
print(f"CR idx {cr_ring_idx} @ iova {cr_data_addr:016X}")
423+
if cr_heads[cr_idx] >= cr_tails[cr_idx]:
424+
range_ = range(cr_tails[cr_idx], cr_heads[cr_idx])
425+
else:
426+
range_ = itertools.chain(range(cr_tails[cr_idx], cr_ring_sz), range(0, cr_heads[cr_idx]))
427+
428+
for i in range_:
429+
cr_data_addr = cr_iova_base + cr_ent_sz * i
430+
print(f"CR{cr_idx} idx {i} @ iova {cr_data_addr:016X}")
403431
cr_data = self.dart_tracer.dart.ioread(STREAM, cr_data_addr, cr_ent_sz)
404432
chexdump(cr_data)
405-
except Exception as e:
406-
print(e)
433+
except Exception as e:
434+
print(e)
407435

408436

409437
BTTracer = BTTracer._reloadcls()

0 commit comments

Comments
 (0)