summaryrefslogtreecommitdiffstats
path: root/src/broadcom/cle
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2017-07-13 13:20:29 -0700
committerEric Anholt <[email protected]>2017-08-18 11:56:58 -0700
commit7c576d60914d47cfd345868521b1dec84ad0e2f2 (patch)
tree2fbc20950a2e81b0ff30f2f3fe2e6cad7d68851d /src/broadcom/cle
parent14fe9fd3f7e39ccad316ef2be17fea0cc1aaad73 (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.c31
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;