aubinator: add a custom handler for immediate register load
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Fri, 9 Sep 2016 10:22:59 +0000 (11:22 +0100)
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>
Tue, 20 Sep 2016 09:47:21 +0000 (10:47 +0100)
Transforming this :

0x00c77084:  0x11000001:  MI_LOAD_REGISTER_IMM
0x00c77088:  0x0000b020 : Dword 1
    Register Offset: 0x0000b020
    0x00c7708c:  0x00880038 : Dword 2
    Data DWord: 8912952

Into this:

0x007880f0:  0x11000001:  MI_LOAD_REGISTER_IMM
0x007880f4:  0x0000b020 : Dword 1
    Register Offset: 0x0000b020
    0x007880f8:  0x00080040 : Dword 2
    Data DWord: 524352
register L3CNTLREG2 (0xb020) : 0x80040
    SLM Enable: 0
    URB Allocation: 32
    URB Low Bandwidth: 0
    RO Allocation: 32
    RO Low Bandwidth: 0
    DC Allocation: 0
    DC Low Bandwidth: 0

v2: Drop unused arguments (Sirisha)
    Print out register name

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
src/intel/tools/aubinator.c
src/intel/tools/decoder.c
src/intel/tools/decoder.h

index fad8aaa27bcedb780816765881be4e80d6db7a69..a31dcb226021df17a49090f576d2f44788b4a908 100644 (file)
@@ -616,6 +616,18 @@ handle_3dstate_scissor_state_pointers(struct gen_spec *spec, uint32_t *p)
    decode_structure(spec, scissor_rect, gtt + start);
 }
 
+static void
+handle_load_register_imm(struct gen_spec *spec, uint32_t *p)
+{
+   struct gen_group *reg = gen_spec_find_register(spec, p[1]);
+
+   if (reg != NULL) {
+      printf("register %s (0x%x): 0x%x\n",
+             reg->name, reg->register_offset, p[2]);
+      decode_structure(spec, reg, &p[2]);
+   }
+}
+
 #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
 
 #define STATE_BASE_ADDRESS                  0x61010000
@@ -654,6 +666,8 @@ handle_3dstate_scissor_state_pointers(struct gen_spec *spec, uint32_t *p)
 #define _3DSTATE_CC_STATE_POINTERS          0x780e0000
 #define _3DSTATE_SCISSOR_STATE_POINTERS     0x780f0000
 
+#define _MI_LOAD_REGISTER_IMM               0x11000000
+
 struct custom_handler {
    uint32_t opcode;
    void (*handle)(struct gen_spec *spec, uint32_t *p);
@@ -687,7 +701,8 @@ struct custom_handler {
    { _3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP, handle_3dstate_viewport_state_pointers_sf_clip },
    { _3DSTATE_BLEND_STATE_POINTERS, handle_3dstate_blend_state_pointers },
    { _3DSTATE_CC_STATE_POINTERS, handle_3dstate_cc_state_pointers },
-   { _3DSTATE_SCISSOR_STATE_POINTERS, handle_3dstate_scissor_state_pointers }
+   { _3DSTATE_SCISSOR_STATE_POINTERS, handle_3dstate_scissor_state_pointers },
+   { _MI_LOAD_REGISTER_IMM, handle_load_register_imm }
 };
 
 static void
index f080437d89477a6ac4de6fa45bf392a5e8d9828f..b5f557cfeedc1f604f1ffaa1d07e8a2868aec1e5 100644 (file)
@@ -88,6 +88,16 @@ gen_spec_find_struct(struct gen_spec *spec, const char *name)
    return NULL;
 }
 
+struct gen_group *
+gen_spec_find_register(struct gen_spec *spec, uint32_t offset)
+{
+   for (int i = 0; i < spec->nregisters; i++)
+      if (spec->registers[i]->register_offset == offset)
+         return spec->registers[i];
+
+   return NULL;
+}
+
 uint32_t
 gen_spec_get_gen(struct gen_spec *spec)
 {
@@ -168,6 +178,19 @@ get_group_offset_count(struct parser_context *ctx, const char *name,
    return;
 }
 
+static void
+get_register_offset(const char **atts, uint32_t *offset)
+{
+   char *p;
+   int i;
+
+   for (i = 0; atts[i]; i += 2) {
+      if (strcmp(atts[i], "num") == 0)
+         *offset = strtoul(atts[i + 1], &p, 0);
+   }
+   return;
+}
+
 static inline uint64_t
 mask(int start, int end)
 {
@@ -288,9 +311,11 @@ start_element(void *data, const char *element_name, const char **atts)
 
       ctx->spec->gen = MAKE_GEN(major, minor);
    } else if (strcmp(element_name, "instruction") == 0 ||
-              strcmp(element_name, "struct") == 0 ||
-              strcmp(element_name, "register") == 0) {
+              strcmp(element_name, "struct") == 0) {
+      ctx->group = create_group(ctx, name, atts);
+   } else if (strcmp(element_name, "register") == 0) {
       ctx->group = create_group(ctx, name, atts);
+      get_register_offset(atts, &ctx->group->register_offset);
    } else if (strcmp(element_name, "group") == 0) {
       get_group_offset_count(ctx, name, atts, &ctx->group->group_offset,
                              &ctx->group->group_count);
index 4ab0765b95db2dd20bb2daf106465502619c042b..f688ba59e8b0c7129a30e3f7a5375da879d13a15 100644 (file)
@@ -39,6 +39,7 @@ struct gen_group *gen_spec_find_struct(struct gen_spec *spec, const char *name);
 struct gen_spec *gen_spec_load(const char *filename);
 uint32_t gen_spec_get_gen(struct gen_spec *spec);
 struct gen_group *gen_spec_find_instruction(struct gen_spec *spec, const uint32_t *p);
+struct gen_group *gen_spec_find_register(struct gen_spec *spec, uint32_t offset);
 int gen_group_get_length(struct gen_group *group, const uint32_t *p);
 const char *gen_group_get_name(struct gen_group *group);
 uint32_t gen_group_get_opcode(struct gen_group *group);
@@ -59,6 +60,9 @@ struct gen_group {
 
    uint32_t opcode_mask;
    uint32_t opcode;
+
+   /* Register specific */
+   uint32_t register_offset;
 };
 
 struct gen_type {