Recent kernels compress the active objects using zlib + ascii85
encoding. This adapts the tool to decompress those inplace.

Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 tools/Makefile.sources     |  1 +
 tools/intel_error_decode.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+)

diff --git a/tools/Makefile.sources b/tools/Makefile.sources
index 48b89db..94c070c 100644
--- a/tools/Makefile.sources
+++ b/tools/Makefile.sources
@@ -42,6 +42,7 @@ intel_dump_decode_SOURCES =   \
 
 intel_error_decode_SOURCES =   \
        intel_error_decode.c
+intel_error_decode_LDFLAGS = -lz
 
 intel_bios_reader_SOURCES =    \
        intel_bios_reader.c     \
diff --git a/tools/intel_error_decode.c b/tools/intel_error_decode.c
index 14589a3..b443e35 100644
--- a/tools/intel_error_decode.c
+++ b/tools/intel_error_decode.c
@@ -51,6 +51,7 @@
 #include <err.h>
 #include <assert.h>
 #include <intel_bufmgr.h>
+#include <zlib.h>
 
 #include "intel_chipset.h"
 #include "intel_io.h"
@@ -334,6 +335,87 @@ static void decode(struct drm_intel_decode *ctx, bool 
is_batch,
        *count = 0;
 }
 
+static int zlib_inflate(uint32_t **ptr, int len)
+{
+       struct z_stream_s zstream;
+       void *out;
+
+       memset(&zstream, 0, sizeof(zstream));
+
+       zstream.next_in = (unsigned char *)*ptr;
+       zstream.avail_in = 4*len;
+
+       if (inflateInit(&zstream) != Z_OK)
+               return 0;
+
+       out = malloc(128*4096); /* approximate obj size */
+       zstream.next_out = out;
+       zstream.avail_out = 40*len;
+
+       do {
+               switch (inflate(&zstream, Z_SYNC_FLUSH)) {
+               case Z_STREAM_END:
+                       goto end;
+               case Z_OK:
+                       break;
+               default:
+                       inflateEnd(&zstream);
+                       return 0;
+               }
+
+               if (zstream.avail_out)
+                       break;
+
+               out = realloc(out, 2*zstream.total_out);
+               if (out == NULL) {
+                       inflateEnd(&zstream);
+                       return 0;
+               }
+
+               zstream.next_out = (unsigned char *)out + zstream.total_out;
+               zstream.avail_out = zstream.total_out;
+       } while (1);
+end:
+       inflateEnd(&zstream);
+       free(*ptr);
+       *ptr = out;
+       return zstream.total_out / 4;
+}
+
+static int ascii85_decode(const char *in, uint32_t **out)
+{
+       int len = 0, size = 1024;
+
+       *out = realloc(*out, sizeof(uint32_t)*size);
+       if (*out == NULL)
+               return 0;
+
+       while (*in != '\n') {
+               uint32_t v = 0;
+
+               if (len == size) {
+                       size *= 2;
+                       *out = realloc(*out, sizeof(uint32_t)*size);
+                       if (*out == NULL)
+                               return 0;
+               }
+
+               if (*in == 'z') {
+                       in++;
+               } else {
+                       v += in[0] - 33; v *= 85;
+                       v += in[1] - 33; v *= 85;
+                       v += in[2] - 33; v *= 85;
+                       v += in[3] - 33; v *= 85;
+                       v += in[4] - 33;
+                       in += 5;
+               }
+               (*out)[len++] = v;
+       }
+
+       return zlib_inflate(out, len);
+}
+
 static void
 read_data_file(FILE *file)
 {
@@ -387,6 +469,17 @@ read_data_file(FILE *file)
                        }
                }
 
+               if (line[0] == ':') {
+                       count = ascii85_decode(line+1, &data);
+                       if (count == 0) {
+                               fprintf(stderr, "ASCII85 decode failed.\n");
+                               exit(1);
+                       }
+                       decode(decode_ctx, is_batch, ring_name, gtt_offset,
+                              data, &count);
+                       continue;
+               }
+
                matched = sscanf(line, "%08x : %08x", &offset, &value);
                if (matched != 2) {
                        unsigned int reg;
-- 
2.1.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to