[Mesa-dev] [PATCH 2/2] aubinator: Fix the tool to correctly decode the DWords

Matt Turner mattst88 at gmail.com
Wed Aug 10 21:31:28 UTC 2016


On Tue, Aug 9, 2016 at 4:52 PM, Sirisha Gandikota
<sirisha.gandikota at intel.com> wrote:
> From: Sirisha Gandikota <Sirisha.Gandikota at intel.com>
>
> Several fixes have been added as part of this as listed below:
>
> 1) Fix the mask and add disassembler handling for STATE_DS, STATE_HS
> as the mask returned wrong values of the fields.
>
> 2) Fix the GEN_TYPE_ADDRESS/GEN_TYPE_OFFSET decoding - the address/
> offset were handled the same way as the other fields and that gives
> the wrong values for the address/offset.
>
> 3) Decode nested/recurssive structures - Many packets contain nested
> structures, ex: 3DSATE_SO_BUFFER, STATE_BASE_ADDRESS, etc contain MOC
> structures. Previously, the aubinator printed 1 if there was a MOC
> structure. Now we decode the entire structure and print out its fields.
>
> 4) Print out the DWord address along with its hex value - For a better
> clarity of information, it is helpful to print both the address and
> hex value of the DWord along with the DWord count. Since the DWord0
> contains the instruction code and the instruction length, it is
> unnecessary to print the decoded values for DWord0. This information
> is already available from the DWord hex value.
>
> 5) Decode the <group> and the corresponding fields in the group- The
> <group> tag can have fields of several types including structures. A
> group can contain one or more number of fields and this has be correctly
> decoded. Previously, aubinator did not decode the groups or the
> fields/structures inside them. Now we decode the <group> in the
> instructions and structures where the fields in it repeat for any number
> of times specified.
>
> Signed-off-by: Sirisha Gandikota <Sirisha.Gandikota at intel.com>
> ---
>  src/intel/tools/aubinator.c | 115 +++++++++++++++++++++++++++++++++++++++++---
>  src/intel/tools/decoder.c   |  95 +++++++++++++++++-------------------
>  src/intel/tools/decoder.h   |  39 +++++++++++++++
>  3 files changed, 192 insertions(+), 57 deletions(-)
>
> diff --git a/src/intel/tools/aubinator.c b/src/intel/tools/aubinator.c
> index 99d67a1..d2f9d13 100644
> --- a/src/intel/tools/aubinator.c
> +++ b/src/intel/tools/aubinator.c
> @@ -84,17 +84,80 @@ valid_offset(uint32_t offset)
>  }
>
>  static void
> +print_dword_val(struct gen_field_iterator *iter, uint64_t offset, int *dword_num)
> +{
> +   struct gen_field *f;
> +   union {
> +      uint32_t dw;
> +      float f;
> +   } v;
> +
> +   f = iter->group->fields[iter->i-1];

Spaces around operators. Occurs many places.

> +   v.dw = iter->p[f->start / 32];
> +
> +   if (*dword_num != (f->start/32)) {
> +      printf("0x%08lx:  0x%08x : Dword %d\n",(offset+4*(f->start/32)), v.dw, f->start/32);
> +      *dword_num = (f->start/32);
> +   }
> +}
> +
> +static char *
> +print_iterator_values(struct gen_field_iterator *iter, int *idx)
> +{
> +    char *token = NULL;
> +    if (strstr(iter->value,"struct") == NULL) {
> +        printf("    %s: %s\n", iter->name, iter->value);
> +    } else {
> +        token = strtok(iter->value, " ");
> +        if (token != NULL) {
> +            token = strtok(NULL, " ");
> +            *idx = atoi(strtok(NULL, ">"));
> +        } else {
> +            token = NULL;
> +        }
> +        printf("    %s:<struct %s>\n", iter->name, token);
> +    }
> +    return token;
> +

Extra new line.

> +}
> +
> +static void
>  decode_structure(struct gen_spec *spec, struct gen_group *strct, const uint32_t *p)
>  {
>     struct gen_field_iterator iter;
> +   char *token = NULL;
> +   int idx = 0, dword_num = 0;
> +   uint64_t offset = 0;
> +
> +   if (option_print_offsets)
> +      offset = (void *) p - gtt;
> +   else
> +      offset = 0;
>
>     gen_field_iterator_init(&iter, strct, p);
>     while (gen_field_iterator_next(&iter)) {
> -      printf("    %s: %s\n", iter.name, iter.value);
> +      idx = 0;
> +      print_dword_val(&iter, offset, &dword_num);
> +      token = print_iterator_values(&iter, &idx);
> +      if (token != NULL) {
> +         struct gen_group *struct_val = gen_spec_find_struct(spec, token);
> +         decode_structure(spec, struct_val, &p[idx]);
> +         token = NULL;
> +      }
>     }
>  }
>
>  static void
> +handle_struct_decode(struct gen_spec *spec, char *struct_name, uint32_t *p)
> +{
> +    if (struct_name == NULL)
> +        return;
> +    struct gen_group *struct_val = gen_spec_find_struct(spec, struct_name);
> +    decode_structure(spec, struct_val, p);
> +

Extra newline.

> +}
> +
> +static void
>  dump_binding_table(struct gen_spec *spec, uint32_t offset)
>  {
>     uint32_t *pointers, i;
> @@ -248,7 +311,8 @@ handle_media_interface_descriptor_load(struct gen_spec *spec, uint32_t *p)
>  }
>
>  /* Heuristic to determine whether a uint32_t is probably actually a float
> - * (http://stackoverflow.com/a/2953466) */
> + * (http://stackoverflow.com/a/2953466)
> + */
>
>  static bool
>  probably_float(uint32_t bits)
> @@ -256,15 +320,15 @@ probably_float(uint32_t bits)
>     int exp = ((bits & 0x7f800000U) >> 23) - 127;
>     uint32_t mant = bits & 0x007fffff;
>
> -   // +- 0.0
> +   /* +- 0.0 */
>     if (exp == -127 && mant == 0)
>        return true;
>
> -   // +- 1 billionth to 1 billion
> +   /* +- 1 billionth to 1 billion */
>     if (-30 <= exp && exp <= 30)
>        return true;
>
> -   // some value with only a few binary digits
> +   /* some value with only a few binary digits */
>     if ((mant & 0x0000ffff) == 0)
>        return true;
>
> @@ -342,6 +406,30 @@ handle_3dstate_vs(struct gen_spec *spec, uint32_t *p)
>  }
>
>  static void
> +handle_3dstate_hs(struct gen_spec *spec, uint32_t *p)
> +{
> +   uint64_t start;
> +   struct brw_instruction *insns;
> +   int hs_enable;
> +
> +   if (gen_spec_get_gen(spec) >= gen_make_gen(8, 0)) {
> +      start = get_qword(&p[4]);
> +   } else {
> +      start = p[4];
> +   }
> +
> +   hs_enable = p[2] & 0x80000000;
> +
> +   if (hs_enable) {
> +      printf("instruction_base %08lx, start %08lx\n",
> +             instruction_base, start);
> +
> +      insns = (struct brw_instruction *) (gtt + instruction_base + start);
> +      gen_disasm_disassemble(disasm, insns, 0, 8192, stdout);
> +   }
> +}
> +
> +static void
>  handle_3dstate_constant(struct gen_spec *spec, uint32_t *p)
>  {
>     int i, j, length;
> @@ -537,6 +625,8 @@ handle_3dstate_scissor_state_pointers(struct gen_spec *spec, uint32_t *p)
>
>  #define _3DSTATE_VS                            0x78100000
>  #define _3DSTATE_GS                            0x78110000
> +#define _3DSTATE_HS                            0x781b0000
> +#define _3DSTATE_DS                            0x781d0000
>
>  #define _3DSTATE_CONSTANT_VS                   0x78150000
>  #define _3DSTATE_CONSTANT_GS                   0x78160000
> @@ -572,7 +662,8 @@ struct custom_handler {
>     { _3DSTATE_INDEX_BUFFER, handle_3dstate_index_buffer },
>     { _3DSTATE_VS, handle_3dstate_vs },
>     { _3DSTATE_GS, handle_3dstate_vs },
> -   /* FIXME: Handle disassmbing for 3DSTATE_HS and 3DSTATE_DS. */
> +   { _3DSTATE_DS, handle_3dstate_vs },
> +   { _3DSTATE_HS, handle_3dstate_hs },
>     { _3DSTATE_CONSTANT_VS, handle_3dstate_constant },
>     { _3DSTATE_CONSTANT_GS, handle_3dstate_constant },
>     { _3DSTATE_CONSTANT_PS, handle_3dstate_constant },
> @@ -637,9 +728,19 @@ parse_commands(struct gen_spec *spec, uint32_t *cmds, int size, int engine)
>
>        if (option_full_decode) {
>           struct gen_field_iterator iter;
> +         char *token = NULL;
> +         int idx = 0, dword_num = 0;
>           gen_field_iterator_init(&iter, inst, p);
>           while (gen_field_iterator_next(&iter)) {
> -            printf("    %s: %s\n", iter.name, iter.value);
> +            idx = 0;
> +            print_dword_val(&iter, offset, &dword_num);
> +            if (dword_num > 0)
> +                token = print_iterator_values(&iter, &idx);
> +            if (token != NULL) {
> +                printf("0x%08lx:  0x%08x : Dword %d\n",(offset+4*idx), p[idx], idx);
> +                handle_struct_decode(spec,token, &p[idx]);
> +                token = NULL;
> +            }
>           }
>
>           for (i = 0; i < ARRAY_LENGTH(custom_handlers); i++) {
> diff --git a/src/intel/tools/decoder.c b/src/intel/tools/decoder.c
> index 7ab3696..060d4ed 100644
> --- a/src/intel/tools/decoder.c
> +++ b/src/intel/tools/decoder.c
> @@ -49,45 +49,6 @@ struct gen_spec {
>     struct gen_group *registers[256];
>  };
>
> -struct gen_group {
> -   char *name;
> -   int nfields;
> -   struct gen_field **fields;
> -
> -   uint32_t opcode_mask;
> -   uint32_t opcode;
> -};
> -
> -struct gen_type {
> -   enum {
> -      GEN_TYPE_UNKNOWN,
> -      GEN_TYPE_INT,
> -      GEN_TYPE_UINT,
> -      GEN_TYPE_BOOL,
> -      GEN_TYPE_FLOAT,
> -      GEN_TYPE_ADDRESS,
> -      GEN_TYPE_OFFSET,
> -      GEN_TYPE_STRUCT,
> -      GEN_TYPE_UFIXED,
> -      GEN_TYPE_SFIXED,
> -      GEN_TYPE_MBO
> -   } kind;
> -
> -   /* Struct definition for  GEN_TYPE_STRUCT*/
> -   struct gen_group *gen_struct;
> -
> -   /* Integer and fractional sizes for GEN_TYPE_UFIXED and GEN_TYPE_SFIXED */
> -   int i, f;
> -};
> -
> -struct gen_field {
> -   char *name;
> -   int start, end;
> -   struct gen_type type;
> -   bool has_default;
> -   uint32_t default_value;
> -};
> -
>  struct location {
>     const char *filename;
>     int line_number;
> @@ -187,23 +148,48 @@ create_group(struct parser_context *ctx, const char *name, const char **atts)
>     if (name)
>        group->name = xstrdup(name);
>
> +   group->group_offset = 0;
> +   group->group_count = 0;
> +
>     return group;
>  }
>
> +static void
> +get_group_offset_count(struct parser_context *ctx, const char *name, const char **atts, uint32_t *offset, uint32_t *count)
> +{
> +   char *p;
> +   int i;
> +
> +   for (i = 0; atts[i]; i += 2) {
> +      if (strcmp(atts[i], "count") == 0)
> +         *count = strtoul(atts[i + 1], &p, 0);
> +      else if (strcmp(atts[i], "start") == 0)
> +         *offset = strtoul(atts[i + 1], &p, 0);
> +   }
> +   return;
> +}
> +
>  static inline uint64_t
>  mask(int start, int end)
>  {
>     uint64_t v;
>
> -   v = ~0ULL >> (63 - end + start);
> +   v = ~0ULL >> (63 - (end%32) + (start%32));

This looks bogus. This function is only expected to work for start and
end values 0-63, I think. Mod by 32 will break that.

>
> -   return v << start;
> +   return v << (start%32);

As does this.

>  }
>
>  static inline uint64_t
>  field(uint64_t value, int start, int end)
>  {
> -   return (value & mask(start, end)) >> start;
> +   return (value & mask(start, end)) >> (start%32);

and this.

> +}
> +
> +static inline uint64_t
> +field_address(uint64_t value, int start, int end)
> +{
> +   /* no need to right shift for address/offset */
> +   return (value & mask(start, end));
>  }
>
>  static struct gen_type
> @@ -249,10 +235,12 @@ create_field(struct parser_context *ctx, const char **atts)
>        if (strcmp(atts[i], "name") == 0)
>           field->name = xstrdup(atts[i + 1]);
>        else if (strcmp(atts[i], "start") == 0)
> -         field->start = strtoul(atts[i + 1], &p, 0);
> -      else if (strcmp(atts[i], "end") == 0)
> -         field->end = strtoul(atts[i + 1], &p, 0);
> -      else if (strcmp(atts[i], "type") == 0)
> +         field->start = ctx->group->group_offset+strtoul(atts[i + 1], &p, 0);
> +      else if (strcmp(atts[i], "end") == 0) {
> +         field->end = ctx->group->group_offset+strtoul(atts[i + 1], &p, 0);
> +         if (ctx->group->group_offset)
> +            ctx->group->group_offset = field->end+1;
> +      } else if (strcmp(atts[i], "type") == 0)
>           field->type = string_to_type(ctx, atts[i + 1]);
>        else if (strcmp(atts[i], "default") == 0 &&
>                 field->start >= 16 && field->end <= 31) {
> @@ -301,8 +289,13 @@ start_element(void *data, const char *element_name, const char **atts)
>                strcmp(element_name, "register") == 0) {
>        ctx->group = create_group(ctx, name, atts);
>     } else if (strcmp(element_name, "group") == 0) {
> +      get_group_offset_count(ctx, name, atts,&ctx->group->group_offset,&ctx->group->group_count);
>     } else if (strcmp(element_name, "field") == 0) {
> -      ctx->fields[ctx->nfields++] = create_field(ctx, atts);
> +      do {
> +         ctx->fields[ctx->nfields++] = create_field(ctx, atts);
> +         if (ctx->group->group_count)
> +            ctx->group->group_count--;
> +      } while (ctx->group->group_count > 0);
>     } else if (strcmp(element_name, "enum") == 0) {
>     } else if (strcmp(element_name, "value") == 0) {
>     }
> @@ -343,6 +336,9 @@ end_element(void *data, const char *name)
>           spec->structs[spec->nstructs++] = group;
>        else if (strcmp(name, "register") == 0)
>           spec->registers[spec->nregisters++] = group;
> +   } else if (strcmp(name, "group") == 0) {
> +      ctx->group->group_offset = 0;
> +      ctx->group->group_count = 0;
>     }
>  }
>
> @@ -497,12 +493,11 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
>     case GEN_TYPE_ADDRESS:
>     case GEN_TYPE_OFFSET:
>        snprintf(iter->value, sizeof(iter->value),
> -               "0x%08lx", field(v.dw, f->start, f->end));
> +               "0x%08lx", field_address(v.dw, f->start, f->end));
>        break;
>     case GEN_TYPE_STRUCT:
> -      /* FIXME: Make iterator decode the struct recursively */
>        snprintf(iter->value, sizeof(iter->value),
> -               "<struct %s>", f->type.gen_struct->name);
> +               "<struct %s %d>", f->type.gen_struct->name, (f->start / 32));
>        break;
>     case GEN_TYPE_UFIXED:
>        snprintf(iter->value, sizeof(iter->value),
> diff --git a/src/intel/tools/decoder.h b/src/intel/tools/decoder.h
> index af9e075..09667ef 100644
> --- a/src/intel/tools/decoder.h
> +++ b/src/intel/tools/decoder.h
> @@ -51,6 +51,45 @@ struct gen_field_iterator {
>     int i;
>  };
>
> +struct gen_group {
> +   char *name;
> +   int nfields;
> +   struct gen_field **fields;
> +   uint32_t group_offset, group_count;
> +
> +   uint32_t opcode_mask;
> +   uint32_t opcode;
> +};
> +struct gen_type {
> +   enum {
> +      GEN_TYPE_UNKNOWN,
> +      GEN_TYPE_INT,
> +      GEN_TYPE_UINT,
> +      GEN_TYPE_BOOL,
> +      GEN_TYPE_FLOAT,
> +      GEN_TYPE_ADDRESS,
> +      GEN_TYPE_OFFSET,
> +      GEN_TYPE_STRUCT,
> +      GEN_TYPE_UFIXED,
> +      GEN_TYPE_SFIXED,
> +      GEN_TYPE_MBO
> +   } kind;
> +
> +   /* Struct definition for  GEN_TYPE_STRUCT*/

Space before */


More information about the mesa-dev mailing list