<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>