[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