<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Aug 9, 2016 at 4:52 PM, Sirisha Gandikota <span dir="ltr"><<a href="mailto:sirisha.gandikota@intel.com" target="_blank">sirisha.gandikota@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Sirisha Gandikota <<a href="mailto:Sirisha.Gandikota@intel.com">Sirisha.Gandikota@intel.com</a>><br>
<br>
Several fixes have been added as part of this as listed below:<br>
<br>
1) Fix the mask and add disassembler handling for STATE_DS, STATE_HS<br>
as the mask returned wrong values of the fields.<br>
<br>
2) Fix the GEN_TYPE_ADDRESS/GEN_TYPE_<wbr>OFFSET decoding - the address/<br>
offset were handled the same way as the other fields and that gives<br>
the wrong values for the address/offset.<br>
<br>
3) Decode nested/recurssive structures - Many packets contain nested<br>
structures, ex: 3DSATE_SO_BUFFER, STATE_BASE_ADDRESS, etc contain MOC<br>
structures. Previously, the aubinator printed 1 if there was a MOC<br>
structure. Now we decode the entire structure and print out its fields.<br>
<br>
4) Print out the DWord address along with its hex value - For a better<br>
clarity of information, it is helpful to print both the address and<br>
hex value of the DWord along with the DWord count. Since the DWord0<br>
contains the instruction code and the instruction length, it is<br>
unnecessary to print the decoded values for DWord0. This information<br>
is already available from the DWord hex value.<br>
<br>
5) Decode the <group> and the corresponding fields in the group- The<br>
<group> tag can have fields of several types including structures. A<br>
group can contain one or more number of fields and this has be correctly<br>
decoded. Previously, aubinator did not decode the groups or the<br>
fields/structures inside them. Now we decode the <group> in the<br>
instructions and structures where the fields in it repeat for any number<br>
of times specified.<br></blockquote><div><br></div><div>One comment for now:  Usually, when making a bunch of changes like this, we try and split each functional change into its own patch.  That way it's more clear what's going on.  This is brand new code, so a couple giant patches may be ok, but having it split up would be nicer. :)  Git has some tools that make this less painful than it might look and I'm available to help if you'd like.<br><br></div><div>I'll try and get around to actually playing with it soon.<br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Signed-off-by: Sirisha Gandikota <<a href="mailto:Sirisha.Gandikota@intel.com">Sirisha.Gandikota@intel.com</a>><br>
---<br>
 src/intel/tools/aubinator.c | 115 ++++++++++++++++++++++++++++++<wbr>+++++++++++---<br>
 src/intel/tools/decoder.c   |  95 +++++++++++++++++-------------<wbr>------<br>
 src/intel/tools/decoder.h   |  39 +++++++++++++++<br>
 3 files changed, 192 insertions(+), 57 deletions(-)<br>
<br>
diff --git a/src/intel/tools/aubinator.c b/src/intel/tools/aubinator.c<br>
index 99d67a1..d2f9d13 100644<br>
--- a/src/intel/tools/aubinator.c<br>
+++ b/src/intel/tools/aubinator.c<br>
@@ -84,17 +84,80 @@ valid_offset(uint32_t offset)<br>
 }<br>
<br>
 static void<br>
