Home | History | Annotate | Line # | Download | only in decode
      1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
      2 
      3 /*
      4  * Copyright (C) 2014 Rob Clark <robclark (at) freedesktop.org>
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the next
     14  * paragraph) shall be included in all copies or substantial portions of the
     15  * Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  * SOFTWARE.
     24  *
     25  * Authors:
     26  *    Rob Clark <robclark (at) freedesktop.org>
     27  */
     28 
     29 #include <assert.h>
     30 #include <err.h>
     31 #include <stdint.h>
     32 #include <stdio.h>
     33 #include <stdlib.h>
     34 #include <string.h>
     35 
     36 #include "rnnutil.h"
     37 
     38 static struct rnndomain *
     39 finddom(struct rnn *rnn, uint32_t regbase)
     40 {
     41    if (rnndec_checkaddr(rnn->vc, rnn->dom[0], regbase, 0))
     42       return rnn->dom[0];
     43    return rnn->dom[1];
     44 }
     45 
     46 void
     47 _rnn_init(struct rnn *rnn, int nocolor)
     48 {
     49    rnn_init();
     50 
     51    rnn->db = rnn_newdb();
     52    rnn->vc_nocolor = rnndec_newcontext(rnn->db);
     53    rnn->vc_nocolor->colors = &envy_null_colors;
     54    if (nocolor) {
     55       rnn->vc = rnn->vc_nocolor;
     56    } else {
     57       rnn->vc = rnndec_newcontext(rnn->db);
     58       rnn->vc->colors = &envy_def_colors;
     59    }
     60 }
     61 
     62 struct rnn *
     63 rnn_new(int nocolor)
     64 {
     65    struct rnn *rnn = calloc(sizeof(*rnn), 1);
     66 
     67    if (!rnn)
     68       return NULL;
     69 
     70    _rnn_init(rnn, nocolor);
     71 
     72    return rnn;
     73 }
     74 
     75 static void
     76 init(struct rnn *rnn, char *file, char *domain)
     77 {
     78    /* prepare rnn stuff for lookup */
     79    rnn_parsefile(rnn->db, file);
     80    rnn_prepdb(rnn->db);
     81    rnn->dom[0] = rnn_finddomain(rnn->db, domain);
     82    if ((strcmp(domain, "A2XX") == 0) || (strcmp(domain, "A3XX") == 0)) {
     83       rnn->dom[1] = rnn_finddomain(rnn->db, "AXXX");
     84    } else {
     85       rnn->dom[1] = rnn->dom[0];
     86    }
     87    if (!rnn->dom[0] && rnn->dom[1]) {
     88       fprintf(stderr, "Could not find domain %s in %s\n", domain, file);
     89    }
     90    rnn->variant = domain;
     91 
     92    rnndec_varadd(rnn->vc, "chip", domain);
     93    if (rnn->vc != rnn->vc_nocolor)
     94       rnndec_varadd(rnn->vc_nocolor, "chip", domain);
     95    if (rnn->db->estatus)
     96       errx(rnn->db->estatus, "failed to parse register database");
     97 }
     98 
     99 void
    100 rnn_load_file(struct rnn *rnn, char *file, char *domain)
    101 {
    102    init(rnn, file, domain);
    103 }
    104 
    105 void
    106 rnn_load(struct rnn *rnn, const char *gpuname)
    107 {
    108    if (strstr(gpuname, "a2")) {
    109       init(rnn, "adreno/a2xx.xml", "A2XX");
    110    } else if (strstr(gpuname, "a3")) {
    111       init(rnn, "adreno/a3xx.xml", "A3XX");
    112    } else if (strstr(gpuname, "a4")) {
    113       init(rnn, "adreno/a4xx.xml", "A4XX");
    114    } else if (strstr(gpuname, "a5")) {
    115       init(rnn, "adreno/a5xx.xml", "A5XX");
    116    } else if (strstr(gpuname, "a6")) {
    117       init(rnn, "adreno/a6xx.xml", "A6XX");
    118    }
    119 }
    120 
    121 uint32_t
    122 rnn_regbase(struct rnn *rnn, const char *name)
    123 {
    124    uint32_t regbase = rnndec_decodereg(rnn->vc_nocolor, rnn->dom[0], name);
    125    if (!regbase)
    126       regbase = rnndec_decodereg(rnn->vc_nocolor, rnn->dom[1], name);
    127    return regbase;
    128 }
    129 
    130 const char *
    131 rnn_regname(struct rnn *rnn, uint32_t regbase, int color)
    132 {
    133    static char buf[128];
    134    struct rnndecaddrinfo *info;
    135 
    136    info = rnndec_decodeaddr(color ? rnn->vc : rnn->vc_nocolor,
    137                             finddom(rnn, regbase), regbase, 0);
    138    if (info) {
    139       strcpy(buf, info->name);
    140       free(info->name);
    141       free(info);
    142       return buf;
    143    }
    144    return NULL;
    145 }
    146 
    147 struct rnndecaddrinfo *
    148 rnn_reginfo(struct rnn *rnn, uint32_t regbase)
    149 {
    150    return rnndec_decodeaddr(rnn->vc, finddom(rnn, regbase), regbase, 0);
    151 }
    152 
    153 const char *
    154 rnn_enumname(struct rnn *rnn, const char *name, uint32_t val)
    155 {
    156    return rnndec_decode_enum(rnn->vc, name, val);
    157 }
    158 
    159 static struct rnndelem *
    160 regelem(struct rnndomain *domain, const char *name)
    161 {
    162    int i;
    163    for (i = 0; i < domain->subelemsnum; i++) {
    164       struct rnndelem *elem = domain->subelems[i];
    165       if (!strcmp(elem->name, name))
    166          return elem;
    167    }
    168    return NULL;
    169 }
    170 
    171 /* Lookup rnndelem by name: */
    172 struct rnndelem *
    173 rnn_regelem(struct rnn *rnn, const char *name)
    174 {
    175    struct rnndelem *elem = regelem(rnn->dom[0], name);
    176    if (elem)
    177       return elem;
    178    return regelem(rnn->dom[1], name);
    179 }
    180 
    181 static struct rnndelem *
    182 regoff(struct rnndomain *domain, uint32_t offset)
    183 {
    184    int i;
    185    for (i = 0; i < domain->subelemsnum; i++) {
    186       struct rnndelem *elem = domain->subelems[i];
    187       if (elem->offset == offset)
    188          return elem;
    189    }
    190    return NULL;
    191 }
    192 
    193 /* Lookup rnndelem by offset: */
    194 struct rnndelem *
    195 rnn_regoff(struct rnn *rnn, uint32_t offset)
    196 {
    197    struct rnndelem *elem = regoff(rnn->dom[0], offset);
    198    if (elem)
    199       return elem;
    200    return regoff(rnn->dom[1], offset);
    201 }
    202 
    203 enum rnnttype
    204 rnn_decodelem(struct rnn *rnn, struct rnntypeinfo *info, uint32_t regval,
    205               union rnndecval *val)
    206 {
    207    val->u = regval;
    208    switch (info->type) {
    209    case RNN_TTYPE_INLINE_ENUM:
    210    case RNN_TTYPE_ENUM:
    211    case RNN_TTYPE_HEX:
    212    case RNN_TTYPE_INT:
    213    case RNN_TTYPE_UINT:
    214    case RNN_TTYPE_FLOAT:
    215    case RNN_TTYPE_BOOLEAN:
    216       return info->type;
    217    case RNN_TTYPE_FIXED:
    218    case RNN_TTYPE_UFIXED:
    219       /* TODO */
    220    default:
    221       return RNN_TTYPE_INVALID;
    222    }
    223 }
    224