From d9c90eee8b8fa4aa9d397605d43d726139ad5429 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Tue, 3 Aug 2021 15:34:56 +0200 Subject: [PATCH] freedreno: Decode a650+ CP_START_BIN/CP_END_BIN packets The blob uses them for GMEM renderpasses. Part-of: --- src/freedreno/.gitlab-ci/reference/afuc_test.asm | 4 +-- src/freedreno/.gitlab-ci/traces/afuc_test.asm | 4 +-- src/freedreno/decode/cffdec.c | 46 ++++++++++++++++++++++++ src/freedreno/registers/adreno/adreno_pm4.xml | 32 ++++++++++++++++- 4 files changed, 81 insertions(+), 5 deletions(-) diff --git a/src/freedreno/.gitlab-ci/reference/afuc_test.asm b/src/freedreno/.gitlab-ci/reference/afuc_test.asm index 920aa4d..f4ad047 100644 --- a/src/freedreno/.gitlab-ci/reference/afuc_test.asm +++ b/src/freedreno/.gitlab-ci/reference/afuc_test.asm @@ -213,8 +213,8 @@ CP_SET_DRAW_INIT_FLAGS: CP_SCRATCH_TO_REG: CP_DRAW_PRED_SET: CP_MEM_WRITE_CNTR: -UNKN80: -CP_SET_BIN_SELECT: +CP_START_BIN: +CP_END_BIN: CP_WAIT_REG_EQ: CP_SMMU_TABLE_UPDATE: UNKN84: diff --git a/src/freedreno/.gitlab-ci/traces/afuc_test.asm b/src/freedreno/.gitlab-ci/traces/afuc_test.asm index 68a3061..089100d 100644 --- a/src/freedreno/.gitlab-ci/traces/afuc_test.asm +++ b/src/freedreno/.gitlab-ci/traces/afuc_test.asm @@ -274,8 +274,8 @@ CP_SET_DRAW_INIT_FLAGS: CP_SCRATCH_TO_REG: CP_DRAW_PRED_SET: CP_MEM_WRITE_CNTR: -UNKN80: -CP_SET_BIN_SELECT: +CP_START_BIN: +CP_END_BIN: CP_WAIT_REG_EQ: CP_SMMU_TABLE_UPDATE: UNKN84: diff --git a/src/freedreno/decode/cffdec.c b/src/freedreno/decode/cffdec.c index cede1dd..b112be7 100644 --- a/src/freedreno/decode/cffdec.c +++ b/src/freedreno/decode/cffdec.c @@ -2190,6 +2190,50 @@ cp_indirect(uint32_t *dwords, uint32_t sizedwords, int level) } static void +cp_start_bin(uint32_t *dwords, uint32_t sizedwords, int level) +{ + uint64_t ibaddr; + uint32_t ibsize; + uint32_t loopcount; + uint32_t *ptr = NULL; + + loopcount = dwords[0]; + ibaddr = dwords[1]; + ibaddr |= ((uint64_t)dwords[2]) << 32; + ibsize = dwords[3]; + + /* map gpuaddr back to hostptr: */ + ptr = hostptr(ibaddr); + + if (ptr) { + /* If the GPU hung within the target IB, the trigger point will be + * just after the current CP_START_BIN. Because the IB is + * executed but never returns. Account for this by checking if + * the IB returned: + */ + highlight_gpuaddr(gpuaddr(&dwords[5])); + + /* TODO: we should duplicate the body of the loop after each bin, so + * that draws get the correct state. We should also figure out if there + * are any registers that can tell us what bin we're in when we hang so + * that crashdec points to the right place. + */ + ib++; + for (uint32_t i = 0; i < loopcount; i++) { + ibs[ib].base = ibaddr; + ibs[ib].size = ibsize; + printf("%sbin %u\n", levels[level], i); + dump_commands(ptr, ibsize, level); + ibaddr += ibsize; + ptr += ibsize; + } + ib--; + } else { + fprintf(stderr, "could not find: %016" PRIx64 " (%d)\n", ibaddr, ibsize); + } +} + +static void cp_wfi(uint32_t *dwords, uint32_t sizedwords, int level) { needs_wfi = false; @@ -2646,6 +2690,8 @@ static const struct type3_op { CP(REG_WRITE, cp_reg_write), CP(SET_CTXSWITCH_IB, cp_set_ctxswitch_ib), + + CP(START_BIN, cp_start_bin), }; static void diff --git a/src/freedreno/registers/adreno/adreno_pm4.xml b/src/freedreno/registers/adreno/adreno_pm4.xml index 12215a8..c53f6a2 100644 --- a/src/freedreno/registers/adreno/adreno_pm4.xml +++ b/src/freedreno/registers/adreno/adreno_pm4.xml @@ -240,7 +240,7 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd"> sets the 64-bit BIN_MASK register in the PFP sets the 64-bit BIN_SELECT register in the PFP - + updates the current context, if needed generate interrupt from the command stream @@ -478,6 +478,20 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd"> --> + + These first appear in a650_sqe.bin. They can in theory be used + to loop any sequence of IB1 commands, but in practice they are + used to loop over bins. There is a fixed-size per-iteration + prefix, used to set per-bin state, and then the following IB1 + commands are executed until CP_END_BIN which are always the same + for each iteration and usually contain a list of + CP_INDIRECT_BUFFER calls to IB2 commands which setup state and + execute restore/draw/save commands. This replaces the previous + technique of just repeating the CP_INDIRECT_BUFFER calls and + "unrolling" the loop. + + + @@ -1758,5 +1772,21 @@ opcode: CP_LOAD_STATE4 (30) (4 dwords) + + + + + + Size of prefix for each bin. For each bin index i, the + prefix commands at PREFIX_ADDR + i * PREFIX_DWORDS are + executed in an IB2 before the IB1 commands following + this packet. + + + + Number of dwords after this packet until CP_END_BIN + + + -- 2.7.4