Commit eb2ee1a2 authored by Mikko Perttunen's avatar Mikko Perttunen Committed by Thierry Reding

gpu: host1x: Improve debug disassembly formatting

The host1x driver prints out "disassembly" dumps of the command FIFO
and gather contents on submission timeouts. However, the output has
been quite difficult to read with unnecessary newlines and occasional
missing parentheses.

Fix these problems by using pr_cont to remove unnecessary newlines
and by fixing other small issues.
Signed-off-by: default avatarMikko Perttunen <mperttunen@nvidia.com>
Reviewed-by: default avatarDmitry Osipenko <digetx@gmail.com>
Tested-by: default avatarDmitry Osipenko <digetx@gmail.com>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 2316f29f
...@@ -40,7 +40,19 @@ void host1x_debug_output(struct output *o, const char *fmt, ...) ...@@ -40,7 +40,19 @@ void host1x_debug_output(struct output *o, const char *fmt, ...)
len = vsnprintf(o->buf, sizeof(o->buf), fmt, args); len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
va_end(args); va_end(args);
o->fn(o->ctx, o->buf, len); o->fn(o->ctx, o->buf, len, false);
}
void host1x_debug_cont(struct output *o, const char *fmt, ...)
{
va_list args;
int len;
va_start(args, fmt);
len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
va_end(args);
o->fn(o->ctx, o->buf, len, true);
} }
static int show_channel(struct host1x_channel *ch, void *data, bool show_fifo) static int show_channel(struct host1x_channel *ch, void *data, bool show_fifo)
......
...@@ -24,22 +24,28 @@ ...@@ -24,22 +24,28 @@
struct host1x; struct host1x;
struct output { struct output {
void (*fn)(void *ctx, const char *str, size_t len); void (*fn)(void *ctx, const char *str, size_t len, bool cont);
void *ctx; void *ctx;
char buf[256]; char buf[256];
}; };
static inline void write_to_seqfile(void *ctx, const char *str, size_t len) static inline void write_to_seqfile(void *ctx, const char *str, size_t len,
bool cont)
{ {
seq_write((struct seq_file *)ctx, str, len); seq_write((struct seq_file *)ctx, str, len);
} }
static inline void write_to_printk(void *ctx, const char *str, size_t len) static inline void write_to_printk(void *ctx, const char *str, size_t len,
bool cont)
{ {
pr_info("%s", str); if (cont)
pr_cont("%s", str);
else
pr_info("%s", str);
} }
void __printf(2, 3) host1x_debug_output(struct output *o, const char *fmt, ...); void __printf(2, 3) host1x_debug_output(struct output *o, const char *fmt, ...);
void __printf(2, 3) host1x_debug_cont(struct output *o, const char *fmt, ...);
extern unsigned int host1x_debug_trace_cmdbuf; extern unsigned int host1x_debug_trace_cmdbuf;
......
...@@ -40,48 +40,59 @@ enum { ...@@ -40,48 +40,59 @@ enum {
static unsigned int show_channel_command(struct output *o, u32 val) static unsigned int show_channel_command(struct output *o, u32 val)
{ {
unsigned int mask, subop; unsigned int mask, subop, num;
switch (val >> 28) { switch (val >> 28) {
case HOST1X_OPCODE_SETCLASS: case HOST1X_OPCODE_SETCLASS:
mask = val & 0x3f; mask = val & 0x3f;
if (mask) { if (mask) {
host1x_debug_output(o, "SETCL(class=%03x, offset=%03x, mask=%02x, [", host1x_debug_cont(o, "SETCL(class=%03x, offset=%03x, mask=%02x, [",
val >> 6 & 0x3ff, val >> 6 & 0x3ff,
val >> 16 & 0xfff, mask); val >> 16 & 0xfff, mask);
return hweight8(mask); return hweight8(mask);
} }
host1x_debug_output(o, "SETCL(class=%03x)\n", val >> 6 & 0x3ff); host1x_debug_cont(o, "SETCL(class=%03x)\n", val >> 6 & 0x3ff);
return 0; return 0;
case HOST1X_OPCODE_INCR: case HOST1X_OPCODE_INCR:
host1x_debug_output(o, "INCR(offset=%03x, [", num = val & 0xffff;
host1x_debug_cont(o, "INCR(offset=%03x, [",
val >> 16 & 0xfff); val >> 16 & 0xfff);
return val & 0xffff; if (!num)
host1x_debug_cont(o, "])\n");
return num;
case HOST1X_OPCODE_NONINCR: case HOST1X_OPCODE_NONINCR:
host1x_debug_output(o, "NONINCR(offset=%03x, [", num = val & 0xffff;
host1x_debug_cont(o, "NONINCR(offset=%03x, [",
val >> 16 & 0xfff); val >> 16 & 0xfff);
return val & 0xffff; if (!num)
host1x_debug_cont(o, "])\n");
return num;
case HOST1X_OPCODE_MASK: case HOST1X_OPCODE_MASK:
mask = val & 0xffff; mask = val & 0xffff;
host1x_debug_output(o, "MASK(offset=%03x, mask=%03x, [", host1x_debug_cont(o, "MASK(offset=%03x, mask=%03x, [",
val >> 16 & 0xfff, mask); val >> 16 & 0xfff, mask);
if (!mask)
host1x_debug_cont(o, "])\n");
return hweight16(mask); return hweight16(mask);
case HOST1X_OPCODE_IMM: case HOST1X_OPCODE_IMM:
host1x_debug_output(o, "IMM(offset=%03x, data=%03x)\n", host1x_debug_cont(o, "IMM(offset=%03x, data=%03x)\n",
val >> 16 & 0xfff, val & 0xffff); val >> 16 & 0xfff, val & 0xffff);
return 0; return 0;
case HOST1X_OPCODE_RESTART: case HOST1X_OPCODE_RESTART:
host1x_debug_output(o, "RESTART(offset=%08x)\n", val << 4); host1x_debug_cont(o, "RESTART(offset=%08x)\n", val << 4);
return 0; return 0;
case HOST1X_OPCODE_GATHER: case HOST1X_OPCODE_GATHER:
host1x_debug_output(o, "GATHER(offset=%03x, insert=%d, type=%d, count=%04x, addr=[", host1x_debug_cont(o, "GATHER(offset=%03x, insert=%d, type=%d, count=%04x, addr=[",
val >> 16 & 0xfff, val >> 15 & 0x1, val >> 16 & 0xfff, val >> 15 & 0x1,
val >> 14 & 0x1, val & 0x3fff); val >> 14 & 0x1, val & 0x3fff);
return 1; return 1;
...@@ -89,16 +100,17 @@ static unsigned int show_channel_command(struct output *o, u32 val) ...@@ -89,16 +100,17 @@ static unsigned int show_channel_command(struct output *o, u32 val)
case HOST1X_OPCODE_EXTEND: case HOST1X_OPCODE_EXTEND:
subop = val >> 24 & 0xf; subop = val >> 24 & 0xf;
if (subop == HOST1X_OPCODE_EXTEND_ACQUIRE_MLOCK) if (subop == HOST1X_OPCODE_EXTEND_ACQUIRE_MLOCK)
host1x_debug_output(o, "ACQUIRE_MLOCK(index=%d)\n", host1x_debug_cont(o, "ACQUIRE_MLOCK(index=%d)\n",
val & 0xff); val & 0xff);
else if (subop == HOST1X_OPCODE_EXTEND_RELEASE_MLOCK) else if (subop == HOST1X_OPCODE_EXTEND_RELEASE_MLOCK)
host1x_debug_output(o, "RELEASE_MLOCK(index=%d)\n", host1x_debug_cont(o, "RELEASE_MLOCK(index=%d)\n",
val & 0xff); val & 0xff);
else else
host1x_debug_output(o, "EXTEND_UNKNOWN(%08x)\n", val); host1x_debug_cont(o, "EXTEND_UNKNOWN(%08x)\n", val);
return 0; return 0;
default: default:
host1x_debug_cont(o, "UNKNOWN\n");
return 0; return 0;
} }
} }
...@@ -126,11 +138,11 @@ static void show_gather(struct output *o, phys_addr_t phys_addr, ...@@ -126,11 +138,11 @@ static void show_gather(struct output *o, phys_addr_t phys_addr,
u32 val = *(map_addr + offset / 4 + i); u32 val = *(map_addr + offset / 4 + i);
if (!data_count) { if (!data_count) {
host1x_debug_output(o, "%08x: %08x:", addr, val); host1x_debug_output(o, "%08x: %08x: ", addr, val);
data_count = show_channel_command(o, val); data_count = show_channel_command(o, val);
} else { } else {
host1x_debug_output(o, "%08x%s", val, host1x_debug_cont(o, "%08x%s", val,
data_count > 0 ? ", " : "])\n"); data_count > 1 ? ", " : "])\n");
data_count--; data_count--;
} }
} }
......
...@@ -111,11 +111,11 @@ static void host1x_debug_show_channel_fifo(struct host1x *host, ...@@ -111,11 +111,11 @@ static void host1x_debug_show_channel_fifo(struct host1x *host,
val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_READ); val = host1x_sync_readl(host, HOST1X_SYNC_CFPEEK_READ);
if (!data_count) { if (!data_count) {
host1x_debug_output(o, "%08x:", val); host1x_debug_output(o, "%08x: ", val);
data_count = show_channel_command(o, val); data_count = show_channel_command(o, val);
} else { } else {
host1x_debug_output(o, "%08x%s", val, host1x_debug_cont(o, "%08x%s", val,
data_count > 0 ? ", " : "])\n"); data_count > 1 ? ", " : "])\n");
data_count--; data_count--;
} }
...@@ -126,7 +126,7 @@ static void host1x_debug_show_channel_fifo(struct host1x *host, ...@@ -126,7 +126,7 @@ static void host1x_debug_show_channel_fifo(struct host1x *host,
} while (rd_ptr != wr_ptr); } while (rd_ptr != wr_ptr);
if (data_count) if (data_count)
host1x_debug_output(o, ", ...])\n"); host1x_debug_cont(o, ", ...])\n");
host1x_debug_output(o, "\n"); host1x_debug_output(o, "\n");
host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL); host1x_sync_writel(host, 0x0, HOST1X_SYNC_CFPEEK_CTRL);
......
...@@ -105,11 +105,12 @@ static void host1x_debug_show_channel_fifo(struct host1x *host, ...@@ -105,11 +105,12 @@ static void host1x_debug_show_channel_fifo(struct host1x *host,
HOST1X_HV_CMDFIFO_PEEK_READ); HOST1X_HV_CMDFIFO_PEEK_READ);
if (!data_count) { if (!data_count) {
host1x_debug_output(o, "%08x:", val); host1x_debug_output(o, "%03x 0x%08x: ",
rd_ptr - start, val);
data_count = show_channel_command(o, val); data_count = show_channel_command(o, val);
} else { } else {
host1x_debug_output(o, "%08x%s", val, host1x_debug_cont(o, "%08x%s", val,
data_count > 0 ? ", " : "])\n"); data_count > 1 ? ", " : "])\n");
data_count--; data_count--;
} }
...@@ -120,7 +121,7 @@ static void host1x_debug_show_channel_fifo(struct host1x *host, ...@@ -120,7 +121,7 @@ static void host1x_debug_show_channel_fifo(struct host1x *host,
} while (rd_ptr != wr_ptr); } while (rd_ptr != wr_ptr);
if (data_count) if (data_count)
host1x_debug_output(o, ", ...])\n"); host1x_debug_cont(o, ", ...])\n");
host1x_debug_output(o, "\n"); host1x_debug_output(o, "\n");
host1x_hypervisor_writel(host, 0x0, HOST1X_HV_CMDFIFO_PEEK_CTRL); host1x_hypervisor_writel(host, 0x0, HOST1X_HV_CMDFIFO_PEEK_CTRL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment