Home | History | Annotate | Line # | Download | only in common
      1 /*
      2  * Copyright  2016 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  */
     23 
     24 #include <stdio.h>
     25 #include <stdbool.h>
     26 #include <stdint.h>
     27 #include <stdarg.h>
     28 #include <string.h>
     29 #include <expat.h>
     30 #include <inttypes.h>
     31 #include <zlib.h>
     32 
     33 #include <util/macros.h>
     34 #include <util/ralloc.h>
     35 
     36 #include "intel_decoder.h"
     37 
     38 #include "isl/isl.h"
     39 #include "genxml/genX_xml.h"
     40 
     41 #define XML_BUFFER_SIZE 4096
     42 #define MAX_VALUE_ITEMS 128
     43 
     44 struct location {
     45    const char *filename;
     46    int line_number;
     47 };
     48 
     49 struct parser_context {
     50    XML_Parser parser;
     51    int foo;
     52    struct location loc;
     53 
     54    struct intel_group *group;
     55    struct intel_enum *enoom;
     56 
     57    int n_values, n_allocated_values;
     58    struct intel_value **values;
     59 
     60    struct intel_field *last_field;
     61 
     62    struct intel_spec *spec;
     63 };
     64 
     65 const char *
     66 intel_group_get_name(struct intel_group *group)
     67 {
     68    return group->name;
     69 }
     70 
     71 uint32_t
     72 intel_group_get_opcode(struct intel_group *group)
     73 {
     74    return group->opcode;
     75 }
     76 
     77 struct intel_group *
     78 intel_spec_find_struct(struct intel_spec *spec, const char *name)
     79 {
     80    struct hash_entry *entry = _mesa_hash_table_search(spec->structs,
     81                                                       name);
     82    return entry ? entry->data : NULL;
     83 }
     84 
     85 struct intel_group *
     86 intel_spec_find_register(struct intel_spec *spec, uint32_t offset)
     87 {
     88    struct hash_entry *entry =
     89       _mesa_hash_table_search(spec->registers_by_offset,
     90                               (void *) (uintptr_t) offset);
     91    return entry ? entry->data : NULL;
     92 }
     93 
     94 struct intel_group *
     95 intel_spec_find_register_by_name(struct intel_spec *spec, const char *name)
     96 {
     97    struct hash_entry *entry =
     98       _mesa_hash_table_search(spec->registers_by_name, name);
     99    return entry ? entry->data : NULL;
    100 }
    101 
    102 struct intel_enum *
    103 intel_spec_find_enum(struct intel_spec *spec, const char *name)
    104 {
    105    struct hash_entry *entry = _mesa_hash_table_search(spec->enums,
    106                                                       name);
    107    return entry ? entry->data : NULL;
    108 }
    109 
    110 uint32_t
    111 intel_spec_get_gen(struct intel_spec *spec)
    112 {
    113    return spec->gen;
    114 }
    115 
    116 static void __attribute__((noreturn))
    117 fail(struct location *loc, const char *msg, ...)
    118 {
    119    va_list ap;
    120 
    121    va_start(ap, msg);
    122    fprintf(stderr, "%s:%d: error: ",
    123            loc->filename, loc->line_number);
    124    vfprintf(stderr, msg, ap);
    125    fprintf(stderr, "\n");
    126    va_end(ap);
    127    exit(EXIT_FAILURE);
    128 }
    129 
    130 static void
    131 get_array_offset_count(const char **atts, uint32_t *offset, uint32_t *count,
    132                        uint32_t *size, bool *variable)
    133 {
    134    for (int i = 0; atts[i]; i += 2) {
    135       char *p;
    136 
    137       if (strcmp(atts[i], "count") == 0) {
    138          *count = strtoul(atts[i + 1], &p, 0);
    139          if (*count == 0)
    140             *variable = true;
    141       } else if (strcmp(atts[i], "start") == 0) {
    142          *offset = strtoul(atts[i + 1], &p, 0);
    143       } else if (strcmp(atts[i], "size") == 0) {
    144          *size = strtoul(atts[i + 1], &p, 0);
    145       }
    146    }
    147    return;
    148 }
    149 
    150 static struct intel_group *
    151 create_group(struct parser_context *ctx,
    152              const char *name,
    153              const char **atts,
    154              struct intel_group *parent,
    155              bool fixed_length)
    156 {
    157    struct intel_group *group;
    158 
    159    group = rzalloc(ctx->spec, struct intel_group);
    160    if (name)
    161       group->name = ralloc_strdup(group, name);
    162 
    163    group->spec = ctx->spec;
    164    group->variable = false;
    165    group->fixed_length = fixed_length;
    166    group->dword_length_field = NULL;
    167    group->dw_length = 0;
    168    group->engine_mask = I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_RENDER) |
    169                         I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_VIDEO) |
    170                         I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_COPY);
    171    group->bias = 1;
    172 
    173    for (int i = 0; atts[i]; i += 2) {
    174       char *p;
    175       if (strcmp(atts[i], "length") == 0) {
    176          group->dw_length = strtoul(atts[i + 1], &p, 0);
    177       } else if (strcmp(atts[i], "bias") == 0) {
    178          group->bias = strtoul(atts[i + 1], &p, 0);
    179       } else if (strcmp(atts[i], "engine") == 0) {
    180          void *mem_ctx = ralloc_context(NULL);
    181          char *tmp = ralloc_strdup(mem_ctx, atts[i + 1]);
    182          char *save_ptr;
    183          char *tok = strtok_r(tmp, "|", &save_ptr);
    184 
    185          group->engine_mask = 0;
    186          while (tok != NULL) {
    187             if (strcmp(tok, "render") == 0) {
    188                group->engine_mask |= I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_RENDER);
    189             } else if (strcmp(tok, "video") == 0) {
    190                group->engine_mask |= I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_VIDEO);
    191             } else if (strcmp(tok, "blitter") == 0) {
    192                group->engine_mask |= I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_COPY);
    193             } else {
    194                fprintf(stderr, "unknown engine class defined for instruction \"%s\": %s\n", name, atts[i + 1]);
    195             }
    196 
    197             tok = strtok_r(NULL, "|", &save_ptr);
    198          }
    199 
    200          ralloc_free(mem_ctx);
    201       }
    202    }
    203 
    204    if (parent) {
    205       group->parent = parent;
    206       get_array_offset_count(atts,
    207                              &group->array_offset,
    208                              &group->array_count,
    209                              &group->array_item_size,
    210                              &group->variable);
    211    }
    212 
    213    return group;
    214 }
    215 
    216 static struct intel_enum *
    217 create_enum(struct parser_context *ctx, const char *name, const char **atts)
    218 {
    219    struct intel_enum *e;
    220 
    221    e = rzalloc(ctx->spec, struct intel_enum);
    222    if (name)
    223       e->name = ralloc_strdup(e, name);
    224 
    225    return e;
    226 }
    227 
    228 static void
    229 get_register_offset(const char **atts, uint32_t *offset)
    230 {
    231    for (int i = 0; atts[i]; i += 2) {
    232       char *p;
    233 
    234       if (strcmp(atts[i], "num") == 0)
    235          *offset = strtoul(atts[i + 1], &p, 0);
    236    }
    237    return;
    238 }
    239 
    240 static void
    241 get_start_end_pos(int *start, int *end)
    242 {
    243    /* start value has to be mod with 32 as we need the relative
    244     * start position in the first DWord. For the end position, add
    245     * the length of the field to the start position to get the
    246     * relative postion in the 64 bit address.
    247     */
    248    if (*end - *start > 32) {
    249       int len = *end - *start;
    250       *start = *start % 32;
    251       *end = *start + len;
    252    } else {
    253       *start = *start % 32;
    254       *end = *end % 32;
    255    }
    256 
    257    return;
    258 }
    259 
    260 static inline uint64_t
    261 mask(int start, int end)
    262 {
    263    uint64_t v;
    264 
    265    v = ~0ULL >> (63 - end + start);
    266 
    267    return v << start;
    268 }
    269 
    270 static inline uint64_t
    271 field_value(uint64_t value, int start, int end)
    272 {
    273    get_start_end_pos(&start, &end);
    274    return (value & mask(start, end)) >> (start);
    275 }
    276 
    277 static struct intel_type
    278 string_to_type(struct parser_context *ctx, const char *s)
    279 {
    280    int i, f;
    281    struct intel_group *g;
    282    struct intel_enum *e;
    283 
    284    if (strcmp(s, "int") == 0)
    285       return (struct intel_type) { .kind = INTEL_TYPE_INT };
    286    else if (strcmp(s, "uint") == 0)
    287       return (struct intel_type) { .kind = INTEL_TYPE_UINT };
    288    else if (strcmp(s, "bool") == 0)
    289       return (struct intel_type) { .kind = INTEL_TYPE_BOOL };
    290    else if (strcmp(s, "float") == 0)
    291       return (struct intel_type) { .kind = INTEL_TYPE_FLOAT };
    292    else if (strcmp(s, "address") == 0)
    293       return (struct intel_type) { .kind = INTEL_TYPE_ADDRESS };
    294    else if (strcmp(s, "offset") == 0)
    295       return (struct intel_type) { .kind = INTEL_TYPE_OFFSET };
    296    else if (sscanf(s, "u%d.%d", &i, &f) == 2)
    297       return (struct intel_type) { .kind = INTEL_TYPE_UFIXED, .i = i, .f = f };
    298    else if (sscanf(s, "s%d.%d", &i, &f) == 2)
    299       return (struct intel_type) { .kind = INTEL_TYPE_SFIXED, .i = i, .f = f };
    300    else if (g = intel_spec_find_struct(ctx->spec, s), g != NULL)
    301       return (struct intel_type) { .kind = INTEL_TYPE_STRUCT, .intel_struct = g };
    302    else if (e = intel_spec_find_enum(ctx->spec, s), e != NULL)
    303       return (struct intel_type) { .kind = INTEL_TYPE_ENUM, .intel_enum = e };
    304    else if (strcmp(s, "mbo") == 0)
    305       return (struct intel_type) { .kind = INTEL_TYPE_MBO };
    306    else
    307       fail(&ctx->loc, "invalid type: %s", s);
    308 }
    309 
    310 static struct intel_field *
    311 create_field(struct parser_context *ctx, const char **atts)
    312 {
    313    struct intel_field *field;
    314 
    315    field = rzalloc(ctx->group, struct intel_field);
    316    field->parent = ctx->group;
    317 
    318    for (int i = 0; atts[i]; i += 2) {
    319       char *p;
    320 
    321       if (strcmp(atts[i], "name") == 0) {
    322          field->name = ralloc_strdup(field, atts[i + 1]);
    323          if (strcmp(field->name, "DWord Length") == 0) {
    324             field->parent->dword_length_field = field;
    325          }
    326       } else if (strcmp(atts[i], "start") == 0) {
    327          field->start = strtoul(atts[i + 1], &p, 0);
    328       } else if (strcmp(atts[i], "end") == 0) {
    329          field->end = strtoul(atts[i + 1], &p, 0);
    330       } else if (strcmp(atts[i], "type") == 0) {
    331          field->type = string_to_type(ctx, atts[i + 1]);
    332       } else if (strcmp(atts[i], "default") == 0 &&
    333                field->start >= 16 && field->end <= 31) {
    334          field->has_default = true;
    335          field->default_value = strtoul(atts[i + 1], &p, 0);
    336       }
    337    }
    338 
    339    return field;
    340 }
    341 
    342 static struct intel_field *
    343 create_array_field(struct parser_context *ctx, struct intel_group *array)
    344 {
    345    struct intel_field *field;
    346 
    347    field = rzalloc(ctx->group, struct intel_field);
    348    field->parent = ctx->group;
    349 
    350    field->array = array;
    351    field->start = field->array->array_offset;
    352 
    353    return field;
    354 }
    355 
    356 static struct intel_value *
    357 create_value(struct parser_context *ctx, const char **atts)
    358 {
    359    struct intel_value *value = rzalloc(ctx->values, struct intel_value);
    360 
    361    for (int i = 0; atts[i]; i += 2) {
    362       if (strcmp(atts[i], "name") == 0)
    363          value->name = ralloc_strdup(value, atts[i + 1]);
    364       else if (strcmp(atts[i], "value") == 0)
    365          value->value = strtoul(atts[i + 1], NULL, 0);
    366    }
    367 
    368    return value;
    369 }
    370 
    371 static struct intel_field *
    372 create_and_append_field(struct parser_context *ctx,
    373                         const char **atts,
    374                         struct intel_group *array)
    375 {
    376    struct intel_field *field = array ?
    377       create_array_field(ctx, array) : create_field(ctx, atts);
    378    struct intel_field *prev = NULL, *list = ctx->group->fields;
    379 
    380    while (list && field->start > list->start) {
    381       prev = list;
    382       list = list->next;
    383    }
    384 
    385    field->next = list;
    386    if (prev == NULL)
    387       ctx->group->fields = field;
    388    else
    389       prev->next = field;
    390 
    391    return field;
    392 }
    393 
    394 static void
    395 start_element(void *data, const char *element_name, const char **atts)
    396 {
    397    struct parser_context *ctx = data;
    398    const char *name = NULL;
    399    const char *gen = NULL;
    400 
    401    ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
    402 
    403    for (int i = 0; atts[i]; i += 2) {
    404       if (strcmp(atts[i], "name") == 0)
    405          name = atts[i + 1];
    406       else if (strcmp(atts[i], "gen") == 0)
    407          gen = atts[i + 1];
    408    }
    409 
    410    if (strcmp(element_name, "genxml") == 0) {
    411       if (name == NULL)
    412          fail(&ctx->loc, "no platform name given");
    413       if (gen == NULL)
    414          fail(&ctx->loc, "no gen given");
    415 
    416       int major, minor;
    417       int n = sscanf(gen, "%d.%d", &major, &minor);
    418       if (n == 0)
    419          fail(&ctx->loc, "invalid gen given: %s", gen);
    420       if (n == 1)
    421          minor = 0;
    422 
    423       ctx->spec->gen = intel_make_gen(major, minor);
    424    } else if (strcmp(element_name, "instruction") == 0) {
    425       ctx->group = create_group(ctx, name, atts, NULL, false);
    426    } else if (strcmp(element_name, "struct") == 0) {
    427       ctx->group = create_group(ctx, name, atts, NULL, true);
    428    } else if (strcmp(element_name, "register") == 0) {
    429       ctx->group = create_group(ctx, name, atts, NULL, true);
    430       get_register_offset(atts, &ctx->group->register_offset);
    431    } else if (strcmp(element_name, "group") == 0) {
    432       struct intel_group *group = create_group(ctx, "", atts, ctx->group, false);
    433       ctx->last_field = create_and_append_field(ctx, NULL, group);
    434       ctx->group = group;
    435    } else if (strcmp(element_name, "field") == 0) {
    436       ctx->last_field = create_and_append_field(ctx, atts, NULL);
    437    } else if (strcmp(element_name, "enum") == 0) {
    438       ctx->enoom = create_enum(ctx, name, atts);
    439    } else if (strcmp(element_name, "value") == 0) {
    440       if (ctx->n_values >= ctx->n_allocated_values) {
    441          ctx->n_allocated_values = MAX2(2, ctx->n_allocated_values * 2);
    442          ctx->values = reralloc_array_size(ctx->spec, ctx->values,
    443                                            sizeof(struct intel_value *),
    444                                            ctx->n_allocated_values);
    445       }
    446       assert(ctx->n_values < ctx->n_allocated_values);
    447       ctx->values[ctx->n_values++] = create_value(ctx, atts);
    448    }
    449 
    450 }
    451 
    452 static void
    453 end_element(void *data, const char *name)
    454 {
    455    struct parser_context *ctx = data;
    456    struct intel_spec *spec = ctx->spec;
    457 
    458    if (strcmp(name, "instruction") == 0 ||
    459        strcmp(name, "struct") == 0 ||
    460        strcmp(name, "register") == 0) {
    461       struct intel_group *group = ctx->group;
    462       struct intel_field *list = group->fields;
    463 
    464       ctx->group = ctx->group->parent;
    465 
    466       while (list && list->end <= 31) {
    467          if (list->start >= 16 && list->has_default) {
    468             group->opcode_mask |=
    469                mask(list->start % 32, list->end % 32);
    470             group->opcode |= list->default_value << list->start;
    471          }
    472          list = list->next;
    473       }
    474 
    475       if (strcmp(name, "instruction") == 0)
    476          _mesa_hash_table_insert(spec->commands, group->name, group);
    477       else if (strcmp(name, "struct") == 0)
    478          _mesa_hash_table_insert(spec->structs, group->name, group);
    479       else if (strcmp(name, "register") == 0) {
    480          _mesa_hash_table_insert(spec->registers_by_name, group->name, group);
    481          _mesa_hash_table_insert(spec->registers_by_offset,
    482                                  (void *) (uintptr_t) group->register_offset,
    483                                  group);
    484       }
    485    } else if (strcmp(name, "group") == 0) {
    486       ctx->group = ctx->group->parent;
    487    } else if (strcmp(name, "field") == 0) {
    488       struct intel_field *field = ctx->last_field;
    489       ctx->last_field = NULL;
    490       field->inline_enum.values = ctx->values;
    491       field->inline_enum.nvalues = ctx->n_values;
    492       ctx->values = ralloc_array(ctx->spec, struct intel_value*, ctx->n_allocated_values = 2);
    493       ctx->n_values = 0;
    494    } else if (strcmp(name, "enum") == 0) {
    495       struct intel_enum *e = ctx->enoom;
    496       e->values = ctx->values;
    497       e->nvalues = ctx->n_values;
    498       ctx->values = ralloc_array(ctx->spec, struct intel_value*, ctx->n_allocated_values = 2);
    499       ctx->n_values = 0;
    500       ctx->enoom = NULL;
    501       _mesa_hash_table_insert(spec->enums, e->name, e);
    502    }
    503 }
    504 
    505 static void
    506 character_data(void *data, const XML_Char *s, int len)
    507 {
    508 }
    509 
    510 static uint32_t zlib_inflate(const void *compressed_data,
    511                              uint32_t compressed_len,
    512                              void **out_ptr)
    513 {
    514    struct z_stream_s zstream;
    515    void *out;
    516 
    517    memset(&zstream, 0, sizeof(zstream));
    518 
    519    zstream.next_in = (unsigned char *)compressed_data;
    520    zstream.avail_in = compressed_len;
    521 
    522    if (inflateInit(&zstream) != Z_OK)
    523       return 0;
    524 
    525    out = malloc(4096);
    526    zstream.next_out = out;
    527    zstream.avail_out = 4096;
    528 
    529    do {
    530       switch (inflate(&zstream, Z_SYNC_FLUSH)) {
    531       case Z_STREAM_END:
    532          goto end;
    533       case Z_OK:
    534          break;
    535       default:
    536          inflateEnd(&zstream);
    537          return 0;
    538       }
    539 
    540       if (zstream.avail_out)
    541          break;
    542 
    543       out = realloc(out, 2*zstream.total_out);
    544       if (out == NULL) {
    545          inflateEnd(&zstream);
    546          return 0;
    547       }
    548 
    549       zstream.next_out = (unsigned char *)out + zstream.total_out;
    550       zstream.avail_out = zstream.total_out;
    551    } while (1);
    552  end:
    553    inflateEnd(&zstream);
    554    *out_ptr = out;
    555    return zstream.total_out;
    556 }
    557 
    558 static uint32_t _hash_uint32(const void *key)
    559 {
    560    return (uint32_t) (uintptr_t) key;
    561 }
    562 
    563 static struct intel_spec *
    564 intel_spec_init(void)
    565 {
    566    struct intel_spec *spec;
    567    spec = rzalloc(NULL, struct intel_spec);
    568    if (spec == NULL)
    569       return NULL;
    570 
    571    spec->commands =
    572       _mesa_hash_table_create(spec, _mesa_hash_string, _mesa_key_string_equal);
    573    spec->structs =
    574       _mesa_hash_table_create(spec, _mesa_hash_string, _mesa_key_string_equal);
    575    spec->registers_by_name =
    576       _mesa_hash_table_create(spec, _mesa_hash_string, _mesa_key_string_equal);
    577    spec->registers_by_offset =
    578       _mesa_hash_table_create(spec, _hash_uint32, _mesa_key_pointer_equal);
    579    spec->enums =
    580       _mesa_hash_table_create(spec, _mesa_hash_string, _mesa_key_string_equal);
    581    spec->access_cache =
    582       _mesa_hash_table_create(spec, _mesa_hash_string, _mesa_key_string_equal);
    583 
    584    return spec;
    585 }
    586 
    587 struct intel_spec *
    588 intel_spec_load(const struct intel_device_info *devinfo)
    589 {
    590    struct parser_context ctx;
    591    void *buf;
    592    uint8_t *text_data = NULL;
    593    uint32_t text_offset = 0, text_length = 0;
    594    ASSERTED uint32_t total_length;
    595    uint32_t ver_10 = devinfo->verx10;
    596 
    597    for (int i = 0; i < ARRAY_SIZE(genxml_files_table); i++) {
    598       if (genxml_files_table[i].ver_10 == ver_10) {
    599          text_offset = genxml_files_table[i].offset;
    600          text_length = genxml_files_table[i].length;
    601          break;
    602       }
    603    }
    604 
    605    if (text_length == 0) {
    606       fprintf(stderr, "unable to find gen (%u) data\n", ver_10);
    607       return NULL;
    608    }
    609 
    610    memset(&ctx, 0, sizeof ctx);
    611    ctx.parser = XML_ParserCreate(NULL);
    612    XML_SetUserData(ctx.parser, &ctx);
    613    if (ctx.parser == NULL) {
    614       fprintf(stderr, "failed to create parser\n");
    615       return NULL;
    616    }
    617 
    618    XML_SetElementHandler(ctx.parser, start_element, end_element);
    619    XML_SetCharacterDataHandler(ctx.parser, character_data);
    620 
    621    ctx.spec = intel_spec_init();
    622    if (ctx.spec == NULL) {
    623       fprintf(stderr, "Failed to create intel_spec\n");
    624       return NULL;
    625    }
    626 
    627    total_length = zlib_inflate(compress_genxmls,
    628                                sizeof(compress_genxmls),
    629                                (void **) &text_data);
    630    assert(text_offset + text_length <= total_length);
    631 
    632    buf = XML_GetBuffer(ctx.parser, text_length);
    633    memcpy(buf, &text_data[text_offset], text_length);
    634 
    635    if (XML_ParseBuffer(ctx.parser, text_length, true) == 0) {
    636       fprintf(stderr,
    637               "Error parsing XML at line %ld col %ld byte %ld/%u: %s\n",
    638               XML_GetCurrentLineNumber(ctx.parser),
    639               XML_GetCurrentColumnNumber(ctx.parser),
    640               XML_GetCurrentByteIndex(ctx.parser), text_length,
    641               XML_ErrorString(XML_GetErrorCode(ctx.parser)));
    642       XML_ParserFree(ctx.parser);
    643       free(text_data);
    644       return NULL;
    645    }
    646 
    647    XML_ParserFree(ctx.parser);
    648    free(text_data);
    649 
    650    return ctx.spec;
    651 }
    652 
    653 struct intel_spec *
    654 intel_spec_load_filename(const char *filename)
    655 {
    656    struct parser_context ctx;
    657    FILE *input;
    658    void *buf;
    659    size_t len;
    660 
    661    input = fopen(filename, "r");
    662    if (input == NULL) {
    663       fprintf(stderr, "failed to open xml description\n");
    664       return NULL;
    665    }
    666 
    667    memset(&ctx, 0, sizeof ctx);
    668    ctx.parser = XML_ParserCreate(NULL);
    669    XML_SetUserData(ctx.parser, &ctx);
    670    if (ctx.parser == NULL) {
    671       fprintf(stderr, "failed to create parser\n");
    672       fclose(input);
    673       return NULL;
    674    }
    675 
    676    XML_SetElementHandler(ctx.parser, start_element, end_element);
    677    XML_SetCharacterDataHandler(ctx.parser, character_data);
    678    ctx.loc.filename = filename;
    679 
    680    ctx.spec = intel_spec_init();
    681    if (ctx.spec == NULL) {
    682       fprintf(stderr, "Failed to create intel_spec\n");
    683       goto end;
    684    }
    685 
    686    do {
    687       buf = XML_GetBuffer(ctx.parser, XML_BUFFER_SIZE);
    688       len = fread(buf, 1, XML_BUFFER_SIZE, input);
    689       if (ferror(input)) {
    690          fprintf(stderr, "fread: %m\n");
    691          intel_spec_destroy(ctx.spec);
    692          ctx.spec = NULL;
    693          goto end;
    694       } else if (len == 0 && feof(input))
    695          goto end;
    696 
    697       if (XML_ParseBuffer(ctx.parser, len, len == 0) == 0) {
    698          fprintf(stderr,
    699                  "Error parsing XML at line %ld col %ld: %s\n",
    700                  XML_GetCurrentLineNumber(ctx.parser),
    701                  XML_GetCurrentColumnNumber(ctx.parser),
    702                  XML_ErrorString(XML_GetErrorCode(ctx.parser)));
    703          intel_spec_destroy(ctx.spec);
    704          ctx.spec = NULL;
    705          goto end;
    706       }
    707    } while (len > 0);
    708 
    709  end:
    710    XML_ParserFree(ctx.parser);
    711 
    712    fclose(input);
    713 
    714    /* free ctx.spec if genxml is empty */
    715    if (ctx.spec &&
    716        _mesa_hash_table_num_entries(ctx.spec->commands) == 0 &&
    717        _mesa_hash_table_num_entries(ctx.spec->structs) == 0) {
    718       fprintf(stderr,
    719               "Error parsing XML: empty spec.\n");
    720       intel_spec_destroy(ctx.spec);
    721       return NULL;
    722    }
    723 
    724    return ctx.spec;
    725 }
    726 
    727 struct intel_spec *
    728 intel_spec_load_from_path(const struct intel_device_info *devinfo,
    729                           const char *path)
    730 {
    731    size_t filename_len = strlen(path) + 20;
    732    char *filename = malloc(filename_len);
    733 
    734    ASSERTED size_t len = snprintf(filename, filename_len, "%s/gen%i.xml",
    735                   path, devinfo->ver);
    736    assert(len < filename_len);
    737 
    738    struct intel_spec *spec = intel_spec_load_filename(filename);
    739    free(filename);
    740 
    741    return spec;
    742 }
    743 
    744 void intel_spec_destroy(struct intel_spec *spec)
    745 {
    746    ralloc_free(spec);
    747 }
    748 
    749 struct intel_group *
    750 intel_spec_find_instruction(struct intel_spec *spec,
    751                             enum drm_i915_gem_engine_class engine,
    752                             const uint32_t *p)
    753 {
    754    hash_table_foreach(spec->commands, entry) {
    755       struct intel_group *command = entry->data;
    756       uint32_t opcode = *p & command->opcode_mask;
    757       if ((command->engine_mask & I915_ENGINE_CLASS_TO_MASK(engine)) &&
    758            opcode == command->opcode)
    759          return command;
    760    }
    761 
    762    return NULL;
    763 }
    764 
    765 struct intel_field *
    766 intel_group_find_field(struct intel_group *group, const char *name)
    767 {
    768    char path[256];
    769    snprintf(path, sizeof(path), "%s/%s", group->name, name);
    770 
    771    struct intel_spec *spec = group->spec;
    772    struct hash_entry *entry = _mesa_hash_table_search(spec->access_cache,
    773                                                       path);
    774    if (entry)
    775       return entry->data;
    776 
    777    struct intel_field *field = group->fields;
    778    while (field) {
    779       if (strcmp(field->name, name) == 0) {
    780          _mesa_hash_table_insert(spec->access_cache,
    781                                  ralloc_strdup(spec, path),
    782                                  field);
    783          return field;
    784       }
    785       field = field->next;
    786    }
    787 
    788    return NULL;
    789 }
    790 
    791 int
    792 intel_group_get_length(struct intel_group *group, const uint32_t *p)
    793 {
    794    if (group) {
    795       if (group->fixed_length)
    796          return group->dw_length;
    797       else {
    798          struct intel_field *field = group->dword_length_field;
    799          if (field) {
    800             return field_value(p[0], field->start, field->end) + group->bias;
    801          }
    802       }
    803    }
    804 
    805    uint32_t h = p[0];
    806    uint32_t type = field_value(h, 29, 31);
    807 
    808    switch (type) {
    809    case 0: /* MI */ {
    810       uint32_t opcode = field_value(h, 23, 28);
    811       if (opcode < 16)
    812          return 1;
    813       else
    814          return field_value(h, 0, 7) + 2;
    815       break;
    816    }
    817 
    818    case 2: /* BLT */ {
    819       return field_value(h, 0, 7) + 2;
    820    }
    821 
    822    case 3: /* Render */ {
    823       uint32_t subtype = field_value(h, 27, 28);
    824       uint32_t opcode = field_value(h, 24, 26);
    825       uint16_t whole_opcode = field_value(h, 16, 31);
    826       switch (subtype) {
    827       case 0:
    828          if (whole_opcode == 0x6104 /* PIPELINE_SELECT_965 */)
    829             return 1;
    830          else if (opcode < 2)
    831             return field_value(h, 0, 7) + 2;
    832          else
    833             return -1;
    834       case 1:
    835          if (opcode < 2)
    836             return 1;
    837          else
    838             return -1;
    839       case 2: {
    840          if (opcode == 0)
    841             return field_value(h, 0, 7) + 2;
    842          else if (opcode < 3)
    843             return field_value(h, 0, 15) + 2;
    844          else
    845             return -1;
    846       }
    847       case 3:
    848          if (whole_opcode == 0x780b)
    849             return 1;
    850          else if (opcode < 4)
    851             return field_value(h, 0, 7) + 2;
    852          else
    853             return -1;
    854       }
    855    }
    856    }
    857 
    858    return -1;
    859 }
    860 
    861 static const char *
    862 intel_get_enum_name(struct intel_enum *e, uint64_t value)
    863 {
    864    for (int i = 0; i < e->nvalues; i++) {
    865       if (e->values[i]->value == value) {
    866          return e->values[i]->name;
    867       }
    868    }
    869    return NULL;
    870 }
    871 
    872 static bool
    873 iter_more_fields(const struct intel_field_iterator *iter)
    874 {
    875    return iter->field != NULL && iter->field->next != NULL;
    876 }
    877 
    878 static uint32_t
    879 iter_array_offset_bits(const struct intel_field_iterator *iter)
    880 {
    881    if (iter->level == 0)
    882       return 0;
    883 
    884    uint32_t offset = 0;
    885    const struct intel_group *group = iter->groups[1];
    886    for (int level = 1; level <= iter->level; level++, group = iter->groups[level]) {
    887       uint32_t array_idx = iter->array_iter[level];
    888       offset += group->array_offset + array_idx * group->array_item_size;
    889    }
    890 
    891    return offset;
    892 }
    893 
    894 /* Checks whether we have more items in the array to iterate, or more arrays to
    895  * iterate through.
    896  */
    897 /* descend into a non-array field */
    898 static void
    899 iter_push_array(struct intel_field_iterator *iter)
    900 {
    901    assert(iter->level >= 0);
    902 
    903    iter->group = iter->field->array;
    904    iter->level++;
    905    assert(iter->level < DECODE_MAX_ARRAY_DEPTH);
    906    iter->groups[iter->level] = iter->group;
    907    iter->array_iter[iter->level] = 0;
    908 
    909    assert(iter->group->fields != NULL); /* an empty <group> makes no sense */
    910    iter->field = iter->group->fields;
    911    iter->fields[iter->level] = iter->field;
    912 }
    913 
    914 static void
    915 iter_pop_array(struct intel_field_iterator *iter)
    916 {
    917    assert(iter->level > 0);
    918 
    919    iter->level--;
    920    iter->field = iter->fields[iter->level];
    921    iter->group = iter->groups[iter->level];
    922 }
    923 
    924 static void
    925 iter_start_field(struct intel_field_iterator *iter, struct intel_field *field)
    926 {
    927    iter->field = field;
    928    iter->fields[iter->level] = field;
    929 
    930    while (iter->field->array)
    931       iter_push_array(iter);
    932 
    933    int array_member_offset = iter_array_offset_bits(iter);
    934 
    935    iter->start_bit = array_member_offset + iter->field->start;
    936    iter->end_bit = array_member_offset + iter->field->end;
    937    iter->struct_desc = NULL;
    938 }
    939 
    940 static void
    941 iter_advance_array(struct intel_field_iterator *iter)
    942 {
    943    assert(iter->level > 0);
    944    int lvl = iter->level;
    945 
    946    if (iter->group->variable)
    947       iter->array_iter[lvl]++;
    948    else {
    949       if ((iter->array_iter[lvl] + 1) < iter->group->array_count) {
    950          iter->array_iter[lvl]++;
    951       }
    952    }
    953 
    954    iter_start_field(iter, iter->group->fields);
    955 }
    956 
    957 static bool
    958 iter_more_array_elems(const struct intel_field_iterator *iter)
    959 {
    960    int lvl = iter->level;
    961    assert(lvl >= 0);
    962 
    963    if (iter->group->variable) {
    964       int length = intel_group_get_length(iter->group, iter->p);
    965       assert(length >= 0 && "error the length is unknown!");
    966       return iter_array_offset_bits(iter) + iter->group->array_item_size <
    967          (length * 32);
    968    } else {
    969       return (iter->array_iter[lvl] + 1) < iter->group->array_count;
    970    }
    971 }
    972 
    973 static bool
    974 iter_advance_field(struct intel_field_iterator *iter)
    975 {
    976    /* Keep looping while we either have more fields to look at, or we are
    977     * inside a <group> and can go up a level.
    978     */
    979    while (iter_more_fields(iter) || iter->level > 0) {
    980       if (iter_more_fields(iter)) {
    981          iter_start_field(iter, iter->field->next);
    982          return true;
    983       }
    984 
    985       assert(iter->level >= 0);
    986 
    987       if (iter_more_array_elems(iter)) {
    988          iter_advance_array(iter);
    989          return true;
    990       }
    991 
    992       /* At this point, we reached the end of the <group> and were on the last
    993        * iteration. So it's time to go back to the parent and then advance the
    994        * field.
    995        */
    996       iter_pop_array(iter);
    997    }
    998 
    999    return false;
   1000 }
   1001 
   1002 static bool
   1003 iter_decode_field_raw(struct intel_field_iterator *iter, uint64_t *qw)
   1004 {
   1005    *qw = 0;
   1006 
   1007    int field_start = iter->p_bit + iter->start_bit;
   1008    int field_end = iter->p_bit + iter->end_bit;
   1009 
   1010    const uint32_t *p = iter->p + (iter->start_bit / 32);
   1011    if (iter->p_end && p >= iter->p_end)
   1012       return false;
   1013 
   1014    if ((field_end - field_start) > 32) {
   1015       if (!iter->p_end || (p + 1) < iter->p_end)
   1016          *qw = ((uint64_t) p[1]) << 32;
   1017       *qw |= p[0];
   1018    } else
   1019       *qw = p[0];
   1020 
   1021    *qw = field_value(*qw, field_start, field_end);
   1022 
   1023    /* Address & offset types have to be aligned to dwords, their start bit is
   1024     * a reminder of the alignment requirement.
   1025     */
   1026    if (iter->field->type.kind == INTEL_TYPE_ADDRESS ||
   1027        iter->field->type.kind == INTEL_TYPE_OFFSET)
   1028       *qw <<= field_start % 32;
   1029 
   1030    return true;
   1031 }
   1032 
   1033 static bool
   1034 iter_decode_field(struct intel_field_iterator *iter)
   1035 {
   1036    union {
   1037       uint64_t qw;
   1038       float f;
   1039    } v;
   1040 
   1041    if (iter->field->name)
   1042       snprintf(iter->name, sizeof(iter->name), "%s", iter->field->name);
   1043    else
   1044       memset(iter->name, 0, sizeof(iter->name));
   1045 
   1046    memset(&v, 0, sizeof(v));
   1047 
   1048    if (!iter_decode_field_raw(iter, &iter->raw_value))
   1049       return false;
   1050 
   1051    const char *enum_name = NULL;
   1052 
   1053    v.qw = iter->raw_value;
   1054    switch (iter->field->type.kind) {
   1055    case INTEL_TYPE_UNKNOWN:
   1056    case INTEL_TYPE_INT: {
   1057       snprintf(iter->value, sizeof(iter->value), "%"PRId64, v.qw);
   1058       enum_name = intel_get_enum_name(&iter->field->inline_enum, v.qw);
   1059       break;
   1060    }
   1061    case INTEL_TYPE_UINT: {
   1062       snprintf(iter->value, sizeof(iter->value), "%"PRIu64, v.qw);
   1063       enum_name = intel_get_enum_name(&iter->field->inline_enum, v.qw);
   1064       break;
   1065    }
   1066    case INTEL_TYPE_BOOL: {
   1067       const char *true_string =
   1068          iter->print_colors ? "\e[0;35mtrue\e[0m" : "true";
   1069       snprintf(iter->value, sizeof(iter->value), "%s",
   1070                v.qw ? true_string : "false");
   1071       break;
   1072    }
   1073    case INTEL_TYPE_FLOAT:
   1074       snprintf(iter->value, sizeof(iter->value), "%f", v.f);
   1075       break;
   1076    case INTEL_TYPE_ADDRESS:
   1077    case INTEL_TYPE_OFFSET:
   1078       snprintf(iter->value, sizeof(iter->value), "0x%08"PRIx64, v.qw);
   1079       break;
   1080    case INTEL_TYPE_STRUCT:
   1081       snprintf(iter->value, sizeof(iter->value), "<struct %s>",
   1082                iter->field->type.intel_struct->name);
   1083       iter->struct_desc =
   1084          intel_spec_find_struct(iter->group->spec,
   1085                                 iter->field->type.intel_struct->name);
   1086       break;
   1087    case INTEL_TYPE_UFIXED:
   1088       snprintf(iter->value, sizeof(iter->value), "%f",
   1089                (float) v.qw / (1 << iter->field->type.f));
   1090       break;
   1091    case INTEL_TYPE_SFIXED: {
   1092       /* Sign extend before converting */
   1093       int bits = iter->field->type.i + iter->field->type.f + 1;
   1094       int64_t v_sign_extend = ((int64_t)(v.qw << (64 - bits))) >> (64 - bits);
   1095       snprintf(iter->value, sizeof(iter->value), "%f",
   1096                (float) v_sign_extend / (1 << iter->field->type.f));
   1097       break;
   1098    }
   1099    case INTEL_TYPE_MBO:
   1100        break;
   1101    case INTEL_TYPE_ENUM: {
   1102       snprintf(iter->value, sizeof(iter->value), "%"PRId64, v.qw);
   1103       enum_name = intel_get_enum_name(iter->field->type.intel_enum, v.qw);
   1104       break;
   1105    }
   1106    }
   1107 
   1108    if (strlen(iter->group->name) == 0) {
   1109       int length = strlen(iter->name);
   1110       assert(iter->level >= 0);
   1111 
   1112       int level = 1;
   1113       char *buf = iter->name + length;
   1114       while (level <= iter->level) {
   1115          int printed = snprintf(buf, sizeof(iter->name) - length,
   1116                                 "[%i]", iter->array_iter[level]);
   1117          level++;
   1118          length += printed;
   1119          buf += printed;
   1120       }
   1121    }
   1122 
   1123    if (enum_name) {
   1124       int length = strlen(iter->value);
   1125       snprintf(iter->value + length, sizeof(iter->value) - length,
   1126                " (%s)", enum_name);
   1127    } else if (strcmp(iter->name, "Surface Format") == 0 ||
   1128               strcmp(iter->name, "Source Element Format") == 0) {
   1129       if (isl_format_is_valid((enum isl_format)v.qw)) {
   1130          const char *fmt_name = isl_format_get_name((enum isl_format)v.qw);
   1131          int length = strlen(iter->value);
   1132          snprintf(iter->value + length, sizeof(iter->value) - length,
   1133                   " (%s)", fmt_name);
   1134       }
   1135    }
   1136 
   1137    return true;
   1138 }
   1139 
   1140 void
   1141 intel_field_iterator_init(struct intel_field_iterator *iter,
   1142                           struct intel_group *group,
   1143                           const uint32_t *p, int p_bit,
   1144                           bool print_colors)
   1145 {
   1146    memset(iter, 0, sizeof(*iter));
   1147 
   1148    iter->groups[iter->level] = group;
   1149    iter->group = group;
   1150    iter->p = p;
   1151    iter->p_bit = p_bit;
   1152 
   1153    int length = intel_group_get_length(iter->group, iter->p);
   1154    assert(length >= 0 && "error the length is unknown!");
   1155    iter->p_end = length >= 0 ? &p[length] : NULL;
   1156    iter->print_colors = print_colors;
   1157 }
   1158 
   1159 bool
   1160 intel_field_iterator_next(struct intel_field_iterator *iter)
   1161 {
   1162    /* Initial condition */
   1163    if (!iter->field) {
   1164       if (iter->group->fields)
   1165          iter_start_field(iter, iter->group->fields);
   1166 
   1167       bool result = iter_decode_field(iter);
   1168       if (!result && iter->p_end) {
   1169          /* We're dealing with a non empty struct of length=0 (BLEND_STATE on
   1170           * Gen 7.5)
   1171           */
   1172          assert(iter->group->dw_length == 0);
   1173       }
   1174 
   1175       return result;
   1176    }
   1177 
   1178    if (!iter_advance_field(iter))
   1179       return false;
   1180 
   1181    if (!iter_decode_field(iter))
   1182       return false;
   1183 
   1184    return true;
   1185 }
   1186 
   1187 static void
   1188 print_dword_header(FILE *outfile,
   1189                    struct intel_field_iterator *iter,
   1190                    uint64_t offset, uint32_t dword)
   1191 {
   1192    fprintf(outfile, "0x%08"PRIx64":  0x%08x : Dword %d\n",
   1193            offset + 4 * dword, iter->p[dword], dword);
   1194 }
   1195 
   1196 bool
   1197 intel_field_is_header(struct intel_field *field)
   1198 {
   1199    uint32_t bits;
   1200 
   1201    /* Instructions are identified by the first DWord. */
   1202    if (field->start >= 32 ||
   1203        field->end >= 32)
   1204       return false;
   1205 
   1206    bits = (1ULL << (field->end - field->start + 1)) - 1;
   1207    bits <<= field->start;
   1208 
   1209    return (field->parent->opcode_mask & bits) != 0;
   1210 }
   1211 
   1212 void
   1213 intel_print_group(FILE *outfile, struct intel_group *group, uint64_t offset,
   1214                   const uint32_t *p, int p_bit, bool color)
   1215 {
   1216    struct intel_field_iterator iter;
   1217    int last_dword = -1;
   1218 
   1219    intel_field_iterator_init(&iter, group, p, p_bit, color);
   1220    while (intel_field_iterator_next(&iter)) {
   1221       int iter_dword = iter.end_bit / 32;
   1222       if (last_dword != iter_dword) {
   1223          for (int i = last_dword + 1; i <= iter_dword; i++)
   1224             print_dword_header(outfile, &iter, offset, i);
   1225          last_dword = iter_dword;
   1226       }
   1227       if (!intel_field_is_header(iter.field)) {
   1228          fprintf(outfile, "    %s: %s\n", iter.name, iter.value);
   1229          if (iter.struct_desc) {
   1230             int struct_dword = iter.start_bit / 32;
   1231             uint64_t struct_offset = offset + 4 * struct_dword;
   1232             intel_print_group(outfile, iter.struct_desc, struct_offset,
   1233                               &p[struct_dword], iter.start_bit % 32, color);
   1234          }
   1235       }
   1236    }
   1237 }
   1238