diff options
Diffstat (limited to 'src/intel/tools/decoder.c')
-rw-r--r-- | src/intel/tools/decoder.c | 97 |
1 files changed, 70 insertions, 27 deletions
diff --git a/src/intel/tools/decoder.c b/src/intel/tools/decoder.c index 633251a44cf..defb0873da0 100644 --- a/src/intel/tools/decoder.c +++ b/src/intel/tools/decoder.c @@ -52,6 +52,8 @@ struct gen_spec { struct gen_group *structs[256]; int nregisters; struct gen_group *registers[256]; + int nenums; + struct gen_enum *enums[256]; }; struct location { @@ -66,10 +68,14 @@ struct parser_context { const char *platform; struct gen_group *group; + struct gen_enum *enoom; int nfields; struct gen_field *fields[128]; + int nvalues; + struct gen_value *values[256]; + struct gen_spec *spec; }; @@ -105,6 +111,16 @@ gen_spec_find_register(struct gen_spec *spec, uint32_t offset) return NULL; } +struct gen_enum * +gen_spec_find_enum(struct gen_spec *spec, const char *name) +{ + for (int i = 0; i < spec->nenums; i++) + if (strcmp(spec->enums[i]->name, name) == 0) + return spec->enums[i]; + + return NULL; +} + uint32_t gen_spec_get_gen(struct gen_spec *spec) { @@ -169,6 +185,20 @@ create_group(struct parser_context *ctx, const char *name, const char **atts) return group; } +static struct gen_enum * +create_enum(struct parser_context *ctx, const char *name, const char **atts) +{ + struct gen_enum *e; + + e = xzalloc(sizeof(*e)); + if (name) + e->name = xstrdup(name); + + e->nvalues = 0; + + return e; +} + static void get_group_offset_count(struct parser_context *ctx, const char *name, const char **atts, uint32_t *offset, uint32_t *count) @@ -248,6 +278,7 @@ string_to_type(struct parser_context *ctx, const char *s) { int i, f; struct gen_group *g; + struct gen_enum *e; if (strcmp(s, "int") == 0) return (struct gen_type) { .kind = GEN_TYPE_INT }; @@ -267,6 +298,8 @@ string_to_type(struct parser_context *ctx, const char *s) return (struct gen_type) { .kind = GEN_TYPE_SFIXED, .i = i, .f = f }; else if (g = gen_spec_find_struct(ctx->spec, s), g != NULL) return (struct gen_type) { .kind = GEN_TYPE_STRUCT, .gen_struct = g }; + else if (e = gen_spec_find_enum(ctx->spec, s), e != NULL) + return (struct gen_type) { .kind = GEN_TYPE_ENUM, .gen_enum = e }; else if (strcmp(s, "mbo") == 0) return (struct gen_type) { .kind = GEN_TYPE_MBO }; else @@ -366,23 +399,9 @@ start_element(void *data, const char *element_name, const char **atts) ctx->group->group_count--; } while (ctx->group->group_count > 0); } else if (strcmp(element_name, "enum") == 0) { + ctx->enoom = create_enum(ctx, name, atts); } else if (strcmp(element_name, "value") == 0) { - if (ctx->nfields > 0) { - struct gen_field *field = ctx->fields[ctx->nfields - 1]; - if (field->n_allocated_values <= field->n_values) { - if (field->n_allocated_values == 0) { - field->n_allocated_values = 2; - field->values = - xzalloc(sizeof(field->values[0]) * field->n_allocated_values); - } else { - field->n_allocated_values *= 2; - field->values = - realloc(field->values, - sizeof(field->values[0]) * field->n_allocated_values); - } - } - field->values[field->n_values++] = create_value(ctx, atts); - } + ctx->values[ctx->nvalues++] = create_value(ctx, atts); } } @@ -390,6 +409,7 @@ static void end_element(void *data, const char *name) { struct parser_context *ctx = data; + struct gen_spec *spec = ctx->spec; if (strcmp(name, "instruction") == 0 || strcmp(name, "struct") == 0 || @@ -414,7 +434,6 @@ end_element(void *data, const char *name) } } - struct gen_spec *spec = ctx->spec; if (strcmp(name, "instruction") == 0) spec->commands[spec->ncommands++] = group; else if (strcmp(name, "struct") == 0) @@ -424,6 +443,23 @@ end_element(void *data, const char *name) } else if (strcmp(name, "group") == 0) { ctx->group->group_offset = 0; ctx->group->group_count = 0; + } else if (strcmp(name, "field") == 0) { + assert(ctx->nfields > 0); + struct gen_field *field = ctx->fields[ctx->nfields - 1]; + size_t size = ctx->nvalues * sizeof(ctx->values[0]); + field->inline_enum.values = xzalloc(size); + field->inline_enum.nvalues = ctx->nvalues; + memcpy(field->inline_enum.values, ctx->values, size); + ctx->nvalues = 0; + } else if (strcmp(name, "enum") == 0) { + struct gen_enum *e = ctx->enoom; + size_t size = ctx->nvalues * sizeof(ctx->values[0]); + e->values = xzalloc(size); + e->nvalues = ctx->nvalues; + memcpy(e->values, ctx->values, size); + ctx->nvalues = 0; + ctx->enoom = NULL; + spec->enums[spec->nenums++] = e; } } @@ -637,13 +673,12 @@ gen_field_iterator_init(struct gen_field_iterator *iter, } static void -gen_field_write_value(char *str, size_t max_length, - struct gen_field *field, - uint64_t value) +gen_enum_write_value(char *str, size_t max_length, + struct gen_enum *e, uint64_t value) { - for (int i = 0; i < field->n_values; i++) { - if (field->values[i]->value == value) { - strncpy(str, field->values[i]->name, max_length); + for (int i = 0; i < e->nvalues; i++) { + if (e->values[i]->value == value) { + strncpy(str, e->values[i]->name, max_length); return; } } @@ -678,16 +713,16 @@ gen_field_iterator_next(struct gen_field_iterator *iter) uint64_t value = field(v.qw, f->start, f->end); snprintf(iter->value, sizeof(iter->value), "%"PRId64, value); - gen_field_write_value(iter->description, sizeof(iter->description), - f, value); + gen_enum_write_value(iter->description, sizeof(iter->description), + &f->inline_enum, value); break; } case GEN_TYPE_UINT: { uint64_t value = field(v.qw, f->start, f->end); snprintf(iter->value, sizeof(iter->value), "%"PRIu64, value); - gen_field_write_value(iter->description, sizeof(iter->description), - f, value); + gen_enum_write_value(iter->description, sizeof(iter->description), + &f->inline_enum, value); break; } case GEN_TYPE_BOOL: { @@ -719,6 +754,14 @@ gen_field_iterator_next(struct gen_field_iterator *iter) break; case GEN_TYPE_MBO: break; + case GEN_TYPE_ENUM: { + uint64_t value = field(v.qw, f->start, f->end); + snprintf(iter->value, sizeof(iter->value), + "%"PRId64, value); + gen_enum_write_value(iter->description, sizeof(iter->description), + f->type.gen_enum, value); + break; + } } return true; |