Path: blob/21.2-virgl/src/freedreno/decode/rnnutil.c
4565 views
/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */12/*3* Copyright (C) 2014 Rob Clark <[email protected]>4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the "Software"),7* to deal in the Software without restriction, including without limitation8* the rights to use, copy, modify, merge, publish, distribute, sublicense,9* and/or sell copies of the Software, and to permit persons to whom the10* Software is furnished to do so, subject to the following conditions:11*12* The above copyright notice and this permission notice (including the next13* paragraph) shall be included in all copies or substantial portions of the14* Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL19* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,21* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE22* SOFTWARE.23*24* Authors:25* Rob Clark <[email protected]>26*/2728#include <assert.h>29#include <err.h>30#include <stdint.h>31#include <stdio.h>32#include <stdlib.h>33#include <string.h>3435#include "rnnutil.h"3637static struct rnndomain *38finddom(struct rnn *rnn, uint32_t regbase)39{40if (rnndec_checkaddr(rnn->vc, rnn->dom[0], regbase, 0))41return rnn->dom[0];42return rnn->dom[1];43}4445void46_rnn_init(struct rnn *rnn, int nocolor)47{48rnn_init();4950rnn->db = rnn_newdb();51rnn->vc_nocolor = rnndec_newcontext(rnn->db);52rnn->vc_nocolor->colors = &envy_null_colors;53if (nocolor) {54rnn->vc = rnn->vc_nocolor;55} else {56rnn->vc = rnndec_newcontext(rnn->db);57rnn->vc->colors = &envy_def_colors;58}59}6061struct rnn *62rnn_new(int nocolor)63{64struct rnn *rnn = calloc(sizeof(*rnn), 1);6566if (!rnn)67return NULL;6869_rnn_init(rnn, nocolor);7071return rnn;72}7374static void75init(struct rnn *rnn, char *file, char *domain)76{77/* prepare rnn stuff for lookup */78rnn_parsefile(rnn->db, file);79rnn_prepdb(rnn->db);80rnn->dom[0] = rnn_finddomain(rnn->db, domain);81if ((strcmp(domain, "A2XX") == 0) || (strcmp(domain, "A3XX") == 0)) {82rnn->dom[1] = rnn_finddomain(rnn->db, "AXXX");83} else {84rnn->dom[1] = rnn->dom[0];85}86if (!rnn->dom[0] && rnn->dom[1]) {87fprintf(stderr, "Could not find domain %s in %s\n", domain, file);88}89rnn->variant = domain;9091rnndec_varadd(rnn->vc, "chip", domain);92if (rnn->vc != rnn->vc_nocolor)93rnndec_varadd(rnn->vc_nocolor, "chip", domain);94if (rnn->db->estatus)95errx(rnn->db->estatus, "failed to parse register database");96}9798void99rnn_load_file(struct rnn *rnn, char *file, char *domain)100{101init(rnn, file, domain);102}103104void105rnn_load(struct rnn *rnn, const char *gpuname)106{107if (strstr(gpuname, "a2")) {108init(rnn, "adreno/a2xx.xml", "A2XX");109} else if (strstr(gpuname, "a3")) {110init(rnn, "adreno/a3xx.xml", "A3XX");111} else if (strstr(gpuname, "a4")) {112init(rnn, "adreno/a4xx.xml", "A4XX");113} else if (strstr(gpuname, "a5")) {114init(rnn, "adreno/a5xx.xml", "A5XX");115} else if (strstr(gpuname, "a6")) {116init(rnn, "adreno/a6xx.xml", "A6XX");117}118}119120uint32_t121rnn_regbase(struct rnn *rnn, const char *name)122{123uint32_t regbase = rnndec_decodereg(rnn->vc_nocolor, rnn->dom[0], name);124if (!regbase)125regbase = rnndec_decodereg(rnn->vc_nocolor, rnn->dom[1], name);126return regbase;127}128129const char *130rnn_regname(struct rnn *rnn, uint32_t regbase, int color)131{132static char buf[128];133struct rnndecaddrinfo *info;134135info = rnndec_decodeaddr(color ? rnn->vc : rnn->vc_nocolor,136finddom(rnn, regbase), regbase, 0);137if (info) {138strcpy(buf, info->name);139free(info->name);140free(info);141return buf;142}143return NULL;144}145146struct rnndecaddrinfo *147rnn_reginfo(struct rnn *rnn, uint32_t regbase)148{149return rnndec_decodeaddr(rnn->vc, finddom(rnn, regbase), regbase, 0);150}151152const char *153rnn_enumname(struct rnn *rnn, const char *name, uint32_t val)154{155return rnndec_decode_enum(rnn->vc, name, val);156}157158static struct rnndelem *159regelem(struct rnndomain *domain, const char *name)160{161int i;162for (i = 0; i < domain->subelemsnum; i++) {163struct rnndelem *elem = domain->subelems[i];164if (!strcmp(elem->name, name))165return elem;166}167return NULL;168}169170/* Lookup rnndelem by name: */171struct rnndelem *172rnn_regelem(struct rnn *rnn, const char *name)173{174struct rnndelem *elem = regelem(rnn->dom[0], name);175if (elem)176return elem;177return regelem(rnn->dom[1], name);178}179180static struct rnndelem *181regoff(struct rnndomain *domain, uint32_t offset)182{183int i;184for (i = 0; i < domain->subelemsnum; i++) {185struct rnndelem *elem = domain->subelems[i];186if (elem->offset == offset)187return elem;188}189return NULL;190}191192/* Lookup rnndelem by offset: */193struct rnndelem *194rnn_regoff(struct rnn *rnn, uint32_t offset)195{196struct rnndelem *elem = regoff(rnn->dom[0], offset);197if (elem)198return elem;199return regoff(rnn->dom[1], offset);200}201202enum rnnttype203rnn_decodelem(struct rnn *rnn, struct rnntypeinfo *info, uint32_t regval,204union rnndecval *val)205{206val->u = regval;207switch (info->type) {208case RNN_TTYPE_INLINE_ENUM:209case RNN_TTYPE_ENUM:210case RNN_TTYPE_HEX:211case RNN_TTYPE_INT:212case RNN_TTYPE_UINT:213case RNN_TTYPE_FLOAT:214case RNN_TTYPE_BOOLEAN:215return info->type;216case RNN_TTYPE_FIXED:217case RNN_TTYPE_UFIXED:218/* TODO */219default:220return RNN_TTYPE_INVALID;221}222}223224225