+print_dword_val(struct gen_field_iterator *iter, uint64_t offset, int *dword_num)<br>
+{<br>
+   struct gen_field *f;<br>
+   union {<br>
+      uint32_t dw;<br>
+      float f;<br>
+   } v;<br>
+<br>
+   f = iter->group->fields[iter->i-1]<wbr>;<br>
+   v.dw = iter->p[f->start / 32];<br>
+<br>
+   if (*dword_num != (f->start/32)) {<br>
+      printf("0x%08lx:  0x%08x : Dword %d\n",(offset+4*(f->start/32))<wbr>, v.dw, f->start/32);<br>
+      *dword_num = (f->start/32);<br>
+   }<br>
+}<br>
+<br>
+static char *<br>
+print_iterator_values(struct gen_field_iterator *iter, int *idx)<br>
+{<br>
+    char *token = NULL;<br>
+    if (strstr(iter->value,"struct") == NULL) {<br>
+        printf("    %s: %s\n", iter->name, iter->value);<br>
+    } else {<br>
+        token = strtok(iter->value, " ");<br>
+        if (token != NULL) {<br>
+            token = strtok(NULL, " ");<br>
+            *idx = atoi(strtok(NULL, ">"));<br>
+        } else {<br>
+            token = NULL;<br>
+        }<br>
+        printf("    %s:<struct %s>\n", iter->name, token);<br>
+    }<br>
+    return token;<br>
+<br>
+}<br>
+<br>
+static void<br>
 decode_structure(struct gen_spec *spec, struct gen_group *strct, const uint32_t *p)<br>
 {<br>
    struct gen_field_iterator iter;<br>
+   char *token = NULL;<br>
+   int idx = 0, dword_num = 0;<br>
+   uint64_t offset = 0;<br>
+<br>
+   if (option_print_offsets)<br>
+      offset = (void *) p - gtt;<br>
+   else<br>
+      offset = 0;<br>
<br>
    gen_field_iterator_init(&iter, strct, p);<br>
    while (gen_field_iterator_next(&<wbr>iter)) {<br>
-      printf("    %s: %s\n", <a href="http://iter.name" rel="noreferrer" target="_blank">iter.name</a>, iter.value);<br>
+      idx = 0;<br>
+      print_dword_val(&iter, offset, &dword_num);<br>
+      token = print_iterator_values(&iter, &idx);<br>
+      if (token != NULL) {<br>
+         struct gen_group *struct_val = gen_spec_find_struct(spec, token);<br>
+         decode_structure(spec, struct_val, &p[idx]);<br>
+         token = NULL;<br>
+      }<br>
    }<br>
 }<br>
<br>
 static void<br>
+handle_struct_decode(struct gen_spec *spec, char *struct_name, uint32_t *p)<br>
+{<br>
+    if (struct_name == NULL)<br>
+        return;<br>
+    struct gen_group *struct_val = gen_spec_find_struct(spec, struct_name);<br>
+    decode_structure(spec, struct_val, p);<br>
+<br>
+}<br>
+<br>
+static void<br>
 dump_binding_table(struct gen_spec *spec, uint32_t offset)<br>
 {<br>
    uint32_t *pointers, i;<br>
@@ -248,7 +311,8 @@ handle_media_interface_<wbr>descriptor_load(struct gen_spec *spec, uint32_t *p)<br>
 }<br>
<br>
 /* Heuristic to determine whether a uint32_t is probably actually a float<br>
- * (<a href="http://stackoverflow.com/a/2953466" rel="noreferrer" target="_blank">http://stackoverflow.com/a/<wbr>2953466</a>) */<br>
+ * (<a href="http://stackoverflow.com/a/2953466" rel="noreferrer" target="_blank">http://stackoverflow.com/a/<wbr>2953466</a>)<br>
+ */<br>
<br>
 static bool<br>
 probably_float(uint32_t bits)<br>
@@ -256,15 +320,15 @@ probably_float(uint32_t bits)<br>
    int exp = ((bits & 0x7f800000U) >> 23) - 127;<br>
    uint32_t mant = bits & 0x007fffff;<br>
<br>
-   // +- 0.0<br>
+   /* +- 0.0 */<br>
    if (exp == -127 && mant == 0)<br>
       return true;<br>
<br>
-   // +- 1 billionth to 1 billion<br>
+   /* +- 1 billionth to 1 billion */<br>
    if (-30 <= exp && exp <= 30)<br>
       return true;<br>
<br>
-   // some value with only a few binary digits<br>
+   /* some value with only a few binary digits */<br>
    if ((mant & 0x0000ffff) == 0)<br>
       return true;<br>
<br>
@@ -342,6 +406,30 @@ handle_3dstate_vs(struct gen_spec *spec, uint32_t *p)<br>
 }<br>
<br>
 static void<br>
