On Tue, Aug 9, 2016 at 4:52 PM, Sirisha Gandikota <sirisha.gandik...@intel.com> wrote: > From: Sirisha Gandikota <sirisha.gandik...@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.gandik...@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 */ _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev