diff options
author | Eric Anholt <[email protected]> | 2017-07-13 13:20:29 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2017-08-18 11:56:58 -0700 |
commit | 7c576d60914d47cfd345868521b1dec84ad0e2f2 (patch) | |
tree | 2fbc20950a2e81b0ff30f2f3fe2e6cad7d68851d /src/broadcom/cle | |
parent | 14fe9fd3f7e39ccad316ef2be17fea0cc1aaad73 (diff) |
broadcom/genxml: Check the sub-id field when decoding instructions.
VC5 introduces packet variants where the same opcode has behavior that is
decided by a sub-id field in the early bits of the packet. Keep iterating
over packets until we find the one with the matching sub-id.
Diffstat (limited to 'src/broadcom/cle')
-rw-r--r-- | src/broadcom/cle/v3d_decoder.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/src/broadcom/cle/v3d_decoder.c b/src/broadcom/cle/v3d_decoder.c index ac33d87191c..4ac40af05e8 100644 --- a/src/broadcom/cle/v3d_decoder.c +++ b/src/broadcom/cle/v3d_decoder.c @@ -356,8 +356,7 @@ create_field(struct parser_context *ctx, const char **atts) size *= 8; } 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) { + else if (strcmp(atts[i], "default") == 0) { field->has_default = true; field->default_value = strtoul(atts[i + 1], &p, 0); } @@ -641,10 +640,32 @@ v3d_spec_load(const struct v3d_device_info *devinfo) struct v3d_group * v3d_spec_find_instruction(struct v3d_spec *spec, const uint8_t *p) { + uint8_t opcode = *p; + for (int i = 0; i < spec->ncommands; i++) { - uint8_t opcode = *p; - if (opcode == spec->commands[i]->opcode) - return spec->commands[i]; + struct v3d_group *group = spec->commands[i]; + + if (opcode != group->opcode) + continue; + + /* If there's a "sub-id" field, make sure that it matches the + * instruction being decoded. + */ + struct v3d_field *subid = NULL; + for (int j = 0; j < group->nfields; j++) { + struct v3d_field *field = group->fields[j]; + if (strcmp(field->name, "sub-id") == 0) { + subid = field; + break; + } + } + + if (subid && (__gen_unpack_uint(p, subid->start, subid->end) != + subid->default_value)) { + continue; + } + + return group; } return NULL; |