|
64 | 64 | CLOSEPIPE_STR = "<B1sH48s" |
65 | 65 |
|
66 | 66 |
|
| 67 | +OpenCompletionRingMessage = namedtuple('OpenCompletionRingMessage', [ |
| 68 | + 'type', |
| 69 | + 'head_size', |
| 70 | + 'foot_size', |
| 71 | + 'pad_0x3_', |
| 72 | + 'cr_idx', |
| 73 | + 'cr_idx_', |
| 74 | + 'ring_iova', |
| 75 | + 'ring_count', |
| 76 | + 'unk_0x12_', |
| 77 | + 'pad_0x16_', |
| 78 | + 'msi', |
| 79 | + 'intmod_delay', |
| 80 | + 'intmod_bytes', |
| 81 | + 'accum_delay', |
| 82 | + 'accum_bytes', |
| 83 | + 'pad_0x2a_', |
| 84 | +]) |
| 85 | +OPENCOMPLETIONRING_STR = "<BBB1sHHQHI6sHHIHI10s" |
| 86 | + |
| 87 | + |
| 88 | +CloseCompletionRingMessage = namedtuple('CloseCompletionRingMessage', [ |
| 89 | + 'type', |
| 90 | + 'pad_0x1_', |
| 91 | + 'cr_idx', |
| 92 | + 'pad_0x4_' |
| 93 | +]) |
| 94 | +CLOSECOMPLETIONRING_STR = "<B1sH48s" |
| 95 | + |
| 96 | + |
67 | 97 | class BTBAR0Regs(RegMap): |
68 | 98 | IMG_DOORBELL = 0x140, Register32 |
69 | 99 | RTI_CONTROL = 0x144, Register32 |
@@ -261,16 +291,26 @@ def hook(name, iova, sz): |
261 | 291 | self.trace(physaddr, sz, TraceMode.SYNC, prefix=name) |
262 | 292 |
|
263 | 293 | hook('perInfo', context.perInfo, 0x10) |
264 | | - hook('crHIA', context.crHIA, 12) |
265 | | - hook('crTIA', context.crTIA, 12) |
266 | | - hook('trHIA', context.trHIA, 18) |
267 | | - hook('trTIA', context.trTIA, 18) |
268 | | - hook('mcr', context.mcr, 0x800) # no idea size |
269 | | - hook('mtr', context.mtr, 0x800) # i _think_ this is correct |
| 294 | + # hook('crHIA', context.crHIA, 12) |
| 295 | + # hook('crTIA', context.crTIA, 12) |
| 296 | + # hook('trHIA', context.trHIA, 18) |
| 297 | + # hook('trTIA', context.trTIA, 18) |
| 298 | + # hook('mcr', context.mcr, 0x800) # no idea size |
| 299 | + # hook('mtr', context.mtr, 0x800) # i _think_ this is correct |
| 300 | + |
| 301 | + crhia_physaddr = self.dart_tracer.dart.iotranslate(STREAM, context.crHIA, 1)[0][0] |
| 302 | + self.hv.add_tracer( |
| 303 | + irange(crhia_physaddr, 4), |
| 304 | + self.ident, |
| 305 | + TraceMode.SYNC, |
| 306 | + self.completion_hax_event, |
| 307 | + None |
| 308 | + ) |
270 | 309 |
|
271 | 310 | self._ctx = context |
272 | 311 | self._last_ring_idx = {} |
273 | 312 | self._open_pipes = {} |
| 313 | + self._open_crs = {} |
274 | 314 |
|
275 | 315 | except Exception as e: |
276 | 316 | print(e) |
@@ -306,26 +346,65 @@ def w_DOORBELL_05(self, val): |
306 | 346 | print(open_pipe) |
307 | 347 |
|
308 | 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 |
309 | 354 | elif msg_type == 3: |
310 | 355 | close_pipe = ClosePipeMessage._make(struct.unpack(CLOSEPIPE_STR, data)) |
311 | 356 | print(close_pipe) |
312 | 357 |
|
313 | 358 | del self._open_pipes[close_pipe.pipe_idx] |
314 | 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 | + |
315 | 366 | elif pipe in self._open_pipes: |
316 | 367 | tr_iova = self._open_pipes[pipe].ring_iova |
| 368 | + tr_ent_sz = self._open_pipes[pipe].foot_size * 4 + 0x10 |
317 | 369 |
|
318 | 370 | for i in range(self._last_ring_idx[pipe], ring_idx): |
319 | | - # FIXME where does this size come from? |
320 | | - tr_data_addr = tr_iova + 0x118 * i |
| 371 | + tr_data_addr = tr_iova + tr_ent_sz * i |
321 | 372 | print(f"TR idx {i} @ iova {tr_data_addr:016X}") |
322 | | - tr_data = self.dart_tracer.dart.ioread(STREAM, tr_data_addr, 0x118) |
| 373 | + tr_data = self.dart_tracer.dart.ioread(STREAM, tr_data_addr, tr_ent_sz) |
323 | 374 | chexdump(tr_data) |
324 | 375 | except Exception as e: |
325 | 376 | print(e) |
326 | 377 |
|
327 | 378 | self._last_ring_idx[pipe] = ring_idx |
328 | 379 |
|
| 380 | + def completion_hax_event(self, evt): |
| 381 | + print("Checking completion rings!") |
| 382 | + try: |
| 383 | + cr_heads = struct.unpack("<HHHHHH", self.dart_tracer.dart.ioread(STREAM, self._ctx.crHIA, 12)) |
| 384 | + cr_tails = struct.unpack("<HHHHHH", self.dart_tracer.dart.ioread(STREAM, self._ctx.crTIA, 12)) |
| 385 | + |
| 386 | + for cr_idx in range(6): |
| 387 | + print(f"CR {cr_idx} head {cr_heads[cr_idx]} tail {cr_tails[cr_idx]}") |
| 388 | + |
| 389 | + if cr_idx == 0: |
| 390 | + cr_iova_base = self._ctx.mcr |
| 391 | + 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 | + |
| 397 | + cr_iova_base = self._open_crs[cr_idx].ring_iova |
| 398 | + cr_ent_sz = self._open_crs[cr_idx].foot_size * 4 + 0x10 |
| 399 | + |
| 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}") |
| 403 | + cr_data = self.dart_tracer.dart.ioread(STREAM, cr_data_addr, cr_ent_sz) |
| 404 | + chexdump(cr_data) |
| 405 | + except Exception as e: |
| 406 | + print(e) |
| 407 | + |
329 | 408 |
|
330 | 409 | BTTracer = BTTracer._reloadcls() |
331 | 410 |
|
|
0 commit comments