+handle_3dstate_hs(struct gen_spec *spec, uint32_t *p)<br>
+{<br>
+   uint64_t start;<br>
+   struct brw_instruction *insns;<br>
+   int hs_enable;<br>
+<br>
+   if (gen_spec_get_gen(spec) >= gen_make_gen(8, 0)) {<br>
+      start = get_qword(&p[4]);<br>
+   } else {<br>
+      start = p[4];<br>
+   }<br>
+<br>
+   hs_enable = p[2] & 0x80000000;<br>
+<br>
+   if (hs_enable) {<br>
+      printf("instruction_base %08lx, start %08lx\n",<br>
+             instruction_base, start);<br>
+<br>
+      insns = (struct brw_instruction *) (gtt + instruction_base + start);<br>
+      gen_disasm_disassemble(disasm, insns, 0, 8192, stdout);<br>
+   }<br>
+}<br>
+<br>
+static void<br>
 handle_3dstate_constant(struct gen_spec *spec, uint32_t *p)<br>
 {<br>
    int i, j, length;<br>
@@ -537,6 +625,8 @@ handle_3dstate_scissor_state_<wbr>pointers(struct gen_spec *spec, uint32_t *p)<br>
<br>
 #define _3DSTATE_VS                            0x78100000<br>
 #define _3DSTATE_GS                            0x78110000<br>
+#define _3DSTATE_HS                            0x781b0000<br>
+#define _3DSTATE_DS                            0x781d0000<br>
<br>
 #define _3DSTATE_CONSTANT_VS                   0x78150000<br>
 #define _3DSTATE_CONSTANT_GS                   0x78160000<br>
@@ -572,7 +662,8 @@ struct custom_handler {<br>
    { _3DSTATE_INDEX_BUFFER, handle_3dstate_index_buffer },<br>
    { _3DSTATE_VS, handle_3dstate_vs },<br>
    { _3DSTATE_GS, handle_3dstate_vs },<br>
-   /* FIXME: Handle disassmbing for 3DSTATE_HS and 3DSTATE_DS. */<br>
+   { _3DSTATE_DS, handle_3dstate_vs },<br>
+   { _3DSTATE_HS, handle_3dstate_hs },<br>
    { _3DSTATE_CONSTANT_VS, handle_3dstate_constant },<br>
    { _3DSTATE_CONSTANT_GS, handle_3dstate_constant },<br>
    { _3DSTATE_CONSTANT_PS, handle_3dstate_constant },<br>
@@ -637,9 +728,19 @@ parse_commands(struct gen_spec *spec, uint32_t *cmds, int size, int engine)<br>
<br>
       if (option_full_decode) {<br>
          struct gen_field_iterator iter;<br>
+         char *token = NULL;<br>
+         int idx = 0, dword_num = 0;<br>
          gen_field_iterator_init(&iter, inst, p);<br>
          while (gen_field_iterator_next(&<wbr>iter)) {<br>
-            printf("    %s: %s\n", <a href="http://iter.name" rel="noreferrer" target="_blank">iter.name</a>, iter.value);<br>
+            idx = 0;<br>
+            print_dword_val(&iter, offset, &dword_num);<br>
+            if (dword_num > 0)<br>
+                token = print_iterator_values(&iter, &idx);<br>
+            if (token != NULL) {<br>
+                printf("0x%08lx:  0x%08x : Dword %d\n",(offset+4*idx), p[idx], idx);<br>
+                handle_struct_decode(spec,<wbr>token, &p[idx]);<br>
+                token = NULL;<br>
+            }<br>
          }<br>
<br>
          for (i = 0; i < ARRAY_LENGTH(custom_handlers); i++) {<br>
diff --git a/src/intel/tools/decoder.c b/src/intel/tools/decoder.c<br>
index 7ab3696..060d4ed 100644<br>
--- a/src/intel/tools/decoder.c<br>
+++ b/src/intel/tools/decoder.c<br>
@@ -49,45 +49,6 @@ struct gen_spec {<br>
    struct gen_group *registers[256];<br>
 };<br>
<br>
-struct gen_group {<br>
-   char *name;<br>
-   int nfields;<br>
-   struct gen_field **fields;<br>
-<br>
-   uint32_t opcode_mask;<br>
-   uint32_t opcode;<br>
-};<br>
-<br>
-struct gen_type {<br>
-   enum {<br>
-      GEN_TYPE_UNKNOWN,<br>
-      GEN_TYPE_INT,<br>
-      GEN_TYPE_UINT,<br>
-      GEN_TYPE_BOOL,<br>
-      GEN_TYPE_FLOAT,<br>
-      GEN_TYPE_ADDRESS,<br>
-      GEN_TYPE_OFFSET,<br>
-      GEN_TYPE_STRUCT,<br>
-      GEN_TYPE_UFIXED,<br>
-      GEN_TYPE_SFIXED,<br>
-      GEN_TYPE_MBO<br>
-   } kind;<br>
-<br>
-   /* Struct definition for  GEN_TYPE_STRUCT*/<br>
-   struct gen_group *gen_struct;<br>
-<br>
-   /* Integer and fractional sizes for GEN_TYPE_UFIXED and GEN_TYPE_SFIXED */<br>
-   int i, f;<br>
-};<br>
-<br>
-struct gen_field {<br>
-   char *name;<br>
-   int start, end;<br>
-   struct gen_type type;<br>
-   bool has_default;<br>
-   uint32_t default_value;<br>
-};<br>
-<br>
 struct location {<br>
    const char *filename;<br>
    int line_number;<br>
@@ -187,23 +148,48 @@ create_group(struct parser_context *ctx, const char *name, const char **atts)<br>
    if (name)<br>
       group->name = xstrdup(name);<br>
<br>
+   group->group_offset = 0;<br>
+   group->group_count = 0;<br>
+<br>
    return group;<br>
 }<br>
<br>
+static void<br>
+get_group_offset_count(struct parser_context *ctx, const char *name, const char **atts, uint32_t *offset, uint32_t *count)<br>
+{<br>
+   char *p;<br>
+   int i;<br>
+<br>
+   for (i = 0; atts[i]; i += 2) {<br>
+      if (strcmp(atts[i], "count") == 0)<br>
+         *count = strtoul(atts[i + 1], &p, 0);<br>
+      else if (strcmp(atts[i], "start") == 0)<br>
+         *offset = strtoul(atts[i + 1], &p, 0);<br>
+   }<br>
+   return;<br>
+}<br>
+<br>
 static inline uint64_t<br>
 mask(int start, int end)<br>
 {<br>
    uint64_t v;<br>
<br>
-   v = ~0ULL >> (63 - end + start);<br>
+   v = ~0ULL >> (63 - (end%32) + (start%32));<br>
<br>
-   return v << start;<br>
+   return v << (start%32);<br>
 }<br>
<br>
 static inline uint64_t<br>
 field(uint64_t value, int start, int end)<br>
 {<br>
-   return (value & mask(start, end)) >> start;<br>
+   return (value & mask(start, end)) >> (start%32);<br>
+}<br>
+<br>
+static inline uint64_t<br>
+field_address(uint64_t value, int start, int end)<br>
+{<br>
+   /* no need to right shift for address/offset */<br>
+   return (value & mask(start, end));<br>
 }<br>
<br>
 static struct gen_type<br>
@@ -249,10 +235,12 @@ create_field(struct parser_context *ctx, const char **atts)<br>
       if (strcmp(atts[i], "name") == 0)<br>
          field->name = xstrdup(atts[i + 1]);<br>
       else if (strcmp(atts[i], "start") == 0)<br>
-         field->start = strtoul(atts[i + 1], &p, 0);<br>
-      else if (strcmp(atts[i], "end") == 0)<br>
-         field->end = strtoul(atts[i + 1], &p, 0);<br>
-      else if (strcmp(atts[i], "type") == 0)<br>
+         field->start = ctx->group->group_offset+<wbr>strtoul(atts[i + 1], &p, 0);<br>
+      else if (strcmp(atts[i], "end") == 0) {<br>
+         field->end = ctx->group->group_offset+<wbr>strtoul(atts[i + 1], &p, 0);<br>
+         if (ctx->group->group_offset)<br>
+            ctx->group->group_offset = field->end+1;<br>
+      } else if (strcmp(atts[i], "type") == 0)<br>
          field->type = string_to_type(ctx, atts[i + 1]);<br>
       else if (strcmp(atts[i], "default") == 0 &&<br>
                field->start >= 16 && field->end <= 31) {<br>
@@ -301,8 +289,13 @@ start_element(void *data, const char *element_name, const char **atts)<br>
               strcmp(element_name, "register") == 0) {<br>
       ctx->group = create_group(ctx, name, atts);<br>
    } else if (strcmp(element_name, "group") == 0) {<br>
+      get_group_offset_count(ctx, name, atts,&ctx->group->group_<wbr>offset,&ctx->group->group_<wbr>count);<br>
    } else if (strcmp(element_name, "field") == 0) {<br>
-      ctx->fields[ctx->nfields++] = create_field(ctx, atts);<br>
+      do {<br>
+         ctx->fields[ctx->nfields++] = create_field(ctx, atts);<br>
+         if (ctx->group->group_count)<br>
+            ctx->group->group_count--;<br>
+      } while (ctx->group->group_count > 0);<br>
    } else if (strcmp(element_name, "enum") == 0) {<br>
    } else if (strcmp(element_name, "value") == 0) {<br>
    }<br>
@@ -343,6 +336,9 @@ end_element(void *data, const char *name)<br>
          spec->structs[spec->nstructs++<wbr>] = group;<br>
       else if (strcmp(name, "register") == 0)<br>
          spec->registers[spec-><wbr>nregisters++] = group;<br>
+   } else if (strcmp(name, "group") == 0) {<br>
+      ctx->group->group_offset = 0;<br>
+      ctx->group->group_count = 0;<br>
    }<br>
 }<br>
<br>
@@ -497,12 +493,11 @@ gen_field_iterator_next(struct gen_field_iterator *iter)<br>
    case GEN_TYPE_ADDRESS:<br>
    case GEN_TYPE_OFFSET:<br>
       snprintf(iter->value, sizeof(iter->value),<br>
-               "0x%08lx", field(v.dw, f->start, f->end));<br>
+               "0x%08lx", field_address(v.dw, f->start, f->end));<br>
       break;<br>
    case GEN_TYPE_STRUCT:<br>
-      /* FIXME: Make iterator decode the struct recursively */<br>
       snprintf(iter->value, sizeof(iter->value),<br>
-               "<struct %s>", f->type.gen_struct->name);<br>
+               "<struct %s %d>", f->type.gen_struct->name, (f->start / 32));<br>
       break;<br>
    case GEN_TYPE_UFIXED:<br>
       snprintf(iter->value, sizeof(iter->value),<br>
diff --git a/src/intel/tools/decoder.h b/src/intel/tools/decoder.h<br>
index af9e075..09667ef 100644<br>
--- a/src/intel/tools/decoder.h<br>
+++ b/src/intel/tools/decoder.h<br>
@@ -51,6 +51,45 @@ struct gen_field_iterator {<br>
    int i;<br>
 };<br>
<br>
+struct gen_group {<br>
+   char *name;<br>
+   int nfields;<br>
+   struct gen_field **fields;<br>
+   uint32_t group_offset, group_count;<br>
+<br>
+   uint32_t opcode_mask;<br>
+   uint32_t opcode;<br>
+};<br>
+struct gen_type {<br>
+   enum {<br>
+      GEN_TYPE_UNKNOWN,<br>
+      GEN_TYPE_INT,<br>
+      GEN_TYPE_UINT,<br>
+      GEN_TYPE_BOOL,<br>
+      GEN_TYPE_FLOAT,<br>
+      GEN_TYPE_ADDRESS,<br>
+      GEN_TYPE_OFFSET,<br>
+      GEN_TYPE_STRUCT,<br>
+      GEN_TYPE_UFIXED,<br>
+      GEN_TYPE_SFIXED,<br>
+      GEN_TYPE_MBO<br>
+   } kind;<br>
+<br>
+   /* Struct definition for  GEN_TYPE_STRUCT*/<br>
+   struct gen_group *gen_struct;<br>
+<br>
+   /* Integer and fractional sizes for GEN_TYPE_UFIXED and GEN_TYPE_SFIXED */<br>
+   int i, f;<br>
+};<br>
+<br>
+struct gen_field {<br>
+   char *name;<br>
+   int start, end;<br>
+   struct gen_type type;<br>
+   bool has_default;<br>
+   uint32_t default_value;<br>
+};<br>
+<br>
 void gen_field_iterator_init(struct gen_field_iterator *iter,<br>
                              struct gen_group *group, const uint32_t *p);<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.7.4<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>