freedreno/crashdec: Use register for RB rptr

The register is usually a few dwords ahead of the memory value used by
the kernel, which can lead to an inaccurate calculation of where the SQE
is.

To compensate for the more accurate rptr, increase the lookback
slightly.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34063>
This commit is contained in:
Connor Abbott
2024-07-25 14:05:27 -04:00
committed by Marge Bot
parent 0709e87c94
commit 4667ec043b
4 changed files with 21 additions and 81 deletions
+7 -1
View File
@@ -1673,7 +1673,13 @@ got rb_base=1000000001000
IB1: 100000000, 5
IB2: 0, 0
found ring!
got cmdszdw=27
got cmdszdw=31
opcode: CP_REG_TO_MEM (3e) (4 dwords)
{ REG = 0x400 | CNT = 2 | 64B }
{ DEST = 0x28 }
{ DEST_HI = 0x10000 }
gpuaddr:0001000000000028
0000000000000000: 0000: 703e8003 40080400 00000028 00010000
opcode: CP_REG_TO_MEM (3e) (4 dwords)
{ REG = 0x1f888 | CNT = 2 | 64B }
{ DEST = 0x38 }
@@ -1886,52 +1886,7 @@ got rb_base=1000000001000
IB1: 10022d000, 4112
IB2: 10021d000, 207
found ring!
got cmdszdw=83
opcode: CP_ME_INIT (48) (9 dwords)
0000000000000000: 0000: 70c80008 0000002f 00000003 20000000 00000000 00000000 00000000 00000000
*
opcode: CP_WHERE_AM_I (62) (3 dwords)
0000000000000000: 0000: 70620002 00011000 00010000
opcode: CP_SET_PROTECTED_MODE (5f) (2 dwords)
0000000000000000: 0000: 70df0001 00000000
opcode: CP_SMMU_TABLE_UPDATE (53) (5 dwords)
{ TTBR0_LO = 0x6d0e5000 }
{ TTBR0_HI = 0x1 | ASID = 0 }
{ CONTEXTIDR = 0 }
{ CONTEXTBANK = 0 }
0000000000000000: 0000: 70d30004 6d0e5000 00000001 00000000 00000000
opcode: CP_MEM_WRITE (3d) (5 dwords)
{ ADDR_LO = 0x808 }
{ ADDR_HI = 0x10000 }
gpuaddr:0001000000000808
0000000000000000: 0000: 6d0e5000 00000001
0000000000000000: 0000: 703d0004 00000808 00010000 6d0e5000 00000001
opcode: CP_EVENT_WRITE (46) (2 dwords)
{ EVENT = CACHE_INVALIDATE }
event CACHE_INVALIDATE
0000000000000000: 0000: 70460001 00000031
opcode: CP_WAIT_REG_MEM (3c) (7 dwords)
{ FUNCTION = WRITE_EQ | POLL = POLL_REGISTER }
{ POLL_ADDR_LO = 0x50f }
{ POLL_ADDR_HI = 0 }
{ REF = 0x1 }
{ MASK = 0x1 }
{ DELAY_LOOP_CYCLES = 0 }
0000000000000000: 0000: 70bc8006 00000003 0000050f 00000000 00000001 00000001 00000000
opcode: CP_SET_PROTECTED_MODE (5f) (2 dwords)
0000000000000000: 0000: 70df0001 00000001
opcode: CP_REG_TO_MEM (3e) (4 dwords)
{ REG = 0x400 | CNT = 2 | 64B }
{ DEST = 0x7e8 }
{ DEST_HI = 0x10000 }
gpuaddr:00010000000007e8
0000000000000000: 0000: 703e8003 40080400 000007e8 00010000
opcode: CP_REG_TO_MEM (3e) (4 dwords)
{ REG = 0x980 | CNT = 2 | 64B }
{ DEST = 0x7f8 }
{ DEST_HI = 0x10000 }
gpuaddr:00010000000007f8
0000000000000000: 0000: 703e8003 40080980 000007f8 00010000
got cmdszdw=38
opcode: CP_EVENT_WRITE (46) (2 dwords)
{ EVENT = PC_CCU_INVALIDATE_DEPTH }
event PC_CCU_INVALIDATE_DEPTH
@@ -1985,7 +1940,6 @@ got cmdszdw=83
mode: (null)
skip_ib2: g=0, l=0
draw[0] register values
!+ 00000001 RBBM_PERFCTR_SRAM_INIT_CMD: 0x1
!+ 100188000 VSC_DRAW_STRM_SIZE_ADDRESS: 0x100188000
!+ 1000e7000 VSC_PRIM_STRM_ADDRESS: 0x1000e7000
!+ 100167800 VSC_DRAW_STRM_ADDRESS: 0x100167800
@@ -2465,36 +2465,7 @@ got rb_base=1000000001000
IB1: 10391e000, 312
IB2: 103d38000, 436
found ring!
got cmdszdw=438
opcode: CP_EVENT_WRITE (46) (5 dwords)
{ EVENT = CACHE_FLUSH_TS | IRQ }
{ ADDR_0_LO = 0x4 }
{ ADDR_0_HI = 0x10000 }
{ 3 = 0x152b }
event CACHE_FLUSH_TS
0000000000000000: 0000: 70460004 80000004 00000004 00010000 0000152b
opcode: CP_WHERE_AM_I (62) (3 dwords)
0000000000000000: 0000: 70620002 00011000 00010000
opcode: CP_REG_TO_MEM (3e) (4 dwords)
{ REG = 0x400 | CNT = 2 | 64B }
{ DEST = 0x588 }
{ DEST_HI = 0x10000 }
gpuaddr:0001000000000588
0000000000000000: 0000: 703e8003 40080400 00000588 00010000
opcode: CP_REG_TO_MEM (3e) (4 dwords)
{ REG = 0x980 | CNT = 2 | 64B }
{ DEST = 0x598 }
{ DEST_HI = 0x10000 }
gpuaddr:0001000000000598
0000000000000000: 0000: 703e8003 40080980 00000598 00010000
opcode: CP_EVENT_WRITE (46) (2 dwords)
{ EVENT = PC_CCU_INVALIDATE_DEPTH }
event PC_CCU_INVALIDATE_DEPTH
0000000000000000: 0000: 70460001 00000018
opcode: CP_EVENT_WRITE (46) (2 dwords)
{ EVENT = PC_CCU_INVALIDATE_COLOR }
event PC_CCU_INVALIDATE_COLOR
0000000000000000: 0000: 70460001 00000019
got cmdszdw=416
opcode: CP_INDIRECT_BUFFER (3f) (4 dwords)
opcode: CP_EVENT_WRITE (46) (2 dwords)
{ EVENT = PC_CCU_INVALIDATE_COLOR }
@@ -2532,7 +2503,6 @@ got cmdszdw=438
mode: (null)
skip_ib2: g=0, l=0
draw[0] register values
!+ 0000152b CP_SCRATCH[0x2].REG: 5419
!+ 03200000 UCHE_UNKNOWN_0E12: 0x3200000
!+ 00000004 UCHE_CLIENT_PF: { PERFSEL = 0x4 }
+ 00000000 GRAS_SU_CONSERVATIVE_RAS_CNTL: { SHIFTAMOUNT = NO_SHIFT }
+12 -2
View File
@@ -362,6 +362,7 @@ dump_cmdstream(void)
options.ibs[2].base = regval64("CP_IB2_BASE");
if (have_rem_info())
options.ibs[2].rem = regval("CP_IB2_REM_SIZE");
uint32_t rb_rptr = regval("CP_RB_RPTR");
/* Adjust remaining size to account for cmdstream slurped into ROQ
* but not yet consumed by SQE
@@ -372,9 +373,11 @@ dump_cmdstream(void)
* TODO it would be nice to be able to extract out register bitfields
* by name rather than hard-coding this.
*/
uint32_t rb_rem = 0;
if (have_rem_info()) {
uint32_t ib1_rem = regval("CP_ROQ_AVAIL_IB1") >> 16;
uint32_t ib2_rem = regval("CP_ROQ_AVAIL_IB2") >> 16;
rb_rem = regval("CP_ROQ_AVAIL_RB") >> 16;
options.ibs[1].rem += ib1_rem ? ib1_rem - 1 : 0;
options.ibs[2].rem += ib2_rem ? ib2_rem - 1 : 0;
}
@@ -410,14 +413,21 @@ dump_cmdstream(void)
/* helper macro to deal with modulo size math: */
#define mod_add(b, v) ((ringszdw + (int)(b) + (int)(v)) % ringszdw)
/* On a7xx, the RPTR seems to be the point the SQE is reading, and on
* a6xx it is the point the ROQ is reading. We really care about where
* the SQE is reading, so back it up on a6xx.
*/
if (is_a6xx())
rb_rptr = mod_add(rb_rptr, -rb_rem);
/* The rptr will (most likely) have moved past the IB to
* userspace cmdstream, so back up a bit, and then advance
* until we find a valid start of a packet.. this is going
* to be less reliable on a4xx and before (pkt0/pkt3),
* compared to pkt4/pkt7 with parity bits
*/
const int lookback = 12;
unsigned rptr = mod_add(ringbuffers[id].rptr, -lookback);
const int lookback = 20;
unsigned rptr = mod_add(rb_rptr, -lookback);
for (int idx = 0; idx < lookback; idx++) {
if (valid_header(ringbuffers[id].buf[rptr]))