static void dump_domain(uint32_t *dwords, uint32_t sizedwords, int level, const char *name) { struct rnndomain *dom; int i; init(); dom = rnn_finddomain(db, name); if (!dom) return; for (i = 0; i < sizedwords; i++) { struct rnndecaddrinfo *info = rnndec_decodeaddr(vc, dom, i, 0); char *decoded; if (!(info && info->typeinfo)) break; decoded = rnndec_decodeval(vc, info->typeinfo, dwords[i], info->width); printf("%s%s\n", levels[level], decoded); free(decoded); free(info->name); free(info); } }
void decode_tic(uint32_t tic, int idx, uint32_t *data) { struct rnndecaddrinfo *ai = rnndec_decodeaddr(g80_texture_ctx, tic_domain, idx * 4, 1); char *dec_addr = ai->name; char *dec_val = rnndec_decodeval(g80_texture_ctx, ai->typeinfo, data[idx], ai->width); fprintf(stdout, "TIC[%d]: 0x%08x %s = %s\n", tic, data[idx], dec_addr, dec_val); free(ai); free(dec_val); free(dec_addr); }
void decode_tsc(struct rnndeccontext *texture_ctx, uint32_t tsc, uint32_t *data) { int idx; for (idx = 0; idx < 8; idx++) { struct rnndecaddrinfo *ai = rnndec_decodeaddr(texture_ctx, tsc_domain, idx * 4, 1); char *dec_val = rnndec_decodeval(texture_ctx, ai->typeinfo, data[idx], ai->width); mmt_printf("TSC[%d]: 0x%08x %s = %s\n", tsc, data[idx], ai->name, dec_val); rnndec_free_decaddrinfo(ai); free(dec_val); } }
static void dump_register_val(uint32_t regbase, uint32_t dword, int level) { struct rnndecaddrinfo *info = rnndec_decodeaddr(vc, finddom(regbase), regbase, 0); if (info && info->typeinfo) { char *decoded = rnndec_decodeval(vc, info->typeinfo, dword, info->width); printf("%s%s: %s\n", levels[level], info->name, decoded); free(decoded); } else if (info) { printf("%s%s: %08x\n", levels[level], info->name, dword); } else { printf("%s<%04x>: %08x\n", levels[level], regbase, dword); } if (info) { free(info->name); free(info); } }
char *rnndec_decodeval(struct rnndeccontext *ctx, struct rnntypeinfo *ti, uint64_t value, int width) { char *res = 0; int i; struct rnnvalue **vals; int valsnum; struct rnnbitfield **bitfields; int bitfieldsnum; char *tmp; uint64_t mask; if (!ti) goto failhex; if (ti->shr) value <<= ti->shr; switch (ti->type) { case RNN_TTYPE_ENUM: vals = ti->eenum->vals; valsnum = ti->eenum->valsnum; goto doenum; case RNN_TTYPE_INLINE_ENUM: vals = ti->vals; valsnum = ti->valsnum; goto doenum; doenum: for (i = 0; i < valsnum; i++) if (rnndec_varmatch(ctx, &vals[i]->varinfo) && vals[i]->valvalid && vals[i]->value == value) { asprintf (&res, "%s%s%s", ctx->colors->eval, vals[i]->name, ctx->colors->reset); return res; } goto failhex; case RNN_TTYPE_BITSET: bitfields = ti->ebitset->bitfields; bitfieldsnum = ti->ebitset->bitfieldsnum; goto dobitset; case RNN_TTYPE_INLINE_BITSET: bitfields = ti->bitfields; bitfieldsnum = ti->bitfieldsnum; goto dobitset; dobitset: mask = 0; for (i = 0; i < bitfieldsnum; i++) { if (!rnndec_varmatch(ctx, &bitfields[i]->varinfo)) continue; uint64_t sval = (value & bitfields[i]->mask) >> bitfields[i]->low; mask |= bitfields[i]->mask; if (bitfields[i]->typeinfo.type == RNN_TTYPE_BOOLEAN) { if (sval == 0) continue; else if (sval == 1) { if (!res) asprintf (&res, "%s%s%s", ctx->colors->mod, bitfields[i]->name, ctx->colors->reset); else { asprintf (&tmp, "%s | %s%s%s", res, ctx->colors->mod, bitfields[i]->name, ctx->colors->reset); free(res); res = tmp; } continue; } } char *subval = rnndec_decodeval(ctx, &bitfields[i]->typeinfo, sval, bitfields[i]->high - bitfields[i]->low + 1); if (!res) asprintf (&res, "%s%s%s = %s", ctx->colors->rname, bitfields[i]->name, ctx->colors->reset, subval); else { asprintf (&tmp, "%s | %s%s%s = %s", res, ctx->colors->rname, bitfields[i]->name, ctx->colors->reset, subval); free(res); res = tmp; } free(subval); } if (value & ~mask) { if (!res) asprintf (&res, "%s%#"PRIx64"%s", ctx->colors->err, value & ~mask, ctx->colors->reset); else { asprintf (&tmp, "%s | %s%#"PRIx64"%s", res, ctx->colors->err, value & ~mask, ctx->colors->reset); free(res); res = tmp; } } if (!res) asprintf (&res, "%s0%s", ctx->colors->num, ctx->colors->reset); asprintf (&tmp, "{ %s }", res); free(res); return tmp; case RNN_TTYPE_SPECTYPE: return rnndec_decodeval(ctx, &ti->spectype->typeinfo, value, width); case RNN_TTYPE_HEX: asprintf (&res, "%s%#"PRIx64"%s", ctx->colors->num, value, ctx->colors->reset); return res; case RNN_TTYPE_UINT: asprintf (&res, "%s%"PRIu64"%s", ctx->colors->num, value, ctx->colors->reset); return res; case RNN_TTYPE_INT: if (value & UINT64_C(1) << (width-1)) asprintf (&res, "%s-%"PRIi64"%s", ctx->colors->num, (UINT64_C(1) << width) - value, ctx->colors->reset); else asprintf (&res, "%s%"PRIi64"%s", ctx->colors->num, value, ctx->colors->reset); return res; case RNN_TTYPE_BOOLEAN: if (value == 0) { asprintf (&res, "%sFALSE%s", ctx->colors->eval, ctx->colors->reset); return res; } else if (value == 1) { asprintf (&res, "%sTRUE%s", ctx->colors->eval, ctx->colors->reset); return res; } case RNN_TTYPE_FLOAT: { union { uint64_t i; float f; double d; } val; val.i = value; if (width == 64) asprintf(&res, "%s%f%s", ctx->colors->num, val.d, ctx->colors->reset); else if (width == 32) asprintf(&res, "%s%f%s", ctx->colors->num, val.f, ctx->colors->reset); else goto failhex; return res; } failhex: default: asprintf (&res, "%s%#"PRIx64"%s", ctx->colors->num, value, ctx->colors->reset); return res; break; } }
int main(int argc, char **argv) { char *file = "nv_mmio.xml"; char *name = "NV_MMIO"; char *variant = NULL; char c, mode = 'd'; uint64_t reg, colors=1, val = 0; struct rnndeccontext *vc; rnn_init(); if (argc < 2) { usage(); } struct rnndb *db = rnn_newdb(); /* Arguments parsing */ while ((c = getopt (argc, argv, "f:a:d:e:b:c")) != -1) { switch (c) { case 'f': file = strdup(optarg); break; case 'e': mode = 'e'; name = strdup(optarg); break; case 'b': mode = 'b'; name = strdup(optarg); break; case 'd': mode = 'd'; name = strdup(optarg); break; case 'a': if (!strncasecmp(optarg, "NV", 2)) variant = strdup(optarg); else asprintf(&variant, "NV%s", optarg); break; case 'c': colors = 0; break; default: usage(); } } rnn_parsefile (db, file); rnn_prepdb (db); vc = rnndec_newcontext(db); if(colors) vc->colors = &rnndec_colorsterm; if (variant) rnndec_varadd(vc, "chipset", variant); /* Parse extra arguments */ while (!strcmp (argv[optind], "-v")) { rnndec_varadd(vc, argv[optind+1], argv[optind+2]); optind+=3; } if (optind >= argc) { fprintf (stderr, "No address specified.\n"); return 1; } reg = strtoull(argv[optind], 0, 16); if (optind + 1 < argc) val = strtoull(argv[optind + 1], 0, 16); if (mode == 'e') { struct rnnenum *en = rnn_findenum (db, name); if (en) { int i; int dec = 0; for (i = 0; i < en->valsnum; i++) if (en->vals[i]->valvalid && en->vals[i]->value == reg) { printf ("%s\n", en->vals[i]->name); dec = 1; break; } if (!dec) printf ("%#"PRIx64"\n", reg); return 0; } else { fprintf(stderr, "Not an enum: '%s'\n", name); return 1; } } else if (mode == 'b') { struct rnnbitset *bs = rnn_findbitset (db, name); if (bs) { printf("TODO\n"); return 0; } else { fprintf(stderr, "Not a bitset: '%s'\n", name); return 1; } } else if (mode == 'd') { struct rnndomain *dom = rnn_finddomain (db, name); if (dom) { struct rnndecaddrinfo *info = rnndec_decodeaddr(vc, dom, reg, 0); if (info && info->typeinfo) printf ("%s => %s\n", info->name, rnndec_decodeval(vc, info->typeinfo, val, info->width)); else if (info) printf ("%s\n", info->name); else return 1; return 0; } else { fprintf(stderr, "Not a domain: '%s'\n", name); return 1; } } else { return 1; } }