From 745dad0446977f983056e1a98d713caaa1fb06c5 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 21 May 2021 08:39:08 -0700 Subject: [PATCH] freedreno/afuc: Add pipe reg name decoding Signed-off-by: Rob Clark Part-of: --- .../.gitlab-ci/reference/afuc_test.asm | 4 +- src/freedreno/afuc/disasm.c | 22 ++++++ src/freedreno/afuc/util.c | 73 ++++++++++++++----- src/freedreno/afuc/util.h | 3 + .../registers/adreno/adreno_pipe_regs.xml | 3 + 5 files changed, 84 insertions(+), 21 deletions(-) diff --git a/src/freedreno/.gitlab-ci/reference/afuc_test.asm b/src/freedreno/.gitlab-ci/reference/afuc_test.asm index 7316504a51d..aa0f370cd66 100644 --- a/src/freedreno/.gitlab-ci/reference/afuc_test.asm +++ b/src/freedreno/.gitlab-ci/reference/afuc_test.asm @@ -19,10 +19,10 @@ CP_ME_INIT: mov $01, $data CP_MEM_WRITE: - mov $addr, 0x00a0 << 24 + mov $addr, 0x00a0 << 24 ; |NRT_ADDR mov $02, 0x0004 (xmov1)add $data, $02, $data - mov $addr, 0xa204 << 16 + mov $addr, 0xa204 << 16 ; |NRT_DATA (rep)(xmov3)mov $data, $data waitin mov $01, $data diff --git a/src/freedreno/afuc/disasm.c b/src/freedreno/afuc/disasm.c index 6dfccb2eae9..145fdbda9a7 100644 --- a/src/freedreno/afuc/disasm.c +++ b/src/freedreno/afuc/disasm.c @@ -269,6 +269,18 @@ print_control_reg(uint32_t id) } } +static void +print_pipe_reg(uint32_t id) +{ + char *name = afuc_pipe_reg_name(id); + if (name) { + printf("|%s", name); + free(name); + } else { + printf("0x%03x", id); + } +} + static void disasm_instr(uint32_t *instrs, unsigned pc) { @@ -385,6 +397,16 @@ disasm_instr(uint32_t *instrs, unsigned pc) if (instr->movi.shift) printf(" << %u", instr->movi.shift); + if ((instr->movi.dst == REG_ADDR) && (instr->movi.shift >= 16)) { + uint32_t val = instr->movi.uimm << instr->movi.shift; + val &= ~0x40000; /* b18 seems to be a flag */ + + if ((val & 0x00ffffff) == 0) { + printf("\t; "); + print_pipe_reg(val >> 24); + break; + } + } /* using mov w/ << 16 is popular way to construct a pkt7 * header to send (for ex, from PFP to ME), so check that * case first diff --git a/src/freedreno/afuc/util.c b/src/freedreno/afuc/util.c index b48cc7a3087..c0be0926816 100644 --- a/src/freedreno/afuc/util.c +++ b/src/freedreno/afuc/util.c @@ -34,6 +34,7 @@ static struct rnndeccontext *ctx; static struct rnndb *db; static struct rnndomain *control_regs; +static struct rnndomain *pipe_regs; struct rnndomain *dom[2]; static struct rnnenum *pm4_packets; @@ -47,22 +48,41 @@ find_reg(struct rnndomain *dom, const char *name) return -1; } +static unsigned +reg(struct rnndomain *dom, const char *type, const char *name) +{ + int val = find_reg(dom, name); + if (val < 0) { + char *endptr = NULL; + val = strtol(name, &endptr, 0); + if (endptr && *endptr) { + printf("invalid %s reg: %s\n", type, name); + exit(2); + } + } + return (unsigned)val; +} + +static char * +reg_name(struct rnndomain *dom, unsigned id) +{ + if (rnndec_checkaddr(ctx, dom, id, 0)) { + struct rnndecaddrinfo *info = rnndec_decodeaddr(ctx, dom, id, 0); + char *name = info->name; + free(info); + return name; + } else { + return NULL; + } +} + /** * Map control reg name to offset. */ unsigned afuc_control_reg(const char *name) { - int val = find_reg(control_regs, name); - if (val < 0) { - char *endptr = NULL; - val = strtol(name, &endptr, 0); - if (endptr) { - printf("invalid control reg: %s\n", name); - exit(2); - } - } - return (unsigned)val; + return reg(control_regs, "control", name); } /** @@ -71,14 +91,25 @@ afuc_control_reg(const char *name) char * afuc_control_reg_name(unsigned id) { - if (rnndec_checkaddr(ctx, control_regs, id, 0)) { - struct rnndecaddrinfo *info = rnndec_decodeaddr(ctx, control_regs, id, 0); - char *name = info->name; - free(info); - return name; - } else { - return NULL; - } + return reg_name(control_regs, id); +} + +/** + * Map pipe reg name to offset. + */ +unsigned +afuc_pipe_reg(const char *name) +{ + return reg(pipe_regs, "pipe", name); +} + +/** + * Map offset to pipe reg name (or NULL), caller frees + */ +char * +afuc_pipe_reg_name(unsigned id) +{ + return reg_name(pipe_regs, id); } /** @@ -93,7 +124,7 @@ afuc_gpu_reg(const char *name) if (val < 0) { char *endptr = NULL; val = strtol(name, &endptr, 0); - if (endptr) { + if (endptr && *endptr) { printf("invalid control reg: %s\n", name); exit(2); } @@ -172,15 +203,18 @@ afuc_printc(enum afuc_color c, const char *fmt, ...) int afuc_util_init(int gpuver, bool colors) { char *name, *control_reg_name; + char *pipe_reg_name = NULL; switch (gpuver) { case 6: name = "A6XX"; control_reg_name = "A6XX_CONTROL_REG"; + pipe_reg_name = "A6XX_PIPE_REG"; break; case 5: name = "A5XX"; control_reg_name = "A5XX_CONTROL_REG"; + pipe_reg_name = "A5XX_PIPE_REG"; break; default: fprintf(stderr, "unknown GPU version!\n"); @@ -200,6 +234,7 @@ int afuc_util_init(int gpuver, bool colors) dom[0] = rnn_finddomain(db, name); dom[1] = rnn_finddomain(db, "AXXX"); control_regs = rnn_finddomain(db, control_reg_name); + pipe_regs = rnn_finddomain(db, pipe_reg_name); rnndec_varadd(ctx, "chip", name); diff --git a/src/freedreno/afuc/util.h b/src/freedreno/afuc/util.h index 436bf63f435..4b70d221ae4 100644 --- a/src/freedreno/afuc/util.h +++ b/src/freedreno/afuc/util.h @@ -33,6 +33,9 @@ unsigned afuc_control_reg(const char *name); char * afuc_control_reg_name(unsigned id); +unsigned afuc_pipe_reg(const char *name); +char * afuc_pipe_reg_name(unsigned id); + unsigned afuc_gpu_reg(const char *name); char * afuc_gpu_reg_name(unsigned id); diff --git a/src/freedreno/registers/adreno/adreno_pipe_regs.xml b/src/freedreno/registers/adreno/adreno_pipe_regs.xml index d5292694cda..70ce19d7cd1 100644 --- a/src/freedreno/registers/adreno/adreno_pipe_regs.xml +++ b/src/freedreno/registers/adreno/adreno_pipe_regs.xml @@ -32,6 +32,9 @@ CP_WAIT_MEM_WRITES: Special type to mark registers with no payload. + + +