freedreno/afuc: Add pipe reg name decoding

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10944>
This commit is contained in:
Rob Clark 2021-05-21 08:39:08 -07:00 committed by Marge Bot
parent 184f474574
commit 745dad0446
5 changed files with 84 additions and 21 deletions

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -32,6 +32,9 @@ CP_WAIT_MEM_WRITES:
<doc>Special type to mark registers with no payload.</doc>
</bitset>
<domain name="A5XX_PIPE_REG" width="32">
</domain>
<domain name="A6XX_PIPE_REG" width="32">
<!-- This replaces CP_WFI_PEND_CTR on a3xx-a5xx -->
<reg32 name="WFI_PEND_DECR" offset="0x81" type="void"/>