diff options
-rw-r--r-- | src/intel/tools/aubinator.c | 104 | ||||
-rw-r--r-- | src/intel/tools/decoder.c | 98 | ||||
-rw-r--r-- | src/intel/tools/decoder.h | 40 |
3 files changed, 189 insertions, 53 deletions
diff --git a/src/intel/tools/aubinator.c b/src/intel/tools/aubinator.c index 250a2e1ecbf..11e1b9dc72f 100644 --- a/src/intel/tools/aubinator.c +++ b/src/intel/tools/aubinator.c @@ -88,17 +88,78 @@ 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]; + 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; +} + +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); +} + +static void dump_binding_table(struct gen_spec *spec, uint32_t offset) { uint32_t *pointers, i; @@ -347,6 +408,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; @@ -543,6 +628,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 @@ -578,7 +665,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 }, @@ -643,9 +731,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 02944dd0062..f57be979038 100644 --- a/src/intel/tools/decoder.c +++ b/src/intel/tools/decoder.c @@ -47,45 +47,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; @@ -185,9 +146,27 @@ 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) { @@ -201,7 +180,18 @@ mask(int start, int end) static inline uint64_t field(uint64_t value, int start, int end) { - return (value & mask(start, end)) >> start; + /* The field values are obtained from the DWord, + * Hence, get the relative start and end positions + * by doing a %32 on the start and end positions + */ + return (value & mask(start % 32, end % 32)) >> (start % 32); +} + +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 % 32, end % 32)); } static struct gen_type @@ -247,10 +237,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) { @@ -299,8 +291,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) { } @@ -328,7 +325,7 @@ end_element(void *data, const char *name) group->fields[i]->end <= 31 && group->fields[i]->has_default) { group->opcode_mask |= - mask(group->fields[i]->start, group->fields[i]->end); + mask(group->fields[i]->start % 32, group->fields[i]->end % 32); group->opcode |= group->fields[i]->default_value << group->fields[i]->start; } @@ -341,6 +338,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; } } @@ -407,7 +407,6 @@ gen_spec_load(const char *filename) struct gen_group * gen_spec_find_instruction(struct gen_spec *spec, const uint32_t *p) { - /* FIXME: Make sure the opcodes put out are correct */ for (int i = 0; i < spec->ncommands; i++) { uint32_t opcode = *p & spec->commands[i]->opcode_mask; if (opcode == spec->commands[i]->opcode) @@ -495,12 +494,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 af9e075f00e..b46e451652f 100644 --- a/src/intel/tools/decoder.h +++ b/src/intel/tools/decoder.h @@ -51,6 +51,46 @@ 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 */ + 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; +}; + void gen_field_iterator_init(struct gen_field_iterator *iter, struct gen_group *group, const uint32_t *p); |